void timed_print(netdissect_options *ndo, const u_char *bp) { const struct tsp *tsp = (const struct tsp *)bp; uint8_t tsp_type; int sec, usec; ndo->ndo_protocol = "timed"; ND_TCHECK_1(tsp->tsp_type); tsp_type = EXTRACT_U_1(tsp->tsp_type); if (tsp_type < TSPTYPENUMBER) ND_PRINT("TSP_%s", tsptype[tsp_type]); else ND_PRINT("(tsp_type %#x)", tsp_type); ND_TCHECK_1(tsp->tsp_vers); ND_PRINT(" vers %u", EXTRACT_U_1(tsp->tsp_vers)); ND_TCHECK_2(tsp->tsp_seq); ND_PRINT(" seq %u", EXTRACT_BE_U_2(tsp->tsp_seq)); switch (tsp_type) { case TSP_LOOP: ND_TCHECK_1(tsp->tsp_hopcnt); ND_PRINT(" hopcnt %u", EXTRACT_U_1(tsp->tsp_hopcnt)); break; case TSP_SETTIME: case TSP_ADJTIME: case TSP_SETDATE: case TSP_SETDATEREQ: ND_TCHECK_8(&tsp->tsp_time); sec = EXTRACT_BE_S_4(tsp->tsp_time.tv_sec); usec = EXTRACT_BE_S_4(tsp->tsp_time.tv_usec); /* XXX The comparison below is always false? */ if (usec < 0) /* invalid, skip the rest of the packet */ return; ND_PRINT(" time "); if (sec < 0 && usec != 0) { sec++; if (sec == 0) ND_PRINT("-"); usec = 1000000 - usec; } ND_PRINT("%d.%06d", sec, usec); break; } ND_PRINT(" name "); if (nd_printzp(ndo, tsp->tsp_name, sizeof(tsp->tsp_name), ndo->ndo_snapend)) goto trunc; return; trunc: nd_print_trunc(ndo); }
static const uint32_t * parsefattr(netdissect_options *ndo, const uint32_t *dp, int verbose, int v3) { const struct nfs_fattr *fap; fap = (const struct nfs_fattr *)dp; ND_TCHECK(fap->fa_gid); if (verbose) { /* * XXX - UIDs and GIDs are unsigned in NFS and in * at least some UN*Xes, but we'll show them as * signed because -2 has traditionally been the * UID for "nobody", rather than 4294967294. */ ND_PRINT(" %s %o ids %d/%d", tok2str(type2str, "unk-ft %u ", EXTRACT_BE_U_4(&fap->fa_type)), EXTRACT_BE_U_4(&fap->fa_mode), EXTRACT_BE_S_4(&fap->fa_uid), EXTRACT_BE_S_4(&fap->fa_gid)); if (v3) { ND_TCHECK(fap->fa3_size); ND_PRINT(" sz %" PRIu64, EXTRACT_BE_U_8((const uint32_t *)&fap->fa3_size)); } else { ND_TCHECK(fap->fa2_size); ND_PRINT(" sz %u", EXTRACT_BE_U_4(&fap->fa2_size)); } } /* print lots more stuff */ if (verbose > 1) { if (v3) { ND_TCHECK(fap->fa3_ctime); ND_PRINT(" nlink %u rdev %u/%u", EXTRACT_BE_U_4(&fap->fa_nlink), EXTRACT_BE_U_4(&fap->fa3_rdev.specdata1), EXTRACT_BE_U_4(&fap->fa3_rdev.specdata2)); ND_PRINT(" fsid %" PRIx64, EXTRACT_BE_U_8((const uint32_t *)&fap->fa3_fsid)); ND_PRINT(" fileid %" PRIx64, EXTRACT_BE_U_8((const uint32_t *)&fap->fa3_fileid)); ND_PRINT(" a/m/ctime %u.%06u", EXTRACT_BE_U_4(&fap->fa3_atime.nfsv3_sec), EXTRACT_BE_U_4(&fap->fa3_atime.nfsv3_nsec)); ND_PRINT(" %u.%06u", EXTRACT_BE_U_4(&fap->fa3_mtime.nfsv3_sec), EXTRACT_BE_U_4(&fap->fa3_mtime.nfsv3_nsec)); ND_PRINT(" %u.%06u", EXTRACT_BE_U_4(&fap->fa3_ctime.nfsv3_sec), EXTRACT_BE_U_4(&fap->fa3_ctime.nfsv3_nsec)); } else { ND_TCHECK(fap->fa2_ctime); ND_PRINT(" nlink %u rdev 0x%x fsid 0x%x nodeid 0x%x a/m/ctime", EXTRACT_BE_U_4(&fap->fa_nlink), EXTRACT_BE_U_4(&fap->fa2_rdev), EXTRACT_BE_U_4(&fap->fa2_fsid), EXTRACT_BE_U_4(&fap->fa2_fileid)); ND_PRINT(" %u.%06u", EXTRACT_BE_U_4(&fap->fa2_atime.nfsv2_sec), EXTRACT_BE_U_4(&fap->fa2_atime.nfsv2_usec)); ND_PRINT(" %u.%06u", EXTRACT_BE_U_4(&fap->fa2_mtime.nfsv2_sec), EXTRACT_BE_U_4(&fap->fa2_mtime.nfsv2_usec)); ND_PRINT(" %u.%06u", EXTRACT_BE_U_4(&fap->fa2_ctime.nfsv2_sec), EXTRACT_BE_U_4(&fap->fa2_ctime.nfsv2_usec)); } } return ((const uint32_t *)((const unsigned char *)dp + (v3 ? NFSX_V3FATTR : NFSX_V2FATTR))); trunc: return (NULL); }
static void rfc1048_print(netdissect_options *ndo, const u_char *bp) { uint16_t tag; u_int len; const char *cp; char c; int first, idx; uint8_t subopt, suboptlen; ND_PRINT("\n\t Vendor-rfc1048 Extensions"); /* Step over magic cookie */ ND_PRINT("\n\t Magic Cookie 0x%08x", EXTRACT_BE_U_4(bp)); bp += sizeof(int32_t); /* Loop while we there is a tag left in the buffer */ while (ND_TTEST_1(bp)) { tag = EXTRACT_U_1(bp); bp++; if (tag == TAG_PAD && ndo->ndo_vflag < 3) continue; if (tag == TAG_END && ndo->ndo_vflag < 3) return; if (tag == TAG_EXTENDED_OPTION) { ND_TCHECK_2(bp + 1); tag = EXTRACT_BE_U_2(bp + 1); /* XXX we don't know yet if the IANA will * preclude overlap of 1-byte and 2-byte spaces. * If not, we need to offset tag after this step. */ cp = tok2str(xtag2str, "?xT%u", tag); } else cp = tok2str(tag2str, "?T%u", tag); c = *cp++; if (tag == TAG_PAD || tag == TAG_END) len = 0; else { /* Get the length; check for truncation */ ND_TCHECK_1(bp); len = EXTRACT_U_1(bp); bp++; } ND_PRINT("\n\t %s Option %u, length %u%s", cp, tag, len, len > 0 ? ": " : ""); if (tag == TAG_PAD && ndo->ndo_vflag > 2) { u_int ntag = 1; while (ND_TTEST_1(bp) && EXTRACT_U_1(bp) == TAG_PAD) { bp++; ntag++; } if (ntag > 1) ND_PRINT(", occurs %u", ntag); } ND_TCHECK_LEN(bp, len); if (tag == TAG_DHCP_MESSAGE && len == 1) { ND_PRINT("%s", tok2str(dhcp_msg_values, "Unknown (%u)", EXTRACT_U_1(bp))); bp++; continue; } if (tag == TAG_PARM_REQUEST) { idx = 0; while (len > 0) { cp = tok2str(tag2str, "?Option %u", EXTRACT_U_1(bp)); bp++; len--; if (idx % 4 == 0) ND_PRINT("\n\t "); else ND_PRINT(", "); ND_PRINT("%s", cp + 1); idx++; } continue; } if (tag == TAG_EXTENDED_REQUEST) { first = 1; while (len > 1) { cp = tok2str(xtag2str, "?xT%u", EXTRACT_BE_U_2(bp)); bp += 2; len -= 2; if (!first) ND_PRINT("+"); ND_PRINT("%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 */ ND_PRINT("\""); if (nd_printn(ndo, bp, len, ndo->ndo_snapend)) { ND_PRINT("\""); goto trunc; } ND_PRINT("\""); bp += len; len = 0; break; case 'i': case 'l': case 'L': /* ip addresses/32-bit words */ while (len >= 4) { if (!first) ND_PRINT(","); if (c == 'i') ND_PRINT("%s", ipaddr_string(ndo, bp)); else if (c == 'L') ND_PRINT("%d", EXTRACT_BE_S_4(bp)); else ND_PRINT("%u", EXTRACT_BE_U_4(bp)); bp += 4; len -= 4; first = 0; } break; case 'p': /* IP address pairs */ while (len >= 2*4) { if (!first) ND_PRINT(","); ND_PRINT("(%s:", ipaddr_string(ndo, bp)); bp += 4; len -= 4; ND_PRINT("%s)", ipaddr_string(ndo, bp)); bp += 4; len -= 4; first = 0; } break; case 's': /* shorts */ while (len >= 2) { if (!first) ND_PRINT(","); ND_PRINT("%u", EXTRACT_BE_U_2(bp)); bp += 2; len -= 2; first = 0; } break; case 'B': /* boolean */ while (len > 0) { uint8_t bool_value; if (!first) ND_PRINT(","); bool_value = EXTRACT_U_1(bp); switch (bool_value) { case 0: ND_PRINT("N"); break; case 1: ND_PRINT("Y"); break; default: ND_PRINT("%u?", bool_value); break; } ++bp; --len; first = 0; } break; case 'b': case 'x': default: /* Bytes */ while (len > 0) { uint8_t byte_value; if (!first) ND_PRINT(c == 'x' ? ":" : "."); byte_value = EXTRACT_U_1(bp); if (c == 'x') ND_PRINT("%02x", byte_value); else ND_PRINT("%u", byte_value); ++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) { ND_PRINT("ERROR: length < 1 bytes"); break; } tag = EXTRACT_U_1(bp); ++bp; --len; ND_PRINT("%s", tok2str(nbo2str, NULL, tag)); break; case TAG_OPT_OVERLOAD: /* this option should be at least 1 byte long */ if (len < 1) { ND_PRINT("ERROR: length < 1 bytes"); break; } tag = EXTRACT_U_1(bp); ++bp; --len; ND_PRINT("%s", tok2str(oo2str, NULL, tag)); break; case TAG_CLIENT_FQDN: /* this option should be at least 3 bytes long */ if (len < 3) { ND_PRINT("ERROR: length < 3 bytes"); bp += len; len = 0; break; } if (EXTRACT_U_1(bp)) ND_PRINT("[%s] ", client_fqdn_flags(EXTRACT_U_1(bp))); bp++; if (EXTRACT_U_1(bp) || EXTRACT_U_1(bp + 1)) ND_PRINT("%u/%u ", EXTRACT_U_1(bp), EXTRACT_U_1(bp + 1)); bp += 2; ND_PRINT("\""); if (nd_printn(ndo, bp, len - 3, ndo->ndo_snapend)) { ND_PRINT("\""); goto trunc; } ND_PRINT("\""); bp += len - 3; len = 0; break; case TAG_CLIENT_ID: { int type; /* this option should be at least 1 byte long */ if (len < 1) { ND_PRINT("ERROR: length < 1 bytes"); break; } type = EXTRACT_U_1(bp); bp++; len--; if (type == 0) { ND_PRINT("\""); if (nd_printn(ndo, bp, len, ndo->ndo_snapend)) { ND_PRINT("\""); goto trunc; } ND_PRINT("\""); bp += len; len = 0; break; } else { ND_PRINT("%s ", tok2str(arp2str, "hardware-type %u,", type)); while (len > 0) { if (!first) ND_PRINT(":"); ND_PRINT("%02x", EXTRACT_U_1(bp)); ++bp; --len; first = 0; } } break; } case TAG_AGENT_CIRCUIT: while (len >= 2) { subopt = EXTRACT_U_1(bp); suboptlen = EXTRACT_U_1(bp + 1); bp += 2; len -= 2; if (suboptlen > len) { ND_PRINT("\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; } ND_PRINT("\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: if (nd_printn(ndo, bp, suboptlen, ndo->ndo_snapend)) goto trunc; break; default: print_unknown_data(ndo, 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) { ND_PRINT("ERROR: length < 5 bytes"); bp += len; len = 0; break; } while (len > 0) { if (!first) ND_PRINT(","); mask_width = EXTRACT_U_1(bp); bp++; len--; /* mask_width <= 32 */ if (mask_width > 32) { ND_PRINT("[ERROR: Mask width (%u) > 32]", mask_width); bp += len; len = 0; break; } significant_octets = (mask_width + 7) / 8; /* significant octets + router(4) */ if (len < significant_octets + 4) { ND_PRINT("[ERROR: Remaining length (%u) < %u bytes]", len, significant_octets + 4); bp += len; len = 0; break; } ND_PRINT("("); if (mask_width == 0) ND_PRINT("default"); else { for (i = 0; i < significant_octets ; i++) { if (i > 0) ND_PRINT("."); ND_PRINT("%u", EXTRACT_U_1(bp)); bp++; } for (i = significant_octets ; i < 4 ; i++) ND_PRINT(".0"); ND_PRINT("/%u", mask_width); } ND_PRINT(":%s)", ipaddr_string(ndo, bp)); bp += 4; len -= (significant_octets + 4); first = 0; } break; } case TAG_USER_CLASS: { u_int suboptnumber = 1; first = 1; if (len < 2) { ND_PRINT("ERROR: length < 2 bytes"); bp += len; len = 0; break; } while (len > 0) { suboptlen = EXTRACT_U_1(bp); bp++; len--; ND_PRINT("\n\t "); ND_PRINT("instance#%u: ", suboptnumber); if (suboptlen == 0) { ND_PRINT("ERROR: suboption length must be non-zero"); bp += len; len = 0; break; } if (len < suboptlen) { ND_PRINT("ERROR: invalid option"); bp += len; len = 0; break; } ND_PRINT("\""); if (nd_printn(ndo, bp, suboptlen, ndo->ndo_snapend)) { ND_PRINT("\""); goto trunc; } ND_PRINT("\""); ND_PRINT(", length %u", suboptlen); suboptnumber++; len -= suboptlen; bp += suboptlen; } break; } default: ND_PRINT("[unknown special tag %u, size %u]", tag, len); bp += len; len = 0; break; } break; } /* Data left over? */ if (len) { ND_PRINT("\n\t trailing data length %u", len); bp += len; } } return; trunc: nd_print_trunc(ndo); }