annotate packages/net/common/current/src/dhcp_prot.c @ 1505:f2168dd5be4e

Initialize bp_secs field for stubborn DHCP servers - from Matt Jerdonek
author gthomas
date Thu, 19 Feb 2004 10:42:00 +0000
parents 69a4719c04ad
children cbea1375c6da
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 // dhcp_prot.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 // DHCP protocol implementation for DHCP client
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: 253
diff changeset
8 //####ECOSGPLCOPYRIGHTBEGIN####
7c34839e7e97 * src/bootp_support.c: Fix licence which should always have been
jlarmour
parents: 253
diff changeset
9 // -------------------------------------------
7c34839e7e97 * src/bootp_support.c: Fix licence which should always have been
jlarmour
parents: 253
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: 253
diff changeset
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
957
db3e0a2fda2f 2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
asl
parents: 897
diff changeset
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: 253
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: 253
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: 253
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: 253
diff changeset
17 //
7c34839e7e97 * src/bootp_support.c: Fix licence which should always have been
jlarmour
parents: 253
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: 253
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: 253
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: 253
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: 253
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: 253
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: 253
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: 253
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: 253
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: 253
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: 253
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: 253
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: 253
diff changeset
32 // in accordance with section (3) of the GNU General Public License.
7c34839e7e97 * src/bootp_support.c: Fix licence which should always have been
jlarmour
parents: 253
diff changeset
33 //
7c34839e7e97 * src/bootp_support.c: Fix licence which should always have been
jlarmour
parents: 253
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: 253
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: 253
diff changeset
36 //
7c34839e7e97 * src/bootp_support.c: Fix licence which should always have been
jlarmour
parents: 253
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: 253
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: 253
diff changeset
39 // -------------------------------------------
7c34839e7e97 * src/bootp_support.c: Fix licence which should always have been
jlarmour
parents: 253
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): hmt
957
db3e0a2fda2f 2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
asl
parents: 897
diff changeset
45 // Contributors: gthomas, andrew.lunn@ascom.ch
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
46 // Date: 2000-07-01
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
47 // Purpose: DHCP support
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 //####DESCRIPTIONEND####
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
51 //
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 #include <pkgconf/system.h>
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
55 #include <pkgconf/net.h>
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 #ifdef CYGPKG_NET_DHCP
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
58
1322
69a4719c04ad * src/dhcp_prot.c (set_default_dhcp_tags):
asl
parents: 1315
diff changeset
59 #ifdef CYGPKG_NET_SNTP
69a4719c04ad * src/dhcp_prot.c (set_default_dhcp_tags):
asl
parents: 1315
diff changeset
60 #include <pkgconf/net_sntp.h>
69a4719c04ad * src/dhcp_prot.c (set_default_dhcp_tags):
asl
parents: 1315
diff changeset
61 #endif /* CYGPKG_NET_SNTP */
69a4719c04ad * src/dhcp_prot.c (set_default_dhcp_tags):
asl
parents: 1315
diff changeset
62
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
63 #if 0
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
64 #define perror( txt ) // nothing
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
65 #endif
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
66
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
67 #include <network.h>
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
68 #include <dhcp.h>
235
f9db7cb0692e Pedantic include of <errno.h>
gthomas
parents: 229
diff changeset
69 #include <errno.h>
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
70
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
71 #include <cyg/infra/cyg_ass.h>
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
72
253
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
73 #ifdef INET6
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
74 #include <net/if_var.h>
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
75 #include <netinet6/in6_var.h>
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
76 #endif
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
77
1128
21aab473590c * src/dhcp_prot.c: Added a declaration for cyg_arc4random() to
nickg
parents: 957
diff changeset
78 extern int cyg_arc4random(void);
21aab473590c * src/dhcp_prot.c: Added a declaration for cyg_arc4random() to
nickg
parents: 957
diff changeset
79
1315
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
80 #ifdef CYGOPT_NET_DHCP_OPTION_HOST_NAME
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
81 static char dhcp_hostname[CYGNUM_NET_DHCP_OPTION_HOST_NAME_LEN+1];
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
82
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
83 // Set the hostname used by the DHCP TAG_HOST_NAME option. We
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
84 // copy the callers name into a private buffer, since we don't
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
85 // know the context in which the callers hostname was allocated.
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
86 void dhcp_set_hostname(char *hostname)
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
87 {
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
88 CYG_ASSERT( (strlen(hostname)<=CYGNUM_NET_DHCP_OPTION_HOST_NAME_LEN), "dhcp hostname too long" );
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
89 strncpy(dhcp_hostname, hostname, CYGNUM_NET_DHCP_OPTION_HOST_NAME_LEN);
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
90 }
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
91 #endif
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
92
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
93 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
94 // Returns a pointer to the end of dhcp message (or NULL if invalid)
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
95 // meaning the address of the byte *after* the TAG_END token in the vendor
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
96 // data.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
97
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
98 static unsigned char *
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
99 scan_dhcp_size( struct bootp *ppkt )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
100 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
101 unsigned char *op;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
102
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
103 op = &ppkt->bp_vend[0];
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
104 // First check for the cookie!
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
105 if ( op[0] != 99 ||
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
106 op[1] != 130 ||
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
107 op[2] != 83 ||
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
108 op[3] != 99 ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
109 CYG_FAIL( "Bad DHCP cookie" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
110 return NULL;
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 op += 4;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
113 while (*op != TAG_END) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
114 op += *(op+1)+2;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
115 if ( op > &ppkt->bp_vend[BP_VEND_LEN-1] ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
116 CYG_FAIL( "Oversize DHCP packet in dhcp_size" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
117 return NULL;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
118 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
119 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
120 // Check op has not gone wild
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
121 CYG_ASSERT( op > (unsigned char *)(&ppkt[0]), "op pointer underflow!" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
122 // Compare op with non-existent "next" struct bootp in the array.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
123 CYG_ASSERT( op < (unsigned char *)(&ppkt[1]), "op pointer overflow!" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
124 return op + 1; // Address of first invalid byte
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
125 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
126
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
127 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
128 // Get the actual packet size of an initialized buffer
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
129
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
130 static int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
131 dhcp_size( struct bootp *ppkt )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
132 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
133 unsigned char *op;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
134
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
135 op = scan_dhcp_size( ppkt );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
136 if ( !op ) return 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
137 return (op - (unsigned char *)ppkt);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
138 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
139
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
140
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
141 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
142 // Get the actual packet size of an initialized buffer
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
143 // This will also pad the packet with 0 if length is less
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
144 // than BP_STD_TX_MINPKTSZ.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
145
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
146 static int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
147 dhcp_size_for_send( struct bootp *ppkt )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
148 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
149 unsigned char *op;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
150
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
151 op = scan_dhcp_size( ppkt );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
152 if ( !op ) return 0; // Better not scribble!
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
153 // Zero extra bytes until the packet is large enough.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
154 for ( ; op < (((unsigned char *)ppkt) + BP_STD_TX_MINPKTSZ); op++ )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
155 *op = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
156 return (op - (unsigned char *)ppkt);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
157 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
158
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
159 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
160 // Insert/set an option value in an initialized buffer
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
161
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
162 static int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
163 set_fixed_tag( struct bootp *ppkt,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
164 unsigned char tag,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
165 cyg_uint32 value,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
166 int len)
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
167 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
168 unsigned char *op;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
169
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
170 // Initially this will only scan the options field.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
171
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
172 op = &ppkt->bp_vend[4];
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
173 while (*op != TAG_END) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
174 if ( op > &ppkt->bp_vend[BP_VEND_LEN-1] ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
175 CYG_FAIL( "Oversize DHCP packet in set_fixed_tag" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
176 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
177 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
178 if (*op == tag) // Found it...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
179 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
180 op += *(op+1)+2;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
181 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
182
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
183 if (*op == tag) { // Found it...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
184 if ( *(op+1) != len ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
185 CYG_FAIL( "Wrong size in set_fixed_tag" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
186 return false; // wrong size
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
187 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
188 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
189 else { // overwrite the end tag and install a new one
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
190 if ( op + len + 2 > &ppkt->bp_vend[BP_VEND_LEN-1] ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
191 CYG_FAIL( "Oversize DHCP packet in set_fixed_tag append" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
192 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
193 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
194 *op = tag;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
195 *(op+1) = len;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
196 *(op + len + 2) = TAG_END;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
197 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
198 // and insert the value. Net order is BE.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
199 op += len + 2 - 1; // point to end of value
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
200 while ( len-- > 0 ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
201 *op-- = (unsigned char)(value & 255);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
202 value >>= 8;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
203 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
204 return true;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
205 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
206
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
207 // Note that this does not permit changing the size of an extant tag.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
208 static int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
209 set_variable_tag( struct bootp *ppkt,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
210 unsigned char tag,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
211 cyg_uint8 *pvalue,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
212 int len)
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
213 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
214 unsigned char *op;
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 // Initially this will only scan the options field.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
217 op = &ppkt->bp_vend[4];
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
218 while (*op != TAG_END) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
219 if ( op > &ppkt->bp_vend[BP_VEND_LEN-1] ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
220 CYG_FAIL( "Oversize DHCP packet in set_variable_tag" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
221 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
222 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
223 if (*op == tag) // Found it...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
224 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
225 op += *(op+1)+2;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
226 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
227
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
228 if (*op == tag) { // Found it...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
229 if ( *(op+1) != len ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
230 CYG_FAIL( "Wrong size in set_variable_tag" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
231 return false; // wrong size
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
232 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
233 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
234 else { // overwrite the end tag and install a new one
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
235 if ( op + len + 2 > &ppkt->bp_vend[BP_VEND_LEN-1] ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
236 CYG_FAIL( "Oversize DHCP packet in set_variable_tag append" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
237 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
238 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
239 *op = tag;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
240 *(op+1) = len;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
241 *(op + len + 2) = TAG_END;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
242 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
243 // and insert the value. No order is implied.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
244 op += 2; // point to start of value
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
245 while ( len-- > 0 ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
246 *op++ = *pvalue++;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
247 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
248 return true;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
249 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
250
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
251 static int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
252 unset_tag( struct bootp *ppkt,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
253 unsigned char tag )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
254 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
255 unsigned char *op, *nextp = 0, *killp = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
256
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
257 // Initially this will only scan the options field.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
258
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
259 op = &ppkt->bp_vend[4];
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
260 while (*op != TAG_END) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
261 if ( op > &ppkt->bp_vend[BP_VEND_LEN-1] ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
262 CYG_FAIL( "Oversize DHCP packet in unset_tag" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
263 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
264 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
265 if (*op == tag) { // Found it...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
266 killp = op; // item to kill
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
267 nextp = op + *(op+1)+2; // next item address
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
268 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
269 op += *(op+1)+2; // scan to the end
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
270 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
271
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
272 if ( !killp )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
273 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
274
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
275 // Obliterate the found op by copying down: *op is the end.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
276 while( nextp <= op ) // <= to copy the TAG_END too.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
277 *killp++ = *nextp++;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
278
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
279 return true;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
280 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
281
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
282 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
283 // Bring up an interface enough to broadcast, before we know who we are
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
284
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
285 static int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
286 bring_half_up(const char *intf, struct ifreq *ifrp )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
287 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
288 int s;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
289 int one = 1;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
290
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
291 struct sockaddr_in *addrp;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
292 struct ecos_rtentry route;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
293
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
294 // Ensure clean slate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
295 cyg_route_reinit(); // Force any existing routes to be forgotten
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
296
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
297 s = socket(AF_INET, SOCK_DGRAM, 0);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
298 if (s < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
299 perror("socket");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
300 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
301 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
302
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
303 if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one))) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
304 perror("setsockopt");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
305 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
306 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
307
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
308 addrp = (struct sockaddr_in *) &ifrp->ifr_addr;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
309 memset(addrp, 0, sizeof(*addrp));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
310 addrp->sin_family = AF_INET;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
311 addrp->sin_len = sizeof(*addrp);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
312 addrp->sin_port = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
313 addrp->sin_addr.s_addr = INADDR_ANY;
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 strcpy(ifrp->ifr_name, intf);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
316 if (ioctl(s, SIOCSIFADDR, ifrp)) { /* set ifnet address */
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
317 perror("SIOCSIFADDR");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
318 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
319 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
320
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
321 if (ioctl(s, SIOCSIFNETMASK, ifrp)) { /* set net addr mask */
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
322 perror("SIOCSIFNETMASK");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
323 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
324 }
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 /* the broadcast address is 255.255.255.255 */
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
327 memset(&addrp->sin_addr, 255, sizeof(addrp->sin_addr));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
328 if (ioctl(s, SIOCSIFBRDADDR, ifrp)) { /* set broadcast addr */
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
329 perror("SIOCSIFBRDADDR");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
330 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
331 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
332
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
333 ifrp->ifr_flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
334 if (ioctl(s, SIOCSIFFLAGS, ifrp)) { /* set ifnet flags */
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
335 perror("SIOCSIFFLAGS up");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
336 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
337 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
338
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
339 if (ioctl(s, SIOCGIFHWADDR, ifrp) < 0) { /* get MAC address */
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
340 perror("SIOCGIFHWADDR 1");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
341 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
342 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
343
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
344 // Set up routing
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
345 addrp->sin_family = AF_INET;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
346 addrp->sin_port = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
347 addrp->sin_len = sizeof(*addrp); // Size of address
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 /* the broadcast address is 255.255.255.255 */
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
350 memset(&addrp->sin_addr, 255, sizeof(addrp->sin_addr));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
351 memset(&route, 0, sizeof(route));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
352 memcpy(&route.rt_gateway, addrp, sizeof(*addrp));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
353
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
354 addrp->sin_addr.s_addr = INADDR_ANY;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
355 memcpy(&route.rt_dst, addrp, sizeof(*addrp));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
356 memcpy(&route.rt_genmask, addrp, sizeof(*addrp));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
357
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
358 route.rt_dev = ifrp->ifr_name;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
359 route.rt_flags = RTF_UP|RTF_GATEWAY;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
360 route.rt_metric = 0;
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 if (ioctl(s, SIOCADDRT, &route)) { /* add route */
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
363 if (errno != EEXIST) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
364 perror("SIOCADDRT 3");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
365 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
366 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
367 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
368
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
369 close(s);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
370
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
371 return true;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
372 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
373
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
374
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
375 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
376 // DHCP retransmission timeouts and number of tries
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 // To work better with simulated failures (or real ones!) so that the rest
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
379 // of the system is tested, rather than DHCP renewal failures pulling
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
380 // everything down, we try a little more zealously than the RFC suggests.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
381
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
382 static unsigned char timeout_random = 0;
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 struct timeout_state {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
385 unsigned int secs;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
386 int countdown;
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
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
389 static inline void reset_timeout( struct timeval *ptv, struct timeout_state *pstate )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
390 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
391 timeout_random++;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
392 pstate->countdown = 4; // initial fast retries
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
393 pstate->secs = 3 + (timeout_random & 3);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
394 ptv->tv_sec = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
395 ptv->tv_usec = 65536 * (2 + (timeout_random & 3)); // 0.1 - 0.3S, about
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
396 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
397
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
398 static inline int next_timeout( struct timeval *ptv, struct timeout_state *pstate )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
399 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
400 if ( 0 < pstate->countdown-- )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
401 return true;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
402 if ( 0 == ptv->tv_sec )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
403 ptv->tv_sec = pstate->secs;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
404 else {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
405 timeout_random++;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
406 pstate->secs = ptv->tv_sec * 2 - 2 + (timeout_random & 3);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
407 pstate->countdown = 2; // later fast retries
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
408 ptv->tv_sec = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
409 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
410 return pstate->secs < 100; // If longer, too many tries...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
411 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
412
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
413 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
414 // Lease expiry and alarms to notify it
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
415
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
416 static cyg_alarm_t alarm_function;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
417
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
418 static void alarm_function(cyg_handle_t alarm, cyg_addrword_t data)
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
419 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
420 struct dhcp_lease *lease = (struct dhcp_lease *)data;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
421 lease->which |= lease->next;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
422 if ( lease->needs_attention )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
423 cyg_semaphore_post( lease->needs_attention );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
424
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
425 // Step the lease on into its next state of being alarmed ;-)
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
426 if ( lease->next & DHCP_LEASE_EX ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
427 cyg_alarm_disable( alarm );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
428 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
429 else if ( lease->next & DHCP_LEASE_T2 ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
430 lease->next = DHCP_LEASE_EX;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
431 cyg_alarm_initialize( lease->alarm, lease->expiry, 0 );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
432 cyg_alarm_enable( lease->alarm );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
433 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
434 else if ( lease->next & DHCP_LEASE_T1 ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
435 lease->next = DHCP_LEASE_T2;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
436 cyg_alarm_initialize( lease->alarm, lease->t2, 0 );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
437 cyg_alarm_enable( lease->alarm );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
438 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
439 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
440
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
441 static inline void no_lease( struct dhcp_lease *lease )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
442 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
443 if ( lease->alarm ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
444 // Already set: delete this.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
445 cyg_alarm_disable( lease->alarm );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
446 cyg_alarm_delete( lease->alarm );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
447 lease->alarm = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
448 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
449 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
450
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
451 static inline void new_lease( struct bootp *bootp, struct dhcp_lease *lease )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
452 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
453 cyg_tick_count_t now = cyg_current_time();
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
454 cyg_tick_count_t then;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
455 cyg_uint32 tag = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
456 cyg_uint32 expiry_then;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
457 cyg_resolution_t resolution =
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
458 cyg_clock_get_resolution(cyg_real_time_clock());
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
459 cyg_handle_t h;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
460 unsigned int length;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
461
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
462 // Silence any jabbering from past lease on this interface
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
463 no_lease( lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
464 lease->which = lease->next = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
465 cyg_clock_to_counter(cyg_real_time_clock(), &h);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
466 cyg_alarm_create( h, alarm_function, (cyg_addrword_t)lease,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
467 &lease->alarm, &lease->alarm_obj );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
468
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
469 // extract the lease time and scale it &c to now.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
470 length = sizeof(tag);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
471 if(!get_bootp_option( bootp, TAG_DHCP_LEASE_TIME, &tag ,&length))
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
472 tag = 0xffffffff;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
473
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
474 if ( 0xffffffff == tag ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
475 lease->expiry = 0xffffffffffffffff;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
476 lease->t2 = 0xffffffffffffffff;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
477 lease->t1 = 0xffffffffffffffff;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
478 return; // it's an infinite lease, hurrah!
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
479 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
480
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
481 then = (cyg_uint64)(ntohl(tag));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
482 expiry_then = then;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
483
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
484 then *= 1000000000; // into nS - we know there is room in a tick_count_t
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
485 then = (then / resolution.dividend) * resolution.divisor; // into system ticks
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
486 lease->expiry = now + then;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
487 length = sizeof(tag);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
488 if (get_bootp_option( bootp, TAG_DHCP_REBIND_TIME, &tag, &length ))
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
489 then = (cyg_uint64)(ntohl(tag));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
490 else
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
491 then = expiry_then - expiry_then/4;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
492 then *= 1000000000; // into nS - we know there is room in a tick_count_t
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
493 then = (then / resolution.dividend) * resolution.divisor; // into system ticks
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
494 lease->t2 = now + then;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
495
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
496 length = sizeof(tag);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
497 if (get_bootp_option( bootp, TAG_DHCP_RENEWAL_TIME, &tag, &length ))
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
498 then = (cyg_uint64)(ntohl(tag));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
499 else
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
500 then = expiry_then/2;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
501 then *= 1000000000; // into nS - we know there is room in a tick_count_t
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
502 then = (then / resolution.dividend) * resolution.divisor; // into system ticks
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
503 lease->t1 = now + then;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
504
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
505 #if 0 // for testing this mechanism
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
506 lease->expiry = now + 5000; // 1000 here makes for failure in the DHCP test
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
507 lease->t2 = now + 3500;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
508 lease->t1 = now + 2500;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
509 #endif
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
510
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
511 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
512 diag_printf("new_lease:\n");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
513 diag_printf(" expiry = %d\n",lease->expiry);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
514 diag_printf(" t1 = %d\n",lease->t1);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
515 diag_printf(" t2 = %d\n",lease->t2);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
516 #endif
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
517
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
518 lease->next = DHCP_LEASE_T1;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
519
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
520 cyg_alarm_initialize( lease->alarm, lease->t1, 0 );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
521 cyg_alarm_enable( lease->alarm );
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
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
524 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
525 // Set all the tags we want to use when sending a packet.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
526 // This has expanded to a large, explicit set to interwork better
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
527 // with a variety of DHCP servers.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
528
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
529 static void set_default_dhcp_tags( struct bootp *xmit )
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 // Explicitly request full set of params that are default for LINUX
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
532 // dhcp servers, but not default for others. This is rather arbitrary,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
533 // but it preserves behaviour for people using those servers.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
534 // Perhaps configury of this set will be needed in future?
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 // Here's the set:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
537 static cyg_uint8 req_list[] = {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
538 #ifdef CYGOPT_NET_DHCP_PARM_REQ_LIST_REPLACE
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
539 CYGOPT_NET_DHCP_PARM_REQ_LIST_REPLACE ,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
540 #else
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
541 TAG_DHCP_SERVER_ID , // DHCP server id: 10.16.19.66
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
542 TAG_DHCP_LEASE_TIME , // DHCP time 51: 60
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
543 TAG_DHCP_RENEWAL_TIME , // DHCP time 58: 30
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
544 TAG_DHCP_REBIND_TIME , // DHCP time 59: 52
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
545 TAG_SUBNET_MASK , // subnet mask: 255.255.255.0
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
546 TAG_GATEWAY , // gateway: 10.16.19.66
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
547 TAG_DOMAIN_SERVER , // domain server: 10.16.19.66
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
548 TAG_DOMAIN_NAME , // domain name: hmt10.cambridge.redhat.com
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
549 TAG_IP_BROADCAST , // IP broadcast: 10.16.19.255
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
550 #endif
1322
69a4719c04ad * src/dhcp_prot.c (set_default_dhcp_tags):
asl
parents: 1315
diff changeset
551 #ifdef CYGNUM_NET_SNTP_UNICAST_MAXDHCP
69a4719c04ad * src/dhcp_prot.c (set_default_dhcp_tags):
asl
parents: 1315
diff changeset
552 TAG_NTP_SERVER , // NTP Server Addresses(es)
69a4719c04ad * src/dhcp_prot.c (set_default_dhcp_tags):
asl
parents: 1315
diff changeset
553 #endif
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
554 #ifdef CYGOPT_NET_DHCP_PARM_REQ_LIST_ADDITIONAL
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
555 CYGOPT_NET_DHCP_PARM_REQ_LIST_ADDITIONAL ,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
556 #endif
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
557 };
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
558
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
559 if ( req_list[0] ) // So that one may easily turn it all off by configury
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
560 set_variable_tag( xmit, TAG_DHCP_PARM_REQ_LIST,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
561 &req_list[0], sizeof( req_list ) );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
562
1315
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
563 #ifdef CYGOPT_NET_DHCP_OPTION_HOST_NAME
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
564 {
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
565 int nlen = strlen(dhcp_hostname);
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
566
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
567 if (nlen > 0)
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
568 set_variable_tag( xmit, TAG_HOST_NAME, dhcp_hostname, nlen + 1);
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
569 }
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
570 #endif
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
571 #ifdef CYGOPT_NET_DHCP_OPTION_DHCP_CLIENTID_MAC
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
572 {
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
573 cyg_uint8 id[16+1]; /* sizeof bp_chaddr[] + 1 */
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
574
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
575 id[0] = 1; /* 1-byte hardware type: 1=ethernet. */
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
576 CYG_ASSERT( xmit->bp_hlen<=(sizeof(id)-1), "HW address invalid" );
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
577 memcpy(&id[1], &xmit->bp_chaddr, xmit->bp_hlen);
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
578 set_variable_tag( xmit, TAG_DHCP_CLIENTID, id, xmit->bp_hlen+1);
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
579 }
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
580 #endif
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
581
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
582 // Explicitly specify our max message size.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
583 set_fixed_tag( xmit, TAG_DHCP_MAX_MSGSZ, BP_MINPKTSZ, 2 );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
584 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
585
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
586 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
587 // the DHCP state machine - this does all the work
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
588
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
589 int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
590 do_dhcp(const char *intf, struct bootp *res,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
591 cyg_uint8 *pstate, struct dhcp_lease *lease)
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
592 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
593 struct ifreq ifr;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
594 struct sockaddr_in cli_addr, broadcast_addr, server_addr, rx_addr;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
595 int s, addrlen;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
596 int one = 1;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
597 unsigned char mincookie[] = {99,130,83,99,255} ;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
598 struct timeval tv;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
599 struct timeout_state timeout_scratch;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
600 cyg_uint8 oldstate = *pstate;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
601 cyg_uint8 msgtype = 0, seen_bootp_reply = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
602 unsigned int length;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
603
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
604 cyg_uint32 xid;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
605
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
606 #define CHECK_XID() ( /* and other details */ \
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
607 received->bp_xid != xid || /* not the same transaction */ \
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
608 received->bp_htype != xmit->bp_htype || /* not the same ESA type */ \
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
609 received->bp_hlen != xmit->bp_hlen || /* not the same length */ \
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
610 bcmp( &received->bp_chaddr, &xmit->bp_chaddr, xmit->bp_hlen ) \
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
611 )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
612
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
613 // IMPORTANT: xmit is the same as res throughout this; *received is a
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
614 // scratch buffer for reception; its contents are always copied to res
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
615 // when we are happy with them. So we always transmit from the
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
616 // existing state.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
617 struct bootp rx_local;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
618 struct bootp *received = &rx_local;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
619 struct bootp *xmit = res;
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
620 struct bootp xmit2;
216
da643977bd0a Improve DHCP reply handling
gthomas
parents: 211
diff changeset
621 int xlen;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
622
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
623 // First, get a socket on the interface in question. But Zeroth, if
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
624 // needs be, bring it to the half-up broadcast only state if needs be.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
625
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
626 if ( DHCPSTATE_INIT == oldstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
627 || DHCPSTATE_FAILED == oldstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
628 || 0 == oldstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
629 // either explicit init state or the beginning of time or retry
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
630 if ( ! bring_half_up( intf, &ifr ) )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
631 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
632
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
633 *pstate = DHCPSTATE_INIT;
1144
c9c183d9b60a * src/dhcp_prot.c (do_dhcp): (re)Initialize the lease when
asl
parents: 1128
diff changeset
634 lease->which = lease->next = 0;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
635 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
636
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
637 s = socket(AF_INET, SOCK_DGRAM, 0);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
638 if (s < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
639 perror("socket");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
640 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
641 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
642
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
643 if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one))) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
644 perror("setsockopt");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
645 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
646 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
647
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
648 memset((char *) &cli_addr, 0, sizeof(cli_addr));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
649 cli_addr.sin_family = AF_INET;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
650 cli_addr.sin_len = sizeof(cli_addr);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
651 cli_addr.sin_addr.s_addr = htonl(INADDR_ANY);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
652 cli_addr.sin_port = htons(IPPORT_BOOTPC);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
653
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
654 memset((char *) &broadcast_addr, 0, sizeof(broadcast_addr));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
655 broadcast_addr.sin_family = AF_INET;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
656 broadcast_addr.sin_len = sizeof(broadcast_addr);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
657 broadcast_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
658 broadcast_addr.sin_port = htons(IPPORT_BOOTPS);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
659
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
660 memset((char *) &server_addr, 0, sizeof(server_addr));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
661 server_addr.sin_family = AF_INET;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
662 server_addr.sin_len = sizeof(server_addr);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
663 server_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); // overwrite later
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
664 server_addr.sin_port = htons(IPPORT_BOOTPS);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
665
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
666 if(bind(s, (struct sockaddr *) &cli_addr, sizeof(cli_addr)) < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
667 perror("bind error");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
668 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
669 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
670 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
671 perror("setsockopt SO_REUSEADDR");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
672 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
673 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
674 if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one))) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
675 perror("setsockopt SO_REUSEPORT");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
676 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
677 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
678
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
679 // Now, we can launch into the DHCP state machine. I think this will
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
680 // be the neatest way to do it; it returns from within the switch arms
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
681 // when all is well, or utterly failed.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
682
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
683 reset_timeout( &tv, &timeout_scratch );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
684
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
685 // Choose a new XID: first get the ESA as a basis:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
686 strcpy(&ifr.ifr_name[0], intf);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
687 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
688 perror("SIOCGIFHWADDR 2");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
689 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
690 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
691
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
692 // Choose from scratch depending on ifr_hwaddr...[]
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
693 xid = ifr.ifr_hwaddr.sa_data[5];
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
694 xid |= (ifr.ifr_hwaddr.sa_data[4]) << 8;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
695 xid |= (ifr.ifr_hwaddr.sa_data[3]) << 16;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
696 xid |= (ifr.ifr_hwaddr.sa_data[2]) << 24;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
697 xid ^= (cyg_arc4random() & 0xffff0000);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
698
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
699 // Avoid adjacent ESAs colliding by increment
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
700 #define NEW_XID(_xid) CYG_MACRO_START (_xid)+= 0x10000; CYG_MACRO_END
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
701
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
702 while ( 1 ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
703
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
704 // If we are active rather than in the process of shutting down,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
705 // check for any lease expiry every time round, so that alarms
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
706 // *can* change the course of events even when already renewing,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
707 // for example.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
708 if ( DHCPSTATE_DO_RELEASE != *pstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
709 && DHCPSTATE_NOTBOUND != *pstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
710 && DHCPSTATE_FAILED != *pstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
711 cyg_uint8 lease_state;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
712
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
713 cyg_scheduler_lock();
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
714 lease_state = lease->which;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
715 lease->which = 0; // flag that we have noticed it
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
716 cyg_scheduler_unlock();
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
717
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
718 if ( lease_state & DHCP_LEASE_EX ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
719 // then the lease has expired completely!
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
720 *pstate = DHCPSTATE_NOTBOUND;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
721 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
722 else if ( lease_state & DHCP_LEASE_T2 ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
723 // Time to renew
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
724 reset_timeout( &tv, &timeout_scratch ); // next conversation
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
725 *pstate = DHCPSTATE_REBINDING;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
726 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
727 else if ( lease_state & DHCP_LEASE_T1 ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
728 // Time to renew
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
729 reset_timeout( &tv, &timeout_scratch ); // next conversation
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
730 *pstate = DHCPSTATE_RENEWING;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
731 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
732 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
733
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
734 switch ( *pstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
735
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
736 case DHCPSTATE_INIT:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
737
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
738 // Send the DHCPDISCOVER packet
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
739
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
740 // Fill in the BOOTP request - DHCPDISCOVER packet
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
741 bzero(xmit, sizeof(*xmit));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
742 xmit->bp_op = BOOTREQUEST;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
743 xmit->bp_htype = HTYPE_ETHERNET;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
744 xmit->bp_hlen = IFHWADDRLEN;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
745 xmit->bp_xid = xid;
1505
f2168dd5be4e Initialize bp_secs field for stubborn DHCP servers - from Matt Jerdonek
gthomas
parents: 1322
diff changeset
746 xmit->bp_secs = cyg_current_time() / 100;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
747 xmit->bp_flags = htons(0x8000); // BROADCAST FLAG
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
748 bcopy(ifr.ifr_hwaddr.sa_data, &xmit->bp_chaddr, xmit->bp_hlen);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
749 bcopy(mincookie, xmit->bp_vend, sizeof(mincookie));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
750
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
751 // remove the next line to test ability to handle bootp packets.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
752 set_fixed_tag( xmit, TAG_DHCP_MESS_TYPE, DHCPDISCOVER, 1 );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
753 // Set all the tags we want to use when sending a packet
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
754 set_default_dhcp_tags( xmit );
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 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
757 diag_printf( "---------DHCPSTATE_INIT sending:\n" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
758 show_bootp( intf, xmit );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
759 #endif
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
760 if(sendto(s, xmit, dhcp_size_for_send(xmit), 0,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
761 (struct sockaddr *)&broadcast_addr, sizeof(broadcast_addr)) < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
762 *pstate = DHCPSTATE_FAILED;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
763 break;
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
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
766 seen_bootp_reply = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
767 *pstate = DHCPSTATE_SELECTING;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
768 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
769
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
770 case DHCPSTATE_SELECTING:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
771 // This is a separate state so that we can listen again
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
772 // *without* retransmitting.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
773
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
774 // listen for the DHCPOFFER reply
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
775
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
776 setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
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 addrlen = sizeof(rx_addr);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
779 if (recvfrom(s, received, sizeof(struct bootp), 0,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
780 (struct sockaddr *)&rx_addr, &addrlen) < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
781 // No packet arrived (this time)
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
782 if ( seen_bootp_reply ) { // then already have a bootp reply
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
783 // Save the good packet in *xmit
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
784 bcopy( received, xmit, dhcp_size(received) );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
785 *pstate = DHCPSTATE_BOOTP_FALLBACK;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
786 NEW_XID( xid ); // Happy to advance, so new XID
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
787 reset_timeout( &tv, &timeout_scratch );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
788 break;
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 // go to the next larger timeout and re-send:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
791 if ( ! next_timeout( &tv, &timeout_scratch ) ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
792 *pstate = DHCPSTATE_FAILED;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
793 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
794 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
795 *pstate = DHCPSTATE_INIT; // to retransmit
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
796 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
797 }
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
798 // Check for well-formed packet with correct termination (not truncated)
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
799 length = dhcp_size( received );
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
800 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
801 diag_printf( "---------DHCPSTATE_SELECTING received:\n" );
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
802 if ( length <= 0 )
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
803 diag_printf( "WARNING! malformed or truncated packet\n" );
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
804 diag_printf( "...rx_addr is family %d, addr %08x, port %d\n",
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
805 rx_addr.sin_family,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
806 rx_addr.sin_addr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
807 rx_addr.sin_port );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
808 show_bootp( intf, received );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
809 #endif
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
810 if ( length <= 0 )
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
811 break;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
812 if ( CHECK_XID() ) // XID and ESA matches?
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
813 break; // listen again...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
814
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
815 if ( 0 == received->bp_siaddr.s_addr ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
816 // then fill in from the options...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
817 length = sizeof(received->bp_siaddr.s_addr);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
818 get_bootp_option( received, TAG_DHCP_SERVER_ID,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
819 &received->bp_siaddr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
820 &length);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
821 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
822
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
823 // see if it was a DHCP reply or a bootp reply; it could be
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
824 // either.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
825 length = sizeof(msgtype);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
826 if ( get_bootp_option( received, TAG_DHCP_MESS_TYPE, &msgtype,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
827 &length) ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
828 if ( DHCPOFFER == msgtype ) { // all is well
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
829 // Save the good packet in *xmit
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
830 bcopy( received, xmit, dhcp_size(received) );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
831 // we like the packet, so reset the timeout for next time
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
832 reset_timeout( &tv, &timeout_scratch );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
833 *pstate = DHCPSTATE_REQUESTING;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
834 NEW_XID( xid ); // Happy to advance, so new XID
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
835 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
836 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
837 else // No TAG_DHCP_MESS_TYPE entry so it's a bootp reply
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
838 seen_bootp_reply = 1; // (keep the bootp packet in received)
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
839
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
840 // If none of the above state changes occurred, we got a packet
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
841 // that "should not happen", OR we have a bootp reply in our
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
842 // hand; so listen again with the same timeout, without
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
843 // retrying the send, in the hope of getting a DHCP reply.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
844 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
845
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
846 case DHCPSTATE_REQUESTING:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
847 // Just send what you got with a DHCPREQUEST in the message type.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
848 // then wait for an ACK in DHCPSTATE_REQUEST_RECV.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
849
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
850 // Fill in the BOOTP request - DHCPREQUEST packet
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
851 xmit->bp_xid = xid;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
852 xmit->bp_op = BOOTREQUEST;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
853 xmit->bp_flags = htons(0x8000); // BROADCAST FLAG
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
854
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
855 set_fixed_tag( xmit, TAG_DHCP_MESS_TYPE, DHCPREQUEST, 1 );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
856 // Set all the tags we want to use when sending a packet
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
857 set_default_dhcp_tags( xmit );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
858 // And this will be a new one:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
859 set_fixed_tag( xmit, TAG_DHCP_REQ_IP, ntohl(xmit->bp_yiaddr.s_addr), 4 );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
860
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
861 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
862 diag_printf( "---------DHCPSTATE_REQUESTING sending:\n" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
863 show_bootp( intf, xmit );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
864 #endif
211
6eb55882e01c Merge from eCos master repository on 2002-05-29-16:32:18-BST
jlarmour
parents: 208
diff changeset
865 // Send back a [modified] copy. Note that some fields are explicitly
6eb55882e01c Merge from eCos master repository on 2002-05-29-16:32:18-BST
jlarmour
parents: 208
diff changeset
866 // cleared, as per the RFC. We need the copy because these fields are
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
867 // still useful to us (and currently stored in the 'result' structure)
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
868 xlen = dhcp_size_for_send( xmit );
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
869 bcopy( xmit, &xmit2, xlen );
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
870 xmit2.bp_yiaddr.s_addr = xmit2.bp_siaddr.s_addr = xmit2.bp_giaddr.s_addr = 0;
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
871 xmit2.bp_hops = 0;
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
872 if(sendto(s, &xmit2, xlen, 0,
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
873 (struct sockaddr *)&broadcast_addr, sizeof(broadcast_addr)) < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
874 *pstate = DHCPSTATE_FAILED;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
875 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
876 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
877
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
878 *pstate = DHCPSTATE_REQUEST_RECV;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
879 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
880
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
881 case DHCPSTATE_REQUEST_RECV:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
882 // wait for an ACK or a NACK - retry by going back to
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
883 // DHCPSTATE_REQUESTING; NACK means go back to INIT.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
884
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
885 setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
886
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
887 addrlen = sizeof(rx_addr);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
888 if (recvfrom(s, received, sizeof(struct bootp), 0,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
889 (struct sockaddr *)&rx_addr, &addrlen) < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
890 // No packet arrived
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
891 // go to the next larger timeout and re-send:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
892 if ( ! next_timeout( &tv, &timeout_scratch ) ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
893 *pstate = DHCPSTATE_FAILED;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
894 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
895 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
896 *pstate = DHCPSTATE_REQUESTING;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
897 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
898 }
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
899 // Check for well-formed packet with correct termination (not truncated)
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
900 length = dhcp_size( received );
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
901 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
902 diag_printf( "---------DHCPSTATE_REQUEST_RECV received:\n" );
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
903 if ( length <= 0 )
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
904 diag_printf( "WARNING! malformed or truncated packet\n" );
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
905 diag_printf( "...rx_addr is family %d, addr %08x, port %d\n",
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
906 rx_addr.sin_family,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
907 rx_addr.sin_addr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
908 rx_addr.sin_port );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
909 show_bootp( intf, received );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
910 #endif
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
911 if ( length <= 0 )
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
912 break;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
913 if ( CHECK_XID() ) // not the same transaction;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
914 break; // listen again...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
915
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
916 if ( 0 == received->bp_siaddr.s_addr ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
917 // then fill in from the options...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
918 length = sizeof(received->bp_siaddr.s_addr );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
919 get_bootp_option( received, TAG_DHCP_SERVER_ID,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
920 &received->bp_siaddr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
921 &length);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
922 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
923
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
924 // check it was a DHCP reply
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
925 length = sizeof(msgtype);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
926 if ( get_bootp_option( received, TAG_DHCP_MESS_TYPE, &msgtype,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
927 &length) ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
928 if ( DHCPACK == msgtype // Same offer & server?
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
929 && received->bp_yiaddr.s_addr == xmit->bp_yiaddr.s_addr
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
930 && received->bp_siaddr.s_addr == xmit->bp_siaddr.s_addr) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
931 // we like the packet, so reset the timeout for next time
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
932 reset_timeout( &tv, &timeout_scratch );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
933 // Record the new lease and set up timers &c
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
934 new_lease( received, lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
935 *pstate = DHCPSTATE_BOUND;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
936 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
937 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
938 if ( DHCPNAK == msgtype // Same server?
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
939 && received->bp_siaddr.s_addr == xmit->bp_siaddr.s_addr) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
940 // we're bounced!
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
941 *pstate = DHCPSTATE_INIT; // So back the start of the rigmarole.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
942 NEW_XID( xid ); // Unhappy to advance, so new XID
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
943 reset_timeout( &tv, &timeout_scratch );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
944 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
945 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
946 // otherwise it's something else, maybe another offer, or a bogus
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
947 // NAK from someone we are not asking!
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
948 // Just listen again, which implicitly discards it.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
949 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
950 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
951
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
952 case DHCPSTATE_BOUND:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
953
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
954 // We are happy now, we have our address.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
955
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
956 // All done with socket
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
957 close(s);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
958
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
959 // Re-initialize the interface with the new state
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
960 if ( DHCPSTATE_BOUND != oldstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
961 // Then need to go down and up
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
962 do_dhcp_down_net( intf, res, &oldstate, lease ); // oldstate used
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
963 if ( 0 != oldstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
964 // Then not called from init_all_network_interfaces()
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
965 // so we must initialize the interface ourselves
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
966 if (!init_net(intf, res)) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
967 do_dhcp_down_net( intf, res, pstate, lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
968 *pstate = DHCPSTATE_FAILED;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
969 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
970 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
971 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
972 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
973
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
974 // Otherwise, nothing whatsoever to do...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
975 return true;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
976
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
977 case DHCPSTATE_RENEWING:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
978 // Just send what you got with a DHCPREQUEST in the message
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
979 // type UNICAST straight to the server. Then wait for an ACK.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
980
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
981 // Fill in the BOOTP request - DHCPREQUEST packet
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
982 xmit->bp_xid = xid;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
983 xmit->bp_op = BOOTREQUEST;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
984 xmit->bp_flags = htons(0); // No BROADCAST FLAG
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
985 // Use the *client* address here:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
986 xmit->bp_ciaddr.s_addr = xmit->bp_yiaddr.s_addr;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
987
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
988 set_fixed_tag( xmit, TAG_DHCP_MESS_TYPE, DHCPREQUEST, 1 );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
989 // These must not be set in this context
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
990 unset_tag( xmit, TAG_DHCP_REQ_IP );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
991 unset_tag( xmit, TAG_DHCP_SERVER_ID );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
992 // Set all the tags we want to use when sending a packet
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
993 set_default_dhcp_tags( xmit );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
994
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
995 // Set unicast address to *server*
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
996 server_addr.sin_addr.s_addr = res->bp_siaddr.s_addr;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
997
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
998 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
999 diag_printf( "---------DHCPSTATE_RENEWING sending:\n" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1000 diag_printf( "UNICAST to family %d, addr %08x, port %d\n",
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1001 server_addr.sin_family,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1002 server_addr.sin_addr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1003 server_addr.sin_port );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1004 show_bootp( intf, xmit );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1005 #endif
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1006
211
6eb55882e01c Merge from eCos master repository on 2002-05-29-16:32:18-BST
jlarmour
parents: 208
diff changeset
1007 // Send back a [modified] copy. Note that some fields are explicitly
6eb55882e01c Merge from eCos master repository on 2002-05-29-16:32:18-BST
jlarmour
parents: 208
diff changeset
1008 // cleared, as per the RFC. We need the copy because these fields are
6eb55882e01c Merge from eCos master repository on 2002-05-29-16:32:18-BST
jlarmour
parents: 208
diff changeset
1009 // still useful to us (and currently stored in the 'result' structure)
216
da643977bd0a Improve DHCP reply handling
gthomas
parents: 211
diff changeset
1010 xlen = dhcp_size_for_send(xmit);
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1011 bcopy( xmit, &xmit2, xlen );
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1012 xmit2.bp_yiaddr.s_addr = xmit2.bp_siaddr.s_addr = xmit2.bp_giaddr.s_addr = 0;
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1013 xmit2.bp_hops = 0;
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1014 if(sendto(s, &xmit2, xlen, 0,
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1015 // UNICAST address of the server:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1016 (struct sockaddr *)&server_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1017 sizeof(server_addr)) < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1018 *pstate = DHCPSTATE_FAILED;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1019 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1020 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1021
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1022 *pstate = DHCPSTATE_RENEW_RECV;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1023 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1024
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1025 case DHCPSTATE_RENEW_RECV:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1026 // wait for an ACK or a NACK - retry by going back to
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1027 // DHCPSTATE_RENEWING; NACK means go to NOTBOUND.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1028 // No answer means just wait for T2, to broadcast.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1029
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1030 setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1031
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1032 addrlen = sizeof(rx_addr);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1033 if (recvfrom(s, received, sizeof(struct bootp), 0,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1034 (struct sockaddr *)&rx_addr, &addrlen) < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1035 // No packet arrived
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1036 // go to the next larger timeout and re-send:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1037 if ( ! next_timeout( &tv, &timeout_scratch ) ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1038 // If we timed out completely, just give up until T2
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1039 // expires - retain the lease meanwhile. The normal
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1040 // lease mechanism will invoke REBINDING as and when
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1041 // necessary.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1042 *pstate = DHCPSTATE_BOUND;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1043 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1044 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1045 *pstate = DHCPSTATE_RENEWING;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1046 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1047 }
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1048 // Check for well-formed packet with correct termination (not truncated)
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1049 length = dhcp_size( received );
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1050 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1051 diag_printf( "---------DHCPSTATE_RENEW_RECV received:\n" );
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1052 if ( length <= 0 )
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1053 diag_printf( "WARNING! malformed or truncated packet\n" );
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1054 diag_printf( "...rx_addr is family %d, addr %08x, port %d\n",
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1055 rx_addr.sin_family,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1056 rx_addr.sin_addr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1057 rx_addr.sin_port );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1058 show_bootp( intf, received );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1059 #endif
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1060 if ( length <= 0 )
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1061 break;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1062 if ( CHECK_XID() ) // not the same transaction;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1063 break; // listen again...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1064
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1065 if ( 0 == received->bp_siaddr.s_addr ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1066 // then fill in from the options...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1067 length = sizeof(received->bp_siaddr.s_addr);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1068 get_bootp_option( received, TAG_DHCP_SERVER_ID,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1069 &received->bp_siaddr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1070 &length);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1071 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1072
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1073 // check it was a DHCP reply
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1074 length = sizeof(msgtype);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1075 if ( get_bootp_option( received, TAG_DHCP_MESS_TYPE, &msgtype,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1076 &length) ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1077 if ( DHCPACK == msgtype // Same offer?
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1078 && received->bp_yiaddr.s_addr == xmit->bp_yiaddr.s_addr) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1079 // we like the packet, so reset the timeout for next time
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1080 reset_timeout( &tv, &timeout_scratch );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1081 // Record the new lease and set up timers &c
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1082 new_lease( received, lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1083 *pstate = DHCPSTATE_BOUND;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1084 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1085 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1086 if ( DHCPNAK == msgtype ) { // we're bounced!
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1087 *pstate = DHCPSTATE_NOTBOUND; // So quit out.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1088 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1089 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1090 // otherwise it's something else, maybe another offer.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1091 // Just listen again, which implicitly discards it.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1092 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1093 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1094
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1095 case DHCPSTATE_REBINDING:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1096 // Just send what you got with a DHCPREQUEST in the message type.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1097 // Then wait for an ACK. This one is BROADCAST.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1098
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1099 // Fill in the BOOTP request - DHCPREQUEST packet
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1100 xmit->bp_xid = xid;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1101 xmit->bp_op = BOOTREQUEST;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1102 xmit->bp_flags = htons(0); // no BROADCAST FLAG
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1103 // Use the *client* address here:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1104 xmit->bp_ciaddr.s_addr = xmit->bp_yiaddr.s_addr;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1105
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1106 set_fixed_tag( xmit, TAG_DHCP_MESS_TYPE, DHCPREQUEST, 1 );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1107 // These must not be set in this context
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1108 unset_tag( xmit, TAG_DHCP_REQ_IP );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1109 unset_tag( xmit, TAG_DHCP_SERVER_ID );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1110 // Set all the tags we want to use when sending a packet
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1111 set_default_dhcp_tags( xmit );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1112
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1113 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1114 diag_printf( "---------DHCPSTATE_REBINDING sending:\n" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1115 show_bootp( intf, xmit );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1116 #endif
211
6eb55882e01c Merge from eCos master repository on 2002-05-29-16:32:18-BST
jlarmour
parents: 208
diff changeset
1117 // Send back a [modified] copy. Note that some fields are explicitly
6eb55882e01c Merge from eCos master repository on 2002-05-29-16:32:18-BST
jlarmour
parents: 208
diff changeset
1118 // cleared, as per the RFC. We need the copy because these fields are
6eb55882e01c Merge from eCos master repository on 2002-05-29-16:32:18-BST
jlarmour
parents: 208
diff changeset
1119 // still useful to us (and currently stored in the 'result' structure)
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1120 xlen = dhcp_size_for_send( xmit );
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1121 bcopy( xmit, &xmit2, xlen );
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1122 xmit2.bp_yiaddr.s_addr = xmit2.bp_siaddr.s_addr = xmit2.bp_giaddr.s_addr = 0;
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1123 xmit2.bp_hops = 0;
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1124 if(sendto(s, &xmit2, xlen, 0,
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1125 (struct sockaddr *)&broadcast_addr, sizeof(broadcast_addr)) < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1126 *pstate = DHCPSTATE_FAILED;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1127 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1128 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1129
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1130 *pstate = DHCPSTATE_REBIND_RECV;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1131 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1132
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1133 case DHCPSTATE_REBIND_RECV:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1134 // wait for an ACK or a NACK - retry by going back to
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1135 // DHCPSTATE_REBINDING; NACK means go to NOTBOUND.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1136 // No answer means just wait for expiry; we tried!
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1137
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1138 setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1139
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1140 addrlen = sizeof(rx_addr);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1141 if (recvfrom(s, received, sizeof(struct bootp), 0,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1142 (struct sockaddr *)&rx_addr, &addrlen) < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1143 // No packet arrived
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1144 // go to the next larger timeout and re-send:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1145 if ( ! next_timeout( &tv, &timeout_scratch ) ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1146 // If we timed out completely, just give up until EX
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1147 // expires - retain the lease meanwhile. The normal
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1148 // lease mechanism will invoke NOTBOUND state as and
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1149 // when necessary.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1150 *pstate = DHCPSTATE_BOUND;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1151 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1152 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1153 *pstate = DHCPSTATE_REBINDING;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1154 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1155 }
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1156 // Check for well-formed packet with correct termination (not truncated)
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1157 length = dhcp_size( received );
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1158 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1159 diag_printf( "---------DHCPSTATE_REBIND_RECV received:\n" );
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1160 if ( length <= 0 )
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1161 diag_printf( "WARNING! malformed or truncated packet\n" );
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1162 diag_printf( "...rx_addr is family %d, addr %08x, port %d\n",
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1163 rx_addr.sin_family,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1164 rx_addr.sin_addr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1165 rx_addr.sin_port );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1166 show_bootp( intf, received );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1167 #endif
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1168 if ( length <= 0 )
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1169 break;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1170 if ( CHECK_XID() ) // not the same transaction;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1171 break; // listen again...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1172
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1173 if ( 0 == received->bp_siaddr.s_addr ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1174 // then fill in from the options...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1175 int length = sizeof(received->bp_siaddr.s_addr );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1176 get_bootp_option( received, TAG_DHCP_SERVER_ID,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1177 &received->bp_siaddr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1178 &length);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1179 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1180
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1181 // check it was a DHCP reply
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1182 length = sizeof(msgtype);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1183 if ( get_bootp_option( received, TAG_DHCP_MESS_TYPE, &msgtype,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1184 &length) ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1185 if ( DHCPACK == msgtype // Same offer?
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1186 && received->bp_yiaddr.s_addr == xmit->bp_yiaddr.s_addr) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1187 // we like the packet, so reset the timeout for next time
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1188 reset_timeout( &tv, &timeout_scratch );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1189 // Record the new lease and set up timers &c
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1190 new_lease( received, lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1191 *pstate = DHCPSTATE_BOUND;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1192 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1193 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1194 else if ( DHCPNAK == msgtype ) { // we're bounced!
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1195 *pstate = DHCPSTATE_NOTBOUND; // So back the start of the rigmarole.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1196 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1197 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1198 // otherwise it's something else, maybe another offer.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1199 // Just listen again, which implicitly discards it.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1200 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1201 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1202
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1203 case DHCPSTATE_BOOTP_FALLBACK:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1204 // All done with socket
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1205 close(s);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1206 // And no lease should have become active, but JIC
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1207 no_lease( lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1208 // Re-initialize the interface with the new state
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1209 if ( DHCPSTATE_BOOTP_FALLBACK != oldstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1210 // Then need to go down and up
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1211 do_dhcp_down_net( intf, res, &oldstate, lease ); // oldstate used
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1212 if ( 0 != oldstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1213 // Then not called from init_all_network_interfaces()
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1214 // so we must initialize the interface ourselves
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1215 if (!init_net(intf, res)) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1216 do_dhcp_down_net( intf, res, pstate, lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1217 *pstate = DHCPSTATE_FAILED;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1218 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1219 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1220 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1221 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1222
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1223 // Otherwise, nothing whatsoever to do...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1224 return true;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1225
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1226 case DHCPSTATE_NOTBOUND:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1227 // All done with socket
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1228 close(s);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1229 // No lease active
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1230 no_lease( lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1231 // Leave interface up so app can tidy.
1144
c9c183d9b60a * src/dhcp_prot.c (do_dhcp): (re)Initialize the lease when
asl
parents: 1128
diff changeset
1232 return true;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1233
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1234 case DHCPSTATE_FAILED:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1235 // All done with socket
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1236 close(s);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1237 // No lease active
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1238 no_lease( lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1239 // Unconditionally down the interface.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1240 do_dhcp_down_net( intf, res, &oldstate, lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1241 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1242
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1243 case DHCPSTATE_DO_RELEASE:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1244 // We have been forced here by external means, to release the
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1245 // lease for graceful shutdown.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1246
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1247 // Just send what you got with a DHCPRELEASE in the message
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1248 // type UNICAST straight to the server. No ACK. Then go to
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1249 // NOTBOUND state.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1250 NEW_XID( xid );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1251 xmit->bp_xid = xid;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1252 xmit->bp_op = BOOTREQUEST;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1253 xmit->bp_flags = htons(0); // no BROADCAST FLAG
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1254 // Use the *client* address here:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1255 xmit->bp_ciaddr.s_addr = xmit->bp_yiaddr.s_addr;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1256
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1257 set_fixed_tag( xmit, TAG_DHCP_MESS_TYPE, DHCPRELEASE, 1 );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1258
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1259 // Set unicast address to *server*
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1260 server_addr.sin_addr.s_addr = res->bp_siaddr.s_addr;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1261
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1262 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1263 diag_printf( "---------DHCPSTATE_DO_RELEASE sending:\n" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1264 diag_printf( "UNICAST to family %d, addr %08x, port %d\n",
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1265 server_addr.sin_family,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1266 server_addr.sin_addr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1267 server_addr.sin_port );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1268 show_bootp( intf, xmit );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1269 #endif
211
6eb55882e01c Merge from eCos master repository on 2002-05-29-16:32:18-BST
jlarmour
parents: 208
diff changeset
1270 // Send back a [modified] copy. Note that some fields are explicitly
6eb55882e01c Merge from eCos master repository on 2002-05-29-16:32:18-BST
jlarmour
parents: 208
diff changeset
1271 // cleared, as per the RFC. We need the copy because these fields are
6eb55882e01c Merge from eCos master repository on 2002-05-29-16:32:18-BST
jlarmour
parents: 208
diff changeset
1272 // still useful to us (and currently stored in the 'result' structure)
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1273 xlen = dhcp_size_for_send( xmit );
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1274 bcopy( xmit, &xmit2, xlen );
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1275 xmit2.bp_yiaddr.s_addr = xmit2.bp_siaddr.s_addr = xmit2.bp_giaddr.s_addr = 0;
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1276 xmit2.bp_hops = 0;
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1277 if(sendto(s, &xmit2, xlen, 0,
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1278 // UNICAST address of the server:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1279 (struct sockaddr *)&server_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1280 sizeof(server_addr)) < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1281 *pstate = DHCPSTATE_FAILED;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1282 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1283 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1284
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1285 *pstate = DHCPSTATE_NOTBOUND;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1286 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1287
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1288 default:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1289 no_lease( lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1290 close(s);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1291 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1292 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1293 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1294 /* NOTREACHED */
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1295 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1296 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1297
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1298 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1299 // Bring an interface down, failed to initialize it or lease is expired
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1300 // Also part of normal startup, bring down for proper reinitialization
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1301
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1302 int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1303 do_dhcp_down_net(const char *intf, struct bootp *res,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1304 cyg_uint8 *pstate, struct dhcp_lease *lease)
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1305 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1306 struct sockaddr_in *addrp;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1307 struct ifreq ifr;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1308 int s;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1309
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1310 // Ensure clean slate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1311 cyg_route_reinit(); // Force any existing routes to be forgotten
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1312
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1313 s = socket(AF_INET, SOCK_DGRAM, 0);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1314 if (s < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1315 perror("socket");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1316 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1317 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1318
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1319 addrp = (struct sockaddr_in *) &ifr.ifr_addr;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1320
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1321 // Remove any existing address
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1322 if ( DHCPSTATE_FAILED == *pstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1323 || DHCPSTATE_INIT == *pstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1324 || 0 == *pstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1325 // it was configured for broadcast only, "half-up"
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1326 memset(addrp, 0, sizeof(*addrp));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1327 addrp->sin_family = AF_INET;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1328 addrp->sin_len = sizeof(*addrp);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1329 addrp->sin_port = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1330 addrp->sin_addr.s_addr = INADDR_ANY;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1331 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1332 else {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1333 // get the specific address that was used
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1334 strcpy(ifr.ifr_name, intf);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1335 if (ioctl(s, SIOCGIFADDR, &ifr)) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1336 perror("SIOCGIFADDR 1");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1337 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1338 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1339 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1340
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1341 strcpy(ifr.ifr_name, intf);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1342 if (ioctl(s, SIOCDIFADDR, &ifr)) { /* delete IF addr */
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1343 perror("SIOCDIFADDR1");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1344 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1345
253
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1346 #ifdef INET6
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1347 {
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1348 int s6;
897
07ad44cfd9a4 * src/dhcp_prot.c (do_dhcp_down_net): SIOCGLIFADDR and SIOCDLIFADDR
asl
parents: 490
diff changeset
1349 struct if_laddrreq iflr;
07ad44cfd9a4 * src/dhcp_prot.c (do_dhcp_down_net): SIOCGLIFADDR and SIOCDLIFADDR
asl
parents: 490
diff changeset
1350
253
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1351 s6 = socket(AF_INET6, SOCK_DGRAM, 0);
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1352 if (s6 < 0) {
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1353 perror("socket AF_INET6");
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1354 return false;
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1355 }
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1356 // Now delete the ipv6 addr
957
db3e0a2fda2f 2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
asl
parents: 897
diff changeset
1357 memset(&iflr,0,sizeof(iflr));
897
07ad44cfd9a4 * src/dhcp_prot.c (do_dhcp_down_net): SIOCGLIFADDR and SIOCDLIFADDR
asl
parents: 490
diff changeset
1358 strcpy(iflr.iflr_name, intf);
957
db3e0a2fda2f 2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
asl
parents: 897
diff changeset
1359 if (!ioctl(s6, SIOCGLIFADDR, &iflr)) {
253
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1360
957
db3e0a2fda2f 2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
asl
parents: 897
diff changeset
1361 strcpy(iflr.iflr_name, intf);
db3e0a2fda2f 2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
asl
parents: 897
diff changeset
1362 if (ioctl(s6, SIOCDLIFADDR, &ifr)) { /* delete IF addr */
db3e0a2fda2f 2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
asl
parents: 897
diff changeset
1363 perror("SIOCDIFADDR_IN61");
db3e0a2fda2f 2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
asl
parents: 897
diff changeset
1364 }
db3e0a2fda2f 2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
asl
parents: 897
diff changeset
1365 close(s6);
253
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1366 }
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1367 }
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1368 #endif /* IP6 */
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1369
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1370 // Shut down interface so it can be reinitialized
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1371 ifr.ifr_flags &= ~(IFF_UP | IFF_RUNNING);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1372 if (ioctl(s, SIOCSIFFLAGS, &ifr)) { /* set ifnet flags */
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1373 perror("SIOCSIFFLAGS down");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1374 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1375 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1376
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1377 // All done with socket
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1378 close(s);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1379
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1380 if ( 0 != *pstate ) // preserve initial state
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1381 *pstate = DHCPSTATE_INIT;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1382
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1383 return true;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1384 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1385
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1386 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1387 // Release (relinquish) a leased address - if we have one - and bring down
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1388 // the interface.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1389 int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1390 do_dhcp_release(const char *intf, struct bootp *res,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1391 cyg_uint8 *pstate, struct dhcp_lease *lease)
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1392 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1393 if ( 0 != *pstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1394 && DHCPSTATE_INIT != *pstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1395 && DHCPSTATE_NOTBOUND != *pstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1396 && DHCPSTATE_FAILED != *pstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1397 && DHCPSTATE_BOOTP_FALLBACK != *pstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1398 *pstate = DHCPSTATE_DO_RELEASE;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1399 do_dhcp( intf, res, pstate, lease ); // to send the release packet
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1400 cyg_thread_delay( 100 ); // to let it leave the building
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1401 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1402 return true;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1403 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1404
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1405 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1406
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1407 #endif // CYGPKG_NET_DHCP
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1408
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1409 // EOF dhcp_prot.c