/* * Print bootp requests */ void bootp_print(struct bootp *bp, int length, u_short sport, u_short dport) { static char tstr[] = " [|bootp]"; static unsigned char vm_cmu[4] = VM_CMU; static unsigned char vm_rfc1048[4] = VM_RFC1048; u_char *ep; int vdlen; #define TCHECK(var, l) if ((u_char *)&(var) > ep - l) goto trunc /* Note funny sized packets */ if (length != sizeof(struct bootp)) (void) printf(" [len=%d]", length); /* 'ep' points to the end of avaible data. */ ep = (u_char *) snapend; switch (bp->bp_op) { case BOOTREQUEST: /* Usually, a request goes from a client to a server */ if (sport != IPPORT_BOOTPC || dport != IPPORT_BOOTPS) printf(" (request)"); break; case BOOTREPLY: /* Usually, a reply goes from a server to a client */ if (sport != IPPORT_BOOTPS || dport != IPPORT_BOOTPC) printf(" (reply)"); break; default: printf(" bootp-#%d", bp->bp_op); } /* The usual hardware address type is 1 (10Mb Ethernet) */ if (bp->bp_htype != 1) printf(" htype:%d", bp->bp_htype); /* The usual length for 10Mb Ethernet address is 6 bytes */ if (bp->bp_hlen != 6) printf(" hlen:%d", bp->bp_hlen); /* Client's Hardware address */ if (bp->bp_hlen) { struct ether_header *eh; char *e; TCHECK(bp->bp_chaddr[0], 6); eh = (struct ether_header *) packetp; if (bp->bp_op == BOOTREQUEST) e = (char *) ESRC(eh); else if (bp->bp_op == BOOTREPLY) e = (char *) EDST(eh); else e = NULL; if (e == NULL || bcmp((char *) bp->bp_chaddr, e, 6)) dump_hex(bp->bp_chaddr, bp->bp_hlen); } /* Only print interesting fields */ if (bp->bp_hops) printf(" hops:%d", bp->bp_hops); if (bp->bp_xid) printf(" xid:%ld", (long)ntohl(bp->bp_xid)); if (bp->bp_secs) printf(" secs:%d", ntohs(bp->bp_secs)); /* Client's ip address */ TCHECK(bp->bp_ciaddr, sizeof(bp->bp_ciaddr)); if (bp->bp_ciaddr.s_addr) printf(" C:%s", ipaddr_string(&bp->bp_ciaddr)); /* 'your' ip address (bootp client) */ TCHECK(bp->bp_yiaddr, sizeof(bp->bp_yiaddr)); if (bp->bp_yiaddr.s_addr) printf(" Y:%s", ipaddr_string(&bp->bp_yiaddr)); /* Server's ip address */ TCHECK(bp->bp_siaddr, sizeof(bp->bp_siaddr)); if (bp->bp_siaddr.s_addr) printf(" S:%s", ipaddr_string(&bp->bp_siaddr)); /* Gateway's ip address */ TCHECK(bp->bp_giaddr, sizeof(bp->bp_giaddr)); if (bp->bp_giaddr.s_addr) printf(" G:%s", ipaddr_string(&bp->bp_giaddr)); TCHECK(bp->bp_sname[0], sizeof(bp->bp_sname)); if (*bp->bp_sname) { printf(" sname:"); if (printfn(bp->bp_sname, ep)) { fputs(tstr + 1, stdout); return; } } TCHECK(bp->bp_file[0], sizeof(bp->bp_file)); if (*bp->bp_file) { printf(" file:"); if (printfn(bp->bp_file, ep)) { fputs(tstr + 1, stdout); return; } } /* Don't try to decode the vendor buffer unless we're verbose */ if (vflag <= 0) return; vdlen = sizeof(bp->bp_vend); /* Vendor data can extend to the end of the packet. */ if (vdlen < (ep - bp->bp_vend)) vdlen = (ep - bp->bp_vend); TCHECK(bp->bp_vend[0], vdlen); printf(" vend"); if (!bcmp(bp->bp_vend, vm_rfc1048, sizeof(u_int32))) rfc1048_print(bp->bp_vend, vdlen); else if (!bcmp(bp->bp_vend, vm_cmu, sizeof(u_int32))) cmu_print(bp->bp_vend, vdlen); else other_print(bp->bp_vend, vdlen); return; trunc: fputs(tstr, stdout); #undef TCHECK }
/* * 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); }
/* * Print bootp requests */ void bootp_print(netdissect_options *ndo, register const u_char *cp, u_int length) { register const struct bootp *bp; static const u_char vm_cmu[4] = VM_CMU; static const u_char vm_rfc1048[4] = VM_RFC1048; bp = (const struct bootp *)cp; ND_TCHECK(bp->bp_op); ND_PRINT((ndo, "BOOTP/DHCP, %s", tok2str(bootp_op_values, "unknown (0x%02x)", bp->bp_op))); if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) { ND_TCHECK2(bp->bp_chaddr[0], 6); ND_PRINT((ndo, " from %s", etheraddr_string(ndo, bp->bp_chaddr))); } ND_PRINT((ndo, ", length %u", length)); if (!ndo->ndo_vflag) return; ND_TCHECK(bp->bp_secs); /* The usual hardware address type is 1 (10Mb Ethernet) */ if (bp->bp_htype != 1) ND_PRINT((ndo, ", htype %d", bp->bp_htype)); /* The usual length for 10Mb Ethernet address is 6 bytes */ if (bp->bp_htype != 1 || bp->bp_hlen != 6) ND_PRINT((ndo, ", hlen %d", bp->bp_hlen)); /* Only print interesting fields */ if (bp->bp_hops) ND_PRINT((ndo, ", hops %d", bp->bp_hops)); if (EXTRACT_32BITS(&bp->bp_xid)) ND_PRINT((ndo, ", xid 0x%x", EXTRACT_32BITS(&bp->bp_xid))); if (EXTRACT_16BITS(&bp->bp_secs)) ND_PRINT((ndo, ", secs %d", EXTRACT_16BITS(&bp->bp_secs))); ND_PRINT((ndo, ", Flags [%s]", bittok2str(bootp_flag_values, "none", EXTRACT_16BITS(&bp->bp_flags)))); if (ndo->ndo_vflag > 1) ND_PRINT((ndo, " (0x%04x)", EXTRACT_16BITS(&bp->bp_flags))); /* Client's ip address */ ND_TCHECK(bp->bp_ciaddr); if (EXTRACT_32BITS(&bp->bp_ciaddr.s_addr)) ND_PRINT((ndo, "\n\t Client-IP %s", ipaddr_string(ndo, &bp->bp_ciaddr))); /* 'your' ip address (bootp client) */ ND_TCHECK(bp->bp_yiaddr); if (EXTRACT_32BITS(&bp->bp_yiaddr.s_addr)) ND_PRINT((ndo, "\n\t Your-IP %s", ipaddr_string(ndo, &bp->bp_yiaddr))); /* Server's ip address */ ND_TCHECK(bp->bp_siaddr); if (EXTRACT_32BITS(&bp->bp_siaddr.s_addr)) ND_PRINT((ndo, "\n\t Server-IP %s", ipaddr_string(ndo, &bp->bp_siaddr))); /* Gateway's ip address */ ND_TCHECK(bp->bp_giaddr); if (EXTRACT_32BITS(&bp->bp_giaddr.s_addr)) ND_PRINT((ndo, "\n\t Gateway-IP %s", ipaddr_string(ndo, &bp->bp_giaddr))); /* Client's Ethernet address */ if (bp->bp_htype == 1 && bp->bp_hlen == 6) { ND_TCHECK2(bp->bp_chaddr[0], 6); ND_PRINT((ndo, "\n\t Client-Ethernet-Address %s", etheraddr_string(ndo, bp->bp_chaddr))); } ND_TCHECK2(bp->bp_sname[0], 1); /* check first char only */ if (*bp->bp_sname) { ND_PRINT((ndo, "\n\t sname \"")); if (fn_print(ndo, bp->bp_sname, ndo->ndo_snapend)) { ND_PRINT((ndo, "\"")); ND_PRINT((ndo, "%s", tstr + 1)); return; } ND_PRINT((ndo, "\"")); } ND_TCHECK2(bp->bp_file[0], 1); /* check first char only */ if (*bp->bp_file) { ND_PRINT((ndo, "\n\t file \"")); if (fn_print(ndo, bp->bp_file, ndo->ndo_snapend)) { ND_PRINT((ndo, "\"")); ND_PRINT((ndo, "%s", tstr + 1)); return; } ND_PRINT((ndo, "\"")); } /* Decode the vendor buffer */ ND_TCHECK(bp->bp_vend[0]); 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_32BITS(&bp->bp_vend); if (ul != 0) ND_PRINT((ndo, "\n\t Vendor-#0x%x", ul)); } return; trunc: ND_PRINT((ndo, "%s", tstr)); }
/* * Print bootp requests */ void bootp_print(const u_char *cp, u_int length, u_short sport, u_short dport) { const struct bootp *bp; static u_char vm_cmu[4] = VM_CMU; static u_char vm_rfc1048[4] = VM_RFC1048; bp = (struct bootp *)cp; TCHECK(bp->bp_op); switch (bp->bp_op) { case BOOTREQUEST: /* Usually, a request goes from a client to a server */ if (sport != IPPORT_BOOTPC || dport != IPPORT_BOOTPS) printf(" (request)"); break; case BOOTREPLY: /* Usually, a reply goes from a server to a client */ if (sport != IPPORT_BOOTPS || dport != IPPORT_BOOTPC) printf(" (reply)"); break; default: printf(" bootp-#%d", bp->bp_op); } TCHECK(bp->bp_flags); /* The usual hardware address type is 1 (10Mb Ethernet) */ if (bp->bp_htype != 1) printf(" htype-#%d", bp->bp_htype); /* The usual length for 10Mb Ethernet address is 6 bytes */ if (bp->bp_htype != 1 || bp->bp_hlen != 6) printf(" hlen:%d", bp->bp_hlen); /* Only print interesting fields */ if (bp->bp_hops) printf(" hops:%d", bp->bp_hops); if (bp->bp_xid) printf(" xid:0x%x", (u_int32_t)ntohl(bp->bp_xid)); if (bp->bp_secs) printf(" secs:%d", ntohs(bp->bp_secs)); if (bp->bp_flags) printf(" flags:0x%x", ntohs(bp->bp_flags)); /* Client's ip address */ TCHECK(bp->bp_ciaddr); if (bp->bp_ciaddr.s_addr) printf(" C:%s", ipaddr_string(&bp->bp_ciaddr)); /* 'your' ip address (bootp client) */ TCHECK(bp->bp_yiaddr); if (bp->bp_yiaddr.s_addr) printf(" Y:%s", ipaddr_string(&bp->bp_yiaddr)); /* Server's ip address */ TCHECK(bp->bp_siaddr); if (bp->bp_siaddr.s_addr) printf(" S:%s", ipaddr_string(&bp->bp_siaddr)); /* Gateway's ip address */ TCHECK(bp->bp_giaddr); if (bp->bp_giaddr.s_addr) printf(" G:%s", ipaddr_string(&bp->bp_giaddr)); /* Client's Ethernet address */ if (bp->bp_htype == 1 && bp->bp_hlen == 6) { const struct ether_header *eh; const char *e; TCHECK2(bp->bp_chaddr[0], 6); eh = (struct ether_header *)packetp; if (bp->bp_op == BOOTREQUEST) e = (const char *)ESRC(eh); else if (bp->bp_op == BOOTREPLY) e = (const char *)EDST(eh); else e = NULL; if (e == 0 || memcmp((char *)bp->bp_chaddr, e, 6) != 0) printf(" ether %s", etheraddr_string(bp->bp_chaddr)); } TCHECK2(bp->bp_sname[0], 1); /* check first char only */ if (*bp->bp_sname) { printf(" sname \""); if (fn_print(bp->bp_sname, snapend)) { putchar('"'); fputs(tstr + 1, stdout); return; } putchar('"'); } TCHECK2(bp->bp_file[0], 1); /* check first char only */ if (*bp->bp_file) { printf(" file \""); if (fn_print(bp->bp_file, snapend)) { putchar('"'); fputs(tstr + 1, stdout); return; } putchar('"'); } /* Decode the vendor buffer */ TCHECK2(bp->bp_vend[0], sizeof(u_int32_t)); length -= sizeof(*bp) - sizeof(bp->bp_vend); if (memcmp((char *)bp->bp_vend, (char *)vm_rfc1048, sizeof(u_int32_t)) == 0) rfc1048_print(bp->bp_vend, length); else if (memcmp((char *)bp->bp_vend, (char *)vm_cmu, sizeof(u_int32_t)) == 0) cmu_print(bp->bp_vend, length); else { u_int32_t ul; memcpy((char *)&ul, (char *)bp->bp_vend, sizeof(ul)); if (ul != 0) printf("vend-#0x%x", ul); } return; trunc: fputs(tstr, stdout); }