/* LCP config options */ static int print_lcp_config_options(netdissect_options *ndo, const u_char *p, int length) { int len, opt; if (length < 2) return 0; ND_TCHECK2(*p, 2); len = p[1]; opt = p[0]; if (length < len) return 0; if (len < 2) { if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) ND_PRINT((ndo, "\n\t %s Option (0x%02x), length %u (length bogus, should be >= 2)", lcpconfopts[opt], opt, len)); else ND_PRINT((ndo, "\n\tunknown LCP option 0x%02x", opt)); return 0; } if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) ND_PRINT((ndo, "\n\t %s Option (0x%02x), length %u", lcpconfopts[opt], opt, len)); else { ND_PRINT((ndo, "\n\tunknown LCP option 0x%02x", opt)); return len; } switch (opt) { case LCPOPT_VEXT: if (len < 6) { ND_PRINT((ndo, " (length bogus, should be >= 6)")); return len; } ND_TCHECK2(*(p + 2), 3); ND_PRINT((ndo, ": Vendor: %s (%u)", tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)), EXTRACT_24BITS(p + 2))); #if 0 ND_TCHECK(p[5]); ND_PRINT((ndo, ", kind: 0x%02x", p[5])); ND_PRINT((ndo, ", Value: 0x")); for (i = 0; i < len - 6; i++) { ND_TCHECK(p[6 + i]); ND_PRINT((ndo, "%02x", p[6 + i])); } #endif break; case LCPOPT_MRU: if (len != 4) { ND_PRINT((ndo, " (length bogus, should be = 4)")); return len; } ND_TCHECK2(*(p + 2), 2); ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2))); break; case LCPOPT_ACCM: if (len != 6) { ND_PRINT((ndo, " (length bogus, should be = 6)")); return len; } ND_TCHECK2(*(p + 2), 4); ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2))); break; case LCPOPT_AP: if (len < 4) { ND_PRINT((ndo, " (length bogus, should be >= 4)")); return len; } ND_TCHECK2(*(p + 2), 2); ND_PRINT((ndo, ": %s", tok2str(ppptype2str, "Unknown Auth Proto (0x04x)", EXTRACT_16BITS(p + 2)))); switch (EXTRACT_16BITS(p+2)) { case PPP_CHAP: ND_TCHECK(p[4]); ND_PRINT((ndo, ", %s", tok2str(authalg_values, "Unknown Auth Alg %u", p[4]))); break; case PPP_PAP: /* fall through */ case PPP_EAP: case PPP_SPAP: case PPP_SPAP_OLD: break; default: print_unknown_data(ndo, p, "\n\t", len); } break; case LCPOPT_QP: if (len < 4) { ND_PRINT((ndo, " (length bogus, should be >= 4)")); return 0; } ND_TCHECK2(*(p + 2), 2); if (EXTRACT_16BITS(p+2) == PPP_LQM) ND_PRINT((ndo, ": LQR")); else ND_PRINT((ndo, ": unknown")); break; case LCPOPT_MN: if (len != 6) { ND_PRINT((ndo, " (length bogus, should be = 6)")); return 0; } ND_TCHECK2(*(p + 2), 4); ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2))); break; case LCPOPT_PFC: break; case LCPOPT_ACFC: break; case LCPOPT_LD: if (len != 4) { ND_PRINT((ndo, " (length bogus, should be = 4)")); return 0; } ND_TCHECK2(*(p + 2), 2); ND_PRINT((ndo, ": 0x%04x", EXTRACT_16BITS(p + 2))); break; case LCPOPT_CBACK: if (len < 3) { ND_PRINT((ndo, " (length bogus, should be >= 3)")); return 0; } ND_PRINT((ndo, ": ")); ND_TCHECK(p[2]); ND_PRINT((ndo, ": Callback Operation %s (%u)", tok2str(ppp_callback_values, "Unknown", p[2]), p[2])); break; case LCPOPT_MLMRRU: if (len != 4) { ND_PRINT((ndo, " (length bogus, should be = 4)")); return 0; } ND_TCHECK2(*(p + 2), 2); ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2))); break; case LCPOPT_MLED: if (len < 3) { ND_PRINT((ndo, " (length bogus, should be >= 3)")); return 0; } ND_TCHECK(p[2]); switch (p[2]) { /* class */ case MEDCLASS_NULL: ND_PRINT((ndo, ": Null")); break; case MEDCLASS_LOCAL: ND_PRINT((ndo, ": Local")); /* XXX */ break; case MEDCLASS_IPV4: if (len != 7) { ND_PRINT((ndo, " (length bogus, should be = 7)")); return 0; } ND_TCHECK2(*(p + 3), 4); ND_PRINT((ndo, ": IPv4 %s", ipaddr_string(ndo, p + 3))); break; case MEDCLASS_MAC: if (len != 9) { ND_PRINT((ndo, " (length bogus, should be = 9)")); return 0; } ND_TCHECK(p[8]); ND_PRINT((ndo, ": MAC %02x:%02x:%02x:%02x:%02x:%02x", p[3], p[4], p[5], p[6], p[7], p[8])); break; case MEDCLASS_MNB: ND_PRINT((ndo, ": Magic-Num-Block")); /* XXX */ break; case MEDCLASS_PSNDN: ND_PRINT((ndo, ": PSNDN")); /* XXX */ break; default: ND_PRINT((ndo, ": Unknown class %u", p[2])); break; } break; /* XXX: to be supported */ #if 0 case LCPOPT_DEP6: case LCPOPT_FCSALT: case LCPOPT_SDP: case LCPOPT_NUMMODE: case LCPOPT_DEP12: case LCPOPT_DEP14: case LCPOPT_DEP15: case LCPOPT_DEP16: case LCPOPT_MLSSNHF: case LCPOPT_PROP: case LCPOPT_DCEID: case LCPOPT_MPP: case LCPOPT_LCPAOPT: case LCPOPT_COBS: case LCPOPT_PE: case LCPOPT_MLHF: case LCPOPT_I18N: case LCPOPT_SDLOS: case LCPOPT_PPPMUX: break; #endif 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((ndo, "[|lcp]")); return 0; }
void arp_print(netdissect_options *ndo, const u_char *bp, u_int length, u_int caplen) { const struct arp_pkthdr *ap; u_short pro, hrd, op, linkaddr; ap = (const struct arp_pkthdr *)bp; ND_TCHECK(*ap); hrd = HRD(ap); pro = PRO(ap); op = OP(ap); /* if its ATM then call the ATM ARP printer for Frame-relay ARP most of the fields are similar to Ethernet so overload the Ethernet Printer and set the linkaddr type for linkaddr_string() accordingly */ switch(hrd) { case ARPHRD_ATM2225: atmarp_print(ndo, bp, length, caplen); return; case ARPHRD_FRELAY: linkaddr = LINKADDR_FRELAY; break; default: linkaddr = LINKADDR_ETHER; break; } if (!ND_TTEST2(*ar_tpa(ap), PROTO_LEN(ap))) { ND_PRINT((ndo, "[|ARP]")); ND_DEFAULTPRINT((const u_char *)ap, length); return; } if (!ndo->ndo_eflag) { ND_PRINT((ndo, "ARP, ")); } /* print hardware type/len and proto type/len */ if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) || PROTO_LEN(ap) != 4 || HRD_LEN(ap) == 0 || ndo->ndo_vflag) { ND_PRINT((ndo, "%s (len %u), %s (len %u)", tok2str(arphrd_values, "Unknown Hardware (%u)", hrd), HRD_LEN(ap), tok2str(ethertype_values, "Unknown Protocol (0x%04x)", pro), PROTO_LEN(ap))); /* don't know know about the address formats */ if (!ndo->ndo_vflag) { goto out; } } /* print operation */ printf("%s%s ", ndo->ndo_vflag ? ", " : "", tok2str(arpop_values, "Unknown (%u)", op)); switch (op) { case ARPOP_REQUEST: ND_PRINT((ndo, "who-has %s", ipaddr_string(TPA(ap)))); if (memcmp((const char *)ezero, (const char *)THA(ap), HRD_LEN(ap)) != 0) ND_PRINT((ndo, " (%s)", linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)))); ND_PRINT((ndo, " tell %s", ipaddr_string(SPA(ap)))); break; case ARPOP_REPLY: ND_PRINT((ndo, "%s is-at %s", ipaddr_string(SPA(ap)), linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap)))); break; case ARPOP_REVREQUEST: ND_PRINT((ndo, "who-is %s tell %s", linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)), linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap)))); break; case ARPOP_REVREPLY: ND_PRINT((ndo, "%s at %s", linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)), ipaddr_string(TPA(ap)))); break; case ARPOP_INVREQUEST: ND_PRINT((ndo, "who-is %s tell %s", linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)), linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap)))); break; case ARPOP_INVREPLY: ND_PRINT((ndo,"%s at %s", linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)), ipaddr_string(TPA(ap)))); break; default: ND_DEFAULTPRINT((const u_char *)ap, caplen); return; } out: ND_PRINT((ndo, ", length %u", length)); return; trunc: ND_PRINT((ndo, "[|ARP]")); }
static int ospf6_decode_v3(netdissect_options *ndo, register const struct ospf6hdr *op, register const u_char *dataend) { register const rtrid_t *ap; register const struct lsr6 *lsrp; register const struct lsa6_hdr *lshp; register const struct lsa6 *lsap; register int i; switch (op->ospf6_type) { case OSPF_TYPE_HELLO: { register const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN); ND_PRINT((ndo, "\n\tOptions [%s]", bittok2str(ospf6_option_values, "none", EXTRACT_32BITS(&hellop->hello_options)))); ND_TCHECK(hellop->hello_deadint); ND_PRINT((ndo, "\n\t Hello Timer %us, Dead Timer %us, Interface-ID %s, Priority %u", EXTRACT_16BITS(&hellop->hello_helloint), EXTRACT_16BITS(&hellop->hello_deadint), ipaddr_string(ndo, &hellop->hello_ifid), hellop->hello_priority)); ND_TCHECK(hellop->hello_dr); if (EXTRACT_32BITS(&hellop->hello_dr) != 0) ND_PRINT((ndo, "\n\t Designated Router %s", ipaddr_string(ndo, &hellop->hello_dr))); ND_TCHECK(hellop->hello_bdr); if (EXTRACT_32BITS(&hellop->hello_bdr) != 0) ND_PRINT((ndo, ", Backup Designated Router %s", ipaddr_string(ndo, &hellop->hello_bdr))); if (ndo->ndo_vflag > 1) { ND_PRINT((ndo, "\n\t Neighbor List:")); ap = hellop->hello_neighbor; while ((const u_char *)ap < dataend) { ND_TCHECK(*ap); ND_PRINT((ndo, "\n\t %s", ipaddr_string(ndo, ap))); ++ap; } } break; /* HELLO */ } case OSPF_TYPE_DD: { register const struct dd6 *ddp = (const struct dd6 *)((const uint8_t *)op + OSPF6HDR_LEN); ND_TCHECK(ddp->db_options); ND_PRINT((ndo, "\n\tOptions [%s]", bittok2str(ospf6_option_values, "none", EXTRACT_32BITS(&ddp->db_options)))); ND_TCHECK(ddp->db_flags); ND_PRINT((ndo, ", DD Flags [%s]", bittok2str(ospf6_dd_flag_values,"none",ddp->db_flags))); ND_TCHECK(ddp->db_seq); ND_PRINT((ndo, ", MTU %u, DD-Sequence 0x%08x", EXTRACT_16BITS(&ddp->db_mtu), EXTRACT_32BITS(&ddp->db_seq))); if (ndo->ndo_vflag > 1) { /* Print all the LS adv's */ lshp = ddp->db_lshdr; while ((const u_char *)lshp < dataend) { if (ospf6_print_lshdr(ndo, lshp++, dataend)) goto trunc; } } break; } case OSPF_TYPE_LS_REQ: if (ndo->ndo_vflag > 1) { lsrp = (const struct lsr6 *)((const uint8_t *)op + OSPF6HDR_LEN); while ((const u_char *)lsrp < dataend) { ND_TCHECK(*lsrp); ND_PRINT((ndo, "\n\t Advertising Router %s", ipaddr_string(ndo, &lsrp->ls_router))); ospf6_print_ls_type(ndo, EXTRACT_16BITS(&lsrp->ls_type), &lsrp->ls_stateid); ++lsrp; } } break; case OSPF_TYPE_LS_UPDATE: if (ndo->ndo_vflag > 1) { register const struct lsu6 *lsup = (const struct lsu6 *)((const uint8_t *)op + OSPF6HDR_LEN); ND_TCHECK(lsup->lsu_count); i = EXTRACT_32BITS(&lsup->lsu_count); lsap = lsup->lsu_lsa; while ((const u_char *)lsap < dataend && i--) { if (ospf6_print_lsa(ndo, lsap, dataend)) goto trunc; lsap = (const struct lsa6 *)((const u_char *)lsap + EXTRACT_16BITS(&lsap->ls_hdr.ls_length)); } } break; case OSPF_TYPE_LS_ACK: if (ndo->ndo_vflag > 1) { lshp = (const struct lsa6_hdr *)((const uint8_t *)op + OSPF6HDR_LEN); while ((const u_char *)lshp < dataend) { if (ospf6_print_lshdr(ndo, lshp++, dataend)) goto trunc; } } break; default: break; } return (0); trunc: return (1); }
static void krb4_print(netdissect_options *ndo, const u_char *cp) { register const struct krb *kp; u_char type; u_short len; #define PRINT if ((cp = c_print(ndo, cp, ndo->ndo_snapend)) == NULL) goto trunc /* True if struct krb is little endian */ #define IS_LENDIAN(kp) (((kp)->type & 0x01) != 0) #define KTOHSP(kp, cp) (IS_LENDIAN(kp) ? EXTRACT_LE_16BITS(cp) : EXTRACT_16BITS(cp)) kp = (struct krb *)cp; if ((&kp->type) >= ndo->ndo_snapend) { ND_PRINT((ndo, "%s", tstr)); return; } type = kp->type & (0xFF << 1); ND_PRINT((ndo, " %s %s: ", IS_LENDIAN(kp) ? "le" : "be", tok2str(type2str, NULL, type))); switch (type) { case AUTH_MSG_KDC_REQUEST: if ((cp = krb4_print_hdr(ndo, cp)) == NULL) return; cp += 4; /* ctime */ ND_TCHECK(*cp); ND_PRINT((ndo, " %dmin ", *cp++ * 5)); PRINT; ND_PRINT((ndo, ".")); PRINT; break; case AUTH_MSG_APPL_REQUEST: cp += 2; ND_TCHECK(*cp); ND_PRINT((ndo, "v%d ", *cp++)); PRINT; ND_TCHECK(*cp); ND_PRINT((ndo, " (%d)", *cp++)); ND_TCHECK(*cp); ND_PRINT((ndo, " (%d)", *cp)); break; case AUTH_MSG_KDC_REPLY: if ((cp = krb4_print_hdr(ndo, cp)) == NULL) return; cp += 10; /* timestamp + n + exp + kvno */ ND_TCHECK2(*cp, sizeof(short)); len = KTOHSP(kp, cp); ND_PRINT((ndo, " (%d)", len)); break; case AUTH_MSG_ERR_REPLY: if ((cp = krb4_print_hdr(ndo, cp)) == NULL) return; cp += 4; /* timestamp */ ND_TCHECK2(*cp, sizeof(short)); ND_PRINT((ndo, " %s ", tok2str(kerr2str, NULL, KTOHSP(kp, cp)))); cp += 4; PRINT; break; default: ND_PRINT((ndo, "(unknown)")); break; } return; trunc: ND_PRINT((ndo, "%s", tstr)); }
/* * Scan a buffer looking for a line ending - LF or CR-LF. * Return the index of the character after the line ending or 0 if * we encounter a non-ASCII or non-printable character or don't find * the line ending. */ static u_int print_txt_line(netdissect_options *ndo, const char *protoname, const char *prefix, const u_char *pptr, u_int idx, u_int len) { u_int startidx; u_int linelen; startidx = idx; while (idx < len) { ND_TCHECK(*(pptr+idx)); if (*(pptr+idx) == '\n') { /* * LF without CR; end of line. * Skip the LF and print the line, with the * exception of the LF. */ linelen = idx - startidx; idx++; goto print; } else if (*(pptr+idx) == '\r') { /* CR - any LF? */ if ((idx+1) >= len) { /* not in this packet */ return (0); } ND_TCHECK(*(pptr+idx+1)); if (*(pptr+idx+1) == '\n') { /* * CR-LF; end of line. * Skip the CR-LF and print the line, with * the exception of the CR-LF. */ linelen = idx - startidx; idx += 2; goto print; } /* * CR followed by something else; treat this * as if it were binary data, and don't print * it. */ return (0); } else if (!isascii(*(pptr+idx)) || (!isprint(*(pptr+idx)) && *(pptr+idx) != '\t')) { /* * Not a printable ASCII character and not a tab; * treat this as if it were binary data, and * don't print it. */ return (0); } idx++; } /* * All printable ASCII, but no line ending after that point * in the buffer; treat this as if it were truncated. */ trunc: linelen = idx - startidx; ND_PRINT((ndo, "%s%.*s[!%s]", prefix, (int)linelen, pptr + startidx, protoname)); return (0); print: ND_PRINT((ndo, "%s%.*s", prefix, (int)linelen, pptr + startidx)); return (idx); }
void lwapp_control_print(netdissect_options *ndo, const u_char *pptr, u_int len, int has_ap_ident) { const struct lwapp_transport_header *lwapp_trans_header; const struct lwapp_control_header *lwapp_control_header; const u_char *tptr; int tlen; int msg_tlen; tptr=pptr; if (has_ap_ident) { /* check if enough bytes for AP identity */ ND_TCHECK2(*tptr, 6); lwapp_trans_header = (const struct lwapp_transport_header *)(pptr+6); } else { lwapp_trans_header = (const struct lwapp_transport_header *)pptr; } ND_TCHECK(*lwapp_trans_header); /* * Sanity checking of the header. */ if (LWAPP_EXTRACT_VERSION(lwapp_trans_header->version) != LWAPP_VERSION) { ND_PRINT((ndo, "LWAPP version %u packet not supported", LWAPP_EXTRACT_VERSION(lwapp_trans_header->version))); return; } /* non-verbose */ if (ndo->ndo_vflag < 1) { ND_PRINT((ndo, "LWAPPv%u, %s frame, Flags [%s], length %u", LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), len)); return; } /* ok they seem to want to know everything - lets fully decode it */ tlen=EXTRACT_16BITS(lwapp_trans_header->length); ND_PRINT((ndo, "LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u", LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", LWAPP_EXTRACT_RID(lwapp_trans_header->version), bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), lwapp_trans_header->frag_id, tlen)); if (has_ap_ident) { ND_PRINT((ndo, "\n\tAP identity: %s", etheraddr_string(ndo, tptr))); tptr+=sizeof(const struct lwapp_transport_header)+6; } else { tptr+=sizeof(const struct lwapp_transport_header); } while(tlen>0) { /* did we capture enough for fully decoding the object header ? */ ND_TCHECK2(*tptr, sizeof(struct lwapp_control_header)); lwapp_control_header = (const struct lwapp_control_header *)tptr; msg_tlen = EXTRACT_16BITS(lwapp_control_header->len); /* print message header */ ND_PRINT((ndo, "\n\t Msg type: %s (%u), Seqnum: %u, Msg len: %d, Session: 0x%08x", tok2str(lwapp_msg_type_values,"Unknown",lwapp_control_header->msg_type), lwapp_control_header->msg_type, lwapp_control_header->seq_num, msg_tlen, EXTRACT_32BITS(lwapp_control_header->session_id))); /* did we capture enough for fully decoding the message */ ND_TCHECK2(*tptr, msg_tlen); /* XXX - Decode sub messages for each message */ switch(lwapp_control_header->msg_type) { case LWAPP_MSGTYPE_DISCOVERY_REQUEST: case LWAPP_MSGTYPE_DISCOVERY_RESPONSE: case LWAPP_MSGTYPE_JOIN_REQUEST: case LWAPP_MSGTYPE_JOIN_RESPONSE: case LWAPP_MSGTYPE_JOIN_ACK: case LWAPP_MSGTYPE_JOIN_CONFIRM: case LWAPP_MSGTYPE_CONFIGURE_REQUEST: case LWAPP_MSGTYPE_CONFIGURE_RESPONSE: case LWAPP_MSGTYPE_CONF_UPDATE_REQUEST: case LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE: case LWAPP_MSGTYPE_WTP_EVENT_REQUEST: case LWAPP_MSGTYPE_WTP_EVENT_RESPONSE: case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST: case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE: case LWAPP_MSGTYPE_ECHO_REQUEST: case LWAPP_MSGTYPE_ECHO_RESPONSE: case LWAPP_MSGTYPE_IMAGE_DATA_REQUEST: case LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE: case LWAPP_MSGTYPE_RESET_REQUEST: case LWAPP_MSGTYPE_RESET_RESPONSE: case LWAPP_MSGTYPE_KEY_UPDATE_REQUEST: case LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE: case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST: case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE: case LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST: case LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE: case LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION: case LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST: case LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE: case LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST: case LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE: default: break; } tptr += sizeof(struct lwapp_control_header) + msg_tlen; tlen -= sizeof(struct lwapp_control_header) + msg_tlen; } return; trunc: ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); }
void msdp_print(netdissect_options *ndo, const u_char *sp, u_int length) { unsigned int type, len; ND_TCHECK2(*sp, 3); /* See if we think we're at the beginning of a compound packet */ type = *sp; len = EXTRACT_16BITS(sp + 1); if (len > 1500 || len < 3 || type == 0 || type > MSDP_TYPE_MAX) goto trunc; /* not really truncated, but still not decodable */ ND_PRINT((ndo, " msdp:")); while (length > 0) { ND_TCHECK2(*sp, 3); type = *sp; len = EXTRACT_16BITS(sp + 1); if (len > 1400 || ndo->ndo_vflag) ND_PRINT((ndo, " [len %u]", len)); if (len < 3) goto trunc; sp += 3; length -= 3; switch (type) { case 1: /* IPv4 Source-Active */ case 3: /* IPv4 Source-Active Response */ if (type == 1) ND_PRINT((ndo, " SA")); else ND_PRINT((ndo, " SA-Response")); ND_TCHECK(*sp); ND_PRINT((ndo, " %u entries", *sp)); if ((u_int)((*sp * 12) + 8) < len) { ND_PRINT((ndo, " [w/data]")); if (ndo->ndo_vflag > 1) { ND_PRINT((ndo, " ")); ip_print(ndo, sp + *sp * 12 + 8 - 3, len - (*sp * 12 + 8)); } } break; case 2: ND_PRINT((ndo, " SA-Request")); ND_TCHECK2(*sp, 5); ND_PRINT((ndo, " for %s", ipaddr_string(ndo, sp + 1))); break; case 4: ND_PRINT((ndo, " Keepalive")); if (len != 3) ND_PRINT((ndo, "[len=%d] ", len)); break; case 5: ND_PRINT((ndo, " Notification")); break; default: ND_PRINT((ndo, " [type=%d len=%d]", type, len)); break; } sp += (len - 3); length -= (len - 3); } return; trunc: ND_PRINT((ndo, " [|msdp]")); }
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) { ND_PRINT((ndo, " %s %o ids %d/%d", tok2str(type2str, "unk-ft %d ", EXTRACT_32BITS(&fap->fa_type)), EXTRACT_32BITS(&fap->fa_mode), EXTRACT_32BITS(&fap->fa_uid), EXTRACT_32BITS(&fap->fa_gid))); if (v3) { ND_TCHECK(fap->fa3_size); ND_PRINT((ndo, " sz %" PRIu64, EXTRACT_64BITS((uint32_t *)&fap->fa3_size))); } else { ND_TCHECK(fap->fa2_size); ND_PRINT((ndo, " sz %d", EXTRACT_32BITS(&fap->fa2_size))); } } /* print lots more stuff */ if (verbose > 1) { if (v3) { ND_TCHECK(fap->fa3_ctime); ND_PRINT((ndo, " nlink %d rdev %d/%d", EXTRACT_32BITS(&fap->fa_nlink), EXTRACT_32BITS(&fap->fa3_rdev.specdata1), EXTRACT_32BITS(&fap->fa3_rdev.specdata2))); ND_PRINT((ndo, " fsid %" PRIx64, EXTRACT_64BITS((uint32_t *)&fap->fa3_fsid))); ND_PRINT((ndo, " fileid %" PRIx64, EXTRACT_64BITS((uint32_t *)&fap->fa3_fileid))); ND_PRINT((ndo, " a/m/ctime %u.%06u", EXTRACT_32BITS(&fap->fa3_atime.nfsv3_sec), EXTRACT_32BITS(&fap->fa3_atime.nfsv3_nsec))); ND_PRINT((ndo, " %u.%06u", EXTRACT_32BITS(&fap->fa3_mtime.nfsv3_sec), EXTRACT_32BITS(&fap->fa3_mtime.nfsv3_nsec))); ND_PRINT((ndo, " %u.%06u", EXTRACT_32BITS(&fap->fa3_ctime.nfsv3_sec), EXTRACT_32BITS(&fap->fa3_ctime.nfsv3_nsec))); } else { ND_TCHECK(fap->fa2_ctime); ND_PRINT((ndo, " nlink %d rdev 0x%x fsid 0x%x nodeid 0x%x a/m/ctime", EXTRACT_32BITS(&fap->fa_nlink), EXTRACT_32BITS(&fap->fa2_rdev), EXTRACT_32BITS(&fap->fa2_fsid), EXTRACT_32BITS(&fap->fa2_fileid))); ND_PRINT((ndo, " %u.%06u", EXTRACT_32BITS(&fap->fa2_atime.nfsv2_sec), EXTRACT_32BITS(&fap->fa2_atime.nfsv2_usec))); ND_PRINT((ndo, " %u.%06u", EXTRACT_32BITS(&fap->fa2_mtime.nfsv2_sec), EXTRACT_32BITS(&fap->fa2_mtime.nfsv2_usec))); ND_PRINT((ndo, " %u.%06u", EXTRACT_32BITS(&fap->fa2_ctime.nfsv2_sec), EXTRACT_32BITS(&fap->fa2_ctime.nfsv2_usec))); } } return ((const uint32_t *)((unsigned char *)dp + (v3 ? NFSX_V3FATTR : NFSX_V2FATTR))); trunc: return (NULL); }
static void interp_reply(netdissect_options *ndo, const struct sunrpc_msg *rp, uint32_t proc, uint32_t vers, int length) { register const uint32_t *dp; register int v3; int er; v3 = (vers == NFS_VER3); if (!v3 && proc < NFS_NPROCS) proc = nfsv3_procid[proc]; ND_PRINT((ndo, " %s", tok2str(nfsproc_str, "proc-%u", proc))); switch (proc) { case NFSPROC_GETATTR: dp = parserep(ndo, rp, length); if (dp != NULL && parseattrstat(ndo, dp, !ndo->ndo_qflag, v3) != 0) return; break; case NFSPROC_SETATTR: if (!(dp = parserep(ndo, rp, length))) return; if (v3) { if (parsewccres(ndo, dp, ndo->ndo_vflag)) return; } else { if (parseattrstat(ndo, dp, !ndo->ndo_qflag, 0) != 0) return; } break; case NFSPROC_LOOKUP: if (!(dp = parserep(ndo, rp, length))) break; if (v3) { if (!(dp = parsestatus(ndo, dp, &er))) break; if (er) { if (ndo->ndo_vflag > 1) { ND_PRINT((ndo, " post dattr:")); dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); } } else { if (!(dp = parsefh(ndo, dp, v3))) break; if ((dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag)) && ndo->ndo_vflag > 1) { ND_PRINT((ndo, " post dattr:")); dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag); } } if (dp) return; } else { if (parsediropres(ndo, dp) != 0) return; } break; case NFSPROC_ACCESS: if (!(dp = parserep(ndo, rp, length))) break; if (!(dp = parsestatus(ndo, dp, &er))) break; if (ndo->ndo_vflag) ND_PRINT((ndo, " attr:")); if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag))) break; if (!er) ND_PRINT((ndo, " c %04x", EXTRACT_32BITS(&dp[0]))); return; case NFSPROC_READLINK: dp = parserep(ndo, rp, length); if (dp != NULL && parselinkres(ndo, dp, v3) != 0) return; break; case NFSPROC_READ: if (!(dp = parserep(ndo, rp, length))) break; if (v3) { if (!(dp = parsestatus(ndo, dp, &er))) break; if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag))) break; if (er) return; if (ndo->ndo_vflag) { ND_TCHECK(dp[1]); ND_PRINT((ndo, " %u bytes", EXTRACT_32BITS(&dp[0]))); if (EXTRACT_32BITS(&dp[1])) ND_PRINT((ndo, " EOF")); } return; } else { if (parseattrstat(ndo, dp, ndo->ndo_vflag, 0) != 0) return; } break; case NFSPROC_WRITE: if (!(dp = parserep(ndo, rp, length))) break; if (v3) { if (!(dp = parsestatus(ndo, dp, &er))) break; if (!(dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag))) break; if (er) return; if (ndo->ndo_vflag) { ND_TCHECK(dp[0]); ND_PRINT((ndo, " %u bytes", EXTRACT_32BITS(&dp[0]))); if (ndo->ndo_vflag > 1) { ND_TCHECK(dp[1]); ND_PRINT((ndo, " <%s>", tok2str(nfsv3_writemodes, NULL, EXTRACT_32BITS(&dp[1])))); } return; } } else { if (parseattrstat(ndo, dp, ndo->ndo_vflag, v3) != 0) return; } break; case NFSPROC_CREATE: case NFSPROC_MKDIR: if (!(dp = parserep(ndo, rp, length))) break; if (v3) { if (parsecreateopres(ndo, dp, ndo->ndo_vflag) != 0) return; } else { if (parsediropres(ndo, dp) != 0) return; } break; case NFSPROC_SYMLINK: if (!(dp = parserep(ndo, rp, length))) break; if (v3) { if (parsecreateopres(ndo, dp, ndo->ndo_vflag) != 0) return; } else { if (parsestatus(ndo, dp, &er) != 0) return; } break; case NFSPROC_MKNOD: if (!(dp = parserep(ndo, rp, length))) break; if (parsecreateopres(ndo, dp, ndo->ndo_vflag) != 0) return; break; case NFSPROC_REMOVE: case NFSPROC_RMDIR: if (!(dp = parserep(ndo, rp, length))) break; if (v3) { if (parsewccres(ndo, dp, ndo->ndo_vflag)) return; } else { if (parsestatus(ndo, dp, &er) != 0) return; } break; case NFSPROC_RENAME: if (!(dp = parserep(ndo, rp, length))) break; if (v3) { if (!(dp = parsestatus(ndo, dp, &er))) break; if (ndo->ndo_vflag) { ND_PRINT((ndo, " from:")); if (!(dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag))) break; ND_PRINT((ndo, " to:")); if (!(dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag))) break; } return; } else { if (parsestatus(ndo, dp, &er) != 0) return; } break; case NFSPROC_LINK: if (!(dp = parserep(ndo, rp, length))) break; if (v3) { if (!(dp = parsestatus(ndo, dp, &er))) break; if (ndo->ndo_vflag) { ND_PRINT((ndo, " file POST:")); if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag))) break; ND_PRINT((ndo, " dir:")); if (!(dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag))) break; return; } } else { if (parsestatus(ndo, dp, &er) != 0) return; } break; case NFSPROC_READDIR: if (!(dp = parserep(ndo, rp, length))) break; if (v3) { if (parsev3rddirres(ndo, dp, ndo->ndo_vflag)) return; } else { if (parserddires(ndo, dp) != 0) return; } break; case NFSPROC_READDIRPLUS: if (!(dp = parserep(ndo, rp, length))) break; if (parsev3rddirres(ndo, dp, ndo->ndo_vflag)) return; break; case NFSPROC_FSSTAT: dp = parserep(ndo, rp, length); if (dp != NULL && parsestatfs(ndo, dp, v3) != 0) return; break; case NFSPROC_FSINFO: dp = parserep(ndo, rp, length); if (dp != NULL && parsefsinfo(ndo, dp) != 0) return; break; case NFSPROC_PATHCONF: dp = parserep(ndo, rp, length); if (dp != NULL && parsepathconf(ndo, dp) != 0) return; break; case NFSPROC_COMMIT: dp = parserep(ndo, rp, length); if (dp != NULL && parsewccres(ndo, dp, ndo->ndo_vflag) != 0) return; break; default: return; } trunc: if (!nfserr) ND_PRINT((ndo, "%s", tstr)); }
static int dccp_print_option(netdissect_options *ndo, const u_char *option, u_int hlen) { uint8_t optlen, i; ND_TCHECK(*option); if (*option >= 32) { ND_TCHECK(*(option+1)); optlen = *(option +1); if (optlen < 2) { if (*option >= 128) ND_PRINT((ndo, "CCID option %u optlen too short", *option)); else ND_PRINT((ndo, "%s optlen too short", tok2str(dccp_option_values, "Option %u", *option))); return 0; } } else optlen = 1; if (hlen < optlen) { if (*option >= 128) ND_PRINT((ndo, "CCID option %u optlen goes past header length", *option)); else ND_PRINT((ndo, "%s optlen goes past header length", tok2str(dccp_option_values, "Option %u", *option))); return 0; } ND_TCHECK2(*option, optlen); if (*option >= 128) { ND_PRINT((ndo, "CCID option %d", *option)); switch (optlen) { case 4: ND_PRINT((ndo, " %u", EXTRACT_16BITS(option + 2))); break; case 6: ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2))); break; default: break; } } else { ND_PRINT((ndo, "%s", tok2str(dccp_option_values, "Option %u", *option))); switch (*option) { case 32: case 33: case 34: case 35: if (optlen < 3) { ND_PRINT((ndo, " optlen too short")); return optlen; } if (*(option + 2) < 10){ ND_PRINT((ndo, " %s", dccp_feature_nums[*(option + 2)])); for (i = 0; i < optlen - 3; i++) ND_PRINT((ndo, " %d", *(option + 3 + i))); } break; case 36: if (optlen > 2) { ND_PRINT((ndo, " 0x")); for (i = 0; i < optlen - 2; i++) ND_PRINT((ndo, "%02x", *(option + 2 + i))); } break; case 37: for (i = 0; i < optlen - 2; i++) ND_PRINT((ndo, " %d", *(option + 2 + i))); break; case 38: if (optlen > 2) { ND_PRINT((ndo, " 0x")); for (i = 0; i < optlen - 2; i++) ND_PRINT((ndo, "%02x", *(option + 2 + i))); } break; case 39: if (optlen > 2) { ND_PRINT((ndo, " 0x")); for (i = 0; i < optlen - 2; i++) ND_PRINT((ndo, "%02x", *(option + 2 + i))); } break; case 40: if (optlen > 2) { ND_PRINT((ndo, " 0x")); for (i = 0; i < optlen - 2; i++) ND_PRINT((ndo, "%02x", *(option + 2 + i))); } break; case 41: if (optlen == 4) ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2))); else ND_PRINT((ndo, " optlen != 4")); break; case 42: if (optlen == 4) ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2))); else ND_PRINT((ndo, " optlen != 4")); break; case 43: if (optlen == 6) ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2))); else if (optlen == 4) ND_PRINT((ndo, " %u", EXTRACT_16BITS(option + 2))); else ND_PRINT((ndo, " optlen != 4 or 6")); break; case 44: if (optlen > 2) { ND_PRINT((ndo, " ")); for (i = 0; i < optlen - 2; i++) ND_PRINT((ndo, "%02x", *(option + 2 + i))); } break; } } return optlen; trunc: ND_PRINT((ndo, "%s", tstr)); return 0; }
void slow_print(netdissect_options *ndo, register const u_char *pptr, register u_int len) { int print_version; slow_com_header = (const struct slow_common_header_t *)pptr; ND_TCHECK(*slow_com_header); /* * Sanity checking of the header. */ switch (slow_com_header->proto_subtype) { case SLOW_PROTO_LACP: if (slow_com_header->version != LACP_VERSION) { ND_PRINT((ndo, "LACP version %u packet not supported",slow_com_header->version)); return; } print_version = 1; break; case SLOW_PROTO_MARKER: if (slow_com_header->version != MARKER_VERSION) { ND_PRINT((ndo, "MARKER version %u packet not supported",slow_com_header->version)); return; } print_version = 1; break; case SLOW_PROTO_OAM: /* fall through */ print_version = 0; break; default: /* print basic information and exit */ print_version = -1; break; } if (print_version) { ND_PRINT((ndo, "%sv%u, length %u", tok2str(slow_proto_values, "unknown (%u)",slow_com_header->proto_subtype), slow_com_header->version, len)); } else { /* some slow protos don't have a version number in the header */ ND_PRINT((ndo, "%s, length %u", tok2str(slow_proto_values, "unknown (%u)",slow_com_header->proto_subtype), len)); } /* unrecognized subtype */ if (print_version == -1) { print_unknown_data(ndo, pptr, "\n\t", len); return; } if (!ndo->ndo_vflag) return; switch (slow_com_header->proto_subtype) { default: /* should not happen */ break; case SLOW_PROTO_OAM: /* skip proto_subtype */ slow_oam_print(ndo, pptr+1, len-1); break; case SLOW_PROTO_LACP: /* LACP and MARKER share the same semantics */ case SLOW_PROTO_MARKER: /* skip slow_common_header */ len -= sizeof(const struct slow_common_header_t); pptr += sizeof(const struct slow_common_header_t); slow_marker_lacp_print(ndo, pptr, len); break; } return; trunc: ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); }
/** * dccp_print - show dccp packet * @bp - beginning of dccp packet * @data2 - beginning of enclosing * @len - lenght of ip packet */ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, u_int len) { const struct dccp_hdr *dh; const struct ip *ip; const struct ip6_hdr *ip6; const u_char *cp; u_short sport, dport; u_int hlen; u_int fixed_hdrlen; uint8_t dccph_type; dh = (const struct dccp_hdr *)bp; ip = (const struct ip *)data2; if (IP_V(ip) == 6) ip6 = (const struct ip6_hdr *)data2; else ip6 = NULL; /* make sure we have enough data to look at the X bit */ cp = (const u_char *)(dh + 1); if (cp > ndo->ndo_snapend) { ND_PRINT((ndo, "[Invalid packet|dccp]")); return; } if (len < sizeof(struct dccp_hdr)) { ND_PRINT((ndo, "truncated-dccp - %u bytes missing!", len - (u_int)sizeof(struct dccp_hdr))); return; } /* get the length of the generic header */ fixed_hdrlen = dccp_basic_hdr_len(dh); if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-dccp - %u bytes missing!", len - fixed_hdrlen)); return; } ND_TCHECK2(*dh, fixed_hdrlen); sport = EXTRACT_16BITS(&dh->dccph_sport); dport = EXTRACT_16BITS(&dh->dccph_dport); hlen = dh->dccph_doff * 4; if (ip6) { ND_PRINT((ndo, "%s.%d > %s.%d: ", ip6addr_string(ndo, &ip6->ip6_src), sport, ip6addr_string(ndo, &ip6->ip6_dst), dport)); } else { ND_PRINT((ndo, "%s.%d > %s.%d: ", ipaddr_string(ndo, &ip->ip_src), sport, ipaddr_string(ndo, &ip->ip_dst), dport)); } ND_PRINT((ndo, "DCCP")); if (ndo->ndo_qflag) { ND_PRINT((ndo, " %d", len - hlen)); if (hlen > len) { ND_PRINT((ndo, " [bad hdr length %u - too long, > %u]", hlen, len)); } return; } /* other variables in generic header */ if (ndo->ndo_vflag) { ND_PRINT((ndo, " (CCVal %d, CsCov %d, ", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh))); } /* checksum calculation */ if (ndo->ndo_vflag && ND_TTEST2(bp[0], len)) { uint16_t sum = 0, dccp_sum; dccp_sum = EXTRACT_16BITS(&dh->dccph_checksum); ND_PRINT((ndo, "cksum 0x%04x ", dccp_sum)); if (IP_V(ip) == 4) sum = dccp_cksum(ndo, ip, dh, len); else if (IP_V(ip) == 6) sum = dccp6_cksum(ndo, ip6, dh, len); if (sum != 0) ND_PRINT((ndo, "(incorrect -> 0x%04x)",in_cksum_shouldbe(dccp_sum, sum))); else ND_PRINT((ndo, "(correct)")); } if (ndo->ndo_vflag) ND_PRINT((ndo, ")")); ND_PRINT((ndo, " ")); dccph_type = DCCPH_TYPE(dh); switch (dccph_type) { case DCCP_PKT_REQUEST: { const struct dccp_hdr_request *dhr = (const struct dccp_hdr_request *)(bp + fixed_hdrlen); fixed_hdrlen += 4; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), len - fixed_hdrlen)); return; } ND_TCHECK(*dhr); ND_PRINT((ndo, "%s (service=%d) ", tok2str(dccp_pkt_type_str, "", dccph_type), EXTRACT_32BITS(&dhr->dccph_req_service))); break; } case DCCP_PKT_RESPONSE: { const struct dccp_hdr_response *dhr = (const struct dccp_hdr_response *)(bp + fixed_hdrlen); fixed_hdrlen += 12; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), len - fixed_hdrlen)); return; } ND_TCHECK(*dhr); ND_PRINT((ndo, "%s (service=%d) ", tok2str(dccp_pkt_type_str, "", dccph_type), EXTRACT_32BITS(&dhr->dccph_resp_service))); break; } case DCCP_PKT_DATA: ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); break; case DCCP_PKT_ACK: { fixed_hdrlen += 8; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), len - fixed_hdrlen)); return; } ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); break; } case DCCP_PKT_DATAACK: { fixed_hdrlen += 8; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), len - fixed_hdrlen)); return; } ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); break; } case DCCP_PKT_CLOSEREQ: fixed_hdrlen += 8; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), len - fixed_hdrlen)); return; } ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); break; case DCCP_PKT_CLOSE: fixed_hdrlen += 8; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), len - fixed_hdrlen)); return; } ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); break; case DCCP_PKT_RESET: { const struct dccp_hdr_reset *dhr = (const struct dccp_hdr_reset *)(bp + fixed_hdrlen); fixed_hdrlen += 12; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), len - fixed_hdrlen)); return; } ND_TCHECK(*dhr); ND_PRINT((ndo, "%s (code=%s) ", tok2str(dccp_pkt_type_str, "", dccph_type), dccp_reset_code(dhr->dccph_reset_code))); break; } case DCCP_PKT_SYNC: fixed_hdrlen += 8; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), len - fixed_hdrlen)); return; } ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); break; case DCCP_PKT_SYNCACK: fixed_hdrlen += 8; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-%s - %u bytes missing!", tok2str(dccp_pkt_type_str, "", dccph_type), len - fixed_hdrlen)); return; } ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); break; default: ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "unknown-type-%u", dccph_type))); break; } if ((DCCPH_TYPE(dh) != DCCP_PKT_DATA) && (DCCPH_TYPE(dh) != DCCP_PKT_REQUEST)) dccp_print_ack_no(ndo, bp); if (ndo->ndo_vflag < 2) return; ND_PRINT((ndo, "seq %" PRIu64, dccp_seqno(bp))); /* process options */ if (hlen > fixed_hdrlen){ u_int optlen; cp = bp + fixed_hdrlen; ND_PRINT((ndo, " <")); hlen -= fixed_hdrlen; while(1){ optlen = dccp_print_option(ndo, cp, hlen); if (!optlen) break; if (hlen <= optlen) break; hlen -= optlen; cp += optlen; ND_PRINT((ndo, ", ")); } ND_PRINT((ndo, ">")); } return; trunc: ND_PRINT((ndo, "%s", tstr)); return; }
/* PAP (see RFC 1334) */ static void handle_pap(netdissect_options *ndo, const u_char *p, int length) { u_int code, len; int peerid_len, passwd_len, msg_len; const u_char *p0; int i; p0 = p; if (length < 1) { ND_PRINT((ndo, "[|pap]")); return; } else if (length < 4) { ND_TCHECK(*p); ND_PRINT((ndo, "[|pap 0x%02x]", *p)); return; } ND_TCHECK(*p); code = *p; ND_PRINT((ndo, "PAP, %s (0x%02x)", tok2str(papcode_values, "unknown", code), code)); p++; ND_TCHECK(*p); ND_PRINT((ndo, ", id %u", *p)); /* ID */ p++; ND_TCHECK2(*p, 2); len = EXTRACT_16BITS(p); p += 2; if ((int)len > length) { ND_PRINT((ndo, ", length %u > packet size", len)); return; } length = len; if (length < (p - p0)) { ND_PRINT((ndo, ", length %u < PAP header length", length)); return; } switch (code) { case PAP_AREQ: if (length - (p - p0) < 1) return; ND_TCHECK(*p); peerid_len = *p; /* Peer-ID Length */ p++; if (length - (p - p0) < peerid_len) return; ND_PRINT((ndo, ", Peer ")); for (i = 0; i < peerid_len; i++) { ND_TCHECK(*p); safeputchar(ndo, *p++); } if (length - (p - p0) < 1) return; ND_TCHECK(*p); passwd_len = *p; /* Password Length */ p++; if (length - (p - p0) < passwd_len) return; ND_PRINT((ndo, ", Name ")); for (i = 0; i < passwd_len; i++) { ND_TCHECK(*p); safeputchar(ndo, *p++); } break; case PAP_AACK: case PAP_ANAK: if (length - (p - p0) < 1) return; ND_TCHECK(*p); msg_len = *p; /* Msg-Length */ p++; if (length - (p - p0) < msg_len) return; ND_PRINT((ndo, ", Msg ")); for (i = 0; i< msg_len; i++) { ND_TCHECK(*p); safeputchar(ndo, *p++); } break; } return; trunc: ND_PRINT((ndo, "[|pap]")); }
/* CHAP */ static void handle_chap(netdissect_options *ndo, const u_char *p, int length) { u_int code, len; int val_size, name_size, msg_size; const u_char *p0; int i; p0 = p; if (length < 1) { ND_PRINT((ndo, "[|chap]")); return; } else if (length < 4) { ND_TCHECK(*p); ND_PRINT((ndo, "[|chap 0x%02x]", *p)); return; } ND_TCHECK(*p); code = *p; ND_PRINT((ndo, "CHAP, %s (0x%02x)", tok2str(chapcode_values,"unknown",code), code)); p++; ND_TCHECK(*p); ND_PRINT((ndo, ", id %u", *p)); /* ID */ p++; ND_TCHECK2(*p, 2); len = EXTRACT_16BITS(p); p += 2; /* * Note that this is a generic CHAP decoding routine. Since we * don't know which flavor of CHAP (i.e. CHAP-MD5, MS-CHAPv1, * MS-CHAPv2) is used at this point, we can't decode packet * specifically to each algorithms. Instead, we simply decode * the GCD (Gratest Common Denominator) for all algorithms. */ switch (code) { case CHAP_CHAL: case CHAP_RESP: if (length - (p - p0) < 1) return; ND_TCHECK(*p); val_size = *p; /* value size */ p++; if (length - (p - p0) < val_size) return; ND_PRINT((ndo, ", Value ")); for (i = 0; i < val_size; i++) { ND_TCHECK(*p); ND_PRINT((ndo, "%02x", *p++)); } name_size = len - (p - p0); ND_PRINT((ndo, ", Name ")); for (i = 0; i < name_size; i++) { ND_TCHECK(*p); safeputchar(ndo, *p++); } break; case CHAP_SUCC: case CHAP_FAIL: msg_size = len - (p - p0); ND_PRINT((ndo, ", Msg ")); for (i = 0; i< msg_size; i++) { ND_TCHECK(*p); safeputchar(ndo, *p++); } break; } return; trunc: ND_PRINT((ndo, "[|chap]")); }
/* * 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)); }
static const uint32_t * parse_sattr3(netdissect_options *ndo, const uint32_t *dp, struct nfsv3_sattr *sa3) { ND_TCHECK(dp[0]); sa3->sa_modeset = EXTRACT_32BITS(dp); dp++; if (sa3->sa_modeset) { ND_TCHECK(dp[0]); sa3->sa_mode = EXTRACT_32BITS(dp); dp++; } ND_TCHECK(dp[0]); sa3->sa_uidset = EXTRACT_32BITS(dp); dp++; if (sa3->sa_uidset) { ND_TCHECK(dp[0]); sa3->sa_uid = EXTRACT_32BITS(dp); dp++; } ND_TCHECK(dp[0]); sa3->sa_gidset = EXTRACT_32BITS(dp); dp++; if (sa3->sa_gidset) { ND_TCHECK(dp[0]); sa3->sa_gid = EXTRACT_32BITS(dp); dp++; } ND_TCHECK(dp[0]); sa3->sa_sizeset = EXTRACT_32BITS(dp); dp++; if (sa3->sa_sizeset) { ND_TCHECK(dp[0]); sa3->sa_size = EXTRACT_32BITS(dp); dp++; } ND_TCHECK(dp[0]); sa3->sa_atimetype = EXTRACT_32BITS(dp); dp++; if (sa3->sa_atimetype == NFSV3SATTRTIME_TOCLIENT) { ND_TCHECK(dp[1]); sa3->sa_atime.nfsv3_sec = EXTRACT_32BITS(dp); dp++; sa3->sa_atime.nfsv3_nsec = EXTRACT_32BITS(dp); dp++; } ND_TCHECK(dp[0]); sa3->sa_mtimetype = EXTRACT_32BITS(dp); dp++; if (sa3->sa_mtimetype == NFSV3SATTRTIME_TOCLIENT) { ND_TCHECK(dp[1]); sa3->sa_mtime.nfsv3_sec = EXTRACT_32BITS(dp); dp++; sa3->sa_mtime.nfsv3_nsec = EXTRACT_32BITS(dp); dp++; } return dp; trunc: return NULL; }
u_int pflog_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p) { u_int length = h->len; u_int hdrlen; u_int caplen = h->caplen; const struct pfloghdr *hdr; uint8_t af; /* check length */ if (caplen < sizeof(uint8_t)) { ND_PRINT((ndo, "%s", tstr)); return (caplen); } #define MIN_PFLOG_HDRLEN 45 hdr = (const struct pfloghdr *)p; if (hdr->length < MIN_PFLOG_HDRLEN) { ND_PRINT((ndo, "[pflog: invalid header length!]")); return (hdr->length); /* XXX: not really */ } hdrlen = BPF_WORDALIGN(hdr->length); if (caplen < hdrlen) { ND_PRINT((ndo, "%s", tstr)); return (hdrlen); /* XXX: true? */ } /* print what we know */ ND_TCHECK(*hdr); if (ndo->ndo_eflag) pflog_print(ndo, hdr); /* skip to the real packet */ af = hdr->af; length -= hdrlen; caplen -= hdrlen; p += hdrlen; switch (af) { case AF_INET: #if OPENBSD_AF_INET != AF_INET case OPENBSD_AF_INET: /* XXX: read pcap files */ #endif ip_print(ndo, p, length); break; #if defined(AF_INET6) || defined(OPENBSD_AF_INET6) #ifdef AF_INET6 case AF_INET6: #endif /* AF_INET6 */ #if !defined(AF_INET6) || OPENBSD_AF_INET6 != AF_INET6 case OPENBSD_AF_INET6: /* XXX: read pcap files */ #endif /* !defined(AF_INET6) || OPENBSD_AF_INET6 != AF_INET6 */ ip6_print(ndo, p, length); break; #endif /* defined(AF_INET6) || defined(OPENBSD_AF_INET6) */ default: /* address family not handled, print raw packet */ if (!ndo->ndo_eflag) pflog_print(ndo, hdr); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } return (hdrlen); trunc: ND_PRINT((ndo, "%s", tstr)); return (hdrlen); }
void nfsreq_print_noaddr(netdissect_options *ndo, register const u_char *bp, u_int length, register const u_char *bp2) { register const struct sunrpc_msg *rp; register const uint32_t *dp; nfs_type type; int v3; uint32_t proc; uint32_t access_flags; struct nfsv3_sattr sa3; ND_PRINT((ndo, "%d", length)); nfserr = 0; /* assume no error */ rp = (const struct sunrpc_msg *)bp; if (!xid_map_enter(ndo, rp, bp2)) /* record proc number for later on */ goto trunc; v3 = (EXTRACT_32BITS(&rp->rm_call.cb_vers) == NFS_VER3); proc = EXTRACT_32BITS(&rp->rm_call.cb_proc); if (!v3 && proc < NFS_NPROCS) proc = nfsv3_procid[proc]; ND_PRINT((ndo, " %s", tok2str(nfsproc_str, "proc-%u", proc))); switch (proc) { case NFSPROC_GETATTR: case NFSPROC_SETATTR: case NFSPROC_READLINK: case NFSPROC_FSSTAT: case NFSPROC_FSINFO: case NFSPROC_PATHCONF: if ((dp = parsereq(ndo, rp, length)) != NULL && parsefh(ndo, dp, v3) != NULL) return; break; case NFSPROC_LOOKUP: case NFSPROC_CREATE: case NFSPROC_MKDIR: case NFSPROC_REMOVE: case NFSPROC_RMDIR: if ((dp = parsereq(ndo, rp, length)) != NULL && parsefhn(ndo, dp, v3) != NULL) return; break; case NFSPROC_ACCESS: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefh(ndo, dp, v3)) != NULL) { ND_TCHECK(dp[0]); access_flags = EXTRACT_32BITS(&dp[0]); if (access_flags & ~NFSV3ACCESS_FULL) { /* NFSV3ACCESS definitions aren't up to date */ ND_PRINT((ndo, " %04x", access_flags)); } else if ((access_flags & NFSV3ACCESS_FULL) == NFSV3ACCESS_FULL) { ND_PRINT((ndo, " NFS_ACCESS_FULL")); } else { char separator = ' '; if (access_flags & NFSV3ACCESS_READ) { ND_PRINT((ndo, " NFS_ACCESS_READ")); separator = '|'; } if (access_flags & NFSV3ACCESS_LOOKUP) { ND_PRINT((ndo, "%cNFS_ACCESS_LOOKUP", separator)); separator = '|'; } if (access_flags & NFSV3ACCESS_MODIFY) { ND_PRINT((ndo, "%cNFS_ACCESS_MODIFY", separator)); separator = '|'; } if (access_flags & NFSV3ACCESS_EXTEND) { ND_PRINT((ndo, "%cNFS_ACCESS_EXTEND", separator)); separator = '|'; } if (access_flags & NFSV3ACCESS_DELETE) { ND_PRINT((ndo, "%cNFS_ACCESS_DELETE", separator)); separator = '|'; } if (access_flags & NFSV3ACCESS_EXECUTE) ND_PRINT((ndo, "%cNFS_ACCESS_EXECUTE", separator)); } return; } break; case NFSPROC_READ: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefh(ndo, dp, v3)) != NULL) { if (v3) { ND_TCHECK(dp[2]); ND_PRINT((ndo, " %u bytes @ %" PRIu64, EXTRACT_32BITS(&dp[2]), EXTRACT_64BITS(&dp[0]))); } else { ND_TCHECK(dp[1]); ND_PRINT((ndo, " %u bytes @ %u", EXTRACT_32BITS(&dp[1]), EXTRACT_32BITS(&dp[0]))); } return; } break; case NFSPROC_WRITE: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefh(ndo, dp, v3)) != NULL) { if (v3) { ND_TCHECK(dp[2]); ND_PRINT((ndo, " %u (%u) bytes @ %" PRIu64, EXTRACT_32BITS(&dp[4]), EXTRACT_32BITS(&dp[2]), EXTRACT_64BITS(&dp[0]))); if (ndo->ndo_vflag) { dp += 3; ND_TCHECK(dp[0]); ND_PRINT((ndo, " <%s>", tok2str(nfsv3_writemodes, NULL, EXTRACT_32BITS(dp)))); } } else { ND_TCHECK(dp[3]); ND_PRINT((ndo, " %u (%u) bytes @ %u (%u)", EXTRACT_32BITS(&dp[3]), EXTRACT_32BITS(&dp[2]), EXTRACT_32BITS(&dp[1]), EXTRACT_32BITS(&dp[0]))); } return; } break; case NFSPROC_SYMLINK: if ((dp = parsereq(ndo, rp, length)) != 0 && (dp = parsefhn(ndo, dp, v3)) != 0) { ND_PRINT((ndo, " ->")); if (v3 && (dp = parse_sattr3(ndo, dp, &sa3)) == 0) break; if (parsefn(ndo, dp) == 0) break; if (v3 && ndo->ndo_vflag) print_sattr3(ndo, &sa3, ndo->ndo_vflag); return; } break; case NFSPROC_MKNOD: if ((dp = parsereq(ndo, rp, length)) != 0 && (dp = parsefhn(ndo, dp, v3)) != 0) { ND_TCHECK(*dp); type = (nfs_type)EXTRACT_32BITS(dp); dp++; if ((dp = parse_sattr3(ndo, dp, &sa3)) == 0) break; ND_PRINT((ndo, " %s", tok2str(type2str, "unk-ft %d", type))); if (ndo->ndo_vflag && (type == NFCHR || type == NFBLK)) { ND_TCHECK(dp[1]); ND_PRINT((ndo, " %u/%u", EXTRACT_32BITS(&dp[0]), EXTRACT_32BITS(&dp[1]))); dp += 2; } if (ndo->ndo_vflag) print_sattr3(ndo, &sa3, ndo->ndo_vflag); return; } break; case NFSPROC_RENAME: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefhn(ndo, dp, v3)) != NULL) { ND_PRINT((ndo, " ->")); if (parsefhn(ndo, dp, v3) != NULL) return; } break; case NFSPROC_LINK: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefh(ndo, dp, v3)) != NULL) { ND_PRINT((ndo, " ->")); if (parsefhn(ndo, dp, v3) != NULL) return; } break; case NFSPROC_READDIR: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefh(ndo, dp, v3)) != NULL) { if (v3) { ND_TCHECK(dp[4]); /* * We shouldn't really try to interpret the * offset cookie here. */ ND_PRINT((ndo, " %u bytes @ %" PRId64, EXTRACT_32BITS(&dp[4]), EXTRACT_64BITS(&dp[0]))); if (ndo->ndo_vflag) ND_PRINT((ndo, " verf %08x%08x", dp[2], dp[3])); } else { ND_TCHECK(dp[1]); /* * Print the offset as signed, since -1 is * common, but offsets > 2^31 aren't. */ ND_PRINT((ndo, " %u bytes @ %d", EXTRACT_32BITS(&dp[1]), EXTRACT_32BITS(&dp[0]))); } return; } break; case NFSPROC_READDIRPLUS: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefh(ndo, dp, v3)) != NULL) { ND_TCHECK(dp[4]); /* * We don't try to interpret the offset * cookie here. */ ND_PRINT((ndo, " %u bytes @ %" PRId64, EXTRACT_32BITS(&dp[4]), EXTRACT_64BITS(&dp[0]))); if (ndo->ndo_vflag) { ND_TCHECK(dp[5]); ND_PRINT((ndo, " max %u verf %08x%08x", EXTRACT_32BITS(&dp[5]), dp[2], dp[3])); } return; } break; case NFSPROC_COMMIT: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefh(ndo, dp, v3)) != NULL) { ND_TCHECK(dp[2]); ND_PRINT((ndo, " %u bytes @ %" PRIu64, EXTRACT_32BITS(&dp[2]), EXTRACT_64BITS(&dp[0]))); return; } break; default: return; } trunc: if (!nfserr) ND_PRINT((ndo, "%s", tstr)); }
void aodv_print(netdissect_options *ndo, const u_char *dat, u_int length, int is_ip6) { uint8_t msg_type; /* * The message type is the first byte; make sure we have it * and then fetch it. */ ND_TCHECK(*dat); msg_type = *dat; ND_PRINT((ndo, " aodv")); switch (msg_type) { case AODV_RREQ: if (is_ip6) aodv_v6_rreq(ndo, dat, length); else aodv_rreq(ndo, dat, length); break; case AODV_RREP: if (is_ip6) aodv_v6_rrep(ndo, dat, length); else aodv_rrep(ndo, dat, length); break; case AODV_RERR: if (is_ip6) aodv_v6_rerr(ndo, dat, length); else aodv_rerr(ndo, dat, length); break; case AODV_RREP_ACK: ND_PRINT((ndo, " rrep-ack %u", length)); break; case AODV_V6_DRAFT_01_RREQ: aodv_v6_draft_01_rreq(ndo, dat, length); break; case AODV_V6_DRAFT_01_RREP: aodv_v6_draft_01_rrep(ndo, dat, length); break; case AODV_V6_DRAFT_01_RERR: aodv_v6_draft_01_rerr(ndo, dat, length); break; case AODV_V6_DRAFT_01_RREP_ACK: ND_PRINT((ndo, " rrep-ack %u", length)); break; default: ND_PRINT((ndo, " type %u %u", msg_type, length)); } return; trunc: ND_PRINT((ndo, " [|aodv]")); }
void tcp_print(netdissect_options *ndo, register const u_char *bp, register u_int length, register const u_char *bp2, int fragmented) { register const struct tcphdr *tp; register const struct ip *ip; register u_char flags; register u_int hlen; register char ch; uint16_t sport, dport, win, urp; uint32_t seq, ack, thseq, thack; u_int utoval; uint16_t magic; register int rev; register const struct ip6_hdr *ip6; tp = (const struct tcphdr *)bp; ip = (const struct ip *)bp2; if (IP_V(ip) == 6) ip6 = (const struct ip6_hdr *)bp2; else ip6 = NULL; ch = '\0'; if (!ND_TTEST(tp->th_dport)) { ND_PRINT((ndo, "%s > %s: [|tcp]", ipaddr_string(ndo, &ip->ip_src), ipaddr_string(ndo, &ip->ip_dst))); return; } sport = EXTRACT_16BITS(&tp->th_sport); dport = EXTRACT_16BITS(&tp->th_dport); hlen = TH_OFF(tp) * 4; if (ip6) { if (ip6->ip6_nxt == IPPROTO_TCP) { ND_PRINT((ndo, "%s.%s > %s.%s: ", ip6addr_string(ndo, &ip6->ip6_src), tcpport_string(ndo, sport), ip6addr_string(ndo, &ip6->ip6_dst), tcpport_string(ndo, dport))); } else { ND_PRINT((ndo, "%s > %s: ", tcpport_string(ndo, sport), tcpport_string(ndo, dport))); } } else { if (ip->ip_p == IPPROTO_TCP) { ND_PRINT((ndo, "%s.%s > %s.%s: ", ipaddr_string(ndo, &ip->ip_src), tcpport_string(ndo, sport), ipaddr_string(ndo, &ip->ip_dst), tcpport_string(ndo, dport))); } else { ND_PRINT((ndo, "%s > %s: ", tcpport_string(ndo, sport), tcpport_string(ndo, dport))); } } if (hlen < sizeof(*tp)) { ND_PRINT((ndo, " tcp %d [bad hdr length %u - too short, < %lu]", length - hlen, hlen, (unsigned long)sizeof(*tp))); return; } ND_TCHECK(*tp); seq = EXTRACT_32BITS(&tp->th_seq); ack = EXTRACT_32BITS(&tp->th_ack); win = EXTRACT_16BITS(&tp->th_win); urp = EXTRACT_16BITS(&tp->th_urp); if (ndo->ndo_qflag) { ND_PRINT((ndo, "tcp %d", length - hlen)); if (hlen > length) { ND_PRINT((ndo, " [bad hdr length %u - too long, > %u]", hlen, length)); } return; } flags = tp->th_flags; ND_PRINT((ndo, "Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags))); if (!ndo->ndo_Sflag && (flags & TH_ACK)) { /* * Find (or record) the initial sequence numbers for * this conversation. (we pick an arbitrary * collating order so there's only one entry for * both directions). */ rev = 0; if (ip6) { register struct tcp_seq_hash6 *th; struct tcp_seq_hash6 *tcp_seq_hash; const struct in6_addr *src, *dst; struct tha6 tha; tcp_seq_hash = tcp_seq_hash6; src = &ip6->ip6_src; dst = &ip6->ip6_dst; if (sport > dport) rev = 1; else if (sport == dport) { if (UNALIGNED_MEMCMP(src, dst, sizeof ip6->ip6_dst) > 0) rev = 1; } if (rev) { UNALIGNED_MEMCPY(&tha.src, dst, sizeof ip6->ip6_dst); UNALIGNED_MEMCPY(&tha.dst, src, sizeof ip6->ip6_src); tha.port = dport << 16 | sport; } else { UNALIGNED_MEMCPY(&tha.dst, dst, sizeof ip6->ip6_dst); UNALIGNED_MEMCPY(&tha.src, src, sizeof ip6->ip6_src); tha.port = sport << 16 | dport; } for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE]; th->nxt; th = th->nxt) if (memcmp((char *)&tha, (char *)&th->addr, sizeof(th->addr)) == 0) break; if (!th->nxt || (flags & TH_SYN)) { /* didn't find it or new conversation */ if (th->nxt == NULL) { th->nxt = (struct tcp_seq_hash6 *) calloc(1, sizeof(*th)); if (th->nxt == NULL) (*ndo->ndo_error)(ndo, "tcp_print: calloc"); } th->addr = tha; if (rev) th->ack = seq, th->seq = ack - 1; else th->seq = seq, th->ack = ack - 1; } else { if (rev) seq -= th->ack, ack -= th->seq; else seq -= th->seq, ack -= th->ack; } thseq = th->seq; thack = th->ack; } else { register struct tcp_seq_hash *th; struct tcp_seq_hash *tcp_seq_hash; struct tha tha; tcp_seq_hash = tcp_seq_hash4; if (sport > dport) rev = 1; else if (sport == dport) { if (UNALIGNED_MEMCMP(&ip->ip_src, &ip->ip_dst, sizeof ip->ip_dst) > 0) rev = 1; } if (rev) { UNALIGNED_MEMCPY(&tha.src, &ip->ip_dst, sizeof ip->ip_dst); UNALIGNED_MEMCPY(&tha.dst, &ip->ip_src, sizeof ip->ip_src); tha.port = dport << 16 | sport; } else { UNALIGNED_MEMCPY(&tha.dst, &ip->ip_dst, sizeof ip->ip_dst); UNALIGNED_MEMCPY(&tha.src, &ip->ip_src, sizeof ip->ip_src); tha.port = sport << 16 | dport; } for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE]; th->nxt; th = th->nxt) if (memcmp((char *)&tha, (char *)&th->addr, sizeof(th->addr)) == 0) break; if (!th->nxt || (flags & TH_SYN)) { /* didn't find it or new conversation */ if (th->nxt == NULL) { th->nxt = (struct tcp_seq_hash *) calloc(1, sizeof(*th)); if (th->nxt == NULL) (*ndo->ndo_error)(ndo, "tcp_print: calloc"); } th->addr = tha; if (rev) th->ack = seq, th->seq = ack - 1; else th->seq = seq, th->ack = ack - 1; } else { if (rev) seq -= th->ack, ack -= th->seq; else seq -= th->seq, ack -= th->ack; } thseq = th->seq; thack = th->ack; } } else { /*fool gcc*/ thseq = thack = rev = 0; } if (hlen > length) { ND_PRINT((ndo, " [bad hdr length %u - too long, > %u]", hlen, length)); return; } if (ndo->ndo_vflag && !ndo->ndo_Kflag && !fragmented) { /* Check the checksum, if possible. */ uint16_t sum, tcp_sum; if (IP_V(ip) == 4) { if (ND_TTEST2(tp->th_sport, length)) { sum = tcp_cksum(ndo, ip, tp, length); tcp_sum = EXTRACT_16BITS(&tp->th_sum); ND_PRINT((ndo, ", cksum 0x%04x", tcp_sum)); if (sum != 0) ND_PRINT((ndo, " (incorrect -> 0x%04x)", in_cksum_shouldbe(tcp_sum, sum))); else ND_PRINT((ndo, " (correct)")); } } else if (IP_V(ip) == 6 && ip6->ip6_plen) { if (ND_TTEST2(tp->th_sport, length)) { sum = nextproto6_cksum(ip6, (const uint8_t *)tp, length, length, IPPROTO_TCP); tcp_sum = EXTRACT_16BITS(&tp->th_sum); ND_PRINT((ndo, ", cksum 0x%04x", tcp_sum)); if (sum != 0) ND_PRINT((ndo, " (incorrect -> 0x%04x)", in_cksum_shouldbe(tcp_sum, sum))); else ND_PRINT((ndo, " (correct)")); } } } length -= hlen; if (ndo->ndo_vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) { ND_PRINT((ndo, ", seq %u", seq)); if (length > 0) { ND_PRINT((ndo, ":%u", seq + length)); } } if (flags & TH_ACK) { ND_PRINT((ndo, ", ack %u", ack)); } ND_PRINT((ndo, ", win %d", win)); if (flags & TH_URG) ND_PRINT((ndo, ", urg %d", urp)); /* * Handle any options. */ if (hlen > sizeof(*tp)) { register const u_char *cp; register u_int i, opt, datalen; register u_int len; hlen -= sizeof(*tp); cp = (const u_char *)tp + sizeof(*tp); ND_PRINT((ndo, ", options [")); while (hlen > 0) { if (ch != '\0') ND_PRINT((ndo, "%c", ch)); ND_TCHECK(*cp); opt = *cp++; if (ZEROLENOPT(opt)) len = 1; else { ND_TCHECK(*cp); len = *cp++; /* total including type, len */ if (len < 2 || len > hlen) goto bad; --hlen; /* account for length byte */ } --hlen; /* account for type byte */ datalen = 0; /* Bail if "l" bytes of data are not left or were not captured */ #define LENCHECK(l) { if ((l) > hlen) goto bad; ND_TCHECK2(*cp, l); } ND_PRINT((ndo, "%s", tok2str(tcp_option_values, "unknown-%u", opt))); switch (opt) { case TCPOPT_MAXSEG: datalen = 2; LENCHECK(datalen); ND_PRINT((ndo, " %u", EXTRACT_16BITS(cp))); break; case TCPOPT_WSCALE: datalen = 1; LENCHECK(datalen); ND_PRINT((ndo, " %u", *cp)); break; case TCPOPT_SACK: datalen = len - 2; if (datalen % 8 != 0) { ND_PRINT((ndo, "invalid sack")); } else { uint32_t s, e; ND_PRINT((ndo, " %d ", datalen / 8)); for (i = 0; i < datalen; i += 8) { LENCHECK(i + 4); s = EXTRACT_32BITS(cp + i); LENCHECK(i + 8); e = EXTRACT_32BITS(cp + i + 4); if (rev) { s -= thseq; e -= thseq; } else { s -= thack; e -= thack; } ND_PRINT((ndo, "{%u:%u}", s, e)); } } break; case TCPOPT_CC: case TCPOPT_CCNEW: case TCPOPT_CCECHO: case TCPOPT_ECHO: case TCPOPT_ECHOREPLY: /* * those options share their semantics. * fall through */ datalen = 4; LENCHECK(datalen); ND_PRINT((ndo, " %u", EXTRACT_32BITS(cp))); break; case TCPOPT_TIMESTAMP: datalen = 8; LENCHECK(datalen); ND_PRINT((ndo, " val %u ecr %u", EXTRACT_32BITS(cp), EXTRACT_32BITS(cp + 4))); break; case TCPOPT_SIGNATURE: datalen = TCP_SIGLEN; LENCHECK(datalen); #ifdef HAVE_LIBCRYPTO switch (tcp_verify_signature(ndo, ip, tp, bp + TH_OFF(tp) * 4, length, cp)) { case SIGNATURE_VALID: ND_PRINT((ndo, "valid")); break; case SIGNATURE_INVALID: ND_PRINT((ndo, "invalid")); break; case CANT_CHECK_SIGNATURE: ND_PRINT((ndo, "can't check - ")); for (i = 0; i < TCP_SIGLEN; ++i) ND_PRINT((ndo, "%02x", cp[i])); break; } #else for (i = 0; i < TCP_SIGLEN; ++i) ND_PRINT((ndo, "%02x", cp[i])); #endif break; case TCPOPT_AUTH: ND_PRINT((ndo, "keyid %d", *cp++)); datalen = len - 3; for (i = 0; i < datalen; ++i) { LENCHECK(i); ND_PRINT((ndo, "%02x", cp[i])); } break; case TCPOPT_EOL: case TCPOPT_NOP: case TCPOPT_SACKOK: /* * Nothing interesting. * fall through */ break; case TCPOPT_UTO: datalen = 2; LENCHECK(datalen); utoval = EXTRACT_16BITS(cp); ND_PRINT((ndo, "0x%x", utoval)); if (utoval & 0x0001) utoval = (utoval >> 1) * 60; else utoval >>= 1; ND_PRINT((ndo, " %u", utoval)); break; case TCPOPT_MPTCP: datalen = len - 2; LENCHECK(datalen); if (!mptcp_print(ndo, cp-2, len, flags)) goto bad; break; case TCPOPT_FASTOPEN: datalen = len - 2; LENCHECK(datalen); print_tcp_fastopen_option(ndo, cp, datalen, FALSE); break; case TCPOPT_EXPERIMENT2: datalen = len - 2; LENCHECK(datalen); if (datalen < 2) goto bad; /* RFC6994 */ magic = EXTRACT_16BITS(cp); ND_PRINT((ndo, "-")); switch(magic) { case 0xf989: /* TCP Fast Open RFC 7413 */ print_tcp_fastopen_option(ndo, cp + 2, datalen - 2, TRUE); break; default: /* Unknown magic number */ ND_PRINT((ndo, "%04x", magic)); break; } break; default: datalen = len - 2; if (datalen) ND_PRINT((ndo, " 0x")); for (i = 0; i < datalen; ++i) { LENCHECK(i); ND_PRINT((ndo, "%02x", cp[i])); } break; } /* Account for data printed */ cp += datalen; hlen -= datalen; /* Check specification against observed length */ ++datalen; /* option octet */ if (!ZEROLENOPT(opt)) ++datalen; /* size octet */ if (datalen != len) ND_PRINT((ndo, "[len %d]", len)); ch = ','; if (opt == TCPOPT_EOL) break; } ND_PRINT((ndo, "]")); }
void vrrp_print(netdissect_options *ndo, register const u_char *bp, register u_int len, register const u_char *bp2, int ttl) { int version, type, auth_type = VRRP_AUTH_NONE; /* keep compiler happy */ const char *type_s; ND_TCHECK(bp[0]); version = (bp[0] & 0xf0) >> 4; type = bp[0] & 0x0f; type_s = tok2str(type2str, "unknown type (%u)", type); ND_PRINT((ndo, "VRRPv%u, %s", version, type_s)); if (ttl != 255) ND_PRINT((ndo, ", (ttl %u)", ttl)); if (version < 2 || version > 3 || type != VRRP_TYPE_ADVERTISEMENT) return; ND_TCHECK(bp[2]); ND_PRINT((ndo, ", vrid %u, prio %u", bp[1], bp[2])); ND_TCHECK(bp[5]); if (version == 2) { auth_type = bp[4]; ND_PRINT((ndo, ", authtype %s", tok2str(auth2str, NULL, auth_type))); ND_PRINT((ndo, ", intvl %us, length %u", bp[5], len)); } else { /* version == 3 */ uint16_t intvl = (bp[4] & 0x0f) << 8 | bp[5]; ND_PRINT((ndo, ", intvl %ucs, length %u", intvl, len)); } if (ndo->ndo_vflag) { int naddrs = bp[3]; int i; char c; if (version == 2 && ND_TTEST2(bp[0], len)) { struct cksum_vec vec[1]; vec[0].ptr = bp; vec[0].len = len; if (in_cksum(vec, 1)) ND_PRINT((ndo, ", (bad vrrp cksum %x)", EXTRACT_16BITS(&bp[6]))); } if (version == 3 && ND_TTEST2(bp[0], len)) { uint16_t cksum = nextproto4_cksum(ndo, (struct ip *)bp2, bp, len, len, IPPROTO_VRRP); if (cksum) ND_PRINT((ndo, ", (bad vrrp cksum %x)", EXTRACT_16BITS(&bp[6]))); } ND_PRINT((ndo, ", addrs")); if (naddrs > 1) ND_PRINT((ndo, "(%d)", naddrs)); ND_PRINT((ndo, ":")); c = ' '; bp += 8; for (i = 0; i < naddrs; i++) { ND_TCHECK(bp[3]); ND_PRINT((ndo, "%c%s", c, ipaddr_string(ndo, bp))); c = ','; bp += 4; } if (version == 2 && auth_type == VRRP_AUTH_SIMPLE) { /* simple text password */ ND_TCHECK(bp[7]); ND_PRINT((ndo, " auth \"")); if (fn_printn(ndo, bp, 8, ndo->ndo_snapend)) { ND_PRINT((ndo, "\"")); goto trunc; } ND_PRINT((ndo, "\"")); } } return; trunc: ND_PRINT((ndo, "[|vrrp]")); }
/* * Print EAP requests / responses */ void eap_print(netdissect_options *ndo, register const u_char *cp, u_int length _U_) { const struct eap_frame_t *eap; const u_char *tptr; u_int tlen, type, subtype; int count=0, len; tptr = cp; tlen = length; eap = (const struct eap_frame_t *)cp; ND_TCHECK(*eap); /* in non-verbose mode just lets print the basic info */ if (ndo->ndo_vflag < 1) { ND_PRINT((ndo, "%s (%u) v%u, len %u", tok2str(eap_frame_type_values, "unknown", eap->type), eap->type, eap->version, EXTRACT_16BITS(eap->length))); return; } ND_PRINT((ndo, "%s (%u) v%u, len %u", tok2str(eap_frame_type_values, "unknown", eap->type), eap->type, eap->version, EXTRACT_16BITS(eap->length))); tptr += sizeof(const struct eap_frame_t); tlen -= sizeof(const struct eap_frame_t); switch (eap->type) { case EAP_FRAME_TYPE_PACKET: type = *(tptr); len = EXTRACT_16BITS(tptr+2); ND_PRINT((ndo, ", %s (%u), id %u, len %u", tok2str(eap_code_values, "unknown", type), type, *(tptr+1), len)); ND_TCHECK2(*tptr, len); if (type <= 2) { /* For EAP_REQUEST and EAP_RESPONSE only */ subtype = *(tptr+4); ND_PRINT((ndo, "\n\t\t Type %s (%u)", tok2str(eap_type_values, "unknown", *(tptr+4)), *(tptr + 4))); switch (subtype) { case EAP_TYPE_IDENTITY: if (len - 5 > 0) { ND_PRINT((ndo, ", Identity: ")); safeputs(ndo, tptr + 5, len - 5); } break; case EAP_TYPE_NOTIFICATION: if (len - 5 > 0) { ND_PRINT((ndo, ", Notification: ")); safeputs(ndo, tptr + 5, len - 5); } break; case EAP_TYPE_NAK: count = 5; /* * one or more octets indicating * the desired authentication * type one octet per type */ while (count < len) { ND_PRINT((ndo, " %s (%u),", tok2str(eap_type_values, "unknown", *(tptr+count)), *(tptr + count))); count++; } break; case EAP_TYPE_TTLS: ND_PRINT((ndo, " TTLSv%u", EAP_TTLS_VERSION(*(tptr + 5)))); /* fall through */ case EAP_TYPE_TLS: ND_PRINT((ndo, " flags [%s] 0x%02x,", bittok2str(eap_tls_flags_values, "none", *(tptr+5)), *(tptr + 5))); if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) { ND_PRINT((ndo, " len %u", EXTRACT_32BITS(tptr + 6))); } break; case EAP_TYPE_FAST: ND_PRINT((ndo, " FASTv%u", EAP_TTLS_VERSION(*(tptr + 5)))); ND_PRINT((ndo, " flags [%s] 0x%02x,", bittok2str(eap_tls_flags_values, "none", *(tptr+5)), *(tptr + 5))); if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) { ND_PRINT((ndo, " len %u", EXTRACT_32BITS(tptr + 6))); } /* FIXME - TLV attributes follow */ break; case EAP_TYPE_AKA: case EAP_TYPE_SIM: ND_PRINT((ndo, " subtype [%s] 0x%02x,", tok2str(eap_aka_subtype_values, "unknown", *(tptr+5)), *(tptr + 5))); /* FIXME - TLV attributes follow */ break; case EAP_TYPE_MD5_CHALLENGE: case EAP_TYPE_OTP: case EAP_TYPE_GTC: case EAP_TYPE_EXPANDED_TYPES: case EAP_TYPE_EXPERIMENTAL: default: break; } } break; case EAP_FRAME_TYPE_LOGOFF: case EAP_FRAME_TYPE_ENCAP_ASF_ALERT: default: break; } return; trunc: ND_PRINT((ndo, "\n\t[|EAP]")); }
void dvmrp_print(netdissect_options *ndo, register const u_char *bp, register u_int len) { register const u_char *ep; register u_char type; ep = (const u_char *)ndo->ndo_snapend; if (bp >= ep) return; ND_TCHECK(bp[1]); type = bp[1]; /* Skip IGMP header */ bp += 8; len -= 8; switch (type) { case DVMRP_PROBE: ND_PRINT((ndo, " Probe")); if (ndo->ndo_vflag) { if (print_probe(ndo, bp, ep, len) < 0) goto trunc; } break; case DVMRP_REPORT: ND_PRINT((ndo, " Report")); if (ndo->ndo_vflag > 1) { if (print_report(ndo, bp, ep, len) < 0) goto trunc; } break; case DVMRP_ASK_NEIGHBORS: ND_PRINT((ndo, " Ask-neighbors(old)")); break; case DVMRP_NEIGHBORS: ND_PRINT((ndo, " Neighbors(old)")); if (print_neighbors(ndo, bp, ep, len) < 0) goto trunc; break; case DVMRP_ASK_NEIGHBORS2: ND_PRINT((ndo, " Ask-neighbors2")); break; case DVMRP_NEIGHBORS2: ND_PRINT((ndo, " Neighbors2")); /* * extract version and capabilities from IGMP group * address field */ bp -= 4; ND_TCHECK2(bp[0], 4); target_level = (bp[0] << 24) | (bp[1] << 16) | (bp[2] << 8) | bp[3]; bp += 4; if (print_neighbors2(ndo, bp, ep, len) < 0) goto trunc; break; case DVMRP_PRUNE: ND_PRINT((ndo, " Prune")); if (print_prune(ndo, bp) < 0) goto trunc; break; case DVMRP_GRAFT: ND_PRINT((ndo, " Graft")); if (print_graft(ndo, bp) < 0) goto trunc; break; case DVMRP_GRAFT_ACK: ND_PRINT((ndo, " Graft-ACK")); if (print_graft_ack(ndo, bp) < 0) goto trunc; break; default: ND_PRINT((ndo, " [type %d]", type)); break; } return; trunc: ND_PRINT((ndo, "[|dvmrp]")); return; }
void vtp_print (netdissect_options *ndo, const u_char *pptr, u_int length) { int type, len, tlv_len, tlv_value, mgmtd_len; const u_char *tptr; const struct vtp_vlan_ *vtp_vlan; if (length < VTP_HEADER_LEN) goto trunc; tptr = pptr; ND_TCHECK2(*tptr, VTP_HEADER_LEN); type = *(tptr+1); ND_PRINT((ndo, "VTPv%u, Message %s (0x%02x), length %u", *tptr, tok2str(vtp_message_type_values,"Unknown message type", type), type, length)); /* In non-verbose mode, just print version and message type */ if (ndo->ndo_vflag < 1) { return; } /* verbose mode print all fields */ ND_PRINT((ndo, "\n\tDomain name: ")); mgmtd_len = *(tptr + 3); if (mgmtd_len < 1 || mgmtd_len > 32) { ND_PRINT((ndo, " [invalid MgmtD Len %d]", mgmtd_len)); return; } fn_printzp(ndo, tptr + 4, mgmtd_len, NULL); ND_PRINT((ndo, ", %s: %u", tok2str(vtp_header_values, "Unknown", type), *(tptr+2))); tptr += VTP_HEADER_LEN; switch (type) { case VTP_SUMMARY_ADV: /* * SUMMARY ADVERTISEMENT * * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Version | Code | Followers | MgmtD Len | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Management Domain Name (zero-padded to 32 bytes) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Configuration revision number | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Updater Identity IP address | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Update Timestamp (12 bytes) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | MD5 digest (16 bytes) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */ ND_TCHECK2(*tptr, 8); ND_PRINT((ndo, "\n\t Config Rev %x, Updater %s", EXTRACT_32BITS(tptr), ipaddr_string(ndo, tptr+4))); tptr += 8; ND_TCHECK2(*tptr, VTP_UPDATE_TIMESTAMP_LEN); ND_PRINT((ndo, ", Timestamp 0x%08x 0x%08x 0x%08x", EXTRACT_32BITS(tptr), EXTRACT_32BITS(tptr + 4), EXTRACT_32BITS(tptr + 8))); tptr += VTP_UPDATE_TIMESTAMP_LEN; ND_TCHECK2(*tptr, VTP_MD5_DIGEST_LEN); ND_PRINT((ndo, ", MD5 digest: %08x%08x%08x%08x", EXTRACT_32BITS(tptr), EXTRACT_32BITS(tptr + 4), EXTRACT_32BITS(tptr + 8), EXTRACT_32BITS(tptr + 12))); tptr += VTP_MD5_DIGEST_LEN; break; case VTP_SUBSET_ADV: /* * SUBSET ADVERTISEMENT * * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Version | Code | Seq number | MgmtD Len | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Management Domain Name (zero-padded to 32 bytes) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Configuration revision number | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | VLAN info field 1 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | ................ | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | VLAN info field N | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */ ND_TCHECK_32BITS(tptr); ND_PRINT((ndo, ", Config Rev %x", EXTRACT_32BITS(tptr))); /* * VLAN INFORMATION * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | V info len | Status | VLAN type | VLAN name len | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | ISL vlan id | MTU size | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | 802.10 index (SAID) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | VLAN name | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */ tptr += 4; while (tptr < (pptr+length)) { ND_TCHECK_8BITS(tptr); len = *tptr; if (len == 0) break; ND_TCHECK2(*tptr, len); vtp_vlan = (const struct vtp_vlan_*)tptr; if (len < VTP_VLAN_INFO_FIXED_PART_LEN) goto trunc; ND_TCHECK(*vtp_vlan); ND_PRINT((ndo, "\n\tVLAN info status %s, type %s, VLAN-id %u, MTU %u, SAID 0x%08x, Name ", tok2str(vtp_vlan_status,"Unknown",vtp_vlan->status), tok2str(vtp_vlan_type_values,"Unknown",vtp_vlan->type), EXTRACT_16BITS(&vtp_vlan->vlanid), EXTRACT_16BITS(&vtp_vlan->mtu), EXTRACT_32BITS(&vtp_vlan->index))); len -= VTP_VLAN_INFO_FIXED_PART_LEN; tptr += VTP_VLAN_INFO_FIXED_PART_LEN; if (len < 4*((vtp_vlan->name_len + 3)/4)) goto trunc; ND_TCHECK2(*tptr, vtp_vlan->name_len); fn_printzp(ndo, tptr, vtp_vlan->name_len, NULL); /* * Vlan names are aligned to 32-bit boundaries. */ len -= 4*((vtp_vlan->name_len + 3)/4); tptr += 4*((vtp_vlan->name_len + 3)/4); /* TLV information follows */ while (len > 0) { /* * Cisco specs say 2 bytes for type + 2 bytes for length; * see http://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm * However, actual packets on the wire appear to use 1 * byte for the type and 1 byte for the length, so that's * what we do. */ if (len < 2) goto trunc; ND_TCHECK2(*tptr, 2); type = *tptr; tlv_len = *(tptr+1); ND_PRINT((ndo, "\n\t\t%s (0x%04x) TLV", tok2str(vtp_vlan_tlv_values, "Unknown", type), type)); if (len < tlv_len * 2 + 2) { ND_PRINT((ndo, " (TLV goes past the end of the packet)")); return; } ND_TCHECK2(*tptr, tlv_len * 2 +2); /* * We assume the value is a 2-byte integer; the length is * in units of 16-bit words. */ if (tlv_len != 1) { ND_PRINT((ndo, " (invalid TLV length %u != 1)", tlv_len)); return; } else { tlv_value = EXTRACT_16BITS(tptr+2); switch (type) { case VTP_VLAN_STE_HOP_COUNT: ND_PRINT((ndo, ", %u", tlv_value)); break; case VTP_VLAN_PRUNING: ND_PRINT((ndo, ", %s (%u)", tlv_value == 1 ? "Enabled" : "Disabled", tlv_value)); break; case VTP_VLAN_STP_TYPE: ND_PRINT((ndo, ", %s (%u)", tok2str(vtp_stp_type_values, "Unknown", tlv_value), tlv_value)); break; case VTP_VLAN_BRIDGE_TYPE: ND_PRINT((ndo, ", %s (%u)", tlv_value == 1 ? "SRB" : "SRT", tlv_value)); break; case VTP_VLAN_BACKUP_CRF_MODE: ND_PRINT((ndo, ", %s (%u)", tlv_value == 1 ? "Backup" : "Not backup", tlv_value)); break; /* * FIXME those are the defined TLVs that lack a decoder * you are welcome to contribute code ;-) */ case VTP_VLAN_SOURCE_ROUTING_RING_NUMBER: case VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER: case VTP_VLAN_PARENT_VLAN: case VTP_VLAN_TRANS_BRIDGED_VLAN: case VTP_VLAN_ARP_HOP_COUNT: default: print_unknown_data(ndo, tptr, "\n\t\t ", 2 + tlv_len*2); break; } } len -= 2 + tlv_len*2; tptr += 2 + tlv_len*2; } } break; case VTP_ADV_REQUEST: /* * ADVERTISEMENT REQUEST * * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Version | Code | Reserved | MgmtD Len | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Management Domain Name (zero-padded to 32 bytes) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Start value | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */ ND_TCHECK2(*tptr, 4); ND_PRINT((ndo, "\n\tStart value: %u", EXTRACT_32BITS(tptr))); break; case VTP_JOIN_MESSAGE: /* FIXME - Could not find message format */ break; default: break; } return; trunc: ND_PRINT((ndo, "[|vtp]")); }
static void atmarp_print(netdissect_options *ndo, const u_char *bp, u_int length, u_int caplen) { const struct atmarp_pkthdr *ap; u_short pro, hrd, op; ap = (const struct atmarp_pkthdr *)bp; ND_TCHECK(*ap); hrd = ATMHRD(ap); pro = ATMPRO(ap); op = ATMOP(ap); if (!ND_TTEST2(*aar_tpa(ap), ATMTPROTO_LEN(ap))) { ND_PRINT((ndo, "[|ARP]")); ND_DEFAULTPRINT((const u_char *)ap, length); return; } if (!ndo->ndo_eflag) { ND_PRINT((ndo, "ARP, ")); } if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) || ATMSPROTO_LEN(ap) != 4 || ATMTPROTO_LEN(ap) != 4 || ndo->ndo_vflag) { ND_PRINT((ndo, "%s, %s (len %u/%u)", tok2str(arphrd_values, "Unknown Hardware (%u)", hrd), tok2str(ethertype_values, "Unknown Protocol (0x%04x)", pro), ATMSPROTO_LEN(ap), ATMTPROTO_LEN(ap))); /* don't know know about the address formats */ if (!ndo->ndo_vflag) { goto out; } } /* print operation */ printf("%s%s ", ndo->ndo_vflag ? ", " : "", tok2str(arpop_values, "Unknown (%u)", op)); switch (op) { case ARPOP_REQUEST: ND_PRINT((ndo, "who-has %s", ipaddr_string(ATMTPA(ap)))); if (ATMTHRD_LEN(ap) != 0) { ND_PRINT((ndo, " (")); atmarp_addr_print(ndo, ATMTHA(ap), ATMTHRD_LEN(ap), ATMTSA(ap), ATMTSLN(ap)); ND_PRINT((ndo, ")")); } ND_PRINT((ndo, "tell %s", ipaddr_string(ATMSPA(ap)))); break; case ARPOP_REPLY: ND_PRINT((ndo, "%s is-at ", ipaddr_string(ATMSPA(ap)))); atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap), ATMSSLN(ap)); break; case ARPOP_INVREQUEST: ND_PRINT((ndo, "who-is ")); atmarp_addr_print(ndo, ATMTHA(ap), ATMTHRD_LEN(ap), ATMTSA(ap), ATMTSLN(ap)); ND_PRINT((ndo, " tell ")); atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap), ATMSSLN(ap)); break; case ARPOP_INVREPLY: atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap), ATMSSLN(ap)); ND_PRINT((ndo, "at %s", ipaddr_string(ATMSPA(ap)))); break; case ARPOP_NAK: ND_PRINT((ndo, "for %s", ipaddr_string(ATMSPA(ap)))); break; default: ND_DEFAULTPRINT((const u_char *)ap, caplen); return; } out: ND_PRINT((ndo, ", length %u", length)); return; trunc: ND_PRINT((ndo, "[|ARP]")); }
static int pdatacnt_print(netdissect_options *ndo, register const u_char * pptr, register u_int len, u_int16_t IDcnt, u_int16_t op_msk, int indent) { u_int i; u_int32_t id; char *ib = indent_pr(indent, 0); if ((op_msk & B_APPND) && ndo->ndo_vflag >= 3) { ND_PRINT((ndo, "%sTABLE APPEND\n", ib)); } for (i = 0; i < IDcnt; i++) { ND_TCHECK2(*pptr, 4); if (len < 4) goto trunc; id = EXTRACT_32BITS(pptr); if (ndo->ndo_vflag >= 3) ND_PRINT((ndo, "%sID#%02u: %d\n", ib, i + 1, id)); len -= 4; pptr += 4; } if ((op_msk & B_TRNG) || (op_msk & B_KEYIN)) { if (op_msk & B_TRNG) { u_int32_t starti, endi; if (len < PTH_DESC_SIZE) { ND_PRINT((ndo, "pathlength %d with key/range too short %d\n", len, PTH_DESC_SIZE)); return -1; } pptr += sizeof(struct forces_tlv); len -= sizeof(struct forces_tlv); starti = EXTRACT_32BITS(pptr); pptr += 4; len -= 4; endi = EXTRACT_32BITS(pptr); pptr += 4; len -= 4; if (ndo->ndo_vflag >= 3) ND_PRINT((ndo, "%sTable range: [%d,%d]\n", ib, starti, endi)); } if (op_msk & B_KEYIN) { struct forces_tlv *keytlv; u_int16_t tll; if (len < PTH_DESC_SIZE) { ND_PRINT((ndo, "pathlength %d with key/range too short %d\n", len, PTH_DESC_SIZE)); return -1; } /* skip keyid */ pptr += 4; len -= 4; keytlv = (struct forces_tlv *)pptr; /* skip header */ pptr += sizeof(struct forces_tlv); len -= sizeof(struct forces_tlv); /* skip key content */ tll = EXTRACT_16BITS(&keytlv->length); if (tll < TLV_HDRL) { ND_PRINT((ndo, "key content length %u < %u\n", tll, TLV_HDRL)); return -1; } tll -= TLV_HDRL; if (len < tll) { ND_PRINT((ndo, "key content too short\n")); return -1; } pptr += tll; len -= tll; } } if (len) { const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; u_int16_t type; u_int16_t tll; int pad = 0; u_int aln; u_int invtlv; ND_TCHECK(*pdtlv); type = EXTRACT_16BITS(&pdtlv->type); invtlv = tlv_valid(pdtlv, len); if (invtlv) { ND_PRINT((ndo, "%s Outstanding bytes %d for TLV type 0x%x TLV len %d\n", tok2str(ForCES_TLV_err, NULL, invtlv), len, type, EXTRACT_16BITS(&pdtlv->length))); goto pd_err; } /* * At this point, tlv_valid() has ensured that the TLV * length is large enough but not too large (it doesn't * go past the end of the containing TLV). */ tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL; aln = F_ALN_LEN(EXTRACT_16BITS(&pdtlv->length)); if (aln > EXTRACT_16BITS(&pdtlv->length)) { if (aln > len) { ND_PRINT((ndo, "Invalid padded pathdata TLV type 0x%x len %d missing %d pad bytes\n", type, EXTRACT_16BITS(&pdtlv->length), aln - len)); } else { pad = aln - EXTRACT_16BITS(&pdtlv->length); } } if (pd_valid(type)) { const struct pdata_ops *ops = get_forces_pd(type); if (ndo->ndo_vflag >= 3 && ops->v != F_TLV_PDAT) { if (pad) ND_PRINT((ndo, "%s %s (Length %d DataLen %d pad %d Bytes)\n", ib, ops->s, EXTRACT_16BITS(&pdtlv->length), tll, pad)); else ND_PRINT((ndo, "%s %s (Length %d DataLen %d Bytes)\n", ib, ops->s, EXTRACT_16BITS(&pdtlv->length), tll)); } chk_op_type(ndo, type, op_msk, ops->op_msk); if (ops->print(ndo, (const u_char *)pdtlv, tll + pad + TLV_HDRL, op_msk, indent + 2) == -1) return -1; len -= (TLV_HDRL + pad + tll); } else { ND_PRINT((ndo, "Invalid path data content type 0x%x len %d\n", type, EXTRACT_16BITS(&pdtlv->length))); pd_err: if (EXTRACT_16BITS(&pdtlv->length)) { hex_print_with_offset(ndo, "Bad Data val\n\t [", pptr, len, 0); ND_PRINT((ndo, "]\n")); return -1; } } } return len; trunc: ND_PRINT((ndo, "%s", tstr)); return -1; }
/* * Print a single link state advertisement. If truncated return 1, else 0. */ static int ospf6_print_lsa(netdissect_options *ndo, register const struct lsa6 *lsap, const u_char *dataend) { register const struct rlalink6 *rlp; #if 0 register const struct tos_metric *tosp; #endif register const rtrid_t *ap; #if 0 register const struct aslametric *almp; register const struct mcla *mcp; #endif register const struct llsa *llsap; register const struct lsa6_prefix *lsapp; #if 0 register const uint32_t *lp; #endif register u_int prefixes; register int bytelen; register u_int length, lsa_length; uint32_t flags32; const uint8_t *tptr; if (ospf6_print_lshdr(ndo, &lsap->ls_hdr, dataend)) return (1); ND_TCHECK(lsap->ls_hdr.ls_length); length = EXTRACT_16BITS(&lsap->ls_hdr.ls_length); /* * The LSA length includes the length of the header; * it must have a value that's at least that length. * If it does, find the length of what follows the * header. */ if (length < sizeof(struct lsa6_hdr) || (const u_char *)lsap + length > dataend) return (1); lsa_length = length - sizeof(struct lsa6_hdr); tptr = (const uint8_t *)lsap+sizeof(struct lsa6_hdr); switch (EXTRACT_16BITS(&lsap->ls_hdr.ls_type)) { case LS_TYPE_ROUTER | LS_SCOPE_AREA: if (lsa_length < sizeof (lsap->lsa_un.un_rla.rla_options)) return (1); lsa_length -= sizeof (lsap->lsa_un.un_rla.rla_options); ND_TCHECK(lsap->lsa_un.un_rla.rla_options); ND_PRINT((ndo, "\n\t Options [%s]", bittok2str(ospf6_option_values, "none", EXTRACT_32BITS(&lsap->lsa_un.un_rla.rla_options)))); ND_PRINT((ndo, ", RLA-Flags [%s]", bittok2str(ospf6_rla_flag_values, "none", lsap->lsa_un.un_rla.rla_flags))); rlp = lsap->lsa_un.un_rla.rla_link; while (lsa_length != 0) { if (lsa_length < sizeof (*rlp)) return (1); lsa_length -= sizeof (*rlp); ND_TCHECK(*rlp); switch (rlp->link_type) { case RLA_TYPE_VIRTUAL: ND_PRINT((ndo, "\n\t Virtual Link: Neighbor Router-ID %s" "\n\t Neighbor Interface-ID %s, Interface %s", ipaddr_string(ndo, &rlp->link_nrtid), ipaddr_string(ndo, &rlp->link_nifid), ipaddr_string(ndo, &rlp->link_ifid))); break; case RLA_TYPE_ROUTER: ND_PRINT((ndo, "\n\t Neighbor Router-ID %s" "\n\t Neighbor Interface-ID %s, Interface %s", ipaddr_string(ndo, &rlp->link_nrtid), ipaddr_string(ndo, &rlp->link_nifid), ipaddr_string(ndo, &rlp->link_ifid))); break; case RLA_TYPE_TRANSIT: ND_PRINT((ndo, "\n\t Neighbor Network-ID %s" "\n\t Neighbor Interface-ID %s, Interface %s", ipaddr_string(ndo, &rlp->link_nrtid), ipaddr_string(ndo, &rlp->link_nifid), ipaddr_string(ndo, &rlp->link_ifid))); break; default: ND_PRINT((ndo, "\n\t Unknown Router Links Type 0x%02x", rlp->link_type)); return (0); } ND_PRINT((ndo, ", metric %d", EXTRACT_16BITS(&rlp->link_metric))); rlp++; } break; case LS_TYPE_NETWORK | LS_SCOPE_AREA: if (lsa_length < sizeof (lsap->lsa_un.un_nla.nla_options)) return (1); lsa_length -= sizeof (lsap->lsa_un.un_nla.nla_options); ND_TCHECK(lsap->lsa_un.un_nla.nla_options); ND_PRINT((ndo, "\n\t Options [%s]", bittok2str(ospf6_option_values, "none", EXTRACT_32BITS(&lsap->lsa_un.un_nla.nla_options)))); ND_PRINT((ndo, "\n\t Connected Routers:")); ap = lsap->lsa_un.un_nla.nla_router; while (lsa_length != 0) { if (lsa_length < sizeof (*ap)) return (1); lsa_length -= sizeof (*ap); ND_TCHECK(*ap); ND_PRINT((ndo, "\n\t\t%s", ipaddr_string(ndo, ap))); ++ap; } break; case LS_TYPE_INTER_AP | LS_SCOPE_AREA: if (lsa_length < sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric)) return (1); lsa_length -= sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric); ND_TCHECK(lsap->lsa_un.un_inter_ap.inter_ap_metric); ND_PRINT((ndo, ", metric %u", EXTRACT_32BITS(&lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC)); tptr = (const uint8_t *)lsap->lsa_un.un_inter_ap.inter_ap_prefix; while (lsa_length != 0) { bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length); if (bytelen < 0) goto trunc; lsa_length -= bytelen; tptr += bytelen; } break; case LS_TYPE_ASE | LS_SCOPE_AS: if (lsa_length < sizeof (lsap->lsa_un.un_asla.asla_metric)) return (1); lsa_length -= sizeof (lsap->lsa_un.un_asla.asla_metric); ND_TCHECK(lsap->lsa_un.un_asla.asla_metric); flags32 = EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric); ND_PRINT((ndo, "\n\t Flags [%s]", bittok2str(ospf6_asla_flag_values, "none", flags32))); ND_PRINT((ndo, " metric %u", EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric) & ASLA_MASK_METRIC)); tptr = (const uint8_t *)lsap->lsa_un.un_asla.asla_prefix; lsapp = (const struct lsa6_prefix *)tptr; bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length); if (bytelen < 0) goto trunc; lsa_length -= bytelen; tptr += bytelen; if ((flags32 & ASLA_FLAG_FWDADDR) != 0) { const struct in6_addr *fwdaddr6; fwdaddr6 = (const struct in6_addr *)tptr; if (lsa_length < sizeof (*fwdaddr6)) return (1); lsa_length -= sizeof (*fwdaddr6); ND_TCHECK(*fwdaddr6); ND_PRINT((ndo, " forward %s", ip6addr_string(ndo, fwdaddr6))); tptr += sizeof(*fwdaddr6); } if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) { if (lsa_length < sizeof (uint32_t)) return (1); lsa_length -= sizeof (uint32_t); ND_TCHECK(*(const uint32_t *)tptr); ND_PRINT((ndo, " tag %s", ipaddr_string(ndo, (const uint32_t *)tptr))); tptr += sizeof(uint32_t); } if (lsapp->lsa_p_metric) { if (lsa_length < sizeof (uint32_t)) return (1); lsa_length -= sizeof (uint32_t); ND_TCHECK(*(const uint32_t *)tptr); ND_PRINT((ndo, " RefLSID: %s", ipaddr_string(ndo, (const uint32_t *)tptr))); tptr += sizeof(uint32_t); } break; case LS_TYPE_LINK: /* Link LSA */ llsap = &lsap->lsa_un.un_llsa; if (lsa_length < sizeof (llsap->llsa_priandopt)) return (1); lsa_length -= sizeof (llsap->llsa_priandopt); ND_TCHECK(llsap->llsa_priandopt); ND_PRINT((ndo, "\n\t Options [%s]", bittok2str(ospf6_option_values, "none", EXTRACT_32BITS(&llsap->llsa_options)))); if (lsa_length < sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix)) return (1); lsa_length -= sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix); prefixes = EXTRACT_32BITS(&llsap->llsa_nprefix); ND_PRINT((ndo, "\n\t Priority %d, Link-local address %s, Prefixes %d:", llsap->llsa_priority, ip6addr_string(ndo, &llsap->llsa_lladdr), prefixes)); tptr = (const uint8_t *)llsap->llsa_prefix; while (prefixes > 0) { bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length); if (bytelen < 0) goto trunc; prefixes--; lsa_length -= bytelen; tptr += bytelen; } break; case LS_TYPE_INTRA_AP | LS_SCOPE_AREA: /* Intra-Area-Prefix LSA */ if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid)) return (1); lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid); ND_TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_rtid); ospf6_print_ls_type(ndo, EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_lstype), &lsap->lsa_un.un_intra_ap.intra_ap_lsid); if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix)) return (1); lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix); ND_TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_nprefix); prefixes = EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_nprefix); ND_PRINT((ndo, "\n\t Prefixes %d:", prefixes)); tptr = (const uint8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix; while (prefixes > 0) { bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length); if (bytelen < 0) goto trunc; prefixes--; lsa_length -= bytelen; tptr += bytelen; } break; case LS_TYPE_GRACE | LS_SCOPE_LINKLOCAL: if (ospf_print_grace_lsa(ndo, tptr, lsa_length) == -1) { return 1; } break; case LS_TYPE_INTRA_ATE | LS_SCOPE_LINKLOCAL: if (ospf_print_te_lsa(ndo, tptr, lsa_length) == -1) { return 1; } break; default: if(!print_unknown_data(ndo,tptr, "\n\t ", lsa_length)) { return (1); } break; } return (0); trunc: return (1); }
static int pdata_print(netdissect_options *ndo, register const u_char * pptr, register u_int len, u_int16_t op_msk, int indent) { const struct pathdata_h *pdh = (struct pathdata_h *)pptr; char *ib = indent_pr(indent, 0); u_int minsize = 0; int more_pd = 0; u_int16_t idcnt = 0; ND_TCHECK(*pdh); if (len < sizeof(struct pathdata_h)) goto trunc; if (ndo->ndo_vflag >= 3) { ND_PRINT((ndo, "\n%sPathdata: Flags 0x%x ID count %d\n", ib, EXTRACT_16BITS(&pdh->pflags), EXTRACT_16BITS(&pdh->pIDcnt))); } if (EXTRACT_16BITS(&pdh->pflags) & F_SELKEY) { op_msk |= B_KEYIN; } /* Table GET Range operation */ if (EXTRACT_16BITS(&pdh->pflags) & F_SELTABRANGE) { op_msk |= B_TRNG; } /* Table SET append operation */ if (EXTRACT_16BITS(&pdh->pflags) & F_TABAPPEND) { op_msk |= B_APPND; } pptr += sizeof(struct pathdata_h); len -= sizeof(struct pathdata_h); idcnt = EXTRACT_16BITS(&pdh->pIDcnt); minsize = idcnt * 4; if (len < minsize) { ND_PRINT((ndo, "\t\t\ttruncated IDs expected %uB got %uB\n", minsize, len)); hex_print_with_offset(ndo, "\t\t\tID Data[", pptr, len, 0); ND_PRINT((ndo, "]\n")); return -1; } if ((op_msk & B_TRNG) && (op_msk & B_KEYIN)) { ND_PRINT((ndo, "\t\t\tIllegal to have both Table ranges and keys\n")); return -1; } more_pd = pdatacnt_print(ndo, pptr, len, idcnt, op_msk, indent); if (more_pd > 0) { int consumed = len - more_pd; pptr += consumed; len = more_pd; /* XXX: Argh, recurse some more */ return recpdoptlv_print(ndo, pptr, len, op_msk, indent+1); } else return 0; trunc: ND_PRINT((ndo, "%s", tstr)); return -1; }
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); }
/* Standard PPP printer */ u_int ppp_print(netdissect_options *ndo, register const u_char *p, u_int length) { u_int proto,ppp_header; u_int olen = length; /* _o_riginal length */ u_int hdr_len = 0; /* * Here, we assume that p points to the Address and Control * field (if they present). */ if (length < 2) goto trunc; ND_TCHECK2(*p, 2); ppp_header = EXTRACT_16BITS(p); switch(ppp_header) { case (PPP_WITHDIRECTION_IN << 8 | PPP_CONTROL): if (ndo->ndo_eflag) ND_PRINT((ndo, "In ")); p += 2; length -= 2; hdr_len += 2; break; case (PPP_WITHDIRECTION_OUT << 8 | PPP_CONTROL): if (ndo->ndo_eflag) ND_PRINT((ndo, "Out ")); p += 2; length -= 2; hdr_len += 2; break; case (PPP_ADDRESS << 8 | PPP_CONTROL): p += 2; /* ACFC not used */ length -= 2; hdr_len += 2; break; default: break; } if (length < 2) goto trunc; ND_TCHECK(*p); if (*p % 2) { proto = *p; /* PFC is used */ p++; length--; hdr_len++; } else { ND_TCHECK2(*p, 2); proto = EXTRACT_16BITS(p); p += 2; length -= 2; hdr_len += 2; } if (ndo->ndo_eflag) ND_PRINT((ndo, "%s (0x%04x), length %u: ", tok2str(ppptype2str, "unknown", proto), proto, olen)); handle_ppp(ndo, proto, p, length); return (hdr_len); trunc: ND_PRINT((ndo, "[|ppp]")); return (0); }