diff options
author | Mike Frysinger <vapier@gentoo.org> | 2006-03-23 23:44:29 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2006-03-23 23:44:29 +0000 |
commit | 787140df3992ccc3ebdc09f6d2dcb584f580f49f (patch) | |
tree | 666fdb071676c676f52bdc204f6df801b17e7196 /networking/udhcp/serverpacket.c | |
parent | e0fe93759339a9e043cd0489f5bfabd59b5fcb78 (diff) | |
download | busybox-w32-787140df3992ccc3ebdc09f6d2dcb584f580f49f.tar.gz busybox-w32-787140df3992ccc3ebdc09f6d2dcb584f580f49f.tar.bz2 busybox-w32-787140df3992ccc3ebdc09f6d2dcb584f580f49f.zip |
remove in place of external link
Diffstat (limited to 'networking/udhcp/serverpacket.c')
-rw-r--r-- | networking/udhcp/serverpacket.c | 275 |
1 files changed, 0 insertions, 275 deletions
diff --git a/networking/udhcp/serverpacket.c b/networking/udhcp/serverpacket.c deleted file mode 100644 index fe880b4a0..000000000 --- a/networking/udhcp/serverpacket.c +++ /dev/null | |||
@@ -1,275 +0,0 @@ | |||
1 | /* serverpacket.c | ||
2 | * | ||
3 | * Construct and send DHCP server packets | ||
4 | * | ||
5 | * Russ Dill <Russ.Dill@asu.edu> July 2001 | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #include <sys/socket.h> | ||
23 | #include <netinet/in.h> | ||
24 | #include <arpa/inet.h> | ||
25 | #include <string.h> | ||
26 | #include <time.h> | ||
27 | |||
28 | #include "common.h" | ||
29 | #include "serverpacket.h" | ||
30 | #include "dhcpd.h" | ||
31 | #include "options.h" | ||
32 | #include "static_leases.h" | ||
33 | |||
34 | /* send a packet to giaddr using the kernel ip stack */ | ||
35 | static int send_packet_to_relay(struct dhcpMessage *payload) | ||
36 | { | ||
37 | DEBUG(LOG_INFO, "Forwarding packet to relay"); | ||
38 | |||
39 | return kernel_packet(payload, server_config.server, SERVER_PORT, | ||
40 | payload->giaddr, SERVER_PORT); | ||
41 | } | ||
42 | |||
43 | |||
44 | /* send a packet to a specific arp address and ip address by creating our own ip packet */ | ||
45 | static int send_packet_to_client(struct dhcpMessage *payload, int force_broadcast) | ||
46 | { | ||
47 | uint8_t *chaddr; | ||
48 | uint32_t ciaddr; | ||
49 | |||
50 | if (force_broadcast) { | ||
51 | DEBUG(LOG_INFO, "broadcasting packet to client (NAK)"); | ||
52 | ciaddr = INADDR_BROADCAST; | ||
53 | chaddr = MAC_BCAST_ADDR; | ||
54 | } else if (payload->ciaddr) { | ||
55 | DEBUG(LOG_INFO, "unicasting packet to client ciaddr"); | ||
56 | ciaddr = payload->ciaddr; | ||
57 | chaddr = payload->chaddr; | ||
58 | } else if (ntohs(payload->flags) & BROADCAST_FLAG) { | ||
59 | DEBUG(LOG_INFO, "broadcasting packet to client (requested)"); | ||
60 | ciaddr = INADDR_BROADCAST; | ||
61 | chaddr = MAC_BCAST_ADDR; | ||
62 | } else { | ||
63 | DEBUG(LOG_INFO, "unicasting packet to client yiaddr"); | ||
64 | ciaddr = payload->yiaddr; | ||
65 | chaddr = payload->chaddr; | ||
66 | } | ||
67 | return raw_packet(payload, server_config.server, SERVER_PORT, | ||
68 | ciaddr, CLIENT_PORT, chaddr, server_config.ifindex); | ||
69 | } | ||
70 | |||
71 | |||
72 | /* send a dhcp packet, if force broadcast is set, the packet will be broadcast to the client */ | ||
73 | static int send_packet(struct dhcpMessage *payload, int force_broadcast) | ||
74 | { | ||
75 | int ret; | ||
76 | |||
77 | if (payload->giaddr) | ||
78 | ret = send_packet_to_relay(payload); | ||
79 | else ret = send_packet_to_client(payload, force_broadcast); | ||
80 | return ret; | ||
81 | } | ||
82 | |||
83 | |||
84 | static void init_packet(struct dhcpMessage *packet, struct dhcpMessage *oldpacket, char type) | ||
85 | { | ||
86 | init_header(packet, type); | ||
87 | packet->xid = oldpacket->xid; | ||
88 | memcpy(packet->chaddr, oldpacket->chaddr, 16); | ||
89 | packet->flags = oldpacket->flags; | ||
90 | packet->giaddr = oldpacket->giaddr; | ||
91 | packet->ciaddr = oldpacket->ciaddr; | ||
92 | add_simple_option(packet->options, DHCP_SERVER_ID, server_config.server); | ||
93 | } | ||
94 | |||
95 | |||
96 | /* add in the bootp options */ | ||
97 | static void add_bootp_options(struct dhcpMessage *packet) | ||
98 | { | ||
99 | packet->siaddr = server_config.siaddr; | ||
100 | if (server_config.sname) | ||
101 | strncpy((char*)packet->sname, server_config.sname, sizeof(packet->sname) - 1); | ||
102 | if (server_config.boot_file) | ||
103 | strncpy((char*)packet->file, server_config.boot_file, sizeof(packet->file) - 1); | ||
104 | } | ||
105 | |||
106 | |||
107 | /* send a DHCP OFFER to a DHCP DISCOVER */ | ||
108 | int sendOffer(struct dhcpMessage *oldpacket) | ||
109 | { | ||
110 | struct dhcpMessage packet; | ||
111 | struct dhcpOfferedAddr *lease = NULL; | ||
112 | uint32_t req_align, lease_time_align = server_config.lease; | ||
113 | uint8_t *req, *lease_time; | ||
114 | struct option_set *curr; | ||
115 | struct in_addr addr; | ||
116 | |||
117 | uint32_t static_lease_ip; | ||
118 | |||
119 | init_packet(&packet, oldpacket, DHCPOFFER); | ||
120 | |||
121 | static_lease_ip = getIpByMac(server_config.static_leases, oldpacket->chaddr); | ||
122 | |||
123 | /* ADDME: if static, short circuit */ | ||
124 | if(!static_lease_ip) | ||
125 | { | ||
126 | /* the client is in our lease/offered table */ | ||
127 | if ((lease = find_lease_by_chaddr(oldpacket->chaddr))) { | ||
128 | if (!lease_expired(lease)) | ||
129 | lease_time_align = lease->expires - time(0); | ||
130 | packet.yiaddr = lease->yiaddr; | ||
131 | |||
132 | /* Or the client has a requested ip */ | ||
133 | } else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) && | ||
134 | |||
135 | /* Don't look here (ugly hackish thing to do) */ | ||
136 | memcpy(&req_align, req, 4) && | ||
137 | |||
138 | /* and the ip is in the lease range */ | ||
139 | ntohl(req_align) >= ntohl(server_config.start) && | ||
140 | ntohl(req_align) <= ntohl(server_config.end) && | ||
141 | |||
142 | !static_lease_ip && /* Check that its not a static lease */ | ||
143 | /* and is not already taken/offered */ | ||
144 | ((!(lease = find_lease_by_yiaddr(req_align)) || | ||
145 | |||
146 | /* or its taken, but expired */ /* ADDME: or maybe in here */ | ||
147 | lease_expired(lease)))) { | ||
148 | packet.yiaddr = req_align; /* FIXME: oh my, is there a host using this IP? */ | ||
149 | |||
150 | /* otherwise, find a free IP */ | ||
151 | } else { | ||
152 | /* Is it a static lease? (No, because find_address skips static lease) */ | ||
153 | packet.yiaddr = find_address(0); | ||
154 | |||
155 | /* try for an expired lease */ | ||
156 | if (!packet.yiaddr) packet.yiaddr = find_address(1); | ||
157 | } | ||
158 | |||
159 | if(!packet.yiaddr) { | ||
160 | LOG(LOG_WARNING, "no IP addresses to give -- OFFER abandoned"); | ||
161 | return -1; | ||
162 | } | ||
163 | |||
164 | if (!add_lease(packet.chaddr, packet.yiaddr, server_config.offer_time)) { | ||
165 | LOG(LOG_WARNING, "lease pool is full -- OFFER abandoned"); | ||
166 | return -1; | ||
167 | } | ||
168 | |||
169 | if ((lease_time = get_option(oldpacket, DHCP_LEASE_TIME))) { | ||
170 | memcpy(&lease_time_align, lease_time, 4); | ||
171 | lease_time_align = ntohl(lease_time_align); | ||
172 | if (lease_time_align > server_config.lease) | ||
173 | lease_time_align = server_config.lease; | ||
174 | } | ||
175 | |||
176 | /* Make sure we aren't just using the lease time from the previous offer */ | ||
177 | if (lease_time_align < server_config.min_lease) | ||
178 | lease_time_align = server_config.lease; | ||
179 | } | ||
180 | /* ADDME: end of short circuit */ | ||
181 | else | ||
182 | { | ||
183 | /* It is a static lease... use it */ | ||
184 | packet.yiaddr = static_lease_ip; | ||
185 | } | ||
186 | |||
187 | add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align)); | ||
188 | |||
189 | curr = server_config.options; | ||
190 | while (curr) { | ||
191 | if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) | ||
192 | add_option_string(packet.options, curr->data); | ||
193 | curr = curr->next; | ||
194 | } | ||
195 | |||
196 | add_bootp_options(&packet); | ||
197 | |||
198 | addr.s_addr = packet.yiaddr; | ||
199 | LOG(LOG_INFO, "sending OFFER of %s", inet_ntoa(addr)); | ||
200 | return send_packet(&packet, 0); | ||
201 | } | ||
202 | |||
203 | |||
204 | int sendNAK(struct dhcpMessage *oldpacket) | ||
205 | { | ||
206 | struct dhcpMessage packet; | ||
207 | |||
208 | init_packet(&packet, oldpacket, DHCPNAK); | ||
209 | |||
210 | DEBUG(LOG_INFO, "sending NAK"); | ||
211 | return send_packet(&packet, 1); | ||
212 | } | ||
213 | |||
214 | |||
215 | int sendACK(struct dhcpMessage *oldpacket, uint32_t yiaddr) | ||
216 | { | ||
217 | struct dhcpMessage packet; | ||
218 | struct option_set *curr; | ||
219 | uint8_t *lease_time; | ||
220 | uint32_t lease_time_align = server_config.lease; | ||
221 | struct in_addr addr; | ||
222 | |||
223 | init_packet(&packet, oldpacket, DHCPACK); | ||
224 | packet.yiaddr = yiaddr; | ||
225 | |||
226 | if ((lease_time = get_option(oldpacket, DHCP_LEASE_TIME))) { | ||
227 | memcpy(&lease_time_align, lease_time, 4); | ||
228 | lease_time_align = ntohl(lease_time_align); | ||
229 | if (lease_time_align > server_config.lease) | ||
230 | lease_time_align = server_config.lease; | ||
231 | else if (lease_time_align < server_config.min_lease) | ||
232 | lease_time_align = server_config.lease; | ||
233 | } | ||
234 | |||
235 | add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align)); | ||
236 | |||
237 | curr = server_config.options; | ||
238 | while (curr) { | ||
239 | if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) | ||
240 | add_option_string(packet.options, curr->data); | ||
241 | curr = curr->next; | ||
242 | } | ||
243 | |||
244 | add_bootp_options(&packet); | ||
245 | |||
246 | addr.s_addr = packet.yiaddr; | ||
247 | LOG(LOG_INFO, "sending ACK to %s", inet_ntoa(addr)); | ||
248 | |||
249 | if (send_packet(&packet, 0) < 0) | ||
250 | return -1; | ||
251 | |||
252 | add_lease(packet.chaddr, packet.yiaddr, lease_time_align); | ||
253 | |||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | |||
258 | int send_inform(struct dhcpMessage *oldpacket) | ||
259 | { | ||
260 | struct dhcpMessage packet; | ||
261 | struct option_set *curr; | ||
262 | |||
263 | init_packet(&packet, oldpacket, DHCPACK); | ||
264 | |||
265 | curr = server_config.options; | ||
266 | while (curr) { | ||
267 | if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) | ||
268 | add_option_string(packet.options, curr->data); | ||
269 | curr = curr->next; | ||
270 | } | ||
271 | |||
272 | add_bootp_options(&packet); | ||
273 | |||
274 | return send_packet(&packet, 0); | ||
275 | } | ||