1 | /*
|
---|
2 | * TAP-Win32 -- A kernel driver to provide virtual tap device functionality
|
---|
3 | * on Windows. Originally derived from the CIPE-Win32
|
---|
4 | * project by Damion K. Wilson, with extensive modifications by
|
---|
5 | * James Yonan.
|
---|
6 | *
|
---|
7 | * All source code which derives from the CIPE-Win32 project is
|
---|
8 | * Copyright (C) Damion K. Wilson, 2003, and is released under the
|
---|
9 | * GPL version 2 (see below).
|
---|
10 | *
|
---|
11 | * All other source code is Copyright (C) 2002-2005 OpenVPN Solutions LLC,
|
---|
12 | * and is released under the GPL version 2 (see below).
|
---|
13 | *
|
---|
14 | * This program is free software; you can redistribute it and/or modify
|
---|
15 | * it under the terms of the GNU General Public License version 2
|
---|
16 | * as published by the Free Software Foundation.
|
---|
17 | *
|
---|
18 | * This program is distributed in the hope that it will be useful,
|
---|
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
21 | * GNU General Public License for more details.
|
---|
22 | *
|
---|
23 | * You should have received a copy of the GNU General Public License
|
---|
24 | * along with this program (see the file COPYING included with this
|
---|
25 | * distribution); if not, write to the Free Software Foundation, Inc.,
|
---|
26 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
---|
27 | */
|
---|
28 |
|
---|
29 | //=========================
|
---|
30 | // Code to set DHCP options
|
---|
31 | //=========================
|
---|
32 |
|
---|
33 | VOID
|
---|
34 | SetDHCPOpt (DHCPMsg *m, void *data, unsigned int len)
|
---|
35 | {
|
---|
36 | if (!m->overflow)
|
---|
37 | {
|
---|
38 | if (m->optlen + len <= DHCP_OPTIONS_BUFFER_SIZE)
|
---|
39 | {
|
---|
40 | if (len)
|
---|
41 | {
|
---|
42 | NdisMoveMemory (m->msg.options + m->optlen, data, len);
|
---|
43 | m->optlen += len;
|
---|
44 | }
|
---|
45 | }
|
---|
46 | else
|
---|
47 | {
|
---|
48 | m->overflow = TRUE;
|
---|
49 | }
|
---|
50 | }
|
---|
51 | }
|
---|
52 |
|
---|
53 | VOID
|
---|
54 | SetDHCPOpt0 (DHCPMsg *msg, int type)
|
---|
55 | {
|
---|
56 | DHCPOPT0 opt;
|
---|
57 | opt.type = (UCHAR) type;
|
---|
58 | SetDHCPOpt (msg, &opt, sizeof (opt));
|
---|
59 | }
|
---|
60 |
|
---|
61 | VOID
|
---|
62 | SetDHCPOpt8 (DHCPMsg *msg, int type, ULONG data)
|
---|
63 | {
|
---|
64 | DHCPOPT8 opt;
|
---|
65 | opt.type = (UCHAR) type;
|
---|
66 | opt.len = sizeof (opt.data);
|
---|
67 | opt.data = (UCHAR) data;
|
---|
68 | SetDHCPOpt (msg, &opt, sizeof (opt));
|
---|
69 | }
|
---|
70 |
|
---|
71 | VOID
|
---|
72 | SetDHCPOpt32 (DHCPMsg *msg, int type, ULONG data)
|
---|
73 | {
|
---|
74 | DHCPOPT32 opt;
|
---|
75 | opt.type = (UCHAR) type;
|
---|
76 | opt.len = sizeof (opt.data);
|
---|
77 | opt.data = data;
|
---|
78 | SetDHCPOpt (msg, &opt, sizeof (opt));
|
---|
79 | }
|
---|
80 |
|
---|
81 | //==============
|
---|
82 | // Checksum code
|
---|
83 | //==============
|
---|
84 |
|
---|
85 | USHORT
|
---|
86 | ip_checksum (const UCHAR *buf, const int len_ip_header)
|
---|
87 | {
|
---|
88 | USHORT word16;
|
---|
89 | ULONG sum = 0;
|
---|
90 | int i;
|
---|
91 |
|
---|
92 | // make 16 bit words out of every two adjacent 8 bit words in the packet
|
---|
93 | // and add them up
|
---|
94 | for (i = 0; i < len_ip_header - 1; i += 2) {
|
---|
95 | word16 = ((buf[i] << 8) & 0xFF00) + (buf[i+1] & 0xFF);
|
---|
96 | sum += (ULONG) word16;
|
---|
97 | }
|
---|
98 |
|
---|
99 | // take only 16 bits out of the 32 bit sum and add up the carries
|
---|
100 | while (sum >> 16)
|
---|
101 | sum = (sum & 0xFFFF) + (sum >> 16);
|
---|
102 |
|
---|
103 | // one's complement the result
|
---|
104 | return ((USHORT) ~sum);
|
---|
105 | }
|
---|
106 |
|
---|
107 | USHORT
|
---|
108 | udp_checksum (const UCHAR *buf,
|
---|
109 | const int len_udp,
|
---|
110 | const UCHAR *src_addr,
|
---|
111 | const UCHAR *dest_addr)
|
---|
112 | {
|
---|
113 | USHORT word16;
|
---|
114 | ULONG sum = 0;
|
---|
115 | int i;
|
---|
116 |
|
---|
117 | // make 16 bit words out of every two adjacent 8 bit words and
|
---|
118 | // calculate the sum of all 16 bit words
|
---|
119 | for (i = 0; i < len_udp; i += 2){
|
---|
120 | word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_udp) ? (buf[i+1] & 0xFF) : 0);
|
---|
121 | sum += word16;
|
---|
122 | }
|
---|
123 |
|
---|
124 | // add the UDP pseudo header which contains the IP source and destination addresses
|
---|
125 | for (i = 0; i < 4; i += 2){
|
---|
126 | word16 =((src_addr[i] << 8) & 0xFF00) + (src_addr[i+1] & 0xFF);
|
---|
127 | sum += word16;
|
---|
128 | }
|
---|
129 | for (i = 0; i < 4; i += 2){
|
---|
130 | word16 =((dest_addr[i] << 8) & 0xFF00) + (dest_addr[i+1] & 0xFF);
|
---|
131 | sum += word16;
|
---|
132 | }
|
---|
133 |
|
---|
134 | // the protocol number and the length of the UDP packet
|
---|
135 | sum += (USHORT) IPPROTO_UDP + (USHORT) len_udp;
|
---|
136 |
|
---|
137 | // keep only the last 16 bits of the 32 bit calculated sum and add the carries
|
---|
138 | while (sum >> 16)
|
---|
139 | sum = (sum & 0xFFFF) + (sum >> 16);
|
---|
140 |
|
---|
141 | // Take the one's complement of sum
|
---|
142 | return ((USHORT) ~sum);
|
---|
143 | }
|
---|
144 |
|
---|
145 | //================================
|
---|
146 | // Set IP and UDP packet checksums
|
---|
147 | //================================
|
---|
148 |
|
---|
149 | VOID
|
---|
150 | SetChecksumDHCPMsg (DHCPMsg *m)
|
---|
151 | {
|
---|
152 | // Set IP checksum
|
---|
153 | m->msg.pre.ip.check = htons (ip_checksum ((UCHAR *) &m->msg.pre.ip, sizeof (IPHDR)));
|
---|
154 |
|
---|
155 | // Set UDP Checksum
|
---|
156 | m->msg.pre.udp.check = htons (udp_checksum ((UCHAR *) &m->msg.pre.udp,
|
---|
157 | sizeof (UDPHDR) + sizeof (DHCP) + m->optlen,
|
---|
158 | (UCHAR *)&m->msg.pre.ip.saddr,
|
---|
159 | (UCHAR *)&m->msg.pre.ip.daddr));
|
---|
160 | }
|
---|
161 |
|
---|
162 | //===================
|
---|
163 | // DHCP message tests
|
---|
164 | //===================
|
---|
165 |
|
---|
166 | int
|
---|
167 | GetDHCPMessageType (const DHCP *dhcp, const int optlen)
|
---|
168 | {
|
---|
169 | const UCHAR *p = (UCHAR *) (dhcp + 1);
|
---|
170 | int i;
|
---|
171 |
|
---|
172 | for (i = 0; i < optlen; ++i)
|
---|
173 | {
|
---|
174 | const UCHAR type = p[i];
|
---|
175 | const int room = optlen - i - 1;
|
---|
176 | if (type == DHCP_END) // didn't find what we were looking for
|
---|
177 | return -1;
|
---|
178 | else if (type == DHCP_PAD) // no-operation
|
---|
179 | ;
|
---|
180 | else if (type == DHCP_MSG_TYPE) // what we are looking for
|
---|
181 | {
|
---|
182 | if (room >= 2)
|
---|
183 | {
|
---|
184 | if (p[i+1] == 1) // message length should be 1
|
---|
185 | return p[i+2]; // return message type
|
---|
186 | }
|
---|
187 | return -1;
|
---|
188 | }
|
---|
189 | else // some other message
|
---|
190 | {
|
---|
191 | if (room >= 1)
|
---|
192 | {
|
---|
193 | const int len = p[i+1]; // get message length
|
---|
194 | i += (len + 1); // advance to next message
|
---|
195 | }
|
---|
196 | }
|
---|
197 | }
|
---|
198 | return -1;
|
---|
199 | }
|
---|
200 |
|
---|
201 | BOOLEAN
|
---|
202 | DHCPMessageOurs (const TapAdapterPointer p_Adapter,
|
---|
203 | const ETH_HEADER *eth,
|
---|
204 | const IPHDR *ip,
|
---|
205 | const UDPHDR *udp,
|
---|
206 | const DHCP *dhcp)
|
---|
207 | {
|
---|
208 | // Must be UDPv4 protocol
|
---|
209 | if (!(eth->proto == htons (ETH_P_IP) && ip->protocol == IPPROTO_UDP))
|
---|
210 | return FALSE;
|
---|
211 |
|
---|
212 | // Source MAC must be our adapter
|
---|
213 | if (!MAC_EQUAL (eth->src, p_Adapter->m_MAC))
|
---|
214 | return FALSE;
|
---|
215 |
|
---|
216 | // Dest MAC must be either broadcast or our virtual DHCP server
|
---|
217 | if (!(MAC_EQUAL (eth->dest, p_Adapter->m_MAC_Broadcast)
|
---|
218 | || MAC_EQUAL (eth->dest, p_Adapter->m_dhcp_server_mac)))
|
---|
219 | return FALSE;
|
---|
220 |
|
---|
221 | // Port numbers must be correct
|
---|
222 | if (!(udp->dest == htons (BOOTPS_PORT)
|
---|
223 | && udp->source == htons (BOOTPC_PORT)))
|
---|
224 | return FALSE;
|
---|
225 |
|
---|
226 | // Hardware address must be MAC addr sized
|
---|
227 | if (!(dhcp->hlen == sizeof (MACADDR)))
|
---|
228 | return FALSE;
|
---|
229 |
|
---|
230 | // Hardware address must match our adapter
|
---|
231 | if (!MAC_EQUAL (eth->src, dhcp->chaddr))
|
---|
232 | return FALSE;
|
---|
233 |
|
---|
234 | return TRUE;
|
---|
235 | }
|
---|
236 |
|
---|
237 |
|
---|
238 | //=====================================================
|
---|
239 | // Build all of DHCP packet except for DHCP options.
|
---|
240 | // Assume that *p has been zeroed before we are called.
|
---|
241 | //=====================================================
|
---|
242 |
|
---|
243 | VOID
|
---|
244 | BuildDHCPPre (const TapAdapterPointer a,
|
---|
245 | DHCPPre *p,
|
---|
246 | const ETH_HEADER *eth,
|
---|
247 | const IPHDR *ip,
|
---|
248 | const UDPHDR *udp,
|
---|
249 | const DHCP *dhcp,
|
---|
250 | const int optlen,
|
---|
251 | const int type)
|
---|
252 | {
|
---|
253 | // Should we broadcast or direct to a specific MAC / IP address?
|
---|
254 | const BOOLEAN broadcast = (type == DHCPNAK
|
---|
255 | || MAC_EQUAL (eth->dest, a->m_MAC_Broadcast));
|
---|
256 | // Build ethernet header
|
---|
257 |
|
---|
258 | COPY_MAC (p->eth.src, a->m_dhcp_server_mac);
|
---|
259 |
|
---|
260 | if (broadcast)
|
---|
261 | COPY_MAC (p->eth.dest, a->m_MAC_Broadcast);
|
---|
262 | else
|
---|
263 | COPY_MAC (p->eth.dest, eth->src);
|
---|
264 |
|
---|
265 | p->eth.proto = htons (ETH_P_IP);
|
---|
266 |
|
---|
267 | // Build IP header
|
---|
268 |
|
---|
269 | p->ip.version_len = (4 << 4) | (sizeof (IPHDR) >> 2);
|
---|
270 | p->ip.tos = 0;
|
---|
271 | p->ip.tot_len = htons (sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen);
|
---|
272 | p->ip.id = 0;
|
---|
273 | p->ip.frag_off = 0;
|
---|
274 | p->ip.ttl = 16;
|
---|
275 | p->ip.protocol = IPPROTO_UDP;
|
---|
276 | p->ip.check = 0;
|
---|
277 | p->ip.saddr = a->m_dhcp_server_ip;
|
---|
278 |
|
---|
279 | if (broadcast)
|
---|
280 | p->ip.daddr = ~0;
|
---|
281 | else
|
---|
282 | p->ip.daddr = a->m_dhcp_addr;
|
---|
283 |
|
---|
284 | // Build UDP header
|
---|
285 |
|
---|
286 | p->udp.source = htons (BOOTPS_PORT);
|
---|
287 | p->udp.dest = htons (BOOTPC_PORT);
|
---|
288 | p->udp.len = htons (sizeof (UDPHDR) + sizeof (DHCP) + optlen);
|
---|
289 | p->udp.check = 0;
|
---|
290 |
|
---|
291 | // Build DHCP response
|
---|
292 |
|
---|
293 | p->dhcp.op = BOOTREPLY;
|
---|
294 | p->dhcp.htype = 1;
|
---|
295 | p->dhcp.hlen = sizeof (MACADDR);
|
---|
296 | p->dhcp.hops = 0;
|
---|
297 | p->dhcp.xid = dhcp->xid;
|
---|
298 | p->dhcp.secs = 0;
|
---|
299 | p->dhcp.flags = 0;
|
---|
300 | p->dhcp.ciaddr = 0;
|
---|
301 |
|
---|
302 | if (type == DHCPNAK)
|
---|
303 | p->dhcp.yiaddr = 0;
|
---|
304 | else
|
---|
305 | p->dhcp.yiaddr = a->m_dhcp_addr;
|
---|
306 |
|
---|
307 | p->dhcp.siaddr = a->m_dhcp_server_ip;
|
---|
308 | p->dhcp.giaddr = 0;
|
---|
309 | COPY_MAC (p->dhcp.chaddr, eth->src);
|
---|
310 | p->dhcp.magic = htonl (0x63825363);
|
---|
311 | }
|
---|
312 | //=============================
|
---|
313 | // Build specific DHCP messages
|
---|
314 | //=============================
|
---|
315 |
|
---|
316 | VOID
|
---|
317 | SendDHCPMsg (const TapAdapterPointer a,
|
---|
318 | const int type,
|
---|
319 | const ETH_HEADER *eth,
|
---|
320 | const IPHDR *ip,
|
---|
321 | const UDPHDR *udp,
|
---|
322 | const DHCP *dhcp)
|
---|
323 | {
|
---|
324 | DHCPMsg *pkt;
|
---|
325 |
|
---|
326 | if (!(type == DHCPOFFER || type == DHCPACK || type == DHCPNAK))
|
---|
327 | {
|
---|
328 | DEBUGP (("[TAP] SendDHCPMsg: Bad DHCP type: %d\n", type));
|
---|
329 | return;
|
---|
330 | }
|
---|
331 |
|
---|
332 | pkt = (DHCPMsg *) MemAlloc (sizeof (DHCPMsg), TRUE);
|
---|
333 |
|
---|
334 | if (pkt)
|
---|
335 | {
|
---|
336 | //-----------------------
|
---|
337 | // Build DHCP options
|
---|
338 | //-----------------------
|
---|
339 |
|
---|
340 | // Message Type
|
---|
341 | SetDHCPOpt8 (pkt, DHCP_MSG_TYPE, type);
|
---|
342 |
|
---|
343 | // Server ID
|
---|
344 | SetDHCPOpt32 (pkt, DHCP_SERVER_ID, a->m_dhcp_server_ip);
|
---|
345 |
|
---|
346 | if (type == DHCPOFFER || type == DHCPACK)
|
---|
347 | {
|
---|
348 | // Lease Time
|
---|
349 | SetDHCPOpt32 (pkt, DHCP_LEASE_TIME, htonl (a->m_dhcp_lease_time));
|
---|
350 |
|
---|
351 | // Netmask
|
---|
352 | SetDHCPOpt32 (pkt, DHCP_NETMASK, a->m_dhcp_netmask);
|
---|
353 |
|
---|
354 | // Other user-defined options
|
---|
355 | SetDHCPOpt (pkt,
|
---|
356 | a->m_dhcp_user_supplied_options_buffer,
|
---|
357 | a->m_dhcp_user_supplied_options_buffer_len);
|
---|
358 | }
|
---|
359 |
|
---|
360 | // End
|
---|
361 | SetDHCPOpt0 (pkt, DHCP_END);
|
---|
362 |
|
---|
363 | if (!DHCPMSG_OVERFLOW (pkt))
|
---|
364 | {
|
---|
365 | // The initial part of the DHCP message (not including options) gets built here
|
---|
366 | BuildDHCPPre (a,
|
---|
367 | &pkt->msg.pre,
|
---|
368 | eth,
|
---|
369 | ip,
|
---|
370 | udp,
|
---|
371 | dhcp,
|
---|
372 | DHCPMSG_LEN_OPT (pkt),
|
---|
373 | type);
|
---|
374 |
|
---|
375 | SetChecksumDHCPMsg (pkt);
|
---|
376 |
|
---|
377 | DUMP_PACKET ("DHCPMsg",
|
---|
378 | DHCPMSG_BUF (pkt),
|
---|
379 | DHCPMSG_LEN_FULL (pkt));
|
---|
380 |
|
---|
381 | // Return DHCP response to kernel
|
---|
382 | InjectPacket (a,
|
---|
383 | DHCPMSG_BUF (pkt),
|
---|
384 | DHCPMSG_LEN_FULL (pkt));
|
---|
385 | }
|
---|
386 | else
|
---|
387 | {
|
---|
388 | DEBUGP (("[TAP] SendDHCPMsg: DHCP buffer overflow\n"));
|
---|
389 | }
|
---|
390 |
|
---|
391 | MemFree (pkt, sizeof (DHCPMsg));
|
---|
392 | }
|
---|
393 | }
|
---|
394 |
|
---|
395 | //===================================================================
|
---|
396 | // Handle a BOOTPS packet produced by the local system to
|
---|
397 | // resolve the address/netmask of this adapter.
|
---|
398 | // If we are in TAP_IOCTL_CONFIG_DHCP_MASQ mode, reply
|
---|
399 | // to the message. Return TRUE if we processed the passed
|
---|
400 | // message, so that downstream stages can ignore it.
|
---|
401 | //===================================================================
|
---|
402 |
|
---|
403 | BOOLEAN
|
---|
404 | ProcessDHCP (TapAdapterPointer p_Adapter,
|
---|
405 | const ETH_HEADER *eth,
|
---|
406 | const IPHDR *ip,
|
---|
407 | const UDPHDR *udp,
|
---|
408 | const DHCP *dhcp,
|
---|
409 | int optlen)
|
---|
410 | {
|
---|
411 | int msg_type;
|
---|
412 |
|
---|
413 | // Sanity check IP header
|
---|
414 | if (!(ntohs (ip->tot_len) == sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen
|
---|
415 | && (ntohs (ip->frag_off) & IP_OFFMASK) == 0))
|
---|
416 | return TRUE;
|
---|
417 |
|
---|
418 | // Does this message belong to us?
|
---|
419 | if (!DHCPMessageOurs (p_Adapter, eth, ip, udp, dhcp))
|
---|
420 | return FALSE;
|
---|
421 |
|
---|
422 | msg_type = GetDHCPMessageType (dhcp, optlen);
|
---|
423 |
|
---|
424 | // Drop non-BOOTREQUEST messages
|
---|
425 | if (dhcp->op != BOOTREQUEST)
|
---|
426 | return TRUE;
|
---|
427 |
|
---|
428 | // Drop any messages except DHCPDISCOVER or DHCPREQUEST
|
---|
429 | if (!(msg_type == DHCPDISCOVER || msg_type == DHCPREQUEST))
|
---|
430 | return TRUE;
|
---|
431 |
|
---|
432 | // Should we reply with DHCPOFFER, DHCPACK, or DHCPNAK?
|
---|
433 | if (msg_type == DHCPREQUEST
|
---|
434 | && ((dhcp->ciaddr && dhcp->ciaddr != p_Adapter->m_dhcp_addr)
|
---|
435 | || !p_Adapter->m_dhcp_received_discover
|
---|
436 | || p_Adapter->m_dhcp_bad_requests >= BAD_DHCPREQUEST_NAK_THRESHOLD))
|
---|
437 | SendDHCPMsg (p_Adapter,
|
---|
438 | DHCPNAK,
|
---|
439 | eth, ip, udp, dhcp);
|
---|
440 | else
|
---|
441 | SendDHCPMsg (p_Adapter,
|
---|
442 | (msg_type == DHCPDISCOVER ? DHCPOFFER : DHCPACK),
|
---|
443 | eth, ip, udp, dhcp);
|
---|
444 |
|
---|
445 | // Remember if we received a DHCPDISCOVER
|
---|
446 | if (msg_type == DHCPDISCOVER)
|
---|
447 | p_Adapter->m_dhcp_received_discover = TRUE;
|
---|
448 |
|
---|
449 | // Is this a bad DHCPREQUEST?
|
---|
450 | if (msg_type == DHCPREQUEST && dhcp->ciaddr != p_Adapter->m_dhcp_addr)
|
---|
451 | ++p_Adapter->m_dhcp_bad_requests;
|
---|
452 |
|
---|
453 | return TRUE;
|
---|
454 | }
|
---|
455 |
|
---|
456 | #if DBG
|
---|
457 |
|
---|
458 | const char *
|
---|
459 | message_op_text (int op)
|
---|
460 | {
|
---|
461 | switch (op)
|
---|
462 | {
|
---|
463 | case BOOTREQUEST:
|
---|
464 | return "BOOTREQUEST";
|
---|
465 | case BOOTREPLY:
|
---|
466 | return "BOOTREPLY";
|
---|
467 | default:
|
---|
468 | return "???";
|
---|
469 | }
|
---|
470 | }
|
---|
471 |
|
---|
472 | const char *
|
---|
473 | message_type_text (int type)
|
---|
474 | {
|
---|
475 | switch (type)
|
---|
476 | {
|
---|
477 | case DHCPDISCOVER:
|
---|
478 | return "DHCPDISCOVER";
|
---|
479 | case DHCPOFFER:
|
---|
480 | return "DHCPOFFER";
|
---|
481 | case DHCPREQUEST:
|
---|
482 | return "DHCPREQUEST";
|
---|
483 | case DHCPDECLINE:
|
---|
484 | return "DHCPDECLINE";
|
---|
485 | case DHCPACK:
|
---|
486 | return "DHCPACK";
|
---|
487 | case DHCPNAK:
|
---|
488 | return "DHCPNAK";
|
---|
489 | case DHCPRELEASE:
|
---|
490 | return "DHCPRELEASE";
|
---|
491 | case DHCPINFORM:
|
---|
492 | return "DHCPINFORM";
|
---|
493 | default:
|
---|
494 | return "???";
|
---|
495 | }
|
---|
496 | }
|
---|
497 |
|
---|
498 | const char *
|
---|
499 | port_name (int port)
|
---|
500 | {
|
---|
501 | switch (port)
|
---|
502 | {
|
---|
503 | case BOOTPS_PORT:
|
---|
504 | return "BOOTPS";
|
---|
505 | case BOOTPC_PORT:
|
---|
506 | return "BOOTPC";
|
---|
507 | default:
|
---|
508 | return "unknown";
|
---|
509 | }
|
---|
510 | }
|
---|
511 |
|
---|
512 | VOID
|
---|
513 | DumpDHCP (const ETH_HEADER *eth,
|
---|
514 | const IPHDR *ip,
|
---|
515 | const UDPHDR *udp,
|
---|
516 | const DHCP *dhcp,
|
---|
517 | const int optlen)
|
---|
518 | {
|
---|
519 | DEBUGP ((" %s", message_op_text (dhcp->op)));
|
---|
520 | DEBUGP ((" %s ", message_type_text (GetDHCPMessageType (dhcp, optlen))));
|
---|
521 | PrIP (ip->saddr);
|
---|
522 | DEBUGP ((":%s[", port_name (ntohs (udp->source))));
|
---|
523 | PrMac (eth->src);
|
---|
524 | DEBUGP (("] -> "));
|
---|
525 | PrIP (ip->daddr);
|
---|
526 | DEBUGP ((":%s[", port_name (ntohs (udp->dest))));
|
---|
527 | PrMac (eth->dest);
|
---|
528 | DEBUGP (("]"));
|
---|
529 | if (dhcp->ciaddr)
|
---|
530 | {
|
---|
531 | DEBUGP ((" ci="));
|
---|
532 | PrIP (dhcp->ciaddr);
|
---|
533 | }
|
---|
534 | if (dhcp->yiaddr)
|
---|
535 | {
|
---|
536 | DEBUGP ((" yi="));
|
---|
537 | PrIP (dhcp->yiaddr);
|
---|
538 | }
|
---|
539 | if (dhcp->siaddr)
|
---|
540 | {
|
---|
541 | DEBUGP ((" si="));
|
---|
542 | PrIP (dhcp->siaddr);
|
---|
543 | }
|
---|
544 | if (dhcp->hlen == sizeof (MACADDR))
|
---|
545 | {
|
---|
546 | DEBUGP ((" ch="));
|
---|
547 | PrMac (dhcp->chaddr);
|
---|
548 | }
|
---|
549 |
|
---|
550 | DEBUGP ((" xid=0x%08x", ntohl (dhcp->xid)));
|
---|
551 |
|
---|
552 | if (ntohl (dhcp->magic) != 0x63825363)
|
---|
553 | DEBUGP ((" ma=0x%08x", ntohl (dhcp->magic)));
|
---|
554 | if (dhcp->htype != 1)
|
---|
555 | DEBUGP ((" htype=%d", dhcp->htype));
|
---|
556 | if (dhcp->hops)
|
---|
557 | DEBUGP ((" hops=%d", dhcp->hops));
|
---|
558 | if (ntohs (dhcp->secs))
|
---|
559 | DEBUGP ((" secs=%d", ntohs (dhcp->secs)));
|
---|
560 | if (ntohs (dhcp->flags))
|
---|
561 | DEBUGP ((" flags=0x%04x", ntohs (dhcp->flags)));
|
---|
562 |
|
---|
563 | // extra stuff
|
---|
564 |
|
---|
565 | if (ip->version_len != 0x45)
|
---|
566 | DEBUGP ((" vl=0x%02x", ip->version_len));
|
---|
567 | if (ntohs (ip->tot_len) != sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen)
|
---|
568 | DEBUGP ((" tl=%d", ntohs (ip->tot_len)));
|
---|
569 | if (ntohs (udp->len) != sizeof (UDPHDR) + sizeof (DHCP) + optlen)
|
---|
570 | DEBUGP ((" ul=%d", ntohs (udp->len)));
|
---|
571 |
|
---|
572 | if (ip->tos)
|
---|
573 | DEBUGP ((" tos=0x%02x", ip->tos));
|
---|
574 | if (ntohs (ip->id))
|
---|
575 | DEBUGP ((" id=0x%04x", ntohs (ip->id)));
|
---|
576 | if (ntohs (ip->frag_off))
|
---|
577 | DEBUGP ((" frag_off=0x%04x", ntohs (ip->frag_off)));
|
---|
578 |
|
---|
579 | DEBUGP ((" ttl=%d", ip->ttl));
|
---|
580 | DEBUGP ((" ic=0x%04x [0x%04x]", ntohs (ip->check),
|
---|
581 | ip_checksum ((UCHAR*)ip, sizeof (IPHDR))));
|
---|
582 | DEBUGP ((" uc=0x%04x [0x%04x/%d]", ntohs (udp->check),
|
---|
583 | udp_checksum ((UCHAR *) udp,
|
---|
584 | sizeof (UDPHDR) + sizeof (DHCP) + optlen,
|
---|
585 | (UCHAR *) &ip->saddr,
|
---|
586 | (UCHAR *) &ip->daddr),
|
---|
587 | optlen));
|
---|
588 |
|
---|
589 | // Options
|
---|
590 | {
|
---|
591 | const UCHAR *opt = (UCHAR *) (dhcp + 1);
|
---|
592 | int i;
|
---|
593 |
|
---|
594 | DEBUGP ((" OPT"));
|
---|
595 | for (i = 0; i < optlen; ++i)
|
---|
596 | {
|
---|
597 | const UCHAR data = opt[i];
|
---|
598 | DEBUGP ((".%d", data));
|
---|
599 | }
|
---|
600 | }
|
---|
601 | }
|
---|
602 |
|
---|
603 | #endif /* DEBUG */
|
---|