X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/d35664b74857a254f469e178a805b36751254610..2bb115bda1b3a404f9e4535d69b83e893d210bd6:/print-bootp.c diff --git a/print-bootp.c b/print-bootp.c index 88e1e847..cde86456 100644 --- a/print-bootp.c +++ b/print-bootp.c @@ -21,8 +21,8 @@ * Format and print bootp packets. */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-bootp.c,v 1.70 2003-03-12 19:25:40 fenner Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-bootp.c,v 1.78 2004-03-02 07:38:10 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -45,42 +45,43 @@ static void cmu_print(const u_char *); static char tstr[] = " [|bootp]"; +static const struct tok bootp_flag_values[] = { + { 0x8000, "Broadcast" }, + { 0, NULL} +}; + +static const struct tok bootp_op_values[] = { + { BOOTPREQUEST, "Request" }, + { BOOTPREPLY, "Reply" }, + { 0, NULL} +}; + /* * Print bootp requests */ void -bootp_print(register const u_char *cp, u_short sport, u_short dport, u_int length) +bootp_print(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; - printf("BOOTP/DHCP, length: %u",length); - - if (!vflag) - return; - bp = (const 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("\n\tRequest"); - break; - - case BOOTREPLY: - /* Usually, a reply goes from a server to a client */ - if (sport == IPPORT_BOOTPS && dport == IPPORT_BOOTPC) - printf("\n\tReply"); - break; - - default: - printf("\n\tbootp-#%d", bp->bp_op); - break; + + printf("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) { + TCHECK2(bp->bp_chaddr[0], 6); + printf(" from %s", etheraddr_string(bp->bp_chaddr)); } + printf(", length: %u", length); + + if (!vflag) + return; + TCHECK(bp->bp_secs); /* The usual hardware address type is 1 (10Mb Ethernet) */ @@ -98,8 +99,11 @@ bootp_print(register const u_char *cp, u_short sport, u_short dport, u_int lengt printf(", xid:0x%x", EXTRACT_32BITS(&bp->bp_xid)); if (bp->bp_secs) printf(", secs:%d", EXTRACT_16BITS(&bp->bp_secs)); - if (bp->bp_flags) - printf(", flags:0x%x", EXTRACT_16BITS(&bp->bp_flags)); + + printf(", flags: [%s]", + bittok2str(bootp_flag_values, "none", EXTRACT_16BITS(&bp->bp_flags))); + if (vflag>1) + printf( " (0x%04x)", EXTRACT_16BITS(&bp->bp_flags)); /* Client's ip address */ TCHECK(bp->bp_ciaddr); @@ -137,7 +141,7 @@ bootp_print(register const u_char *cp, u_short sport, u_short dport, u_int lengt } putchar('"'); } - TCHECK2(bp->bp_sname[0], 1); /* check first char only */ + TCHECK2(bp->bp_file[0], 1); /* check first char only */ if (*bp->bp_file) { printf("\n\t file \""); if (fn_print(bp->bp_file, snapend)) { @@ -273,7 +277,7 @@ static struct tok tag2str[] = { { TAG_NS_SEARCH, "sNSSEARCH" }, /* XXX 's' */ /* RFC 3011 */ { TAG_IP4_SUBNET_SELECT, "iSUBNET" }, -/* ftp://ftp.isi.edu/.../assignments/bootp-dhcp-extensions */ +/* http://www.iana.org/assignments/bootp-dhcp-extensions/index.htm */ { TAG_USER_CLASS, "aCLASS" }, { TAG_SLP_NAMING_AUTH, "aSLP-NA" }, { TAG_CLIENT_FQDN, "$FQDN" }, @@ -552,6 +556,10 @@ rfc1048_print(register const u_char *bp) break; case TAG_CLIENT_FQDN: + /* option 81 should be at least 4 bytes long */ + if (len < 4) + printf("ERROR: options 81 len %u < 4 bytes", len); + break; if (*bp++) printf("[svrreg]"); if (*bp)