Mercurial > ecos
annotate packages/net/common/current/src/tftp_server.c @ 957:db3e0a2fda2f
2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
* src/network_support.c (init_loopback_interface): Close the
socket when things go wrong otherwise we leak sockets.
* src/tftp_server.c (tftpd_server): Added support for IPv6 as well
as IPv4. Extended the multithreading support so that it works
correctly when there are multiple servers on multiple ports.
* doc/tcpip.sgml: Documentation for the changes made to the tftp
server.
2003-04-10 Andrew Lunn <andrew.lunn@ascom.ch>
* src/network_support.c (init_all_network_interfaces): Wait upto 4
seconds for a router solicit message to be received. Once we have
received the message we know we have a valid IPv6 address.
* src/tftp_client.c: Added support for IPv6. This requires two new
functions, tftp_client_{get|put} which are protocol version
independent.
* tests/tftp_client_test.c (tftp_test): Added tests which use IPv6
addresses.
2003-04-07 Andrew Lunn <andrew.lunn@ascom.ch>
* src/getaddrinfo.c (getaddrinfo): Correctly deal with node when
its not NULL. Its OK for the address to not parse for an address
family when AF_UNSPEC is passed in hints. Also get the socktype
correct when wildcarding for services that use UDP.
* tests/addr_test.c: Added more test cases which test IP addresses
in number format as node.
2003-04-05 Andrew Lunn <andrew.lunn@ascom.ch>
* cdl/net.cdl: Added addr_tests to the HW tests.
* tests/addr_test.c (net_test): void function not int.
* tests/ping_test.c (net_test): Added IPv6 ping test. This pings
the router which answers our router solicit message.
* src/ipv6_routing_thread.c (cyg_rs): Print out the router
advertisement message. Cleaned up the debug messages so they can
be disabled.
* src/ipv6_routing_thread.c (cyg_net_get_ipv6_advrouter): New
function to return the address of the router.
* include/network.h: Added prototype for above and
ipv6_start_routing_thread which did not have a prototype.
* src/ipv6_routing_thread.c (cyg_rs): Only wait 2 seconds before
sending the first solicit request rather than 10.
* src/dhcp_prot.c (do_dhcp_down_net): clear the if_laddrreq
before using it. If the request fails finish the IPv4 code rather
than returning,.
2003-04-02 Andrew Lunn <andrew.lunn@ascom.ch>
* tests/ping_lo_test.c: Added IPv6 ping test.
* src/getproto.c: Added the protocol ipv6-icmp.
| author | asl |
|---|---|
| date | Wed, 23 Apr 2003 08:52:08 +0000 |
| parents | 7c34839e7e97 |
| children | 16d247bb9c70 |
| rev | line source |
|---|---|
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
1 //========================================================================== |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
2 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
3 // lib/tftp_server.c |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
4 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
5 // TFTP server support |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
6 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
7 //========================================================================== |
|
490
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
8 //####ECOSGPLCOPYRIGHTBEGIN#### |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
9 // ------------------------------------------- |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
10 // This file is part of eCos, the Embedded Configurable Operating System. |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
| 957 | 12 // Copyright (C) 2003 Andrew Lunn |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
13 // |
|
490
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
14 // eCos is free software; you can redistribute it and/or modify it under |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
15 // the terms of the GNU General Public License as published by the Free |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
16 // Software Foundation; either version 2 or (at your option) any later version. |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
17 // |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
21 // for more details. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
22 // |
|
490
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
23 // You should have received a copy of the GNU General Public License along |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
24 // with eCos; if not, write to the Free Software Foundation, Inc., |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
26 // |
|
490
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
27 // As a special exception, if other files instantiate templates or use macros |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
28 // or inline functions from this file, or you compile this file and link it |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
29 // with other works to produce a work based on this file, this file does not |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
30 // by itself cause the resulting work to be covered by the GNU General Public |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
31 // License. However the source code for this file must still be made available |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
32 // in accordance with section (3) of the GNU General Public License. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
33 // |
|
490
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
34 // This exception does not invalidate any other reasons why a work based on |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
35 // this file might be covered by the GNU General Public License. |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
36 // |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
38 // at http://sources.redhat.com/ecos/ecos-license/ |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
39 // ------------------------------------------- |
|
7c34839e7e97
* src/bootp_support.c: Fix licence which should always have been
jlarmour
parents:
270
diff
changeset
|
40 //####ECOSGPLCOPYRIGHTEND#### |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
41 //========================================================================== |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
42 //#####DESCRIPTIONBEGIN#### |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
43 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
44 // Author(s): gthomas |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
45 // Contributors: gthomas, hmt, andrew.lunn@ascom.ch (Andrew Lunn) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
46 // Date: 2000-04-06 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
47 // Purpose: |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
48 // Description: |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
49 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
50 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
51 //####DESCRIPTIONEND#### |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
52 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
53 //========================================================================== |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
54 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
55 // TFTP server support |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
56 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
57 #include <network.h> // Basic networking support |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
58 #include <arpa/tftp.h> // TFTP protocol definitions |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
59 #include <tftp_support.h> // TFTPD structures |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
60 #include <cyg/kernel/kapi.h> |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
61 #include <stdlib.h> // For malloc |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
62 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
63 #define nCYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
64 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
65 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
66 struct subinfo { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
67 int rx; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
68 int rx_repeat; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
69 int rx_skip; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
70 int send; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
71 int resend; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
72 }; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
73 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
74 struct info { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
75 struct subinfo ack, data; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
76 int err_send; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
77 int total_transactions; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
78 }; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
79 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
80 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
81 static struct info tftp_server_instrument = { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
82 { 0,0,0,0,0 }, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
83 { 0,0,0,0,0 }, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
84 0, 0, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
85 }; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
86 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
87 #endif // CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
88 |
| 957 | 89 #ifdef CYGSEM_NET_TFTPD_MULTITHREADED |
| 90 struct tftpd_sem { | |
| 91 int port; | |
| 92 cyg_sem_t sem; | |
| 93 }; | |
| 94 | |
| 95 static struct tftpd_sem tftpd_sems[CYGNUM_NET_TFTPD_MULTITHREADED_PORTS]; | |
| 96 #endif //CYGSEM_NET_TFTPD_MULTITHREADED | |
| 97 | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
98 #define STACK_SIZE (((CYGNUM_HAL_STACK_SIZE_TYPICAL+(3*(SEGSIZE+sizeof(struct tftphdr)))) + CYGARC_ALIGNMENT-1) & ~(CYGARC_ALIGNMENT-1)) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
99 static char *TFTP_tag = "TFTPD"; |
| 957 | 100 #define CYGNUM_NET_MAX_INET_PROTOS 2 |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
101 struct tftp_server { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
102 char *tag; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
103 char stack[STACK_SIZE]; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
104 cyg_thread thread_data; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
105 cyg_handle_t thread_handle; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
106 int port; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
107 struct tftpd_fileops *ops; |
| 957 | 108 int s[CYGNUM_NET_MAX_INET_PROTOS], num_s; |
| 109 struct addrinfo *res; | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
110 }; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
111 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
112 static char * errmsg[] = { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
113 "Undefined error code", // 0 nothing defined |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
114 "File not found", // 1 TFTP_ENOTFOUND |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
115 "Access violation", // 2 TFTP_EACCESS |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
116 "Disk full or allocation exceeded", // 3 TFTP_ENOSPACE |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
117 "Illegal TFTP operation", // 4 TFTP_EBADOP |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
118 "Unknown transfer ID", // 5 TFTP_EBADID |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
119 "File already exists", // 6 TFTP_EEXISTS |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
120 "No such user", // 7 TFTP_ENOUSER |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
121 }; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
122 |
| 957 | 123 // Little helper function to set the port number in an address |
| 124 static void set_port(struct sockaddr * address, int port) { | |
| 125 | |
| 126 switch (address->sa_family) { | |
| 127 case AF_INET:{ | |
| 128 struct sockaddr_in *addr = (struct sockaddr_in *)address; | |
| 129 addr->sin_port = ntohs(port); | |
| 130 break; | |
| 131 } | |
| 132 #ifdef CYGPKG_NET_INET6 | |
| 133 case AF_INET6: | |
| 134 { | |
| 135 struct sockaddr_in6 *addr = (struct sockaddr_in6 *)address; | |
| 136 addr->sin6_port = ntohs(port); | |
| 137 break; | |
| 138 } | |
| 139 #endif | |
| 140 default: | |
| 141 break; | |
| 142 } | |
| 143 } | |
| 144 | |
| 145 #ifdef CYGSEM_NET_TFTPD_MULTITHREADED | |
| 146 | |
| 147 // Allocate a semaphore for a given port number if one is not already | |
| 148 // allocated. | |
| 149 static void sem_alloc(int port) { | |
| 150 int i; | |
| 151 | |
| 152 CYG_ASSERT(port != 0, "Invalid port number"); | |
| 153 | |
| 154 cyg_scheduler_lock(); // Avoid race with other tftpd's | |
| 155 for (i=0; i < CYGNUM_NET_TFTPD_MULTITHREADED_PORTS; i++) { | |
| 156 if (tftpd_sems[i].port == port) { | |
| 157 cyg_scheduler_unlock(); | |
| 158 return; | |
| 159 } | |
| 160 if (tftpd_sems[i].port == 0) { | |
| 161 tftpd_sems[i].port = port; | |
| 162 cyg_semaphore_init(&tftpd_sems[i].sem,1); | |
| 163 cyg_scheduler_unlock(); | |
| 164 return ; | |
| 165 } | |
| 166 } | |
| 167 cyg_scheduler_unlock(); | |
| 168 diag_printf("TFTPD: Unable to allocate a semaphore for port %d\n",port); | |
| 169 } | |
| 170 | |
| 171 // Wait on the semaphore for a given port number. | |
| 172 static void sem_wait(int port) { | |
| 173 int i; | |
| 174 CYG_ASSERT(port != 0, "Invalid port number"); | |
| 175 | |
| 176 for (i=0; i < CYGNUM_NET_TFTPD_MULTITHREADED_PORTS; i++) { | |
| 177 if (tftpd_sems[i].port == port) { | |
| 178 cyg_semaphore_wait(&tftpd_sems[i].sem); | |
| 179 return; | |
| 180 } | |
| 181 } | |
| 182 diag_printf("TFTPD: No semaphore for port %d\n",port); | |
| 183 } | |
| 184 | |
| 185 // Release the semaphore for a given port number. | |
| 186 static void sem_post(int port) { | |
| 187 int i; | |
| 188 CYG_ASSERT(port != 0, "Invalid port number"); | |
| 189 | |
| 190 for (i=0; i < CYGNUM_NET_TFTPD_MULTITHREADED_PORTS; i++) { | |
| 191 if (tftpd_sems[i].port == port) { | |
| 192 cyg_semaphore_post(&tftpd_sems[i].sem); | |
| 193 return; | |
| 194 } | |
| 195 } | |
| 196 diag_printf("TFTPD: No semaphore for port %d\n",port); | |
| 197 } | |
| 198 #endif | |
| 199 | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
200 /* Send an error packet to the client */ |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
201 static void |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
202 tftpd_send_error(int s, struct tftphdr * reply, int err, |
| 957 | 203 struct sockaddr *from_addr, int from_len) |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
204 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
205 CYG_ASSERT( 0 <= err, "err underflow" ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
206 CYG_ASSERT( sizeof(errmsg)/sizeof(errmsg[0]) > err, "err overflow" ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
207 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
208 reply->th_opcode = htons(ERROR); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
209 reply->th_code = htons(err); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
210 if ( (0 > err) || (sizeof(errmsg)/sizeof(errmsg[0]) <= err) ) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
211 err = 0; // Do not copy a random string from hyperspace |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
212 strcpy(reply->th_msg, errmsg[err]); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
213 sendto(s, reply, 4+strlen(reply->th_msg)+1, 0, |
| 957 | 214 from_addr, from_len); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
215 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
216 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
217 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
218 // Receive a file from the client |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
219 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
220 static void |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
221 tftpd_write_file(struct tftp_server *server, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
222 struct tftphdr *hdr, |
| 957 | 223 struct sockaddr *from_addr, int from_len) |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
224 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
225 char data_out[SEGSIZE+sizeof(struct tftphdr)]; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
226 char data_in[SEGSIZE+sizeof(struct tftphdr)]; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
227 struct tftphdr *reply = (struct tftphdr *)data_out; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
228 struct tftphdr *response = (struct tftphdr *)data_in; |
| 270 | 229 int fd, len, ok, tries, closed, data_len, s; |
| 230 unsigned short block; | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
231 struct timeval timeout; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
232 fd_set fds; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
233 int total_timeouts = 0; |
| 957 | 234 struct sockaddr client_addr; |
| 235 struct addrinfo hints; | |
| 236 struct addrinfo *res; | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
237 int client_len; |
| 957 | 238 int error; |
| 239 | |
| 240 memset(&hints,0,sizeof(hints)); | |
| 241 hints.ai_family = from_addr->sa_family; | |
| 242 hints.ai_flags = AI_PASSIVE; | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
243 |
| 957 | 244 error = getaddrinfo(NULL,"tftp",&hints, &res); |
| 245 if (0 != error) { | |
| 246 diag_printf("TFTPD: can't get a suitable local address: %s\n", | |
| 247 gai_strerror(error)); | |
| 248 return; | |
| 249 } | |
| 250 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
251 if (s < 0) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
252 diag_printf("TFTPD: can't open socket for 'write_file'\n"); |
| 957 | 253 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
254 return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
255 } |
| 957 | 256 |
| 257 // We want the stack to pick a free local port number | |
| 258 set_port(res->ai_addr,0); | |
| 259 | |
| 260 if (bind(s, res->ai_addr, res->ai_addrlen) < 0) { | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
261 // Problem setting up my end |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
262 diag_printf("TFTPD: can't bind to reply port for 'write_file'\n"); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
263 close(s); |
| 957 | 264 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
265 return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
266 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
267 if ((fd = (server->ops->open)(hdr->th_stuff, O_WRONLY)) < 0) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
268 tftpd_send_error(s,reply,TFTP_ENOTFOUND,from_addr, from_len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
269 close(s); |
| 957 | 270 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
271 return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
272 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
273 ok = true; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
274 closed = false; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
275 block = 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
276 while (ok) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
277 // Send ACK telling client he can send data |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
278 reply->th_opcode = htons(ACK); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
279 reply->th_block = htons(block++); // postincrement |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
280 for (tries = 0; tries < TFTP_RETRIES_MAX; tries++) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
281 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
282 tftp_server_instrument.ack.send++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
283 #endif |
| 957 | 284 sendto(s, reply, 4, 0, from_addr, from_len); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
285 repeat_select: |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
286 timeout.tv_sec = TFTP_TIMEOUT_PERIOD; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
287 timeout.tv_usec = 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
288 FD_ZERO(&fds); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
289 FD_SET(s, &fds); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
290 if (select(s+1, &fds, 0, 0, &timeout) <= 0) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
291 if (++total_timeouts > TFTP_TIMEOUT_MAX) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
292 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
293 tftp_server_instrument.err_send++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
294 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
295 tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
296 ok = false; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
297 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
298 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
299 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
300 tftp_server_instrument.ack.resend++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
301 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
302 continue; // retry the send, using up one retry. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
303 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
304 // Some data has arrived |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
305 data_len = sizeof(data_in); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
306 client_len = sizeof(client_addr); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
307 if ((data_len = recvfrom(s, data_in, data_len, 0, |
| 957 | 308 &client_addr, &client_len)) < 0) { |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
309 // What happened? No data here! |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
310 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
311 tftp_server_instrument.ack.resend++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
312 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
313 continue; // retry the send, using up one retry. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
314 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
315 if (ntohs(response->th_opcode) == DATA && |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
316 ntohs(response->th_block) < block) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
317 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
318 tftp_server_instrument.data.rx_repeat++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
319 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
320 // Then it is repeat DATA with an old block; listen again, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
321 // but do not repeat sending the current ack, and do not |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
322 // use up a retry count. (we do re-send the ack if |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
323 // subsequently we time out) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
324 goto repeat_select; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
325 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
326 if (ntohs(response->th_opcode) == DATA && |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
327 ntohs(response->th_block) == block) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
328 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
329 tftp_server_instrument.data.rx++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
330 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
331 // Good data - write to file |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
332 len = (server->ops->write)(fd, response->th_data, data_len-4); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
333 if (len < (data_len-4)) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
334 // File is "full" |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
335 tftpd_send_error(s,reply,TFTP_ENOSPACE, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
336 from_addr, from_len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
337 ok = false; // Give up |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
338 break; // out of the retries loop |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
339 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
340 if (data_len < (SEGSIZE+4)) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
341 // End of file |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
342 closed = true; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
343 ok = false; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
344 if ((server->ops->close)(fd) == -1) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
345 tftpd_send_error(s,reply,TFTP_EACCESS, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
346 from_addr, from_len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
347 break; // out of the retries loop |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
348 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
349 // Exception to the loop structure: we must ACK the last |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
350 // packet, the one that implied EOF: |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
351 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
352 tftp_server_instrument.ack.send++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
353 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
354 reply->th_opcode = htons(ACK); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
355 reply->th_block = htons(block++); // postincrement |
| 957 | 356 sendto(s, reply, 4, 0, from_addr, from_len); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
357 break; // out of the retries loop |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
358 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
359 // Happy! Break out of the retries loop. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
360 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
361 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
362 // Otherwise, we got something we do not understand! So repeat |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
363 // sending the current ACK, and use up a retry count. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
364 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
365 if ( (ntohs(response->th_opcode) == DATA) ) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
366 tftp_server_instrument.data.rx_skip++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
367 tftp_server_instrument.ack.resend++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
368 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
369 } // End of the retries loop. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
370 if (TFTP_RETRIES_MAX <= tries) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
371 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
372 tftp_server_instrument.err_send++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
373 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
374 tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
375 ok = false; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
376 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
377 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
378 close(s); |
| 957 | 379 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
380 if (!closed) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
381 (server->ops->close)(fd); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
382 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
383 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
384 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
385 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
386 // Send a file to the client |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
387 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
388 static void |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
389 tftpd_read_file(struct tftp_server *server, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
390 struct tftphdr *hdr, |
| 957 | 391 struct sockaddr *from_addr, int from_len) |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
392 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
393 char data_out[SEGSIZE+sizeof(struct tftphdr)]; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
394 char data_in[SEGSIZE+sizeof(struct tftphdr)]; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
395 struct tftphdr *reply = (struct tftphdr *)data_out; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
396 struct tftphdr *response = (struct tftphdr *)data_in; |
| 270 | 397 int fd, len, tries, ok, data_len, s; |
| 398 unsigned short block; | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
399 struct timeval timeout; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
400 fd_set fds; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
401 int total_timeouts = 0; |
| 957 | 402 struct sockaddr client_addr; |
| 403 struct addrinfo hints; | |
| 404 struct addrinfo *res; | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
405 int client_len; |
| 957 | 406 int error; |
| 407 | |
| 408 memset(&hints,0,sizeof(hints)); | |
| 409 hints.ai_family = from_addr->sa_family; | |
| 410 hints.ai_flags = AI_PASSIVE; | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
411 |
| 957 | 412 error = getaddrinfo(NULL,"tftp",&hints, &res); |
| 413 if (0 != error) { | |
| 414 diag_printf("TFTPD: can't get a suitable local address: %s\n", | |
| 415 gai_strerror(error)); | |
| 416 return; | |
| 417 } | |
| 418 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
419 if (s < 0) { |
| 957 | 420 diag_printf("TFTPD: can't open socket for 'write_file'\n"); |
| 421 freeaddrinfo(res); | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
422 return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
423 } |
| 957 | 424 |
| 425 // We want the stack to pick a free local port number | |
| 426 set_port(res->ai_addr,0); | |
| 427 | |
| 428 if (bind(s, res->ai_addr, res->ai_addrlen) < 0) { | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
429 // Problem setting up my end |
| 957 | 430 diag_printf("TFTPD: can't bind to reply port for 'write_file'\n"); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
431 close(s); |
| 957 | 432 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
433 return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
434 } |
| 957 | 435 |
| 436 if ((fd = (server->ops->open)(hdr->th_stuff, O_WRONLY)) < 0) { | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
437 tftpd_send_error(s,reply,TFTP_ENOTFOUND,from_addr, from_len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
438 close(s); |
| 957 | 439 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
440 return; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
441 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
442 block = 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
443 ok = true; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
444 while (ok) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
445 // Read next chunk of file |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
446 len = (server->ops->read)(fd, reply->th_data, SEGSIZE); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
447 reply->th_block = htons(++block); // preincrement |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
448 reply->th_opcode = htons(DATA); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
449 for (tries = 0; tries < TFTP_RETRIES_MAX; tries++) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
450 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
451 tftp_server_instrument.data.send++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
452 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
453 if (sendto(s, reply, 4+len, 0, |
| 957 | 454 from_addr, from_len) < 0) { |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
455 // Something went wrong with the network! |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
456 ok = false; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
457 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
458 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
459 repeat_select: |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
460 timeout.tv_sec = TFTP_TIMEOUT_PERIOD; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
461 timeout.tv_usec = 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
462 FD_ZERO(&fds); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
463 FD_SET(s, &fds); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
464 if (select(s+1, &fds, 0, 0, &timeout) <= 0) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
465 if (++total_timeouts > TFTP_TIMEOUT_MAX) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
466 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
467 tftp_server_instrument.err_send++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
468 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
469 tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
470 ok = false; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
471 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
472 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
473 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
474 tftp_server_instrument.data.resend++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
475 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
476 continue; // retry the send, using up one retry. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
477 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
478 data_len = sizeof(data_in); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
479 client_len = sizeof(client_addr); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
480 if ((data_len = recvfrom(s, data_in, data_len, 0, |
| 957 | 481 &client_addr, |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
482 &client_len)) < 0) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
483 // What happened? Maybe someone lied to us... |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
484 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
485 tftp_server_instrument.data.resend++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
486 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
487 continue; // retry the send, using up one retry. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
488 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
489 if ((ntohs(response->th_opcode) == ACK) && |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
490 (ntohs(response->th_block) < block)) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
491 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
492 tftp_server_instrument.ack.rx_repeat++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
493 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
494 // Then it is a repeat ACK for an old block; listen again, |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
495 // but do not repeat sending the current block, and do not |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
496 // use up a retry count. (we do re-send the data if |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
497 // subsequently we time out) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
498 goto repeat_select; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
499 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
500 if ((ntohs(response->th_opcode) == ACK) && |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
501 (ntohs(response->th_block) == block)) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
502 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
503 tftp_server_instrument.ack.rx++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
504 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
505 // Happy! Break out of the retries loop. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
506 break; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
507 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
508 // Otherwise, we got something we do not understand! So repeat |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
509 // sending the current block, and use up a retry count. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
510 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
511 if ( (ntohs(response->th_opcode) == ACK) ) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
512 tftp_server_instrument.ack.rx_skip++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
513 tftp_server_instrument.data.resend++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
514 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
515 } // End of the retries loop. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
516 if (TFTP_RETRIES_MAX <= tries) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
517 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
518 tftp_server_instrument.err_send++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
519 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
520 tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
521 ok = false; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
522 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
523 if (len < SEGSIZE) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
524 break; // That's end of file then. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
525 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
526 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
527 close(s); |
| 957 | 528 freeaddrinfo(res); |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
529 (server->ops->close)(fd); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
530 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
531 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
532 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
533 // Actual TFTP server |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
534 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
535 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
536 static void |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
537 tftpd_server(cyg_addrword_t p) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
538 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
539 struct tftp_server *server = (struct tftp_server *)p; |
| 957 | 540 int max_s = 0; |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
541 int data_len, recv_len, from_len; |
| 957 | 542 struct sockaddr from_addr; |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
543 char data[SEGSIZE+sizeof(struct tftphdr)]; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
544 struct tftphdr *hdr = (struct tftphdr *)data; |
| 957 | 545 struct addrinfo hints; |
| 546 struct addrinfo *ai; | |
| 547 fd_set readfds; | |
| 548 char name[64]; | |
| 549 int error; | |
| 550 int i; | |
| 551 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT | |
| 552 struct info o = tftp_server_instrument; | |
| 553 #endif | |
| 554 | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
555 #ifndef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
556 // Otherwise routine printfs fail the test - interrupts disabled too long. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
557 diag_printf("TFTPD [%x]: port %d\n", p, server->port); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
558 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
559 |
| 957 | 560 memset(&hints,0,sizeof(hints)); |
| 561 hints.ai_family = PF_UNSPEC; | |
| 562 hints.ai_flags = AI_PASSIVE; | |
| 563 | |
| 564 error = getaddrinfo(NULL,"tftp",&hints, &server->res); | |
| 565 if (0 != error) { | |
| 566 diag_printf("TFTPD [%p] : can't get a local server address to bind to: %s\n", | |
| 567 p, gai_strerror(error)); | |
| 568 return; | |
| 569 } | |
| 570 | |
| 571 // If the port is 0, we need to use the default TFTP port. Extrace | |
| 572 // the port number from one of the addresses returned by | |
| 573 // getaddrinfo. | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
574 if (server->port == 0) { |
| 957 | 575 switch (server->res->ai_family) { |
| 576 case AF_INET: | |
| 577 { | |
| 578 struct sockaddr_in *addr = (struct sockaddr_in *)server->res->ai_addr; | |
| 579 server->port = ntohs(addr->sin_port); | |
| 580 break; | |
| 581 } | |
| 582 #ifdef CYGPKG_NET_INET6 | |
| 583 case AF_INET6: | |
| 584 { | |
| 585 struct sockaddr_in6 *addr = (struct sockaddr_in6 *)server->res->ai_addr; | |
| 586 server->port = ntohs(addr->sin6_port); | |
| 587 break; | |
| 588 } | |
| 589 #endif | |
| 590 default: | |
| 591 break; | |
| 592 } | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
593 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
594 |
| 957 | 595 #ifdef CYGSEM_NET_TFTPD_MULTITHREADED |
| 596 sem_alloc(server->port); | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
597 while (true) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
598 #endif |
| 957 | 599 // Iterate over the addresses and create a local port to listen for requests |
| 600 ai = server->res; | |
| 601 memset(server->s,0,sizeof(server->s)); | |
| 602 server->num_s = 0; | |
| 603 while (ai && (server->num_s < CYGNUM_NET_MAX_INET_PROTOS)) { | |
| 604 server->s[server->num_s] = socket(ai->ai_family, | |
| 605 ai->ai_socktype, | |
| 606 ai->ai_protocol); | |
| 607 if (server->s[server->num_s] < 0 ) { | |
| 608 diag_printf("TFTPD [%x]: can't open socket\n", p); | |
| 609 freeaddrinfo(server->res); | |
| 610 server->res = NULL; | |
| 611 return; | |
| 612 } | |
| 613 | |
| 614 set_port(ai->ai_addr, server->port); | |
| 615 | |
| 616 #ifdef CYGSEM_NET_TFTPD_MULTITHREADED | |
| 617 sem_wait(server->port); | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
618 #endif |
| 957 | 619 if (bind(server->s[server->num_s],ai->ai_addr, ai->ai_addrlen) < 0) { |
| 620 // Problem setting up my end | |
| 621 diag_printf("TFTPD [%x]: can't bind to server port\n",p); | |
| 622 close(server->s[server->num_s]); | |
| 623 server->s[server->num_s] = 0; | |
| 624 ai = ai->ai_next; | |
| 625 continue; | |
| 626 } | |
| 627 // We need to know the highest socket number for select. | |
| 628 if (server->s[server->num_s] > max_s) | |
| 629 max_s = server->s[server->num_s]; | |
| 630 server->num_s++; | |
| 631 ai = ai->ai_next; | |
| 632 } | |
| 633 | |
| 634 #ifndef CYGSEM_NET_TFTPD_MULTITHREADED | |
| 635 while (true) { | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
636 #endif |
| 957 | 637 FD_ZERO(&readfds); |
| 638 for (i=0; i < CYGNUM_NET_MAX_INET_PROTOS; i++) { | |
| 639 if (server->s[i]) { | |
| 640 FD_SET(server->s[i],&readfds); | |
| 641 } | |
| 642 } | |
| 643 error = select(max_s+1,&readfds,NULL,NULL,NULL); | |
| 644 if ( -1 == error) { | |
| 645 diag_printf("TFTPD [%x]: error in select\n",p); | |
| 646 } | |
| 647 for (i=0; i < CYGNUM_NET_MAX_INET_PROTOS; i++) { | |
| 648 if (server->s[i] && FD_ISSET(server->s[i],&readfds)) { | |
| 649 recv_len = sizeof(data); | |
| 650 from_len = sizeof(from_addr); | |
| 651 data_len = recvfrom(server->s[i], hdr, recv_len, 0, | |
| 652 &from_addr, &from_len); | |
| 653 if ( data_len < 0) { | |
| 654 diag_printf("TFTPD [%x]: can't read request\n", p); | |
| 655 } else { | |
| 656 #ifdef CYGSEM_NET_TFTPD_MULTITHREADED | |
| 657 // Close the socket and post on the semaphore some | |
| 658 // another thread can start listening for requests. This | |
| 659 // is not quite right. select could of returned with more than | |
| 660 // one socket with data to read. Here we only deal with one of them | |
| 661 for (i=0; i < CYGNUM_NET_MAX_INET_PROTOS; i++) { | |
| 662 if (server->s[i]) { | |
| 663 close (server->s[i]); | |
| 664 server->s[i] = 0; | |
| 665 } | |
| 666 } | |
| 667 sem_post(server->port); | |
| 668 #endif | |
| 669 #ifndef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS | |
| 670 getnameinfo(&from_addr,sizeof(from_addr), name, sizeof(name),0,0,0); | |
| 671 diag_printf("TFTPD [%x]: received %x from %s\n", p, | |
| 672 ntohs(hdr->th_opcode), name); | |
| 673 #endif | |
| 674 switch (ntohs(hdr->th_opcode)) { | |
| 675 case WRQ: | |
| 676 tftpd_write_file(server, hdr, &from_addr, from_len); | |
| 677 break; | |
| 678 case RRQ: | |
| 679 tftpd_read_file(server, hdr, &from_addr, from_len); | |
| 680 break; | |
| 681 case ACK: | |
| 682 case DATA: | |
| 683 case ERROR: | |
| 684 // Ignore | |
| 685 break; | |
| 686 default: | |
| 687 getnameinfo(&from_addr,sizeof(from_addr), name, sizeof(name),0,0,0); | |
| 688 diag_printf("TFTPD [%x]: bogus request %x from %s\n", p, | |
| 689 ntohs(hdr->th_opcode), | |
| 690 name); | |
| 691 tftpd_send_error(server->s[i],hdr,TFTP_EBADOP,&from_addr,from_len); | |
| 692 } | |
| 693 | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
694 #ifdef CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
| 957 | 695 tftp_server_instrument.total_transactions++; |
| 696 | |
| 697 o.data.rx -= tftp_server_instrument.data.rx ; | |
| 698 o.data.rx_repeat -= tftp_server_instrument.data.rx_repeat; | |
| 699 o.data.rx_skip -= tftp_server_instrument.data.rx_skip ; | |
| 700 o.data.send -= tftp_server_instrument.data.send ; | |
| 701 o.data.resend -= tftp_server_instrument.data.resend ; | |
| 702 | |
| 703 o.ack.rx -= tftp_server_instrument.ack.rx ; | |
| 704 o.ack.rx_repeat -= tftp_server_instrument.ack.rx_repeat ; | |
| 705 o.ack.rx_skip -= tftp_server_instrument.ack.rx_skip ; | |
| 706 o.ack.send -= tftp_server_instrument.ack.send ; | |
| 707 o.ack.resend -= tftp_server_instrument.ack.resend ; | |
| 708 | |
| 709 o.err_send -= tftp_server_instrument.err_send ; | |
| 710 | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
711 #ifndef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS |
| 957 | 712 if ( o.data.rx ) diag_printf( "data rx %4d\n", -o.data.rx ); |
| 713 if ( o.data.rx_repeat ) diag_printf( "data rx_repeat%4d\n", -o.data.rx_repeat ); | |
| 714 if ( o.data.rx_skip ) diag_printf( "data rx_skip %4d\n", -o.data.rx_skip ); | |
| 715 if ( o.data.send ) diag_printf( "data send %4d\n", -o.data.send ); | |
| 716 if ( o.data.resend ) diag_printf( "data resend %4d\n", -o.data.resend ); | |
| 717 | |
| 718 if ( o.ack.rx ) diag_printf( " ack rx %4d\n", -o.ack.rx ); | |
| 719 if ( o.ack.rx_repeat ) diag_printf( " ack rx_repeat%4d\n", -o.ack.rx_repeat ); | |
| 720 if ( o.ack.rx_skip ) diag_printf( " ack rx_skip %4d\n", -o.ack.rx_skip ); | |
| 721 if ( o.ack.send ) diag_printf( " ack send %4d\n", -o.ack.send ); | |
| 722 if ( o.ack.resend ) diag_printf( " ack resend %4d\n", -o.ack.resend ); | |
| 723 | |
| 724 if ( o.err_send ) diag_printf( "*error sends %4d\n", -o.err_send ); | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
725 #endif // CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
726 #endif // CYGOPT_NET_TFTP_SERVER_INSTRUMENT |
| 957 | 727 #ifdef CYGSEM_NET_TFTPD_MULTITHREADED |
| 728 break; | |
| 729 #endif | |
| 730 } | |
| 731 } | |
| 732 } | |
| 733 // The following looks a little strange, but it keeps emacs's | |
| 734 // auto indention happy. | |
| 735 #ifndef CYGSEM_NET_TFTPD_MULTITHREADED | |
| 736 } | |
| 737 #endif | |
| 738 #ifdef CYGSEM_NET_TFTPD_MULTITHREADED | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
739 } |
| 957 | 740 #endif |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
741 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
742 |
| 957 | 743 |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
744 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
745 // This function is used to create a new server [thread] which supports |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
746 // the TFTP protocol on the given port. A server 'id' will be returned |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
747 // which can later be used to destroy the server. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
748 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
749 // Note: all [memory] resources for the server thread will be allocated |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
750 // dynamically. If there are insufficient resources, an error will be |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
751 // returned. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
752 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
753 int |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
754 tftpd_start(int port, struct tftpd_fileops *ops) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
755 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
756 struct tftp_server *server; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
757 #ifdef CYGSEM_TFTP_SERVER_MULTITHREADED |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
758 static char init = 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
759 if ( 0 == init ) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
760 init++; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
761 cyg_semaphore_init( &tftp_server_sem, 0 ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
762 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
763 #endif |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
764 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
765 if ((server = malloc(sizeof(struct tftp_server)))) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
766 server->tag = TFTP_tag; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
767 server->port = port; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
768 server->ops = ops; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
769 cyg_thread_create(CYGPKG_NET_TFTPD_THREAD_PRIORITY, // Priority |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
770 tftpd_server, // entry |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
771 (cyg_addrword_t)server, // entry parameter |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
772 "TFTP server", // Name |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
773 &server->stack[0], // Stack |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
774 STACK_SIZE, // Size |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
775 &server->thread_handle, // Handle |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
776 &server->thread_data // Thread data structure |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
777 ); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
778 cyg_thread_resume(server->thread_handle); // Start it |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
779 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
780 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
781 return (int)server; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
782 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
783 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
784 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
785 // Destroy a TFTP server, using a previously created server 'id'. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
786 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
787 int |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
788 tftpd_stop(int p) |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
789 { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
790 struct tftp_server *server = (struct tftp_server *)p; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
791 // Simple sanity check |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
792 if (server->tag == TFTP_tag) { |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
793 cyg_thread_kill(server->thread_handle); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
794 cyg_thread_set_priority(server->thread_handle, 0); |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
795 cyg_thread_delay(1); // Make sure it gets to die... |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
796 if (cyg_thread_delete(server->thread_handle)) { |
| 957 | 797 // Success shutting down the thread. Close all its sockets. |
| 798 int i; | |
| 799 for (i = 0 ; i < CYGNUM_NET_MAX_INET_PROTOS; i++) { | |
| 800 if (server->s[i]) { | |
| 801 close (server->s[i]); | |
| 802 } | |
| 803 } | |
| 804 freeaddrinfo(server->res); | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
805 free(server); // Give up memory |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
806 return 1; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
807 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
808 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
809 return 0; |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
810 } |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
811 |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff
changeset
|
812 // EOF tftp_server.c |
