static void egpnrprint(netdissect_options *ndo, const struct egp_packet *egp, u_int length) { const uint8_t *cp; uint32_t addr; uint32_t net; u_int netlen; u_int gateways, distances, networks; u_int intgw, extgw, t_gateways; const char *comma; addr = EXTRACT_IPV4_TO_NETWORK_ORDER(egp->egp_sourcenet); if (IN_CLASSA(addr)) { net = addr & IN_CLASSA_NET; netlen = 1; } else if (IN_CLASSB(addr)) { net = addr & IN_CLASSB_NET; netlen = 2; } else if (IN_CLASSC(addr)) { net = addr & IN_CLASSC_NET; netlen = 3; } else { net = 0; netlen = 0; } cp = (const uint8_t *)(egp + 1); length -= sizeof(*egp); intgw = EXTRACT_U_1(egp->egp_intgw); extgw = EXTRACT_U_1(egp->egp_extgw); t_gateways = intgw + extgw; for (gateways = 0; gateways < t_gateways; ++gateways) { /* Pickup host part of gateway address */ addr = 0; if (length < 4 - netlen) goto trunc; ND_TCHECK_LEN(cp, 4 - netlen); switch (netlen) { case 1: addr = EXTRACT_U_1(cp); cp++; /* fall through */ case 2: addr = (addr << 8) | EXTRACT_U_1(cp); cp++; /* fall through */ case 3: addr = (addr << 8) | EXTRACT_U_1(cp); cp++; break; } addr |= net; length -= 4 - netlen; if (length < 1) goto trunc; ND_TCHECK_1(cp); distances = EXTRACT_U_1(cp); cp++; length--; ND_PRINT(" %s %s ", gateways < intgw ? "int" : "ext", ipaddr_string(ndo, (const u_char *)&addr)); comma = ""; ND_PRINT("("); while (distances != 0) { if (length < 2) goto trunc; ND_TCHECK_2(cp); ND_PRINT("%sd%u:", comma, EXTRACT_U_1(cp)); cp++; comma = ", "; networks = EXTRACT_U_1(cp); cp++; length -= 2; while (networks != 0) { /* Pickup network number */ if (length < 1) goto trunc; ND_TCHECK_1(cp); addr = ((uint32_t) EXTRACT_U_1(cp)) << 24; cp++; length--; if (IN_CLASSB(addr)) { if (length < 1) goto trunc; ND_TCHECK_1(cp); addr |= ((uint32_t) EXTRACT_U_1(cp)) << 16; cp++; length--; } else if (!IN_CLASSA(addr)) { if (length < 2) goto trunc; ND_TCHECK_2(cp); addr |= ((uint32_t) EXTRACT_U_1(cp)) << 16; cp++; addr |= ((uint32_t) EXTRACT_U_1(cp)) << 8; cp++; length -= 2; } ND_PRINT(" %s", ipaddr_string(ndo, (const u_char *)&addr)); networks--; } distances--; } ND_PRINT(")"); } return; trunc: ND_PRINT("[|]"); }
/* * Print bootp requests */ void bootp_print(netdissect_options *ndo, const u_char *cp, u_int length) { const struct bootp *bp; static const u_char vm_cmu[4] = VM_CMU; static const u_char vm_rfc1048[4] = VM_RFC1048; uint8_t bp_op, bp_htype, bp_hlen; ndo->ndo_protocol = "bootp"; bp = (const struct bootp *)cp; ND_TCHECK_1(bp->bp_op); bp_op = EXTRACT_U_1(bp->bp_op); ND_PRINT("BOOTP/DHCP, %s", tok2str(bootp_op_values, "unknown (0x%02x)", bp_op)); ND_TCHECK_1(bp->bp_hlen); bp_htype = EXTRACT_U_1(bp->bp_htype); bp_hlen = EXTRACT_U_1(bp->bp_hlen); if (bp_htype == 1 && bp_hlen == 6 && bp_op == BOOTPREQUEST) { ND_TCHECK_6(bp->bp_chaddr); ND_PRINT(" from %s", etheraddr_string(ndo, bp->bp_chaddr)); } ND_PRINT(", length %u", length); if (!ndo->ndo_vflag) return; ND_TCHECK_2(bp->bp_secs); /* The usual hardware address type is 1 (10Mb Ethernet) */ if (bp_htype != 1) ND_PRINT(", htype %u", bp_htype); /* The usual length for 10Mb Ethernet address is 6 bytes */ if (bp_htype != 1 || bp_hlen != 6) ND_PRINT(", hlen %u", bp_hlen); /* Only print interesting fields */ if (EXTRACT_U_1(bp->bp_hops)) ND_PRINT(", hops %u", EXTRACT_U_1(bp->bp_hops)); if (EXTRACT_BE_U_4(bp->bp_xid)) ND_PRINT(", xid 0x%x", EXTRACT_BE_U_4(bp->bp_xid)); if (EXTRACT_BE_U_2(bp->bp_secs)) ND_PRINT(", secs %u", EXTRACT_BE_U_2(bp->bp_secs)); ND_TCHECK_2(bp->bp_flags); ND_PRINT(", Flags [%s]", bittok2str(bootp_flag_values, "none", EXTRACT_BE_U_2(bp->bp_flags))); if (ndo->ndo_vflag > 1) ND_PRINT(" (0x%04x)", EXTRACT_BE_U_2(bp->bp_flags)); /* Client's ip address */ ND_TCHECK_4(bp->bp_ciaddr); if (EXTRACT_IPV4_TO_NETWORK_ORDER(bp->bp_ciaddr)) ND_PRINT("\n\t Client-IP %s", ipaddr_string(ndo, bp->bp_ciaddr)); /* 'your' ip address (bootp client) */ ND_TCHECK_4(bp->bp_yiaddr); if (EXTRACT_IPV4_TO_NETWORK_ORDER(bp->bp_yiaddr)) ND_PRINT("\n\t Your-IP %s", ipaddr_string(ndo, bp->bp_yiaddr)); /* Server's ip address */ ND_TCHECK_4(bp->bp_siaddr); if (EXTRACT_IPV4_TO_NETWORK_ORDER(bp->bp_siaddr)) ND_PRINT("\n\t Server-IP %s", ipaddr_string(ndo, bp->bp_siaddr)); /* Gateway's ip address */ ND_TCHECK_4(bp->bp_giaddr); if (EXTRACT_IPV4_TO_NETWORK_ORDER(bp->bp_giaddr)) ND_PRINT("\n\t Gateway-IP %s", ipaddr_string(ndo, bp->bp_giaddr)); /* Client's Ethernet address */ if (bp_htype == 1 && bp_hlen == 6) { ND_TCHECK_6(bp->bp_chaddr); ND_PRINT("\n\t Client-Ethernet-Address %s", etheraddr_string(ndo, bp->bp_chaddr)); } ND_TCHECK_1(bp->bp_sname); /* check first char only */ if (EXTRACT_U_1(bp->bp_sname)) { ND_PRINT("\n\t sname \""); if (nd_printztn(ndo, bp->bp_sname, (u_int)sizeof(bp->bp_sname), ndo->ndo_snapend) == 0) { ND_PRINT("\""); nd_print_trunc(ndo); return; } ND_PRINT("\""); } ND_TCHECK_1(bp->bp_file); /* check first char only */ if (EXTRACT_U_1(bp->bp_file)) { ND_PRINT("\n\t file \""); if (nd_printztn(ndo, bp->bp_file, (u_int)sizeof(bp->bp_file), ndo->ndo_snapend) == 0) { ND_PRINT("\""); nd_print_trunc(ndo); return; } ND_PRINT("\""); } /* Decode the vendor buffer */ ND_TCHECK_4(bp->bp_vend); if (memcmp((const char *)bp->bp_vend, vm_rfc1048, sizeof(uint32_t)) == 0) rfc1048_print(ndo, bp->bp_vend); else if (memcmp((const char *)bp->bp_vend, vm_cmu, sizeof(uint32_t)) == 0) cmu_print(ndo, bp->bp_vend); else { uint32_t ul; ul = EXTRACT_BE_U_4(bp->bp_vend); if (ul != 0) ND_PRINT("\n\t Vendor-#0x%x", ul); } return; trunc: nd_print_trunc(ndo); }