Mercurial > ecos
annotate packages/net/tcpip/current/src/lib/tftp_server.c @ 132:0ae0bc38e387 ecos-sw-2000-10-31
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
| author | jlarmour |
|---|---|
| date | Tue, 31 Oct 2000 20:53:09 +0000 |
| parents | 0c2b7be0d798 |
| children | e2d866e32dac |
| rev | line source |
|---|---|
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
1 //========================================================================== |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
2 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
3 // lib/tftp_server.c |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
4 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
5 // TFTP server support |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
6 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
7 //========================================================================== |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
8 //####COPYRIGHTBEGIN#### |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
9 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
10 // ------------------------------------------- |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
11 // The contents of this file are subject to the Red Hat eCos Public License |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
12 // Version 1.1 (the "License"); you may not use this file except in |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
13 // compliance with the License. You may obtain a copy of the License at |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
14 // http://www.redhat.com/ |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
15 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
16 // Software distributed under the License is distributed on an "AS IS" |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
18 // License for the specific language governing rights and limitations under |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
19 // the License. |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
20 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
21 // The Original Code is eCos - Embedded Configurable Operating System, |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
22 // released September 30, 1998. |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
23 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
24 // The Initial Developer of the Original Code is Red Hat. |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
25 // Portions created by Red Hat are |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
26 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc. |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
27 // All Rights Reserved. |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
28 // ------------------------------------------- |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
29 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
30 //####COPYRIGHTEND#### |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
31 //####BSDCOPYRIGHTBEGIN#### |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
32 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
33 // ------------------------------------------- |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
34 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
35 // Portions of this software may have been derived from OpenBSD or other sources, |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
36 // and are covered by the appropriate copyright disclaimers included herein. |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
37 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
38 // ------------------------------------------- |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
39 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
40 //####BSDCOPYRIGHTEND#### |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
41 //========================================================================== |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
42 //#####DESCRIPTIONBEGIN#### |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
43 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
44 // Author(s): gthomas |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
112
diff
changeset
|
45 // Contributors: gthomas, hmt, andrew.lunn@ascom.ch (Andrew Lunn) |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
46 // Date: 2000-04-06 |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
47 // Purpose: |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
48 // Description: |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
49 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
50 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
51 //####DESCRIPTIONEND#### |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
52 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
53 //========================================================================== |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
54 |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
55 // TFTP server support |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
56 |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
57 #include <network.h> // Basic networking support |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
58 #include <arpa/tftp.h> // TFTP protocol definitions |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
59 #include <tftp_support.h> // TFTPD structures |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
60 #include <cyg/kernel/kapi.h> |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
61 #include <stdlib.h> // For malloc |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
62 |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
63 #define nCYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
64 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
65 |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
66 struct subinfo { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
67 int rx; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
68 int rx_repeat; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
69 int rx_skip; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
70 int send; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
71 int resend; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
72 }; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
73 |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
74 struct info { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
75 struct subinfo ack, data; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
76 int err_send; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
77 int total_transactions; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
78 }; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
79 |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
80 |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
81 static struct info tftp_server_instrument = { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
82 { 0,0,0,0,0 }, |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
83 { 0,0,0,0,0 }, |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
84 0, 0, |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
85 }; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
86 |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
87 #endif // CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
88 |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
89 #define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL+(3*(SEGSIZE+sizeof(struct tftphdr)))) |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
90 static char *TFTP_tag = "TFTPD"; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
91 struct tftp_server { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
92 char *tag; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
93 char stack[STACK_SIZE]; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
94 cyg_thread thread_data; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
95 cyg_handle_t thread_handle; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
96 int port; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
97 struct tftpd_fileops *ops; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
98 }; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
99 |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
112
diff
changeset
|
100 static char * errmsg[] = { |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
101 "Undefined error code", // 0 nothing defined |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
102 "File not found", // 1 TFTP_ENOTFOUND |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
103 "Access violation", // 2 TFTP_EACCESS |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
104 "Disk full or allocation exceeded", // 3 TFTP_ENOSPACE |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
105 "Illegal TFTP operation", // 4 TFTP_EBADOP |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
106 "Unknown transfer ID", // 5 TFTP_EBADID |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
107 "File already exists", // 6 TFTP_EEXISTS |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
108 "No such user", // 7 TFTP_ENOUSER |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
112
diff
changeset
|
109 }; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
112
diff
changeset
|
110 |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
111 /* Send an error packet to the client */ |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
112 static void |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
113 tftpd_send_error(int s, struct tftphdr * reply, int err, |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
114 struct sockaddr_in *from_addr, int from_len) |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
115 { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
116 CYG_ASSERT( 0 <= err, "err underflow" ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
117 CYG_ASSERT( sizeof(errmsg)/sizeof(errmsg[0]) > err, "err overflow" ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
118 |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
119 reply->th_opcode = htons(ERROR); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
120 reply->th_code = htons(err); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
121 if ( (0 > err) || (sizeof(errmsg)/sizeof(errmsg[0]) <= err) ) |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
122 err = 0; // Do not copy a random string from hyperspace |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
123 strcpy(reply->th_msg, errmsg[err]); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
124 sendto(s, reply, 4+strlen(reply->th_msg)+1, 0, |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
125 (struct sockaddr *)from_addr, from_len); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
126 } |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
112
diff
changeset
|
127 |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
128 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
129 // Receive a file from the client |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
130 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
131 static void |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
132 tftpd_write_file(struct tftp_server *server, |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
133 struct tftphdr *hdr, |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
134 struct sockaddr_in *from_addr, int from_len) |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
135 { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
136 char data_out[SEGSIZE+sizeof(struct tftphdr)]; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
137 char data_in[SEGSIZE+sizeof(struct tftphdr)]; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
138 struct tftphdr *reply = (struct tftphdr *)data_out; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
139 struct tftphdr *response = (struct tftphdr *)data_in; |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
140 int fd, block, len, ok, tries, closed, data_len, s; |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
141 struct timeval timeout; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
142 fd_set fds; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
143 int total_timeouts = 0; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
144 struct sockaddr_in client_addr, local_addr; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
145 int client_len; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
146 |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
147 s = socket(AF_INET, SOCK_DGRAM, 0); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
148 if (s < 0) { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
149 diag_printf("TFTPD: can't open socket for 'write_file'\n"); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
150 return; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
151 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
152 memset((char *)&local_addr, 0, sizeof(local_addr)); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
153 local_addr.sin_family = AF_INET; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
154 local_addr.sin_addr.s_addr = htonl(INADDR_ANY); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
155 local_addr.sin_port = htons(INADDR_ANY); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
156 if (bind(s, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
157 // Problem setting up my end |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
158 diag_printf("TFTPD: can't bind to reply port for 'write_file'\n"); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
159 close(s); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
160 return; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
161 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
162 if ((fd = (server->ops->open)(hdr->th_stuff, O_WRONLY)) < 0) { |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
163 tftpd_send_error(s,reply,TFTP_ENOTFOUND,from_addr, from_len); |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
164 close(s); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
165 return; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
166 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
167 ok = true; |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
112
diff
changeset
|
168 closed = false; |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
169 block = 0; |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
170 while (ok) { |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
171 // Send ACK telling client he can send data |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
172 reply->th_opcode = htons(ACK); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
173 reply->th_block = htons(block++); // postincrement |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
174 for (tries = 0; tries < TFTP_RETRIES_MAX; tries++) { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
175 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
176 tftp_server_instrument.ack.send++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
177 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
178 sendto(s, reply, 4, 0, (struct sockaddr *)from_addr, from_len); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
179 repeat_select: |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
180 timeout.tv_sec = TFTP_TIMEOUT_PERIOD; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
181 timeout.tv_usec = 0; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
182 FD_ZERO(&fds); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
183 FD_SET(s, &fds); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
184 if (select(s+1, &fds, 0, 0, &timeout) <= 0) { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
185 if (++total_timeouts > TFTP_TIMEOUT_MAX) { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
186 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
187 tftp_server_instrument.err_send++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
188 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
189 tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
190 ok = false; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
191 break; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
192 } |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
193 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
194 tftp_server_instrument.ack.resend++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
195 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
196 continue; // retry the send, using up one retry. |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
197 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
198 // Some data has arrived |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
199 data_len = sizeof(data_in); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
200 client_len = sizeof(client_addr); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
201 if ((data_len = recvfrom(s, data_in, data_len, 0, |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
202 (struct sockaddr *)&client_addr, &client_len)) < 0) { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
203 // What happened? No data here! |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
204 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
205 tftp_server_instrument.ack.resend++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
206 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
207 continue; // retry the send, using up one retry. |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
208 } |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
209 if (ntohs(response->th_opcode) == DATA && |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
210 ntohs(response->th_block) < block) { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
211 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
212 tftp_server_instrument.data.rx_repeat++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
213 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
214 // Then it is repeat DATA with an old block; listen again, |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
215 // but do not repeat sending the current ack, and do not |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
216 // use up a retry count. (we do re-send the ack if |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
217 // subsequently we time out) |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
218 goto repeat_select; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
219 } |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
220 if (ntohs(response->th_opcode) == DATA && |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
221 ntohs(response->th_block) == block) { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
222 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
223 tftp_server_instrument.data.rx++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
224 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
225 // Good data - write to file |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
226 len = (server->ops->write)(fd, response->th_data, data_len-4); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
227 if (len < (data_len-4)) { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
228 // File is "full" |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
229 tftpd_send_error(s,reply,TFTP_ENOSPACE, |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
230 from_addr, from_len); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
231 ok = false; // Give up |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
232 break; // out of the retries loop |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
233 } |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
234 if (data_len < (SEGSIZE+4)) { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
235 // End of file |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
236 closed = true; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
237 ok = false; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
238 if ((server->ops->close)(fd) == -1) { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
239 tftpd_send_error(s,reply,TFTP_EACCESS, |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
240 from_addr, from_len); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
241 break; // out of the retries loop |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
242 } |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
243 // Exception to the loop structure: we must ACK the last |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
244 // packet, the one that implied EOF: |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
245 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
246 tftp_server_instrument.ack.send++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
247 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
248 reply->th_opcode = htons(ACK); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
249 reply->th_block = htons(block++); // postincrement |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
250 sendto(s, reply, 4, 0, (struct sockaddr *)from_addr, from_len); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
251 break; // out of the retries loop |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
252 } |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
253 // Happy! Break out of the retries loop. |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
254 break; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
255 } |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
256 // Otherwise, we got something we do not understand! So repeat |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
257 // sending the current ACK, and use up a retry count. |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
258 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
259 if ( (ntohs(response->th_opcode) == DATA) ) |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
260 tftp_server_instrument.data.rx_skip++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
261 tftp_server_instrument.ack.resend++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
262 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
263 } // End of the retries loop. |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
264 if (TFTP_RETRIES_MAX <= tries) { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
265 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
266 tftp_server_instrument.err_send++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
267 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
268 tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
269 ok = false; |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
270 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
271 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
272 close(s); |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
112
diff
changeset
|
273 if (!closed) { |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
112
diff
changeset
|
274 (server->ops->close)(fd); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
112
diff
changeset
|
275 } |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
276 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
277 |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
278 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
279 // Send a file to the client |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
280 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
281 static void |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
282 tftpd_read_file(struct tftp_server *server, |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
283 struct tftphdr *hdr, |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
284 struct sockaddr_in *from_addr, int from_len) |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
285 { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
286 char data_out[SEGSIZE+sizeof(struct tftphdr)]; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
287 char data_in[SEGSIZE+sizeof(struct tftphdr)]; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
288 struct tftphdr *reply = (struct tftphdr *)data_out; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
289 struct tftphdr *response = (struct tftphdr *)data_in; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
290 int fd, block, len, tries, ok, data_len, s; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
291 struct timeval timeout; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
292 fd_set fds; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
293 int total_timeouts = 0; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
294 struct sockaddr_in client_addr, local_addr; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
295 int client_len; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
296 |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
297 s = socket(AF_INET, SOCK_DGRAM, 0); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
298 if (s < 0) { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
299 diag_printf("TFTPD: can't open socket for 'read_file'\n"); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
300 return; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
301 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
302 memset((char *)&local_addr, 0, sizeof(local_addr)); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
303 local_addr.sin_family = AF_INET; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
304 local_addr.sin_addr.s_addr = htonl(INADDR_ANY); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
305 local_addr.sin_port = htons(INADDR_ANY); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
306 if (bind(s, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
307 // Problem setting up my end |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
308 diag_printf("TFTPD: can't bind to reply port for 'read_file'\n"); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
309 close(s); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
310 return; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
311 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
312 if ((fd = (server->ops->open)(hdr->th_stuff, O_RDONLY)) < 0) { |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
313 tftpd_send_error(s,reply,TFTP_ENOTFOUND,from_addr, from_len); |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
314 close(s); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
315 return; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
316 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
317 block = 0; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
318 ok = true; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
319 while (ok) { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
320 // Read next chunk of file |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
321 len = (server->ops->read)(fd, reply->th_data, SEGSIZE); |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
322 reply->th_block = htons(++block); // preincrement |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
323 reply->th_opcode = htons(DATA); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
324 for (tries = 0; tries < TFTP_RETRIES_MAX; tries++) { |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
325 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
326 tftp_server_instrument.data.send++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
327 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
328 if (sendto(s, reply, 4+len, 0, |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
329 (struct sockaddr *)from_addr, from_len) < 0) { |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
330 // Something went wrong with the network! |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
331 ok = false; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
332 break; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
333 } |
|
112
02ea4320376c
Merge from eCos master repository on 2000-07-21-21:01:39-BST
jlarmour
parents:
97
diff
changeset
|
334 repeat_select: |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
335 timeout.tv_sec = TFTP_TIMEOUT_PERIOD; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
336 timeout.tv_usec = 0; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
337 FD_ZERO(&fds); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
338 FD_SET(s, &fds); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
339 if (select(s+1, &fds, 0, 0, &timeout) <= 0) { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
340 if (++total_timeouts > TFTP_TIMEOUT_MAX) { |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
341 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
342 tftp_server_instrument.err_send++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
343 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
344 tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len); |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
345 ok = false; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
346 break; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
347 } |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
348 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
349 tftp_server_instrument.data.resend++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
350 #endif |
|
112
02ea4320376c
Merge from eCos master repository on 2000-07-21-21:01:39-BST
jlarmour
parents:
97
diff
changeset
|
351 continue; // retry the send, using up one retry. |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
352 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
353 data_len = sizeof(data_in); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
354 client_len = sizeof(client_addr); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
355 if ((data_len = recvfrom(s, data_in, data_len, 0, |
|
112
02ea4320376c
Merge from eCos master repository on 2000-07-21-21:01:39-BST
jlarmour
parents:
97
diff
changeset
|
356 (struct sockaddr *)&client_addr, |
|
02ea4320376c
Merge from eCos master repository on 2000-07-21-21:01:39-BST
jlarmour
parents:
97
diff
changeset
|
357 &client_len)) < 0) { |
|
02ea4320376c
Merge from eCos master repository on 2000-07-21-21:01:39-BST
jlarmour
parents:
97
diff
changeset
|
358 // What happened? Maybe someone lied to us... |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
359 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
360 tftp_server_instrument.data.resend++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
361 #endif |
|
112
02ea4320376c
Merge from eCos master repository on 2000-07-21-21:01:39-BST
jlarmour
parents:
97
diff
changeset
|
362 continue; // retry the send, using up one retry. |
|
02ea4320376c
Merge from eCos master repository on 2000-07-21-21:01:39-BST
jlarmour
parents:
97
diff
changeset
|
363 } |
|
02ea4320376c
Merge from eCos master repository on 2000-07-21-21:01:39-BST
jlarmour
parents:
97
diff
changeset
|
364 if ((ntohs(response->th_opcode) == ACK) && |
|
02ea4320376c
Merge from eCos master repository on 2000-07-21-21:01:39-BST
jlarmour
parents:
97
diff
changeset
|
365 (ntohs(response->th_block) < block)) { |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
366 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
367 tftp_server_instrument.ack.rx_repeat++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
368 #endif |
|
112
02ea4320376c
Merge from eCos master repository on 2000-07-21-21:01:39-BST
jlarmour
parents:
97
diff
changeset
|
369 // Then it is a repeat ACK for an old block; listen again, |
|
02ea4320376c
Merge from eCos master repository on 2000-07-21-21:01:39-BST
jlarmour
parents:
97
diff
changeset
|
370 // but do not repeat sending the current block, and do not |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
371 // use up a retry count. (we do re-send the data if |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
372 // subsequently we time out) |
|
112
02ea4320376c
Merge from eCos master repository on 2000-07-21-21:01:39-BST
jlarmour
parents:
97
diff
changeset
|
373 goto repeat_select; |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
374 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
375 if ((ntohs(response->th_opcode) == ACK) && |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
376 (ntohs(response->th_block) == block)) { |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
377 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
378 tftp_server_instrument.ack.rx++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
379 #endif |
|
112
02ea4320376c
Merge from eCos master repository on 2000-07-21-21:01:39-BST
jlarmour
parents:
97
diff
changeset
|
380 // Happy! Break out of the retries loop. |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
381 break; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
382 } |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
383 // Otherwise, we got something we do not understand! So repeat |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
384 // sending the current block, and use up a retry count. |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
385 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
386 if ( (ntohs(response->th_opcode) == ACK) ) |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
387 tftp_server_instrument.ack.rx_skip++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
388 tftp_server_instrument.data.resend++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
389 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
390 } // End of the retries loop. |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
391 if (TFTP_RETRIES_MAX <= tries) { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
392 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
393 tftp_server_instrument.err_send++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
394 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
395 tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
396 ok = false; |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
397 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
398 if (len < SEGSIZE) { |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
399 break; // That's end of file then. |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
400 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
401 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
402 close(s); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
403 (server->ops->close)(fd); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
404 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
405 |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
406 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
407 // Actual TFTP server |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
408 // |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
409 #define CYGSEM_TFTP_SERVER_MULTITHREADED |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
410 #ifdef CYGSEM_TFTP_SERVER_MULTITHREADED |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
411 static cyg_sem_t tftp_server_sem; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
412 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
413 |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
414 static void |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
415 tftpd_server(cyg_addrword_t p) |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
416 { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
417 struct tftp_server *server = (struct tftp_server *)p; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
418 int s; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
419 int data_len, recv_len, from_len; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
420 struct sockaddr_in local_addr, from_addr; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
421 struct servent *server_info; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
422 char data[SEGSIZE+sizeof(struct tftphdr)]; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
423 struct tftphdr *hdr = (struct tftphdr *)data; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
424 |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
425 #ifndef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS |
|
132
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
128
diff
changeset
|
426 #ifndef CYGPKG_NET_AUTOTEST // cut the chatter if automated testing |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
427 // Otherwise routine printfs fail the test - interrupts disabled too long. |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
428 diag_printf("TFTPD [%x]: port %d\n", p, server->port); |
|
132
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
128
diff
changeset
|
429 #endif // !CYGPKG_NET_AUTOTEST |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
430 #endif |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
431 |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
432 // Set up port |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
433 if (server->port == 0) { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
434 server_info = getservbyname("tftp", "udp"); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
435 if (server_info == (struct servent *)0) { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
436 diag_printf("TFTPD: can't get TFTP service information\n"); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
437 return; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
438 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
439 server->port = server_info->s_port; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
440 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
441 |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
442 while (true) { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
443 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
444 struct info o = tftp_server_instrument; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
445 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
446 // Create socket |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
447 s = socket(AF_INET, SOCK_DGRAM, 0); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
448 if (s < 0) { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
449 diag_printf("TFTPD [%x]: can't open socket\n", p); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
450 return; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
451 } |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
452 memset((char *)&local_addr, 0, sizeof(local_addr)); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
453 local_addr.sin_family = AF_INET; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
454 local_addr.sin_addr.s_addr = htonl(INADDR_ANY); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
455 local_addr.sin_port = htons(server->port); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
456 if (bind(s, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
457 // Problem setting up my end |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
458 close(s); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
459 #ifdef CYGSEM_TFTP_SERVER_MULTITHREADED |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
460 #ifndef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS |
|
132
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
128
diff
changeset
|
461 #ifndef CYGPKG_NET_AUTOTEST // cut the chatter if automated testing |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
462 diag_printf("TFTPD [%x]: waiting to bind to service port\n", p); |
|
132
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
128
diff
changeset
|
463 #endif // !CYGPKG_NET_AUTOTEST |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
464 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
465 // Wait until the socket is free... |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
466 cyg_semaphore_wait( &tftp_server_sem ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
467 continue; // try re-opening and rebinding the socket. |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
468 #else |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
469 diag_printf("TFTPD [%x]: can't bind to service port\n", p); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
470 return; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
471 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
472 } |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
473 |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
474 recv_len = sizeof(data); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
475 from_len = sizeof(from_addr); |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
476 data_len = recvfrom(s, hdr, recv_len, 0, |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
477 (struct sockaddr *)&from_addr, &from_len); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
478 close(s); // so that other servers can bind to the TFTP socket |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
479 #ifdef CYGSEM_TFTP_SERVER_MULTITHREADED |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
480 // The socket is free... |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
481 cyg_semaphore_post( &tftp_server_sem ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
482 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
483 |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
484 if ( data_len < 0) { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
485 diag_printf("TFTPD [%x]: can't read request\n", p); |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
486 } else { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
487 #ifndef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS |
|
132
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
128
diff
changeset
|
488 #ifndef CYGPKG_NET_AUTOTEST // cut the chatter if automated testing |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
489 diag_printf("TFTPD [%x]: received %x from %s:%d\n", p, |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
490 ntohs(hdr->th_opcode), inet_ntoa(from_addr.sin_addr), |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
491 from_addr.sin_port); |
|
132
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
128
diff
changeset
|
492 #endif // !CYGPKG_NET_AUTOTEST |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
493 #endif |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
494 switch (ntohs(hdr->th_opcode)) { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
495 case WRQ: |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
496 tftpd_write_file(server, hdr, &from_addr, from_len); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
497 break; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
498 case RRQ: |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
499 tftpd_read_file(server, hdr, &from_addr, from_len); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
500 break; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
501 case ACK: |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
502 case DATA: |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
503 case ERROR: |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
504 // Ignore |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
505 break; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
506 default: |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
507 diag_printf("TFTPD [%x]: bogus request %x from %s:%d\n", p, |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
508 ntohs(hdr->th_opcode), |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
509 inet_ntoa(from_addr.sin_addr), |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
510 from_addr.sin_port ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
511 tftpd_send_error(s,hdr,TFTP_EBADOP,&from_addr,from_len); |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
512 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
513 } |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
514 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
515 tftp_server_instrument.total_transactions++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
516 |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
517 o.data.rx -= tftp_server_instrument.data.rx ; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
518 o.data.rx_repeat -= tftp_server_instrument.data.rx_repeat; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
519 o.data.rx_skip -= tftp_server_instrument.data.rx_skip ; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
520 o.data.send -= tftp_server_instrument.data.send ; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
521 o.data.resend -= tftp_server_instrument.data.resend ; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
522 |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
523 o.ack.rx -= tftp_server_instrument.ack.rx ; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
524 o.ack.rx_repeat -= tftp_server_instrument.ack.rx_repeat ; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
525 o.ack.rx_skip -= tftp_server_instrument.ack.rx_skip ; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
526 o.ack.send -= tftp_server_instrument.ack.send ; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
527 o.ack.resend -= tftp_server_instrument.ack.resend ; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
528 |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
529 o.err_send -= tftp_server_instrument.err_send ; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
530 |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
531 #ifndef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
532 if ( o.data.rx ) diag_printf( "data rx %4d\n", -o.data.rx ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
533 if ( o.data.rx_repeat ) diag_printf( "data rx_repeat%4d\n", -o.data.rx_repeat ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
534 if ( o.data.rx_skip ) diag_printf( "data rx_skip %4d\n", -o.data.rx_skip ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
535 if ( o.data.send ) diag_printf( "data send %4d\n", -o.data.send ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
536 if ( o.data.resend ) diag_printf( "data resend %4d\n", -o.data.resend ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
537 |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
538 if ( o.ack.rx ) diag_printf( " ack rx %4d\n", -o.ack.rx ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
539 if ( o.ack.rx_repeat ) diag_printf( " ack rx_repeat%4d\n", -o.ack.rx_repeat ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
540 if ( o.ack.rx_skip ) diag_printf( " ack rx_skip %4d\n", -o.ack.rx_skip ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
541 if ( o.ack.send ) diag_printf( " ack send %4d\n", -o.ack.send ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
542 if ( o.ack.resend ) diag_printf( " ack resend %4d\n", -o.ack.resend ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
543 |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
544 if ( o.err_send ) diag_printf( "*error sends %4d\n", -o.err_send ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
545 #endif // CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
546 #endif // CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
547 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
548 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
549 |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
550 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
551 // This function is used to create a new server [thread] which supports |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
552 // the TFTP protocol on the given port. A server 'id' will be returned |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
553 // which can later be used to destroy the server. |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
554 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
555 // Note: all [memory] resources for the server thread will be allocated |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
556 // dynamically. If there are insufficient resources, an error will be |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
557 // returned. |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
558 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
559 int |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
560 tftpd_start(int port, struct tftpd_fileops *ops) |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
561 { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
562 struct tftp_server *server; |
|
128
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
563 #ifdef CYGSEM_TFTP_SERVER_MULTITHREADED |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
564 static char init = 0; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
565 if ( 0 == init ) { |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
566 init++; |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
567 cyg_semaphore_init( &tftp_server_sem, 0 ); |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
568 } |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
569 #endif |
|
0c2b7be0d798
Merge from eCos master repository on 2000-10-12-08:46:24-BST
jlarmour
parents:
115
diff
changeset
|
570 |
|
97
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
571 if ((server = malloc(sizeof(struct tftp_server)))) { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
572 server->tag = TFTP_tag; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
573 server->port = port; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
574 server->ops = ops; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
575 cyg_thread_create(CYGPKG_NET_TFTPD_THREAD_PRIORITY, // Priority |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
576 tftpd_server, // entry |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
577 (cyg_addrword_t)server, // entry parameter |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
578 "TFTP server", // Name |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
579 &server->stack[0], // Stack |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
580 STACK_SIZE, // Size |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
581 &server->thread_handle, // Handle |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
582 &server->thread_data // Thread data structure |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
583 ); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
584 cyg_thread_resume(server->thread_handle); // Start it |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
585 |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
586 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
587 return (int)server; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
588 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
589 |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
590 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
591 // Destroy a TFTP server, using a previously created server 'id'. |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
592 // |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
593 int |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
594 tftpd_stop(int p) |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
595 { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
596 struct tftp_server *server = (struct tftp_server *)p; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
597 // Simple sanity check |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
598 if (server->tag == TFTP_tag) { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
599 cyg_thread_kill(server->thread_handle); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
600 cyg_thread_set_priority(server->thread_handle, 0); |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
601 cyg_thread_delay(1); // Make sure it gets to die... |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
602 if (cyg_thread_delete(server->thread_handle)) { |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
603 // Success shutting down the thread |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
604 free(server); // Give up memory |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
605 return 1; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
606 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
607 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
608 return 0; |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
609 } |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
610 |
|
ced4577552cd
Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff
changeset
|
611 // EOF tftp_server.c |
