print-bootp.c
来自「TCPDUMP的C语言源代码,是在数据链路层的应用」· C语言 代码 · 共 832 行 · 第 1/2 页
C
832 行
bp++; ntag++; } if (ntag > 1) printf(", occurs %u", ntag); } if (!TTEST2(*bp, len)) { printf("[|rfc1048 %u]", len); return; } if (tag == TAG_DHCP_MESSAGE && len == 1) { uc = *bp++; printf("%s", tok2str(dhcp_msg_values, "Unknown (%u)", uc)); continue; } if (tag == TAG_PARM_REQUEST) { idx = 0; while (len-- > 0) { uc = *bp++; cp = tok2str(tag2str, "?Option %u", uc); if (idx % 4 == 0) printf("\n\t "); else printf(", "); printf("%s", cp + 1); idx++; } continue; } if (tag == TAG_EXTENDED_REQUEST) { first = 1; while (len > 1) { len -= 2; us = EXTRACT_16BITS(bp); bp += 2; cp = tok2str(xtag2str, "?xT%u", us); if (!first) putchar('+'); printf("%s", cp + 1); first = 0; } continue; } /* Print data */ if (c == '?') { /* Base default formats for unknown tags on data size */ if (len & 1) c = 'b'; else if (len & 2) c = 's'; else c = 'l'; } first = 1; switch (c) { case 'a': /* ascii strings */ putchar('"'); if (fn_printn(bp, len, snapend)) { putchar('"'); goto trunc; } putchar('"'); bp += len; len = 0; break; case 'i': case 'l': case 'L': /* ip addresses/32-bit words */ while (len >= sizeof(ul)) { if (!first) putchar(','); ul = EXTRACT_32BITS(bp); if (c == 'i') { ul = htonl(ul); printf("%s", ipaddr_string(&ul)); } else if (c == 'L') printf("%d", ul); else printf("%u", ul); bp += sizeof(ul); len -= sizeof(ul); first = 0; } break; case 'p': /* IP address pairs */ while (len >= 2*sizeof(ul)) { if (!first) putchar(','); memcpy((char *)&ul, (const char *)bp, sizeof(ul)); printf("(%s:", ipaddr_string(&ul)); bp += sizeof(ul); memcpy((char *)&ul, (const char *)bp, sizeof(ul)); printf("%s)", ipaddr_string(&ul)); bp += sizeof(ul); len -= 2*sizeof(ul); first = 0; } break; case 's': /* shorts */ while (len >= sizeof(us)) { if (!first) putchar(','); us = EXTRACT_16BITS(bp); printf("%u", us); bp += sizeof(us); len -= sizeof(us); first = 0; } break; case 'B': /* boolean */ while (len > 0) { if (!first) putchar(','); switch (*bp) { case 0: putchar('N'); break; case 1: putchar('Y'); break; default: printf("%u?", *bp); break; } ++bp; --len; first = 0; } break; case 'b': case 'x': default: /* Bytes */ while (len > 0) { if (!first) putchar(c == 'x' ? ':' : '.'); if (c == 'x') printf("%02x", *bp); else printf("%u", *bp); ++bp; --len; first = 0; } break; case '$': /* Guys we can't handle with one of the usual cases */ switch (tag) { case TAG_NETBIOS_NODE: /* this option should be at least 1 byte long */ if (len < 1) { printf("ERROR: option %u len %u < 1 bytes", TAG_NETBIOS_NODE, len); bp += len; len = 0; break; } tag = *bp++; --len; fputs(tok2str(nbo2str, NULL, tag), stdout); break; case TAG_OPT_OVERLOAD: /* this option should be at least 1 byte long */ if (len < 1) { printf("ERROR: option %u len %u < 1 bytes", TAG_OPT_OVERLOAD, len); bp += len; len = 0; break; } tag = *bp++; --len; fputs(tok2str(oo2str, NULL, tag), stdout); break; case TAG_CLIENT_FQDN: /* this option should be at least 3 bytes long */ if (len < 3) { printf("ERROR: option %u len %u < 3 bytes", TAG_CLIENT_FQDN, len); bp += len; len = 0; break; } if (*bp) printf("[%s] ", client_fqdn_flags(*bp)); bp++; if (*bp || *(bp+1)) printf("%u/%u ", *bp, *(bp+1)); bp += 2; putchar('"'); if (fn_printn(bp, len - 3, snapend)) { putchar('"'); goto trunc; } putchar('"'); bp += len - 3; len = 0; break; case TAG_CLIENT_ID: { int type; /* this option should be at least 1 byte long */ if (len < 1) { printf("ERROR: option %u len %u < 1 bytes", TAG_CLIENT_ID, len); bp += len; len = 0; break; } type = *bp++; len--; if (type == 0) { putchar('"'); if (fn_printn(bp, len, snapend)) { putchar('"'); goto trunc; } putchar('"'); bp += len; len = 0; break; } else { printf("%s ", tok2str(arp2str, "hardware-type %u,", type)); while (len > 0) { if (!first) putchar(':'); printf("%02x", *bp); ++bp; --len; first = 0; } } break; } case TAG_AGENT_CIRCUIT: while (len >= 2) { subopt = *bp++; suboptlen = *bp++; len -= 2; if (suboptlen > len) { printf("\n\t %s SubOption %u, length %u: length goes past end of option", tok2str(agent_suboption_values, "Unknown", subopt), subopt, suboptlen); bp += len; len = 0; break; } printf("\n\t %s SubOption %u, length %u: ", tok2str(agent_suboption_values, "Unknown", subopt), subopt, suboptlen); switch (subopt) { case AGENT_SUBOPTION_CIRCUIT_ID: /* fall through */ case AGENT_SUBOPTION_REMOTE_ID: case AGENT_SUBOPTION_SUBSCRIBER_ID: fn_printn(bp, suboptlen, NULL); break; default: print_unknown_data(bp, "\n\t\t", suboptlen); } len -= suboptlen; bp += suboptlen; } break; case TAG_CLASSLESS_STATIC_RT: case TAG_CLASSLESS_STA_RT_MS: { u_int mask_width, significant_octets, i; /* this option should be at least 5 bytes long */ if (len < 5) { printf("ERROR: option %u len %u < 5 bytes", TAG_CLASSLESS_STATIC_RT, len); bp += len; len = 0; break; } while (len > 0) { if (!first) putchar(','); mask_width = *bp++; len--; /* mask_width <= 32 */ if (mask_width > 32) { printf("[ERROR: Mask width (%d) > 32]", mask_width); bp += len; len = 0; break; } significant_octets = (mask_width + 7) / 8; /* significant octets + router(4) */ if (len < significant_octets + 4) { printf("[ERROR: Remaining length (%u) < %u bytes]", len, significant_octets + 4); bp += len; len = 0; break; } putchar('('); if (mask_width == 0) printf("default"); else { for (i = 0; i < significant_octets ; i++) { if (i > 0) putchar('.'); printf("%d", *bp++); } for (i = significant_octets ; i < 4 ; i++) printf(".0"); printf("/%d", mask_width); } memcpy((char *)&ul, (const char *)bp, sizeof(ul)); printf(":%s)", ipaddr_string(&ul)); bp += sizeof(ul); len -= (significant_octets + 4); first = 0; } } break; default: printf("[unknown special tag %u, size %u]", tag, len); bp += len; len = 0; break; } break; } /* Data left over? */ if (len) { printf("\n\t trailing data length %u", len); bp += len; } } return;trunc: printf("|[rfc1048]");}static voidcmu_print(register const u_char *bp){ register const struct cmu_vend *cmu;#define PRINTCMUADDR(m, s) { TCHECK(cmu->m); \ if (cmu->m.s_addr != 0) \ printf(" %s:%s", s, ipaddr_string(&cmu->m.s_addr)); } printf(" vend-cmu"); cmu = (const struct cmu_vend *)bp; /* Only print if there are unknown bits */ TCHECK(cmu->v_flags); if ((cmu->v_flags & ~(VF_SMASK)) != 0) printf(" F:0x%x", cmu->v_flags); PRINTCMUADDR(v_dgate, "DG"); PRINTCMUADDR(v_smask, cmu->v_flags & VF_SMASK ? "SM" : "SM*"); PRINTCMUADDR(v_dns1, "NS1"); PRINTCMUADDR(v_dns2, "NS2"); PRINTCMUADDR(v_ins1, "IEN1"); PRINTCMUADDR(v_ins2, "IEN2"); PRINTCMUADDR(v_ts1, "TS1"); PRINTCMUADDR(v_ts2, "TS2"); return;trunc: fputs(tstr, stdout);#undef PRINTCMUADDR}static char *client_fqdn_flags(u_int flags){ static char buf[8+1]; int i = 0; if (flags & CLIENT_FQDN_FLAGS_S) buf[i++] = 'S'; if (flags & CLIENT_FQDN_FLAGS_O) buf[i++] = 'O'; if (flags & CLIENT_FQDN_FLAGS_E) buf[i++] = 'E'; if (flags & CLIENT_FQDN_FLAGS_N) buf[i++] = 'N'; buf[i] = '\0'; return buf;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?