packetdisp.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. /*
  2. * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  9. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  10. * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  11. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  12. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  13. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  14. * PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include <stdio.h>
  17. #include <unistd.h>
  18. #include <strings.h>
  19. #include <string.h>
  20. #include "perfdhcp.h"
  21. #include "dkdebug.h"
  22. static const char * enum_lookup(const char * const table[], size_t size, unsigned index);
  23. static const char *optionName(int v6, unsigned optnum);
  24. static void printOption(int v6, unsigned optnum, size_t len, const unsigned char *value);
  25. static void print_dhcpv4_packet(const struct dhcp_packet *pkt, size_t len);
  26. static void print_dhcpv6_packet(const struct dhcpv6_packet *pkt, size_t len);
  27. typedef enum { T_UNK, T_STRING, T_PERIOD, T_IPADDR, T_MTYPE, T_STATUS } opt_type;
  28. struct dhcp_option_desc {
  29. char *name;
  30. opt_type type;
  31. };
  32. static struct dhcp_option_desc option_desc[] = {
  33. [DHO_PAD] = { "PAD", T_UNK },
  34. [DHO_SUBNET_MASK] = { "SUBNET_MASK", T_UNK },
  35. [DHO_TIME_OFFSET] = { "TIME_OFFSET", T_PERIOD },
  36. [DHO_ROUTERS] = { "ROUTERS", T_IPADDR },
  37. [DHO_TIME_SERVERS] = { "TIME_SERVERS", T_UNK },
  38. [DHO_NAME_SERVERS] = { "NAME_SERVERS", T_UNK },
  39. [DHO_DOMAIN_NAME_SERVERS] = { "DOMAIN_NAME_SERVERS", T_IPADDR },
  40. [DHO_LOG_SERVERS] = { "LOG_SERVERS", T_UNK },
  41. [DHO_COOKIE_SERVERS] = { "COOKIE_SERVERS", T_UNK },
  42. [DHO_LPR_SERVERS] = { "LPR_SERVERS", T_IPADDR },
  43. [DHO_IMPRESS_SERVERS] = { "IMPRESS_SERVERS", T_UNK },
  44. [DHO_RESOURCE_LOCATION_SERVERS] = { "RESOURCE_LOCATION_SERVERS", T_UNK },
  45. [DHO_HOST_NAME] = { "HOST_NAME", T_UNK },
  46. [DHO_BOOT_SIZE] = { "BOOT_SIZE", T_UNK },
  47. [DHO_MERIT_DUMP] = { "MERIT_DUMP", T_UNK },
  48. [DHO_DOMAIN_NAME] = { "DOMAIN_NAME", T_STRING },
  49. [DHO_SWAP_SERVER] = { "SWAP_SERVER", T_UNK },
  50. [DHO_ROOT_PATH] = { "ROOT_PATH", T_UNK },
  51. [DHO_EXTENSIONS_PATH] = { "EXTENSIONS_PATH", T_UNK },
  52. [DHO_IP_FORWARDING] = { "IP_FORWARDING", T_UNK },
  53. [DHO_NON_LOCAL_SOURCE_ROUTING] = { "NON_LOCAL_SOURCE_ROUTING", T_UNK },
  54. [DHO_POLICY_FILTER] = { "POLICY_FILTER", T_UNK },
  55. [DHO_MAX_DGRAM_REASSEMBLY] = { "MAX_DGRAM_REASSEMBLY", T_UNK },
  56. [DHO_DEFAULT_IP_TTL] = { "DEFAULT_IP_TTL", T_UNK },
  57. [DHO_PATH_MTU_AGING_TIMEOUT] = { "PATH_MTU_AGING_TIMEOUT", T_UNK },
  58. [DHO_PATH_MTU_PLATEAU_TABLE] = { "PATH_MTU_PLATEAU_TABLE", T_UNK },
  59. [DHO_INTERFACE_MTU] = { "INTERFACE_MTU", T_UNK },
  60. [DHO_ALL_SUBNETS_LOCAL] = { "ALL_SUBNETS_LOCAL", T_UNK },
  61. [DHO_BROADCAST_ADDRESS] = { "BROADCAST_ADDRESS", T_UNK },
  62. [DHO_PERFORM_MASK_DISCOVERY] = { "PERFORM_MASK_DISCOVERY", T_UNK },
  63. [DHO_MASK_SUPPLIER] = { "MASK_SUPPLIER", T_UNK },
  64. [DHO_ROUTER_DISCOVERY] = { "ROUTER_DISCOVERY", T_UNK },
  65. [DHO_ROUTER_SOLICITATION_ADDRESS] = { "ROUTER_SOLICITATION_ADDRESS", T_UNK },
  66. [DHO_STATIC_ROUTES] = { "STATIC_ROUTES", T_UNK },
  67. [DHO_TRAILER_ENCAPSULATION] = { "TRAILER_ENCAPSULATION", T_UNK },
  68. [DHO_ARP_CACHE_TIMEOUT] = { "ARP_CACHE_TIMEOUT", T_UNK },
  69. [DHO_IEEE802_3_ENCAPSULATION] = { "IEEE802_3_ENCAPSULATION", T_UNK },
  70. [DHO_DEFAULT_TCP_TTL] = { "DEFAULT_TCP_TTL", T_UNK },
  71. [DHO_TCP_KEEPALIVE_INTERVAL] = { "TCP_KEEPALIVE_INTERVAL", T_UNK },
  72. [DHO_TCP_KEEPALIVE_GARBAGE] = { "TCP_KEEPALIVE_GARBAGE", T_UNK },
  73. [DHO_NIS_DOMAIN] = { "NIS_DOMAIN", T_UNK },
  74. [DHO_NIS_SERVERS] = { "NIS_SERVERS", T_UNK },
  75. [DHO_NTP_SERVERS] = { "NTP_SERVERS", T_IPADDR },
  76. [DHO_VENDOR_ENCAPSULATED_OPTIONS] = { "VENDOR_ENCAPSULATED_OPTIONS", T_UNK },
  77. [DHO_NETBIOS_NAME_SERVERS] = { "NETBIOS_NAME_SERVERS", T_UNK },
  78. [DHO_NETBIOS_DD_SERVER] = { "NETBIOS_DD_SERVER", T_UNK },
  79. [DHO_NETBIOS_NODE_TYPE] = { "NETBIOS_NODE_TYPE", T_UNK },
  80. [DHO_NETBIOS_SCOPE] = { "NETBIOS_SCOPE", T_UNK },
  81. [DHO_FONT_SERVERS] = { "FONT_SERVERS", T_UNK },
  82. [DHO_X_DISPLAY_MANAGER] = { "X_DISPLAY_MANAGER", T_UNK },
  83. [DHO_DHCP_REQUESTED_ADDRESS] = { "DHCP_REQUESTED_ADDRESS", T_IPADDR },
  84. [DHO_DHCP_LEASE_TIME] = { "DHCP_LEASE_TIME", T_PERIOD },
  85. [DHO_DHCP_OPTION_OVERLOAD] = { "DHCP_OPTION_OVERLOAD", T_UNK },
  86. [DHO_DHCP_MESSAGE_TYPE] = { "DHCP_MESSAGE_TYPE", T_MTYPE },
  87. [DHO_DHCP_SERVER_IDENTIFIER] = { "DHCP_SERVER_IDENTIFIER", T_UNK },
  88. [DHO_DHCP_PARAMETER_REQUEST_LIST] = { "DHCP_PARAMETER_REQUEST_LIST", T_UNK },
  89. [DHO_DHCP_MESSAGE] = { "DHCP_MESSAGE", T_UNK },
  90. [DHO_DHCP_MAX_MESSAGE_SIZE] = { "DHCP_MAX_MESSAGE_SIZE", T_UNK },
  91. [DHO_DHCP_RENEWAL_TIME] = { "DHCP_RENEWAL_TIME", T_UNK },
  92. [DHO_DHCP_REBINDING_TIME] = { "DHCP_REBINDING_TIME", T_UNK },
  93. [DHO_VENDOR_CLASS_IDENTIFIER] = { "VENDOR_CLASS_IDENTIFIER", T_UNK },
  94. [DHO_DHCP_CLIENT_IDENTIFIER] = { "DHCP_CLIENT_IDENTIFIER", T_UNK },
  95. [DHO_NWIP_DOMAIN_NAME] = { "NWIP_DOMAIN_NAME", T_UNK },
  96. [DHO_NWIP_SUBOPTIONS] = { "NWIP_SUBOPTIONS", T_UNK },
  97. [DHO_USER_CLASS] = { "USER_CLASS", T_UNK },
  98. [DHO_USER_CLASS] = { "USER_CLASS", T_UNK },
  99. [DHO_FQDN] = { "FQDN", T_UNK },
  100. [DHO_DHCP_AGENT_OPTIONS] = { "DHCP_AGENT_OPTIONS", T_UNK },
  101. [DHO_AUTHENTICATE] = { "AUTHENTICATE", T_UNK },
  102. [DHO_CLIENT_LAST_TRANSACTION_TIME] = { "CLIENT_LAST_TRANSACTION_TIME", T_UNK },
  103. [DHO_ASSOCIATED_IP] = { "ASSOCIATED_IP", T_UNK },
  104. [DHO_SUBNET_SELECTION] = { "SUBNET_SELECTION", T_UNK },
  105. [DHO_DOMAIN_SEARCH] = { "DOMAIN_SEARCH", T_UNK },
  106. [DHO_VIVCO_SUBOPTIONS] = { "VIVCO_SUBOPTIONS", T_UNK },
  107. [DHO_VIVSO_SUBOPTIONS] = { "VIVSO_SUBOPTIONS", T_UNK },
  108. [DHO_END] = { "END", T_UNK },
  109. [64] = { "NIS Domain", T_UNK },
  110. [65] = { "NIS Servers", T_UNK },
  111. [66] = { "TFTP Server", T_UNK },
  112. [67] = { "Bootfile name", T_UNK },
  113. [68] = { "Mobile IP Home Agent", T_UNK },
  114. [69] = { "SMTP Server", T_IPADDR },
  115. [70] = { "POP Server", T_IPADDR },
  116. [71] = { "NNTP Server", T_IPADDR },
  117. [72] = { "WWW Server", T_IPADDR },
  118. [73] = { "Finger Server", T_IPADDR },
  119. [74] = { "IRC Server", T_IPADDR },
  120. [75] = { "StreetTalk Server", T_IPADDR },
  121. [76] = { "StreetTalk Directory Assistance Server", T_IPADDR }
  122. };
  123. static const char * const message_types[] = {
  124. [DHCPDISCOVER] = "DHCPDISCOVER",
  125. [DHCPOFFER] = "DHCPOFFER",
  126. [DHCPREQUEST] = "DHCPREQUEST",
  127. [DHCPDECLINE] = "DHCPDECLINE",
  128. [DHCPACK] = "DHCPACK",
  129. [DHCPNAK] = "DHCPNAK",
  130. [DHCPRELEASE] = "DHCPRELEASE",
  131. [DHCPINFORM] = "DHCPINFORM",
  132. [DHCPLEASEQUERY] = "DHCPLEASEQUERY",
  133. [DHCPLEASEUNASSIGNED] = "DHCPLEASEUNASSIGNED",
  134. [DHCPLEASEUNKNOWN] = "DHCPLEASEUNKNOWN",
  135. [DHCPLEASEACTIVE] = "DHCPLEASEACTIVE"
  136. };
  137. static struct dhcp_option_desc option6_desc[] = {
  138. [D6O_CLIENTID] = { "D6O_CLIENTID", T_UNK },
  139. [D6O_SERVERID] = { "D6O_SERVERID", T_UNK },
  140. [D6O_IA_NA] = { "D6O_IA_NA", T_UNK },
  141. [D6O_IA_TA] = { "D6O_IA_TA", T_UNK },
  142. [D6O_IAADDR] = { "D6O_IAADDR", T_UNK },
  143. [D6O_ORO] = { "D6O_ORO", T_UNK },
  144. [D6O_PREFERENCE] = { "D6O_PREFERENCE", T_UNK },
  145. [D6O_ELAPSED_TIME] = { "D6O_ELAPSED_TIME", T_PERIOD },
  146. [D6O_RELAY_MSG] = { "D6O_RELAY_MSG", T_UNK },
  147. [D6O_AUTH] = { "D6O_AUTH", T_UNK },
  148. [D6O_UNICAST] = { "D6O_UNICAST", T_UNK },
  149. [D6O_STATUS_CODE] = { "D6O_STATUS_CODE", T_STATUS },
  150. [D6O_RAPID_COMMIT] = { "D6O_RAPID_COMMIT", T_UNK },
  151. [D6O_USER_CLASS] = { "D6O_USER_CLASS", T_UNK },
  152. [D6O_VENDOR_CLASS] = { "D6O_VENDOR_CLASS", T_UNK },
  153. [D6O_VENDOR_OPTS] = { "D6O_VENDOR_OPTS", T_UNK },
  154. [D6O_INTERFACE_ID] = { "D6O_INTERFACE_ID", T_UNK },
  155. [D6O_RECONF_MSG] = { "D6O_RECONF_MSG", T_UNK },
  156. [D6O_RECONF_ACCEPT] = { "D6O_RECONF_ACCEPT", T_UNK },
  157. [D6O_SIP_SERVERS_DNS] = { "D6O_SIP_SERVERS_DNS", T_UNK },
  158. [D6O_SIP_SERVERS_ADDR] = { "D6O_SIP_SERVERS_ADDR", T_UNK },
  159. [D6O_NAME_SERVERS] = { "D6O_NAME_SERVERS", T_IPADDR },
  160. [D6O_DOMAIN_SEARCH] = { "D6O_DOMAIN_SEARCH", T_UNK },
  161. [D6O_IA_PD] = { "D6O_IA_PD", T_UNK },
  162. [D6O_IAPREFIX] = { "D6O_IAPREFIX", T_UNK },
  163. [D6O_NIS_SERVERS] = { "D6O_NIS_SERVERS", T_UNK },
  164. [D6O_NISP_SERVERS] = { "D6O_NISP_SERVERS", T_UNK },
  165. [D6O_NIS_DOMAIN_NAME] = { "D6O_NIS_DOMAIN_NAME", T_UNK },
  166. [D6O_NISP_DOMAIN_NAME] = { "D6O_NISP_DOMAIN_NAME", T_UNK },
  167. [D6O_SNTP_SERVERS] = { "D6O_SNTP_SERVERS", T_UNK },
  168. [D6O_INFORMATION_REFRESH_TIME] = { "D6O_INFORMATION_REFRESH_TIME", T_UNK },
  169. [D6O_BCMCS_SERVER_D] = { "D6O_BCMCS_SERVER_D", T_UNK },
  170. [D6O_BCMCS_SERVER_A] = { "D6O_BCMCS_SERVER_A", T_UNK },
  171. [D6O_GEOCONF_CIVIC] = { "D6O_GEOCONF_CIVIC", T_UNK },
  172. [D6O_REMOTE_ID] = { "D6O_REMOTE_ID", T_UNK },
  173. [D6O_SUBSCRIBER_ID] = { "D6O_SUBSCRIBER_ID", T_UNK },
  174. [D6O_CLIENT_FQDN] = { "D6O_CLIENT_FQDN", T_UNK },
  175. [D6O_PANA_AGENT] = { "D6O_PANA_AGENT", T_UNK },
  176. [D6O_NEW_POSIX_TIMEZONE] = { "D6O_NEW_POSIX_TIMEZONE", T_UNK },
  177. [D6O_NEW_TZDB_TIMEZONE] = { "D6O_NEW_TZDB_TIMEZONE", T_UNK },
  178. [D6O_ERO] = { "D6O_ERO", T_UNK },
  179. [D6O_LQ_QUERY] = { "D6O_LQ_QUERY", T_UNK },
  180. [D6O_CLIENT_DATA] = { "D6O_CLIENT_DATA", T_UNK },
  181. [D6O_CLT_TIME] = { "D6O_CLT_TIME", T_UNK },
  182. [D6O_LQ_RELAY_DATA] = { "D6O_LQ_RELAY_DATA", T_UNK },
  183. [D6O_LQ_CLIENT_LINK] = { "D6O_LQ_CLIENT_LINK", T_UNK }
  184. };
  185. static const char * const message6_types[] = {
  186. [DHCPV6_SOLICIT] = "DHCPV6_SOLICIT",
  187. [DHCPV6_ADVERTISE] = "DHCPV6_ADVERTISE",
  188. [DHCPV6_REQUEST] = "DHCPV6_REQUEST",
  189. [DHCPV6_CONFIRM] = "DHCPV6_CONFIRM",
  190. [DHCPV6_RENEW] = "DHCPV6_RENEW",
  191. [DHCPV6_REBIND] = "DHCPV6_REBIND",
  192. [DHCPV6_REPLY] = "DHCPV6_REPLY",
  193. [DHCPV6_RELEASE] = "DHCPV6_RELEASE",
  194. [DHCPV6_DECLINE] = "DHCPV6_DECLINE",
  195. [DHCPV6_RECONFIGURE] = "DHCPV6_RECONFIGURE",
  196. [DHCPV6_INFORMATION_REQUEST] = "DHCPV6_INFORMATION_REQUEST",
  197. [DHCPV6_RELAY_FORW] = "DHCPV6_RELAY_FORW",
  198. [DHCPV6_RELAY_REPL] = "DHCPV6_RELAY_REPL",
  199. [DHCPV6_LEASEQUERY] = "DHCPV6_LEASEQUERY",
  200. [DHCPV6_LEASEQUERY_REPLY] = "DHCPV6_LEASEQUERY_REPLY"
  201. };
  202. static const char * const status_codes[] = {
  203. [STATUS_Success] = "Success",
  204. [STATUS_UnspecFail] = "UnspecFail",
  205. [STATUS_NoAddrsAvail] = "NoAddrsAvail",
  206. [STATUS_NoBinding] = "NoBinding",
  207. [STATUS_NotOnLink] = "NotOnLink",
  208. [STATUS_UseMulticast] = "UseMulticast",
  209. [STATUS_NoPrefixAvail] = "NoPrefixAvail",
  210. [STATUS_UnknownQueryType] = "UnknownQueryType",
  211. [STATUS_MalformedQuery] = "MalformedQuery",
  212. [STATUS_NotConfigured] = "NotConfigured",
  213. [STATUS_NotAllowed] = "NotAllowed",
  214. };
  215. void
  216. print_dhcp_packet(int v6, const void *pkt, size_t len)
  217. {
  218. if (v6)
  219. print_dhcpv6_packet((struct dhcpv6_packet *)pkt, len);
  220. else
  221. print_dhcpv4_packet((struct dhcp_packet *)pkt, len);
  222. if (dk_set(DK_PACKET)) {
  223. unsigned i;
  224. fprintf(stderr, "Raw packet contents (%zu bytes):\n", len);
  225. for (i = 0; i < len; i++)
  226. fprintf(stderr, "%02x ", ((unsigned char *)pkt)[i]);
  227. fputc('\n', stderr);
  228. }
  229. }
  230. /*
  231. * Note: Not reentrant
  232. */
  233. static const char *
  234. enum_lookup(const char * const table[], size_t size, unsigned index)
  235. {
  236. static char numbuf[10];
  237. if (index < (size / sizeof(char *)) && table[index] != NULL)
  238. return table[index];
  239. else {
  240. snprintf(numbuf, sizeof(numbuf), "%u", index);
  241. return numbuf;
  242. }
  243. }
  244. /*
  245. * Note: Not reentrant
  246. */
  247. static const char *
  248. optionName(int v6, unsigned optnum)
  249. {
  250. static char numbuf[16];
  251. unsigned maxOpt = ((v6 ? sizeof(option6_desc) : sizeof(option_desc)) - 1) /
  252. sizeof(struct dhcp_option_desc);
  253. struct dhcp_option_desc *descTable;
  254. if (optnum > maxOpt) {
  255. snprintf(numbuf, sizeof(numbuf), "invalid (%u)", optnum);
  256. return numbuf;
  257. }
  258. descTable = v6 ? option6_desc : option_desc;
  259. if (descTable[optnum].name == NULL) {
  260. snprintf(numbuf, sizeof(numbuf), "%u", optnum);
  261. return numbuf;
  262. }
  263. else
  264. return descTable[optnum].name;
  265. }
  266. /*
  267. *
  268. * Output variables: None
  269. */
  270. static void
  271. printOption(int v6, unsigned optnum, size_t len, const unsigned char *value)
  272. {
  273. struct dhcp_option_desc *descTable = v6 ? option6_desc : option_desc;
  274. char buf[ADDR_NAME_BUFSIZE];
  275. unsigned i;
  276. unsigned maxOpt = ((v6 ? sizeof(option6_desc) : sizeof(option_desc)) - 1) / sizeof(struct dhcp_option_desc);
  277. unsigned statusCode;
  278. fprintf(stderr, "Option %s (%d) length %zu value ", optionName(v6, optnum), optnum, len);
  279. switch (optnum > maxOpt ? T_UNK : descTable[optnum].type) {
  280. case T_STRING:
  281. fprintf(stderr, "\"%.*s\"\n", (int) len, value);
  282. break;
  283. case T_PERIOD:
  284. fprintf(stderr, "%d seconds\n", ntohl(*(int *)value));
  285. break;
  286. case T_MTYPE:
  287. fprintf(stderr, "%s\n", enum_lookup(message_types, sizeof(message_types), *value));
  288. break;
  289. case T_IPADDR:
  290. for (i = 0; len - i >= 4; i += 4)
  291. fprintf(stderr, "%s%s", addrtoa(AF_INET, (struct in_addr *)(value+i), buf), len - i > 4 ? ", " : "\n");
  292. break;
  293. case T_STATUS:
  294. statusCode = ntohs(*(uint16_t *)value);
  295. fprintf(stderr, "%s: %*.*s\n",
  296. enum_lookup(status_codes, sizeof(status_codes), statusCode),
  297. (int)len - 2, (int)len - 2, value + 2);
  298. break;
  299. default:
  300. for (i = 0; i < len; i++)
  301. fprintf(stderr, "%02x", value[i]);
  302. fputc('\n', stderr);
  303. break;
  304. }
  305. }
  306. static void
  307. print_dhcpv4_packet(const struct dhcp_packet *pkt, size_t msglen)
  308. {
  309. int i;
  310. const unsigned char *p;
  311. aaddr_buf buf1, buf2, buf3, buf4;
  312. fprintf(stderr,
  313. "opcode %u\n\
  314. htype %u\n\
  315. hlen %u\n\
  316. hops %u\n\
  317. xid 0x%0x\n\
  318. secs %u\n\
  319. flags 0x%x\n\
  320. ciaddr %s\n\
  321. yiaddr %s\n\
  322. siaddr %s\n\
  323. giaddr %s\n\
  324. chaddr ",
  325. pkt->op,
  326. pkt->htype,
  327. pkt->hlen,
  328. pkt->hops,
  329. pkt->xid,
  330. pkt->secs,
  331. pkt->flags,
  332. addrtoa(AF_INET, &pkt->ciaddr, buf1),
  333. addrtoa(AF_INET, &pkt->yiaddr, buf2),
  334. addrtoa(AF_INET, &pkt->siaddr, buf3),
  335. addrtoa(AF_INET, &pkt->giaddr, buf4));
  336. for (i = 0; i < pkt->hlen; i++)
  337. fprintf(stderr, "%02x", pkt->chaddr[i]);
  338. fputc('\n', stderr);
  339. fprintf(stderr, "magic 0x%x\n", *(unsigned int *)&pkt->options);
  340. p = &pkt->options[4];
  341. while ((unsigned) (p - (unsigned char *)pkt) < msglen && *p != DHO_END) {
  342. if (*p == DHO_PAD) {
  343. fprintf(stderr, "Option PAD\n");
  344. p++;
  345. }
  346. else {
  347. unsigned optnum = *p++;
  348. size_t len = *p++;
  349. printOption(0, optnum, len, p);
  350. p += len;
  351. }
  352. }
  353. }
  354. static void
  355. print_dhcpv6_packet(const struct dhcpv6_packet *pkt, size_t msglen)
  356. {
  357. int i;
  358. const unsigned char *p;
  359. struct v6_option *opt;
  360. fprintf(stderr, "msgtype\t%s\ntid\t", enum_lookup(message6_types, sizeof(message6_types), pkt->msg_type));
  361. for (i = 0; i <= 2; i++)
  362. fprintf(stderr, "%02x", pkt->transaction_id[i]);
  363. fputc('\n', stderr);
  364. p = pkt->options;
  365. opt = (struct v6_option *)p;
  366. while ((unsigned) (p - (unsigned char *)pkt) < msglen && opt->code != 0) {
  367. unsigned optlen = ntohs(opt->len);
  368. printOption(1, ntohs(opt->code), optlen, &opt->value);
  369. p += 4 + optlen;
  370. opt = (struct v6_option *)p;
  371. }
  372. }