annotate packages/net/common/current/src/dhcp_prot.c @ 2920:ca9867bef994

DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
author gthomas
date Wed, 23 Sep 2009 14:28:48 +0000
parents 74dbf4c3f2e1
children 9306ff8edcbf
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 //==========================================================================
2729
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
8 // ####ECOSGPLCOPYRIGHTBEGIN####
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
9 // -------------------------------------------
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
10 // This file is part of eCos, the Embedded Configurable Operating System.
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
12 //
2729
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
13 // eCos is free software; you can redistribute it and/or modify it under
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
14 // the terms of the GNU General Public License as published by the Free
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
15 // Software Foundation; either version 2 or (at your option) any later
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
16 // version.
490
7c34839e7e97 * src/bootp_support.c: Fix licence which should always have been
jlarmour
parents: 253
diff changeset
17 //
2729
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
18 // eCos is distributed in the hope that it will be useful, but WITHOUT
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
19 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
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 //
2729
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
23 // You should have received a copy of the GNU General Public License
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
24 // along with eCos; if not, write to the Free Software Foundation, Inc.,
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
25 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
26 //
2729
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
27 // As a special exception, if other files instantiate templates or use
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
28 // macros or inline functions from this file, or you compile this file
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
29 // and link it with other works to produce a work based on this file,
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
30 // this file does not by itself cause the resulting work to be covered by
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
31 // the GNU General Public License. However the source code for this file
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
32 // must still be made available in accordance with section (3) of the GNU
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
33 // General Public License v2.
490
7c34839e7e97 * src/bootp_support.c: Fix licence which should always have been
jlarmour
parents: 253
diff changeset
34 //
2729
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
35 // This exception does not invalidate any other reasons why a work based
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
36 // on this file might be covered by the GNU General Public License.
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
37 // -------------------------------------------
74dbf4c3f2e1 Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents: 2156
diff changeset
38 // ####ECOSGPLCOPYRIGHTEND####
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
39 //==========================================================================
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
40 //#####DESCRIPTIONBEGIN####
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 // Author(s): hmt
957
db3e0a2fda2f 2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
asl
parents: 897
diff changeset
43 // 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
44 // Date: 2000-07-01
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
45 // Purpose: DHCP support
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
46 // Description:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
47 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
48 //####DESCRIPTIONEND####
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
49 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
50 //========================================================================*/
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
51
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
52 #include <pkgconf/system.h>
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
53 #include <pkgconf/net.h>
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
54
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
55 #ifdef CYGPKG_NET_DHCP
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
56
1322
69a4719c04ad * src/dhcp_prot.c (set_default_dhcp_tags):
asl
parents: 1315
diff changeset
57 #ifdef CYGPKG_NET_SNTP
69a4719c04ad * src/dhcp_prot.c (set_default_dhcp_tags):
asl
parents: 1315
diff changeset
58 #include <pkgconf/net_sntp.h>
69a4719c04ad * src/dhcp_prot.c (set_default_dhcp_tags):
asl
parents: 1315
diff changeset
59 #endif /* CYGPKG_NET_SNTP */
69a4719c04ad * src/dhcp_prot.c (set_default_dhcp_tags):
asl
parents: 1315
diff changeset
60
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
61 #if 0
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
62 #define perror( txt ) // nothing
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
63 #endif
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
64
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
65 #include <network.h>
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
66 #include <dhcp.h>
235
f9db7cb0692e Pedantic include of <errno.h>
gthomas
parents: 229
diff changeset
67 #include <errno.h>
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
68
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
69 #include <cyg/infra/cyg_ass.h>
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
70
253
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
71 #ifdef INET6
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
72 #include <net/if_var.h>
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
73 #include <netinet6/in6_var.h>
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
74 #endif
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
75
1128
21aab473590c * src/dhcp_prot.c: Added a declaration for cyg_arc4random() to
nickg
parents: 957
diff changeset
76 extern int cyg_arc4random(void);
21aab473590c * src/dhcp_prot.c: Added a declaration for cyg_arc4random() to
nickg
parents: 957
diff changeset
77
1315
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
78 #ifdef CYGOPT_NET_DHCP_OPTION_HOST_NAME
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
79 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
80
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
81 // 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
82 // 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
83 // 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
84 void dhcp_set_hostname(char *hostname)
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
85 {
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
86 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
87 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
88 }
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
89 #endif
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
90
2156
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
91 /* Forward reference prototypes. */
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
92 static int unset_tag( struct bootp *ppkt, unsigned char tag );
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
93
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
94 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
95 // 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
96 // 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
97 // data.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
98
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
99 static unsigned char *
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
100 scan_dhcp_size( struct bootp *ppkt )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
101 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
102 unsigned char *op;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
103
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
104 op = &ppkt->bp_vend[0];
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
105 // First check for the cookie!
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
106 if ( op[0] != 99 ||
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
107 op[1] != 130 ||
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
108 op[2] != 83 ||
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
109 op[3] != 99 ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
110 CYG_FAIL( "Bad DHCP cookie" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
111 return NULL;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
112 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
113 op += 4;
1632
a5c7a6799462 + * src/bootp_support.c (get_bootp_option, show_bootp):
asl
parents: 1583
diff changeset
114
a5c7a6799462 + * src/bootp_support.c (get_bootp_option, show_bootp):
asl
parents: 1583
diff changeset
115 // This will only scan the options field.
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
116 while (*op != TAG_END) {
1632
a5c7a6799462 + * src/bootp_support.c (get_bootp_option, show_bootp):
asl
parents: 1583
diff changeset
117 if ( *op == TAG_PAD ) {
a5c7a6799462 + * src/bootp_support.c (get_bootp_option, show_bootp):
asl
parents: 1583
diff changeset
118 op++;
a5c7a6799462 + * src/bootp_support.c (get_bootp_option, show_bootp):
asl
parents: 1583
diff changeset
119 } else {
a5c7a6799462 + * src/bootp_support.c (get_bootp_option, show_bootp):
asl
parents: 1583
diff changeset
120 op += *(op+1)+2;
a5c7a6799462 + * src/bootp_support.c (get_bootp_option, show_bootp):
asl
parents: 1583
diff changeset
121 }
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
122 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
123 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
124 return NULL;
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 // Check op has not gone wild
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
128 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
129 // 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
130 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
131 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
132 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
133
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 // 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
136
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
137 static int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
138 dhcp_size( struct bootp *ppkt )
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 unsigned char *op;
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 op = scan_dhcp_size( ppkt );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
143 if ( !op ) return 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
144 return (op - (unsigned char *)ppkt);
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
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
147
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 // 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
150 // 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
151 // than BP_STD_TX_MINPKTSZ.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
152
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
153 static int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
154 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
155 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
156 unsigned char *op;
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 op = scan_dhcp_size( ppkt );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
159 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
160 // 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
161 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
162 *op = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
163 return (op - (unsigned char *)ppkt);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
164 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
165
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
166 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
167 // 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
168
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
169 static int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
170 set_fixed_tag( struct bootp *ppkt,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
171 unsigned char tag,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
172 cyg_uint32 value,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
173 int len)
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
174 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
175 unsigned char *op;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
176
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
177 // 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
178
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
179 op = &ppkt->bp_vend[4];
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
180 while (*op != TAG_END) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
181 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
182 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
183 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
184 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
185 if (*op == tag) // Found it...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
186 break;
2156
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
187 if ( *op == TAG_PAD ) {
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
188 op++;
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
189 } else {
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
190 op += *(op+1)+2;
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
191 }
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
192 }
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 if (*op == tag) { // Found it...
2156
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
195 /* There are three possibilities:
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
196 * 1) *(op+1) == len
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
197 * 2) *(op+1) > len
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
198 * 3) *(op+1) < len
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
199 * For 1, just overwrite the existing option data.
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
200 * For 2, overwrite the existing option data and pullup the
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
201 * remaining option data (if any).
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
202 * For 3, pullup any remaining option data to remove the option
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
203 * and then add the option to the end.
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
204 * For simplicity, for case 2 and 3, we just call unset_tag()
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
205 * and re-add the option to the end.
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
206 */
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
207 if ( *(op+1) != len ) {
2156
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
208 /* Remove existing option entry. */
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
209 unset_tag(ppkt, tag);
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
210 /* Adjust the op pointer to re-add at the end. */
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
211 op = scan_dhcp_size(ppkt);
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
212 CYG_ASSERT(op!=NULL, "Invalid options size in set_fixed_tag" );
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
213 op--;
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
214 CYG_ASSERT(*op==TAG_END, "Missing TAG_END in set_fixed_tag");
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
215 if ( op + len + 2 > &ppkt->bp_vend[BP_VEND_LEN-1] ) {
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
216 CYG_FAIL( "Oversize DHCP packet in set_fixed_tag replace" );
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
217 return false;
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
218 }
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
219 *op = tag;
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
220 *(op+1) = len;
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
221 *(op + len + 2) = TAG_END;
208
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 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
224 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
225 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
226 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
227 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
228 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
229 *op = tag;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
230 *(op+1) = len;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
231 *(op + len + 2) = TAG_END;
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 // 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
234 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
235 while ( len-- > 0 ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
236 *op-- = (unsigned char)(value & 255);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
237 value >>= 8;
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 return true;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
240 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
241
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
242 static int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
243 set_variable_tag( struct bootp *ppkt,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
244 unsigned char tag,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
245 cyg_uint8 *pvalue,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
246 int len)
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 unsigned char *op;
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 // 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
251 op = &ppkt->bp_vend[4];
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
252 while (*op != TAG_END) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
253 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
254 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
255 return false;
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 if (*op == tag) // Found it...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
258 break;
2156
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
259 if ( *op == TAG_PAD ) {
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
260 op++;
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
261 } else {
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
262 op += *(op+1)+2;
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
263 }
208
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
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
266 if (*op == tag) { // Found it...
2156
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
267 /* There are three possibilities:
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
268 * 1) *(op+1) == len
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
269 * 2) *(op+1) > len
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
270 * 3) *(op+1) < len
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
271 * For 1, just overwrite the existing option data.
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
272 * For 2, overwrite the existing option data and pullup the
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
273 * remaining option data (if any).
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
274 * For 3, pullup any remaining option data to remove the option
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
275 * and then add the option to the end.
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
276 * For simplicity, for case 2 and 3, we just call unset_tag()
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
277 * and re-add the option to the end.
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
278 */
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
279 if ( *(op+1) != len ) {
2156
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
280 /* Remove existing option entry. */
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
281 unset_tag(ppkt, tag);
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
282 /* Adjust the op pointer to re-add at the end. */
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
283 op = scan_dhcp_size(ppkt);
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
284 CYG_ASSERT(op!=NULL, "Invalid options size in set_variable_tag" );
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
285 op--;
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
286 CYG_ASSERT(*op==TAG_END, "Missing TAG_END in set_variable_tag");
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
287 if ( op + len + 2 > &ppkt->bp_vend[BP_VEND_LEN-1] ) {
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
288 CYG_FAIL( "Oversize DHCP packet in set_variable_tag replace" );
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
289 return false;
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
290 }
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
291 *op = tag;
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
292 *(op+1) = len;
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
293 *(op + len + 2) = TAG_END;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
294 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
295 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
296 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
297 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
298 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
299 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
300 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
301 *op = tag;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
302 *(op+1) = len;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
303 *(op + len + 2) = TAG_END;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
304 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
305 // 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
306 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
307 while ( len-- > 0 ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
308 *op++ = *pvalue++;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
309 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
310 return true;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
311 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
312
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
313 static int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
314 unset_tag( struct bootp *ppkt,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
315 unsigned char tag )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
316 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
317 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
318
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
319 // 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
320
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
321 op = &ppkt->bp_vend[4];
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
322 while (*op != TAG_END) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
323 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
324 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
325 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
326 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
327 if (*op == tag) { // Found it...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
328 killp = op; // item to kill
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
329 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
330 }
2156
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
331 if ( *op == TAG_PAD ) {
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
332 op++;
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
333 } else {
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
334 op += *(op+1)+2;
1cde7dd73fff * src/dhcp_prot.c: Updated set_fixed_tag(), set_variable_tag(),
asl
parents: 2025
diff changeset
335 }
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
336 }
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 if ( !killp )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
339 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
340
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
341 // 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
342 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
343 *killp++ = *nextp++;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
344
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
345 return true;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
346 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
347
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 // 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
350
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
351 static int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
352 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
353 {
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
354 int s = -1;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
355 int one = 1;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
356
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
357 struct sockaddr_in *addrp;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
358 struct ecos_rtentry route;
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
359 int retcode = false;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
360
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
361 // Ensure clean slate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
362 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
363
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
364 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
365 if (s < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
366 perror("socket");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
367 goto out;
208
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
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
370 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
371 perror("setsockopt");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
372 goto out;
208
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 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
376 memset(addrp, 0, sizeof(*addrp));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
377 addrp->sin_family = AF_INET;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
378 addrp->sin_len = sizeof(*addrp);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
379 addrp->sin_port = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
380 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
381
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
382 strcpy(ifrp->ifr_name, intf);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
383 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
384 perror("SIOCSIFADDR");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
385 goto out;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
386 }
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 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
389 perror("SIOCSIFNETMASK");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
390 goto out;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
391 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
392
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
393 /* 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
394 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
395 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
396 perror("SIOCSIFBRDADDR");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
397 goto out;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
398 }
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 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
401 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
402 perror("SIOCSIFFLAGS up");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
403 goto out;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
404 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
405
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
406 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
407 perror("SIOCGIFHWADDR 1");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
408 goto out;
208
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
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
411 // Set up routing
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
412 addrp->sin_family = AF_INET;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
413 addrp->sin_port = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
414 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
415
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
416 /* 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
417 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
418 memset(&route, 0, sizeof(route));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
419 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
420
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
421 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
422 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
423 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
424
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
425 route.rt_dev = ifrp->ifr_name;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
426 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
427 route.rt_metric = 0;
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 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
430 if (errno != EEXIST) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
431 perror("SIOCADDRT 3");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
432 goto out;
208
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 }
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
435 retcode = true;
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
436 out:
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
437 if (s != -1)
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
438 close(s);
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
439
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
440 return retcode;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
441 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
442
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
443
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
444 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
445 // 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
446 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
447 // 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
448 // 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
449 // 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
450
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
451 static unsigned char timeout_random = 0;
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 struct timeout_state {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
454 unsigned int secs;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
455 int countdown;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
456 };
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
457
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
458 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
459 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
460 timeout_random++;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
461 pstate->countdown = 4; // initial fast retries
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
462 pstate->secs = 3 + (timeout_random & 3);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
463 ptv->tv_sec = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
464 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
465 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
466
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
467 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
468 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
469 if ( 0 < pstate->countdown-- )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
470 return true;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
471 if ( 0 == ptv->tv_sec )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
472 ptv->tv_sec = pstate->secs;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
473 else {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
474 timeout_random++;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
475 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
476 pstate->countdown = 2; // later fast retries
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
477 ptv->tv_sec = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
478 }
1531
cbea1375c6da * cdl/net.cdl:
asl
parents: 1505
diff changeset
479 // If longer, too many tries...
cbea1375c6da * cdl/net.cdl:
asl
parents: 1505
diff changeset
480 return pstate->secs < CYGNUM_NET_DHCP_MIN_RETRY_TIME;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
481 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
482
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 // 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
485
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
486 static cyg_alarm_t alarm_function;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
487
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
488 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
489 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
490 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
491 lease->which |= lease->next;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
492 if ( lease->needs_attention )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
493 cyg_semaphore_post( lease->needs_attention );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
494
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
495 // 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
496 if ( lease->next & DHCP_LEASE_EX ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
497 cyg_alarm_disable( alarm );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
498 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
499 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
500 lease->next = DHCP_LEASE_EX;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
501 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
502 cyg_alarm_enable( lease->alarm );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
503 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
504 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
505 lease->next = DHCP_LEASE_T2;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
506 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
507 cyg_alarm_enable( lease->alarm );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
508 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
509 }
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 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
512 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
513 if ( lease->alarm ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
514 // Already set: delete this.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
515 cyg_alarm_disable( lease->alarm );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
516 cyg_alarm_delete( lease->alarm );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
517 lease->alarm = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
518 }
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
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
521 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
522 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
523 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
524 cyg_tick_count_t then;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
525 cyg_uint32 tag = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
526 cyg_uint32 expiry_then;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
527 cyg_resolution_t resolution =
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
528 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
529 cyg_handle_t h;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
530 unsigned int length;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
531
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
532 // 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
533 no_lease( lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
534 lease->which = lease->next = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
535 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
536 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
537 &lease->alarm, &lease->alarm_obj );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
538
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
539 // 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
540 length = sizeof(tag);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
541 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
542 tag = 0xffffffff;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
543
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
544 if ( 0xffffffff == tag ) {
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
545 lease->expiry = 0xffffffff;
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
546 lease->t2 = 0xffffffff;
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
547 lease->t1 = 0xffffffff;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
548 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
549 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
550
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
551 then = (cyg_uint64)(ntohl(tag));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
552 expiry_then = then;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
553
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
554 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
555 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
556 lease->expiry = now + then;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
557 length = sizeof(tag);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
558 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
559 then = (cyg_uint64)(ntohl(tag));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
560 else
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
561 then = expiry_then - expiry_then/4;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
562 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
563 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
564 lease->t2 = now + then;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
565
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
566 length = sizeof(tag);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
567 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
568 then = (cyg_uint64)(ntohl(tag));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
569 else
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
570 then = expiry_then/2;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
571 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
572 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
573 lease->t1 = now + then;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
574
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
575 #if 0 // for testing this mechanism
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
576 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
577 lease->t2 = now + 3500;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
578 lease->t1 = now + 2500;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
579 #endif
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
580
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
581 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
582 diag_printf("new_lease:\n");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
583 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
584 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
585 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
586 #endif
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
587
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
588 lease->next = DHCP_LEASE_T1;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
589
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
590 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
591 cyg_alarm_enable( lease->alarm );
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
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
594 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
595 // 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
596 // 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
597 // with a variety of DHCP servers.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
598
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
599 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
600 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
601 // 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
602 // 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
603 // 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
604 // 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
605 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
606 // Here's the set:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
607 static cyg_uint8 req_list[] = {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
608 #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
609 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
610 #else
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
611 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
612 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
613 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
614 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
615 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
616 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
617 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
618 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
619 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
620 #endif
1322
69a4719c04ad * src/dhcp_prot.c (set_default_dhcp_tags):
asl
parents: 1315
diff changeset
621 #ifdef CYGNUM_NET_SNTP_UNICAST_MAXDHCP
69a4719c04ad * src/dhcp_prot.c (set_default_dhcp_tags):
asl
parents: 1315
diff changeset
622 TAG_NTP_SERVER , // NTP Server Addresses(es)
69a4719c04ad * src/dhcp_prot.c (set_default_dhcp_tags):
asl
parents: 1315
diff changeset
623 #endif
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
624 #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
625 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
626 #endif
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
627 };
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
628
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
629 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
630 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
631 &req_list[0], sizeof( req_list ) );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
632
1315
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
633 #ifdef CYGOPT_NET_DHCP_OPTION_HOST_NAME
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
634 {
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
635 int nlen = strlen(dhcp_hostname);
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
636
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
637 if (nlen > 0)
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
638 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
639 }
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
640 #endif
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
641 #ifdef CYGOPT_NET_DHCP_OPTION_DHCP_CLIENTID_MAC
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
642 {
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
643 cyg_uint8 id[16+1]; /* sizeof bp_chaddr[] + 1 */
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
644
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
645 id[0] = 1; /* 1-byte hardware type: 1=ethernet. */
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
646 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
647 memcpy(&id[1], &xmit->bp_chaddr, xmit->bp_hlen);
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
648 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
649 }
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
650 #endif
49e5a36e706d * include/dhcp.h: Added prototype for dhcp_set_hostname().
asl
parents: 1144
diff changeset
651
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
652 // Explicitly specify our max message size.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
653 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
654 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
655
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
656 // ------------------------------------------------------------------------
2920
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
657 // Get BOOTP/DHCP response.
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
658 // Wait up to the amount of time specified by *tvp.
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
659
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
660 static int
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
661 get_response(int s, struct bootp *response, struct sockaddr_in *from, struct timeval *tvp)
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
662 {
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
663 int pktlen;
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
664 socklen_t addrlen;
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
665
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
666 setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, tvp, sizeof(*tvp));
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
667
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
668 addrlen = sizeof(*from);
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
669 pktlen = recvfrom(s, response, sizeof(*response), 0, (struct sockaddr *)from, &addrlen);
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
670 /* Some DHCP servers don't terminate the options list with
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
671 * an END tag. Append one if we can.
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
672 */
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
673 if ((pktlen >= 0) && (pktlen < sizeof(*response)))
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
674 {
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
675 /* Do not count the added END tag in the returned packet length.
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
676 * The returned packet length is the number of bytes received
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
677 * from the DHCP server. The added END tag is only used
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
678 * internally for packet parsing purposes.
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
679 */
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
680 ((unsigned char *)response)[pktlen] = TAG_END;
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
681 }
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
682 return pktlen;
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
683 }
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
684
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
685 // ------------------------------------------------------------------------
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
686 // 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
687
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
688 int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
689 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
690 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
691 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
692 struct ifreq ifr;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
693 struct sockaddr_in cli_addr, broadcast_addr, server_addr, rx_addr;
2025
2de3997bad7b * src/tftp_dummy_file.c: unsigned char when needed to prevent warnings.
asl
parents: 1632
diff changeset
694 int s = -1;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
695 int one = 1;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
696 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
697 struct timeval tv;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
698 struct timeout_state timeout_scratch;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
699 cyg_uint8 oldstate = *pstate;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
700 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
701 unsigned int length;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
702
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
703 cyg_uint32 xid;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
704
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
705 #define CHECK_XID() ( /* and other details */ \
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
706 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
707 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
708 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
709 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
710 )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
711
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
712 // 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
713 // 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
714 // 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
715 // existing state.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
716 struct bootp rx_local;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
717 struct bootp *received = &rx_local;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
718 struct bootp *xmit = res;
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
719 struct bootp xmit2;
216
da643977bd0a Improve DHCP reply handling
gthomas
parents: 211
diff changeset
720 int xlen;
208
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 // 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
723 // 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
724
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
725 if ( DHCPSTATE_INIT == oldstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
726 || DHCPSTATE_FAILED == oldstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
727 || 0 == oldstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
728 // 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
729 if ( ! bring_half_up( intf, &ifr ) )
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
730 return false;
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 *pstate = DHCPSTATE_INIT;
1144
c9c183d9b60a * src/dhcp_prot.c (do_dhcp): (re)Initialize the lease when
asl
parents: 1128
diff changeset
733 lease->which = lease->next = 0;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
734 }
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 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
737 if (s < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
738 perror("socket");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
739 goto out;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
740 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
741
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
742 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
743 perror("setsockopt");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
744 goto out;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
745 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
746
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
747 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
748 cli_addr.sin_family = AF_INET;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
749 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
750 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
751 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
752
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
753 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
754 broadcast_addr.sin_family = AF_INET;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
755 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
756 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
757 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
758
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
759 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
760 server_addr.sin_family = AF_INET;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
761 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
762 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
763 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
764
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
765 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
766 perror("bind error");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
767 goto out;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
768 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
769 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
770 perror("setsockopt SO_REUSEADDR");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
771 goto out;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
772 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
773 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
774 perror("setsockopt SO_REUSEPORT");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
775 goto out;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
776 }
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 // 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
779 // 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
780 // 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
781
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
782 reset_timeout( &tv, &timeout_scratch );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
783
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
784 // 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
785 strcpy(&ifr.ifr_name[0], intf);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
786 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
787 perror("SIOCGIFHWADDR 2");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
788 goto out;
208
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
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
791 // 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
792 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
793 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
794 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
795 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
796 xid ^= (cyg_arc4random() & 0xffff0000);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
797
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
798 // Avoid adjacent ESAs colliding by increment
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
799 #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
800
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
801 while ( 1 ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
802
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
803 // 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
804 // 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
805 // *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
806 // for example.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
807 if ( DHCPSTATE_DO_RELEASE != *pstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
808 && DHCPSTATE_NOTBOUND != *pstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
809 && DHCPSTATE_FAILED != *pstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
810 cyg_uint8 lease_state;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
811
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
812 cyg_scheduler_lock();
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
813 lease_state = lease->which;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
814 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
815 cyg_scheduler_unlock();
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
816
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
817 if ( lease_state & DHCP_LEASE_EX ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
818 // then the lease has expired completely!
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
819 *pstate = DHCPSTATE_NOTBOUND;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
820 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
821 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
822 // Time to renew
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
823 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
824 *pstate = DHCPSTATE_REBINDING;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
825 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
826 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
827 // Time to renew
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
828 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
829 *pstate = DHCPSTATE_RENEWING;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
830 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
831 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
832
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
833 switch ( *pstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
834
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
835 case DHCPSTATE_INIT:
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 // Send the DHCPDISCOVER packet
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
838
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
839 // 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
840 bzero(xmit, sizeof(*xmit));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
841 xmit->bp_op = BOOTREQUEST;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
842 xmit->bp_htype = HTYPE_ETHERNET;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
843 xmit->bp_hlen = IFHWADDRLEN;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
844 xmit->bp_xid = xid;
1505
f2168dd5be4e Initialize bp_secs field for stubborn DHCP servers - from Matt Jerdonek
gthomas
parents: 1322
diff changeset
845 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
846 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
847 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
848 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
849
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
850 // 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
851 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
852 // 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
853 set_default_dhcp_tags( xmit );
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 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
856 diag_printf( "---------DHCPSTATE_INIT sending:\n" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
857 show_bootp( intf, xmit );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
858 #endif
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
859 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
860 (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
861 *pstate = DHCPSTATE_FAILED;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
862 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
863 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
864
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
865 seen_bootp_reply = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
866 *pstate = DHCPSTATE_SELECTING;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
867 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
868
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
869 case DHCPSTATE_SELECTING:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
870 // 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
871 // *without* retransmitting.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
872
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
873 // listen for the DHCPOFFER reply
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
874
2920
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
875 if (get_response(s, received, &rx_addr, &tv) < 0) {
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
876 // No packet arrived (this time)
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
877 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
878 // Save the good packet in *xmit
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
879 bcopy( received, xmit, dhcp_size(received) );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
880 *pstate = DHCPSTATE_BOOTP_FALLBACK;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
881 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
882 reset_timeout( &tv, &timeout_scratch );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
883 break;
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 // 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
886 if ( ! next_timeout( &tv, &timeout_scratch ) ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
887 *pstate = DHCPSTATE_FAILED;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
888 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
889 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
890 *pstate = DHCPSTATE_INIT; // to retransmit
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
891 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
892 }
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
893 // 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
894 length = dhcp_size( received );
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
895 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
896 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
897 if ( length <= 0 )
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
898 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
899 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
900 rx_addr.sin_family,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
901 rx_addr.sin_addr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
902 rx_addr.sin_port );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
903 show_bootp( intf, received );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
904 #endif
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
905 if ( length <= 0 )
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
906 break;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
907 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
908 break; // listen again...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
909
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
910 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
911 // then fill in from the options...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
912 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
913 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
914 &received->bp_siaddr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
915 &length);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
916 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
917
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
918 // 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
919 // either.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
920 length = sizeof(msgtype);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
921 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
922 &length) ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
923 if ( DHCPOFFER == msgtype ) { // all is well
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
924 // Save the good packet in *xmit
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
925 bcopy( received, xmit, dhcp_size(received) );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
926 // 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
927 reset_timeout( &tv, &timeout_scratch );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
928 *pstate = DHCPSTATE_REQUESTING;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
929 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
930 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
931 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
932 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
933 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
934
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
935 // 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
936 // 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
937 // 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
938 // 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
939 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
940
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
941 case DHCPSTATE_REQUESTING:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
942 // 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
943 // 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
944
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
945 // 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
946 xmit->bp_xid = xid;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
947 xmit->bp_op = BOOTREQUEST;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
948 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
949
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
950 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
951 // 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
952 set_default_dhcp_tags( xmit );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
953 // 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
954 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
955
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
956 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
957 diag_printf( "---------DHCPSTATE_REQUESTING sending:\n" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
958 show_bootp( intf, xmit );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
959 #endif
211
6eb55882e01c Merge from eCos master repository on 2002-05-29-16:32:18-BST
jlarmour
parents: 208
diff changeset
960 // 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
961 // 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
962 // 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
963 xlen = dhcp_size_for_send( xmit );
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
964 bcopy( xmit, &xmit2, xlen );
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
965 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
966 xmit2.bp_hops = 0;
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
967 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
968 (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
969 *pstate = DHCPSTATE_FAILED;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
970 break;
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 *pstate = DHCPSTATE_REQUEST_RECV;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
974 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
975
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
976 case DHCPSTATE_REQUEST_RECV:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
977 // 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
978 // 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
979
2920
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
980 if (get_response(s, received, &rx_addr, &tv) < 0) {
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
981 // No packet arrived
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
982 // 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
983 if ( ! next_timeout( &tv, &timeout_scratch ) ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
984 *pstate = DHCPSTATE_FAILED;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
985 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
986 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
987 *pstate = DHCPSTATE_REQUESTING;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
988 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
989 }
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
990 // 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
991 length = dhcp_size( received );
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
992 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
993 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
994 if ( length <= 0 )
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
995 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
996 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
997 rx_addr.sin_family,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
998 rx_addr.sin_addr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
999 rx_addr.sin_port );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1000 show_bootp( intf, received );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1001 #endif
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1002 if ( length <= 0 )
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1003 break;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1004 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
1005 break; // listen again...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1006
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1007 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
1008 // then fill in from the options...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1009 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
1010 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
1011 &received->bp_siaddr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1012 &length);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1013 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1014
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1015 // check it was a DHCP reply
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1016 length = sizeof(msgtype);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1017 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
1018 &length) ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1019 if ( DHCPACK == msgtype // Same offer & server?
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1020 && 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
1021 && 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
1022 // 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
1023 reset_timeout( &tv, &timeout_scratch );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1024 // 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
1025 new_lease( received, lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1026 *pstate = DHCPSTATE_BOUND;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1027 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1028 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1029 if ( DHCPNAK == msgtype // Same server?
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1030 && 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
1031 // we're bounced!
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1032 *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
1033 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
1034 reset_timeout( &tv, &timeout_scratch );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1035 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1036 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1037 // 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
1038 // 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
1039 // 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
1040 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1041 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1042
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1043 case DHCPSTATE_BOUND:
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 // 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
1046
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1047 // All done with socket
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1048 close(s);
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1049 s = -1;
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1050
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1051 // 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
1052 if ( DHCPSTATE_BOUND != oldstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1053 // 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
1054 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
1055 if ( 0 != oldstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1056 // 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
1057 // 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
1058 if (!init_net(intf, res)) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1059 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
1060 *pstate = DHCPSTATE_FAILED;
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1061 goto out;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1062 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1063 }
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
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1066 // Otherwise, nothing whatsoever to do...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1067 return true;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1068
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1069 case DHCPSTATE_RENEWING:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1070 // 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
1071 // 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
1072
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1073 // 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
1074 xmit->bp_xid = xid;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1075 xmit->bp_op = BOOTREQUEST;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1076 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
1077 // Use the *client* address here:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1078 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
1079
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1080 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
1081 // 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
1082 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
1083 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
1084 // 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
1085 set_default_dhcp_tags( xmit );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1086
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1087 // Set unicast address to *server*
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1088 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
1089
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1090 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1091 diag_printf( "---------DHCPSTATE_RENEWING sending:\n" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1092 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
1093 server_addr.sin_family,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1094 server_addr.sin_addr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1095 server_addr.sin_port );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1096 show_bootp( intf, xmit );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1097 #endif
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1098
211
6eb55882e01c Merge from eCos master repository on 2002-05-29-16:32:18-BST
jlarmour
parents: 208
diff changeset
1099 // 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
1100 // 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
1101 // still useful to us (and currently stored in the 'result' structure)
216
da643977bd0a Improve DHCP reply handling
gthomas
parents: 211
diff changeset
1102 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
1103 bcopy( xmit, &xmit2, xlen );
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1104 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
1105 xmit2.bp_hops = 0;
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1106 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
1107 // UNICAST address of the server:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1108 (struct sockaddr *)&server_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1109 sizeof(server_addr)) < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1110 *pstate = DHCPSTATE_FAILED;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1111 break;
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
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1114 *pstate = DHCPSTATE_RENEW_RECV;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1115 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1116
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1117 case DHCPSTATE_RENEW_RECV:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1118 // 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
1119 // 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
1120 // 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
1121
2920
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
1122 if (get_response(s, received, &rx_addr, &tv) < 0) {
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1123 // No packet arrived
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1124 // 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
1125 if ( ! next_timeout( &tv, &timeout_scratch ) ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1126 // 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
1127 // 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
1128 // 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
1129 // necessary.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1130 *pstate = DHCPSTATE_BOUND;
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 *pstate = DHCPSTATE_RENEWING;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1134 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1135 }
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1136 // 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
1137 length = dhcp_size( received );
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1138 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1139 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
1140 if ( length <= 0 )
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1141 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
1142 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
1143 rx_addr.sin_family,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1144 rx_addr.sin_addr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1145 rx_addr.sin_port );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1146 show_bootp( intf, received );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1147 #endif
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1148 if ( length <= 0 )
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1149 break;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1150 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
1151 break; // listen again...
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 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
1154 // then fill in from the options...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1155 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
1156 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
1157 &received->bp_siaddr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1158 &length);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1159 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1160
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1161 // check it was a DHCP reply
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1162 length = sizeof(msgtype);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1163 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
1164 &length) ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1165 if ( DHCPACK == msgtype // Same offer?
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1166 && 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
1167 // 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
1168 reset_timeout( &tv, &timeout_scratch );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1169 // 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
1170 new_lease( received, lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1171 *pstate = DHCPSTATE_BOUND;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1172 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1173 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1174 if ( DHCPNAK == msgtype ) { // we're bounced!
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1175 *pstate = DHCPSTATE_NOTBOUND; // So quit out.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1176 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1177 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1178 // 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
1179 // 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
1180 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1181 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1182
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1183 case DHCPSTATE_REBINDING:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1184 // 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
1185 // 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
1186
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1187 // 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
1188 xmit->bp_xid = xid;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1189 xmit->bp_op = BOOTREQUEST;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1190 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
1191 // Use the *client* address here:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1192 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
1193
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1194 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
1195 // 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
1196 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
1197 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
1198 // 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
1199 set_default_dhcp_tags( xmit );
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 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1202 diag_printf( "---------DHCPSTATE_REBINDING sending:\n" );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1203 show_bootp( intf, xmit );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1204 #endif
211
6eb55882e01c Merge from eCos master repository on 2002-05-29-16:32:18-BST
jlarmour
parents: 208
diff changeset
1205 // 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
1206 // 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
1207 // 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
1208 xlen = dhcp_size_for_send( xmit );
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1209 bcopy( xmit, &xmit2, xlen );
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1210 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
1211 xmit2.bp_hops = 0;
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1212 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
1213 (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
1214 *pstate = DHCPSTATE_FAILED;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1215 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1216 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1217
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1218 *pstate = DHCPSTATE_REBIND_RECV;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1219 break;
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 case DHCPSTATE_REBIND_RECV:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1222 // 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
1223 // 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
1224 // 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
1225
2920
ca9867bef994 DHCP parsing improvement/bugfix from Jay Foster <jay@systech.com>
gthomas
parents: 2729
diff changeset
1226 if (get_response(s, received, &rx_addr, &tv) < 0) {
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1227 // No packet arrived
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1228 // 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
1229 if ( ! next_timeout( &tv, &timeout_scratch ) ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1230 // 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
1231 // 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
1232 // 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
1233 // when necessary.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1234 *pstate = DHCPSTATE_BOUND;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1235 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1236 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1237 *pstate = DHCPSTATE_REBINDING;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1238 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1239 }
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1240 // 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
1241 length = dhcp_size( received );
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1242 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1243 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
1244 if ( length <= 0 )
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1245 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
1246 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
1247 rx_addr.sin_family,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1248 rx_addr.sin_addr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1249 rx_addr.sin_port );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1250 show_bootp( intf, received );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1251 #endif
229
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1252 if ( length <= 0 )
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1253 break;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1254 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
1255 break; // listen again...
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 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
1258 // then fill in from the options...
2025
2de3997bad7b * src/tftp_dummy_file.c: unsigned char when needed to prevent warnings.
asl
parents: 1632
diff changeset
1259 unsigned int length = sizeof(received->bp_siaddr.s_addr );
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1260 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
1261 &received->bp_siaddr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1262 &length);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1263 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1264
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1265 // check it was a DHCP reply
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1266 length = sizeof(msgtype);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1267 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
1268 &length) ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1269 if ( DHCPACK == msgtype // Same offer?
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1270 && 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
1271 // 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
1272 reset_timeout( &tv, &timeout_scratch );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1273 // 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
1274 new_lease( received, lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1275 *pstate = DHCPSTATE_BOUND;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1276 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1277 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1278 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
1279 *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
1280 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1281 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1282 // 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
1283 // 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
1284 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1285 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1286
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1287 case DHCPSTATE_BOOTP_FALLBACK:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1288 // All done with socket
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1289 close(s);
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1290 s = -1;
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1291
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1292 // 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
1293 no_lease( lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1294 // 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
1295 if ( DHCPSTATE_BOOTP_FALLBACK != oldstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1296 // 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
1297 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
1298 if ( 0 != oldstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1299 // 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
1300 // 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
1301 if (!init_net(intf, res)) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1302 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
1303 *pstate = DHCPSTATE_FAILED;
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1304 goto out;
208
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 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1307 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1308
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1309 // Otherwise, nothing whatsoever to do...
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1310 return true;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1311
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1312 case DHCPSTATE_NOTBOUND:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1313 // All done with socket
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1314 close(s);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1315 // No lease active
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1316 no_lease( lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1317 // 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
1318 return true;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1319
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1320 case DHCPSTATE_FAILED:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1321 // All done with socket
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1322 close(s);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1323 // No lease active
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1324 no_lease( lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1325 // Unconditionally down the interface.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1326 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
1327 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1328
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1329 case DHCPSTATE_DO_RELEASE:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1330 // 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
1331 // lease for graceful shutdown.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1332
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1333 // 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
1334 // 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
1335 // NOTBOUND state.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1336 NEW_XID( xid );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1337 xmit->bp_xid = xid;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1338 xmit->bp_op = BOOTREQUEST;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1339 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
1340 // Use the *client* address here:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1341 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
1342
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1343 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
1344
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1345 // Set unicast address to *server*
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1346 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
1347
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1348 #ifdef CYGDBG_NET_DHCP_CHATTER
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1349 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
1350 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
1351 server_addr.sin_family,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1352 server_addr.sin_addr.s_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1353 server_addr.sin_port );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1354 show_bootp( intf, xmit );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1355 #endif
211
6eb55882e01c Merge from eCos master repository on 2002-05-29-16:32:18-BST
jlarmour
parents: 208
diff changeset
1356 // 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
1357 // 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
1358 // 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
1359 xlen = dhcp_size_for_send( xmit );
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1360 bcopy( xmit, &xmit2, xlen );
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1361 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
1362 xmit2.bp_hops = 0;
ff3465255c3a * src/dhcp_prot.c (_dhcp_copy): Remove. Unnecessary as we can never
jlarmour
parents: 216
diff changeset
1363 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
1364 // UNICAST address of the server:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1365 (struct sockaddr *)&server_addr,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1366 sizeof(server_addr)) < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1367 *pstate = DHCPSTATE_FAILED;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1368 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1369 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1370
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1371 *pstate = DHCPSTATE_NOTBOUND;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1372 break;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1373
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1374 default:
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1375 no_lease( lease );
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1376 close(s);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1377 return false;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1378 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1379 }
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1380 out:
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1381 if (s != -1)
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1382 close (s);
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1383
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1384 return false;
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 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1388 // 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
1389 // 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
1390
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1391 int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1392 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
1393 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
1394 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1395 struct sockaddr_in *addrp;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1396 struct ifreq ifr;
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1397 int s = -1;
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1398 int retcode = false;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1399
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1400 // Ensure clean slate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1401 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
1402
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1403 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
1404 if (s < 0) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1405 perror("socket");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1406 goto out;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1407 }
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 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
1410
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1411 // Remove any existing address
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1412 if ( DHCPSTATE_FAILED == *pstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1413 || DHCPSTATE_INIT == *pstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1414 || 0 == *pstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1415 // 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
1416 memset(addrp, 0, sizeof(*addrp));
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1417 addrp->sin_family = AF_INET;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1418 addrp->sin_len = sizeof(*addrp);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1419 addrp->sin_port = 0;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1420 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
1421 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1422 else {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1423 // 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
1424 strcpy(ifr.ifr_name, intf);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1425 if (ioctl(s, SIOCGIFADDR, &ifr)) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1426 perror("SIOCGIFADDR 1");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1427 goto out;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1428 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1429 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1430
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1431 strcpy(ifr.ifr_name, intf);
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1432 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
1433 perror("SIOCDIFADDR1");
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1434 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1435
253
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1436 #ifdef INET6
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1437 {
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1438 int s6;
897
07ad44cfd9a4 * src/dhcp_prot.c (do_dhcp_down_net): SIOCGLIFADDR and SIOCDLIFADDR
asl
parents: 490
diff changeset
1439 struct if_laddrreq iflr;
07ad44cfd9a4 * src/dhcp_prot.c (do_dhcp_down_net): SIOCGLIFADDR and SIOCDLIFADDR
asl
parents: 490
diff changeset
1440
253
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1441 s6 = socket(AF_INET6, SOCK_DGRAM, 0);
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1442 if (s6 < 0) {
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1443 perror("socket AF_INET6");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1444 close (s);
253
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1445 return false;
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1446 }
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1447 // Now delete the ipv6 addr
957
db3e0a2fda2f 2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
asl
parents: 897
diff changeset
1448 memset(&iflr,0,sizeof(iflr));
897
07ad44cfd9a4 * src/dhcp_prot.c (do_dhcp_down_net): SIOCGLIFADDR and SIOCDLIFADDR
asl
parents: 490
diff changeset
1449 strcpy(iflr.iflr_name, intf);
957
db3e0a2fda2f 2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
asl
parents: 897
diff changeset
1450 if (!ioctl(s6, SIOCGLIFADDR, &iflr)) {
253
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1451
957
db3e0a2fda2f 2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
asl
parents: 897
diff changeset
1452 strcpy(iflr.iflr_name, intf);
db3e0a2fda2f 2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
asl
parents: 897
diff changeset
1453 if (ioctl(s6, SIOCDLIFADDR, &ifr)) { /* delete IF addr */
db3e0a2fda2f 2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
asl
parents: 897
diff changeset
1454 perror("SIOCDIFADDR_IN61");
db3e0a2fda2f 2003-04-12 Andrew Lunn <andrew.lunn@ascom.ch>
asl
parents: 897
diff changeset
1455 }
253
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1456 }
1583
3d8f3b1724be * src/bootp_support.c (do_bootp): Return false when we should.
asl
parents: 1581
diff changeset
1457 close(s6);
253
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1458 }
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1459 #endif /* IP6 */
d364b93024e5 From Red Hat - fix problem with IPv6 when using DHCP.
gthomas
parents: 235
diff changeset
1460
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1461 // 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
1462 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
1463 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
1464 perror("SIOCSIFFLAGS down");
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1465 goto out;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1466 }
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1467 retcode = true;
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1468
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1469 if ( 0 != *pstate ) // preserve initial state
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1470 *pstate = DHCPSTATE_INIT;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1471
1581
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1472
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1473 out:
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1474 if (s != -1)
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1475 close(s);
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1476
bad894bd648f * src/bootp_support.c:
asl
parents: 1531
diff changeset
1477 return retcode;
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1478 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1479
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1480 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1481 // 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
1482 // the interface.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1483 int
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1484 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
1485 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
1486 {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1487 if ( 0 != *pstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1488 && DHCPSTATE_INIT != *pstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1489 && DHCPSTATE_NOTBOUND != *pstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1490 && DHCPSTATE_FAILED != *pstate
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1491 && DHCPSTATE_BOOTP_FALLBACK != *pstate ) {
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1492 *pstate = DHCPSTATE_DO_RELEASE;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1493 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
1494 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
1495 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1496 return true;
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1497 }
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1498
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1499 // ------------------------------------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1500
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1501 #endif // CYGPKG_NET_DHCP
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1502
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
diff changeset
1503 // EOF dhcp_prot.c