static inline void ipnet_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length) { const ipnet_hdr_t *hdr; hdr = (const ipnet_hdr_t *)bp; ND_TCHECK_SIZE(hdr); ND_PRINT("%u > %u", EXTRACT_BE_U_4(hdr->iph_zsrc), EXTRACT_BE_U_4(hdr->iph_zdst)); if (!ndo->ndo_qflag) { ND_PRINT(", family %s (%u)", tok2str(ipnet_values, "Unknown", EXTRACT_U_1(hdr->iph_family)), EXTRACT_U_1(hdr->iph_family)); } else { ND_PRINT(", %s", tok2str(ipnet_values, "Unknown Ethertype (0x%04x)", EXTRACT_U_1(hdr->iph_family))); } ND_PRINT(", length %u: ", length); return; trunc: ND_PRINT(" %s", tstr); }
static const uint32_t * parsev3rddirres(netdissect_options *ndo, const uint32_t *dp, int verbose) { u_int er; if (!(dp = parsestatus(ndo, dp, &er))) return (0); if (ndo->ndo_vflag) ND_PRINT(" POST:"); if (!(dp = parse_post_op_attr(ndo, dp, verbose))) return (0); if (er) return dp; if (ndo->ndo_vflag) { ND_TCHECK_4(dp + 1); /* * This displays the 8 bytes of the verifier in order, * from the low-order byte to the high-order byte. */ ND_PRINT(" verf %08x%08x", EXTRACT_BE_U_4(dp), EXTRACT_BE_U_4(dp + 1)); dp += 2; } return dp; trunc: return (NULL); }
void nfsreply_print(netdissect_options *ndo, const u_char *bp, u_int length, const u_char *bp2) { const struct sunrpc_msg *rp; char srcid[20], dstid[20]; /*fits 32bit*/ nfserr = 0; /* assume no error */ rp = (const struct sunrpc_msg *)bp; ND_TCHECK_4(rp->rm_xid); if (!ndo->ndo_nflag) { strlcpy(srcid, "nfs", sizeof(srcid)); snprintf(dstid, sizeof(dstid), "%u", EXTRACT_BE_U_4(rp->rm_xid)); } else { snprintf(srcid, sizeof(srcid), "%u", NFS_PORT); snprintf(dstid, sizeof(dstid), "%u", EXTRACT_BE_U_4(rp->rm_xid)); } print_nfsaddr(ndo, bp2, srcid, dstid); nfsreply_noaddr_print(ndo, bp, length, bp2); return; trunc: if (!nfserr) ND_PRINT("%s", tstr); }
void nfsreply_noaddr_print(netdissect_options *ndo, const u_char *bp, u_int length, const u_char *bp2) { const struct sunrpc_msg *rp; uint32_t proc, vers, reply_stat; enum sunrpc_reject_stat rstat; uint32_t rlow; uint32_t rhigh; enum sunrpc_auth_stat rwhy; nfserr = 0; /* assume no error */ rp = (const struct sunrpc_msg *)bp; ND_TCHECK(rp->rm_reply.rp_stat); reply_stat = EXTRACT_BE_U_4(&rp->rm_reply.rp_stat); switch (reply_stat) { case SUNRPC_MSG_ACCEPTED: ND_PRINT("reply ok %u", length); if (xid_map_find(rp, bp2, &proc, &vers) >= 0) interp_reply(ndo, rp, proc, vers, length); break; case SUNRPC_MSG_DENIED: ND_PRINT("reply ERR %u: ", length); ND_TCHECK(rp->rm_reply.rp_reject.rj_stat); rstat = EXTRACT_BE_U_4(&rp->rm_reply.rp_reject.rj_stat); switch (rstat) { case SUNRPC_RPC_MISMATCH: ND_TCHECK(rp->rm_reply.rp_reject.rj_vers.high); rlow = EXTRACT_BE_U_4(&rp->rm_reply.rp_reject.rj_vers.low); rhigh = EXTRACT_BE_U_4(&rp->rm_reply.rp_reject.rj_vers.high); ND_PRINT("RPC Version mismatch (%u-%u)", rlow, rhigh); break; case SUNRPC_AUTH_ERROR: ND_TCHECK(rp->rm_reply.rp_reject.rj_why); rwhy = EXTRACT_BE_U_4(&rp->rm_reply.rp_reject.rj_why); ND_PRINT("Auth %s", tok2str(sunrpc_auth_str, "Invalid failure code %u", rwhy)); break; default: ND_PRINT("Unknown reason for rejecting rpc message %u", (unsigned int)rstat); break; } break; default: ND_PRINT("reply Unknown rpc response code=%u %u", reply_stat, length); break; } return; trunc: if (!nfserr) ND_PRINT("%s", tstr); }
/* * Return a pointer to the first file handle in the packet. * If the packet was truncated, return 0. */ static const uint32_t * parsereq(netdissect_options *ndo, const struct sunrpc_msg *rp, u_int length) { const uint32_t *dp; u_int len; /* * find the start of the req data (if we captured it) */ dp = (const uint32_t *)&rp->rm_call.cb_cred; ND_TCHECK_4(dp + 1); len = EXTRACT_BE_U_4(dp + 1); if (len < length) { dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); ND_TCHECK_4(dp + 1); len = EXTRACT_BE_U_4(dp + 1); if (len < length) { dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); ND_TCHECK_LEN(dp, 0); return (dp); } } trunc: return (NULL); }
static void print_attr_address(netdissect_options *ndo, const u_char *data, u_int length, u_short attr_code) { if (length != 4) { ND_PRINT("ERROR: length %u != 4", length); return; } ND_TCHECK_4(data); switch(attr_code) { case FRM_IPADDR: case LOG_IPHOST: if (EXTRACT_BE_U_4(data) == 0xFFFFFFFF ) ND_PRINT("User Selected"); else if (EXTRACT_BE_U_4(data) == 0xFFFFFFFE ) ND_PRINT("NAS Select"); else ND_PRINT("%s",ipaddr_string(ndo, data)); break; default: ND_PRINT("%s", ipaddr_string(ndo, data)); break; } return; trunc: nd_print_trunc(ndo); }
static void pptp_bearer_cap_print(netdissect_options *ndo, const nd_uint32_t *bearer_cap) { ND_PRINT(" BEARER_CAP(%s%s)", EXTRACT_BE_U_4(*bearer_cap) & PPTP_BEARER_CAP_DIGITAL_MASK ? "D" : "", EXTRACT_BE_U_4(*bearer_cap) & PPTP_BEARER_CAP_ANALOG_MASK ? "A" : ""); }
/* * Print RRCP requests */ void rrcp_print(netdissect_options *ndo, const u_char *cp, u_int length _U_, const struct lladdr_info *src, const struct lladdr_info *dst) { uint8_t rrcp_proto; uint8_t rrcp_opcode; ndo->ndo_protocol = "rrcp"; ND_TCHECK_1(cp + RRCP_PROTO_OFFSET); rrcp_proto = EXTRACT_U_1(cp + RRCP_PROTO_OFFSET); ND_TCHECK_1(cp + RRCP_OPCODE_ISREPLY_OFFSET); rrcp_opcode = EXTRACT_U_1((cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK; if (src != NULL && dst != NULL) { ND_PRINT("%s > %s, ", (src->addr_string)(ndo, src->addr), (dst->addr_string)(ndo, dst->addr)); } ND_PRINT("%s %s", tok2str(proto_values,"RRCP-0x%02x",rrcp_proto), ((EXTRACT_U_1(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query"); if (rrcp_proto==1){ ND_PRINT(": %s", tok2str(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode)); } if (rrcp_opcode==1 || rrcp_opcode==2){ ND_TCHECK_6(cp + RRCP_REG_ADDR_OFFSET); ND_PRINT(" addr=0x%04x, data=0x%08x", EXTRACT_LE_U_2(cp + RRCP_REG_ADDR_OFFSET), EXTRACT_LE_U_4(cp + RRCP_REG_DATA_OFFSET)); } if (rrcp_proto==1){ ND_TCHECK_2(cp + RRCP_AUTHKEY_OFFSET); ND_PRINT(", auth=0x%04x", EXTRACT_BE_U_2(cp + RRCP_AUTHKEY_OFFSET)); } if (rrcp_proto==1 && rrcp_opcode==0 && ((EXTRACT_U_1(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){ ND_TCHECK_4(cp + RRCP_VENDOR_ID_OFFSET); ND_PRINT(" downlink_port=%u, uplink_port=%u, uplink_mac=%s, vendor_id=%08x ,chip_id=%04x ", EXTRACT_U_1(cp + RRCP_DOWNLINK_PORT_OFFSET), EXTRACT_U_1(cp + RRCP_UPLINK_PORT_OFFSET), etheraddr_string(ndo, cp + RRCP_UPLINK_MAC_OFFSET), EXTRACT_BE_U_4(cp + RRCP_VENDOR_ID_OFFSET), EXTRACT_BE_U_2(cp + RRCP_CHIP_ID_OFFSET)); }else if (rrcp_opcode==1 || rrcp_opcode==2 || rrcp_proto==2){ ND_TCHECK_4(cp + RRCP_COOKIE2_OFFSET); ND_PRINT(", cookie=0x%08x%08x ", EXTRACT_BE_U_4(cp + RRCP_COOKIE2_OFFSET), EXTRACT_BE_U_4(cp + RRCP_COOKIE1_OFFSET)); } return; trunc: nd_print_trunc(ndo); }
static const uint32_t * parse_wcc_attr(netdissect_options *ndo, const uint32_t *dp) { /* Our caller has already checked this */ ND_PRINT(" sz %" PRIu64, EXTRACT_BE_U_8(dp)); ND_PRINT(" mtime %u.%06u ctime %u.%06u", EXTRACT_BE_U_4(dp + 2), EXTRACT_BE_U_4(dp + 3), EXTRACT_BE_U_4(dp + 4), EXTRACT_BE_U_4(dp + 5)); return (dp + 6); }
/* * Return a pointer to the first file handle in the packet. * If the packet was truncated, return 0. */ static const uint32_t * parsereq(netdissect_options *ndo, const struct sunrpc_msg *rp, u_int length) { const uint32_t *dp; u_int len, rounded_len; /* * Find the start of the req data (if we captured it). * First, get the length of the credentials, and make sure * we have all of the opaque part of the credentials. */ dp = (const uint32_t *)&rp->rm_call.cb_cred; if (length < 2 * sizeof(*dp)) goto trunc; ND_TCHECK_4(dp + 1); len = EXTRACT_BE_U_4(dp + 1); rounded_len = roundup2(len, 4); ND_TCHECK_LEN(dp + 2, rounded_len); if (2 * sizeof(*dp) + rounded_len <= length) { /* * We have all of the credentials. Skip past them; they * consist of 4 bytes of flavor, 4 bytes of length, * and len-rounded-up-to-a-multiple-of-4 bytes of * data. */ dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); length -= 2 * sizeof(*dp) + rounded_len; /* * Now get the length of the verifier, and make sure * we have all of the opaque part of the verifier. */ if (length < 2 * sizeof(*dp)) goto trunc; ND_TCHECK_4(dp + 1); len = EXTRACT_BE_U_4(dp + 1); rounded_len = roundup2(len, 4); ND_TCHECK_LEN(dp + 2, rounded_len); if (2 * sizeof(*dp) + rounded_len < length) { /* * We have all of the verifier. Skip past it; * it consists of 4 bytes of flavor, 4 bytes of * length, and len-rounded-up-to-a-multiple-of-4 * bytes of data. */ dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); return (dp); } } trunc: return (NULL); }
static void pptp_framing_cap_print(netdissect_options *ndo, const nd_uint32_t *framing_cap) { ND_PRINT(" FRAME_CAP("); if (EXTRACT_BE_U_4(*framing_cap) & PPTP_FRAMING_CAP_ASYNC_MASK) { ND_PRINT("A"); /* Async */ } if (EXTRACT_BE_U_4(*framing_cap) & PPTP_FRAMING_CAP_SYNC_MASK) { ND_PRINT("S"); /* Sync */ } ND_PRINT(")"); }
/* * Return a pointer to the beginning of the actual results. * If the packet was truncated, return 0. */ static const uint32_t * parserep(netdissect_options *ndo, const struct sunrpc_msg *rp, u_int length) { const uint32_t *dp; u_int len; enum sunrpc_accept_stat astat; /* * Portability note: * Here we find the address of the ar_verf credentials. * Originally, this calculation was * dp = (uint32_t *)&rp->rm_reply.rp_acpt.ar_verf * On the wire, the rp_acpt field starts immediately after * the (32 bit) rp_stat field. However, rp_acpt (which is a * "struct accepted_reply") contains a "struct opaque_auth", * whose internal representation contains a pointer, so on a * 64-bit machine the compiler inserts 32 bits of padding * before rp->rm_reply.rp_acpt.ar_verf. So, we cannot use * the internal representation to parse the on-the-wire * representation. Instead, we skip past the rp_stat field, * which is an "enum" and so occupies one 32-bit word. */ dp = ((const uint32_t *)&rp->rm_reply) + 1; ND_TCHECK_4(dp + 1); len = EXTRACT_BE_U_4(dp + 1); if (len >= length) return (NULL); /* * skip past the ar_verf credentials. */ dp += (len + (2*sizeof(uint32_t) + 3)) / sizeof(uint32_t); /* * now we can check the ar_stat field */ ND_TCHECK_4(dp); astat = (enum sunrpc_accept_stat) EXTRACT_BE_U_4(dp); if (astat != SUNRPC_SUCCESS) { ND_PRINT(" %s", tok2str(sunrpc_str, "ar_stat %u", astat)); nfserr = 1; /* suppress trunc string */ return (NULL); } /* successful return */ ND_TCHECK_LEN(dp, sizeof(astat)); return ((const uint32_t *) (sizeof(astat) + ((const char *)dp))); trunc: return (0); }
/* * Print out a file name and return pointer to 32-bit word past it. * If packet was truncated, return 0. */ static const uint32_t * parsefn(netdissect_options *ndo, const uint32_t *dp) { uint32_t len; const u_char *cp; /* Bail if we don't have the string length */ ND_TCHECK_4(dp); /* Fetch big-endian string length */ len = EXTRACT_BE_U_4(dp); dp++; ND_TCHECK_LEN(dp, ((len + 3) & ~3)); cp = (const u_char *)dp; /* Update 32-bit pointer (NFS filenames padded to 32-bit boundaries) */ dp += ((len + 3) & ~3) / sizeof(*dp); ND_PRINT("\""); if (fn_printn(ndo, cp, len, ndo->ndo_snapend)) { ND_PRINT("\""); goto trunc; } ND_PRINT("\""); return (dp); trunc: return NULL; }
/* * This is the top level routine of the printer. 'p' points * to the bluetooth header of the packet, 'h->ts' is the timestamp, * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ u_int bt_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { u_int length = h->len; u_int caplen = h->caplen; const pcap_bluetooth_h4_header* hdr = (const pcap_bluetooth_h4_header*)p; ndo->ndo_protocol = "bt_if"; if (caplen < BT_HDRLEN || length < BT_HDRLEN) goto trunc; caplen -= BT_HDRLEN; length -= BT_HDRLEN; p += BT_HDRLEN; ND_TCHECK_4(&hdr->direction); if (ndo->ndo_eflag) ND_PRINT("hci length %u, direction %s, ", length, (EXTRACT_BE_U_4(&hdr->direction)&0x1) ? "in" : "out"); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); trunc: ND_PRINT("%s", tstr); return (BT_HDRLEN); }
static const uint32_t * parsecreateopres(netdissect_options *ndo, const uint32_t *dp, int verbose) { u_int er; if (!(dp = parsestatus(ndo, dp, &er))) return (0); if (er) dp = parse_wcc_data(ndo, dp, verbose); else { ND_TCHECK_4(dp); if (!EXTRACT_BE_U_4(dp)) return (dp + 1); dp++; if (!(dp = parsefh(ndo, dp, 1))) return (0); if (verbose) { if (!(dp = parse_post_op_attr(ndo, dp, verbose))) return (0); if (ndo->ndo_vflag > 1) { ND_PRINT(" dir attr:"); dp = parse_wcc_data(ndo, dp, verbose); } } } return (dp); trunc: return (NULL); }
static int ahcp_time_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) { time_t t; struct tm *tm; char buf[BUFSIZE]; if (cp + 4 != ep) goto invalid; ND_TCHECK_4(cp); t = EXTRACT_BE_U_4(cp); if (NULL == (tm = gmtime(&t))) ND_PRINT(": gmtime() error"); else if (0 == strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm)) ND_PRINT(": strftime() error"); else ND_PRINT(": %s UTC", buf); return 0; invalid: ND_PRINT("%s", istr); ND_TCHECK_LEN(cp, ep - cp); return 0; trunc: nd_print_trunc(ndo); return -1; }
static void print_attr_time(netdissect_options *ndo, const u_char *data, u_int length, u_short attr_code _U_) { time_t attr_time; char string[26]; if (length != 4) { ND_PRINT("ERROR: length %u != 4", length); return; } ND_TCHECK_4(data); attr_time = EXTRACT_BE_U_4(data); strlcpy(string, ctime(&attr_time), sizeof(string)); /* Get rid of the newline */ string[24] = '\0'; ND_PRINT("%.24s", string); return; trunc: nd_print_trunc(ndo); }
static void pptp_framing_type_print(netdissect_options *ndo, const nd_uint32_t *framing_type) { ND_PRINT(" FRAME_TYPE(%s)", tok2str(pptp_ftype_str, "?", EXTRACT_BE_U_4(*framing_type))); }
static void pptp_bearer_type_print(netdissect_options *ndo, const nd_uint32_t *bearer_type) { ND_PRINT(" BEARER_TYPE(%s)", tok2str(pptp_btype_str, "?", EXTRACT_BE_U_4(*bearer_type))); }
static int xid_map_enter(netdissect_options *ndo, const struct sunrpc_msg *rp, const u_char *bp) { const struct ip *ip = NULL; const struct ip6_hdr *ip6 = NULL; struct xid_map_entry *xmep; if (!ND_TTEST_4(rp->rm_call.cb_proc)) return (0); switch (IP_V((const struct ip *)bp)) { case 4: ip = (const struct ip *)bp; break; case 6: ip6 = (const struct ip6_hdr *)bp; break; default: return (1); } xmep = &xid_map[xid_map_next]; if (++xid_map_next >= XIDMAPSIZE) xid_map_next = 0; UNALIGNED_MEMCPY(&xmep->xid, &rp->rm_xid, sizeof(xmep->xid)); if (ip) { xmep->ipver = 4; UNALIGNED_MEMCPY(&xmep->client, ip->ip_src, sizeof(ip->ip_src)); UNALIGNED_MEMCPY(&xmep->server, ip->ip_dst, sizeof(ip->ip_dst)); } else if (ip6) { xmep->ipver = 6; UNALIGNED_MEMCPY(&xmep->client, ip6->ip6_src, sizeof(ip6->ip6_src)); UNALIGNED_MEMCPY(&xmep->server, ip6->ip6_dst, sizeof(ip6->ip6_dst)); } xmep->proc = EXTRACT_BE_U_4(&rp->rm_call.cb_proc); xmep->vers = EXTRACT_BE_U_4(&rp->rm_call.cb_vers); return (1); }
/* * print vendor specific attributes */ static void print_vendor_attr(netdissect_options *ndo, const u_char *data, u_int length, u_short attr_code _U_) { u_int idx; u_int vendor_id; u_int vendor_type; u_int vendor_length; if (length < 4) goto trunc; ND_TCHECK_4(data); vendor_id = EXTRACT_BE_U_4(data); data+=4; length-=4; ND_PRINT("Vendor: %s (%u)", tok2str(smi_values,"Unknown",vendor_id), vendor_id); while (length >= 2) { ND_TCHECK_2(data); vendor_type = EXTRACT_U_1(data); vendor_length = EXTRACT_U_1(data + 1); if (vendor_length < 2) { ND_PRINT("\n\t Vendor Attribute: %u, Length: %u (bogus, must be >= 2)", vendor_type, vendor_length); return; } if (vendor_length > length) { ND_PRINT("\n\t Vendor Attribute: %u, Length: %u (bogus, goes past end of vendor-specific attribute)", vendor_type, vendor_length); return; } data+=2; vendor_length-=2; length-=2; ND_TCHECK_LEN(data, vendor_length); ND_PRINT("\n\t Vendor Attribute: %u, Length: %u, Value: ", vendor_type, vendor_length); for (idx = 0; idx < vendor_length ; idx++, data++) ND_PRINT("%c", ND_ISPRINT(EXTRACT_U_1(data)) ? EXTRACT_U_1(data) : '.'); length-=vendor_length; } return; trunc: nd_print_trunc(ndo); }
static void pflog_print(netdissect_options *ndo, const struct pfloghdr *hdr) { uint32_t rulenr, subrulenr; ndo->ndo_protocol = "pflog"; rulenr = EXTRACT_BE_U_4(&hdr->rulenr); subrulenr = EXTRACT_BE_U_4(&hdr->subrulenr); if (subrulenr == (uint32_t)-1) ND_PRINT("rule %u/", rulenr); else ND_PRINT("rule %u.%s.%u/", rulenr, hdr->ruleset, subrulenr); ND_PRINT("%s: %s %s on %s: ", tok2str(pf_reasons, "unkn(%u)", EXTRACT_U_1(&hdr->reason)), tok2str(pf_actions, "unkn(%u)", EXTRACT_U_1(&hdr->action)), tok2str(pf_directions, "unkn(%u)", EXTRACT_U_1(&hdr->dir)), hdr->ifname); }
static int lwres_printaddr(netdissect_options *ndo, const u_char *p0) { const u_char *p; const lwres_addr_t *ap; uint16_t l; int i; p = p0; ap = (const lwres_addr_t *)p; ND_TCHECK_2(ap->length); l = EXTRACT_BE_U_2(ap->length); p += LWRES_ADDR_LEN; ND_TCHECK_LEN(p, l); switch (EXTRACT_BE_U_4(ap->family)) { case 1: /* IPv4 */ if (l < 4) return -1; ND_PRINT(" %s", ipaddr_string(ndo, p)); p += sizeof(nd_ipv4); break; case 2: /* IPv6 */ if (l < 16) return -1; ND_PRINT(" %s", ip6addr_string(ndo, p)); p += sizeof(nd_ipv6); break; default: ND_PRINT(" %u/", EXTRACT_BE_U_4(ap->family)); for (i = 0; i < l; i++) { ND_PRINT("%02x", EXTRACT_U_1(p)); p++; } } return p - p0; trunc: return -1; }
/* BACP config options */ static u_int print_bacp_config_options(netdissect_options *ndo, const u_char *p, u_int length) { u_int opt, len; if (length < 2) return 0; ND_TCHECK_2(p); opt = EXTRACT_U_1(p); len = EXTRACT_U_1(p + 1); if (length < len) return 0; if (len < 2) { ND_PRINT("\n\t %s Option (0x%02x), length %u (length bogus, should be >= 2)", tok2str(bacconfopts_values, "Unknown", opt), opt, len); return 0; } ND_PRINT("\n\t %s Option (0x%02x), length %u", tok2str(bacconfopts_values, "Unknown", opt), opt, len); switch (opt) { case BACPOPT_FPEER: if (len != 6) { ND_PRINT(" (length bogus, should be = 6)"); return len; } ND_TCHECK_4(p + 2); ND_PRINT(": Magic-Num 0x%08x", EXTRACT_BE_U_4(p + 2)); break; default: /* * Unknown option; dump it as raw bytes now if we're * not going to do so below. */ if (ndo->ndo_vflag < 2) print_unknown_data(ndo, p + 2, "\n\t ", len - 2); break; } if (ndo->ndo_vflag > 1) print_unknown_data(ndo, p + 2, "\n\t ", len - 2); /* exclude TLV header */ return len; trunc: ND_PRINT("[|bacp]"); return 0; }
/* Print a single OpenFlow message. */ static const u_char * of_header_body_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) { uint8_t version, type; uint16_t length; uint32_t xid; if (ep < cp + OF_HEADER_LEN) goto invalid; /* version */ ND_TCHECK_1(cp); version = EXTRACT_U_1(cp); cp += 1; /* type */ ND_TCHECK_1(cp); type = EXTRACT_U_1(cp); cp += 1; /* length */ ND_TCHECK_2(cp); length = EXTRACT_BE_U_2(cp); cp += 2; /* xid */ ND_TCHECK_4(cp); xid = EXTRACT_BE_U_4(cp); cp += 4; /* Message length includes the header length and a message always includes * the basic header. A message length underrun fails decoding of the rest of * the current packet. At the same time, try decoding as much of the current * message as possible even when it does not end within the current TCP * segment. */ if (length < OF_HEADER_LEN) { of_header_print(ndo, version, type, length, xid); goto invalid; } /* Decode known protocol versions further without printing the header (the * type decoding is version-specific. */ switch (version) { case OF_VER_1_0: return of10_header_body_print(ndo, cp, ep, type, length, xid); default: of_header_print(ndo, version, type, length, xid); ND_TCHECK_LEN(cp, length - OF_HEADER_LEN); return cp + length - OF_HEADER_LEN; /* done with current message */ } invalid: /* fail current packet */ ND_PRINT("%s", istr); ND_TCHECK_LEN(cp, ep - cp); return ep; trunc: ND_PRINT("%s", tstr); return ep; }
static int parsepathconf(netdissect_options *ndo, const uint32_t *dp) { u_int er; const struct nfsv3_pathconf *spp; if (!(dp = parsestatus(ndo, dp, &er))) return (0); if (ndo->ndo_vflag) ND_PRINT(" POST:"); if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag))) return (0); if (er) return (1); spp = (const struct nfsv3_pathconf *)dp; ND_TCHECK_SIZE(spp); ND_PRINT(" linkmax %u namemax %u %s %s %s %s", EXTRACT_BE_U_4(&spp->pc_linkmax), EXTRACT_BE_U_4(&spp->pc_namemax), EXTRACT_BE_U_4(&spp->pc_notrunc) ? "notrunc" : "", EXTRACT_BE_U_4(&spp->pc_chownrestricted) ? "chownres" : "", EXTRACT_BE_U_4(&spp->pc_caseinsensitive) ? "igncase" : "", EXTRACT_BE_U_4(&spp->pc_casepreserving) ? "keepcase" : ""); return (1); trunc: return (0); }
/* * Print dhcp6 packets */ void dhcp6_print(netdissect_options *ndo, const u_char *cp, u_int length) { const struct dhcp6 *dh6; const struct dhcp6_relay *dh6relay; uint8_t msgtype; const u_char *ep; const u_char *extp; const char *name; ND_PRINT("dhcp6"); ep = ndo->ndo_snapend; if (cp + length < ep) ep = cp + length; dh6 = (const struct dhcp6 *)cp; dh6relay = (const struct dhcp6_relay *)cp; ND_TCHECK_4(dh6->dh6_msgtypexid.xid); msgtype = EXTRACT_U_1(dh6->dh6_msgtypexid.msgtype); name = tok2str(dh6_msgtype_str, "msgtype-%u", msgtype); if (!ndo->ndo_vflag) { ND_PRINT(" %s", name); return; } /* XXX relay agent messages have to be handled differently */ ND_PRINT(" %s (", name); /*)*/ if (msgtype != DH6_RELAY_FORW && msgtype != DH6_RELAY_REPLY) { ND_PRINT("xid=%x", EXTRACT_BE_U_4(dh6->dh6_msgtypexid.xid) & DH6_XIDMASK); extp = (const u_char *)(dh6 + 1); dhcp6opt_print(ndo, extp, ep); } else { /* relay messages */ ND_TCHECK_16(dh6relay->dh6relay_peeraddr); ND_PRINT("linkaddr=%s", ip6addr_string(ndo, dh6relay->dh6relay_linkaddr)); ND_PRINT(" peeraddr=%s", ip6addr_string(ndo, dh6relay->dh6relay_peeraddr)); dhcp6opt_print(ndo, (const u_char *)(dh6relay + 1), ep); } /*(*/ ND_PRINT(")"); return; trunc: ND_PRINT("[|dhcp6]"); }
/* * Post operation attributes are printed if vflag >= 1 */ static const uint32_t * parse_post_op_attr(netdissect_options *ndo, const uint32_t *dp, int verbose) { ND_TCHECK_4(dp); if (!EXTRACT_BE_U_4(dp)) return (dp + 1); dp++; if (verbose) { return parsefattr(ndo, dp, verbose, 1); } else return (dp + (NFSX_V3FATTR / sizeof (uint32_t))); trunc: return (NULL); }
static int parserddires(netdissect_options *ndo, const uint32_t *dp) { u_int er; dp = parsestatus(ndo, dp, &er); if (dp == NULL) return (0); if (er) return (1); if (ndo->ndo_qflag) return (1); ND_TCHECK_4(dp + 2); ND_PRINT(" offset 0x%x size %u ", EXTRACT_BE_U_4(dp), EXTRACT_BE_U_4(dp + 1)); if (EXTRACT_BE_U_4(dp + 2) != 0) ND_PRINT(" eof"); return (1); trunc: return (0); }
static int ahcp_seconds_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) { if (cp + 4 != ep) goto invalid; ND_TCHECK_4(cp); ND_PRINT(": %us", EXTRACT_BE_U_4(cp)); return 0; invalid: ND_PRINT("%s", istr); ND_TCHECK_LEN(cp, ep - cp); return 0; trunc: nd_print_trunc(ndo); return -1; }