void interpret_icmp_mip_ext(uchar_t *p, int len) { show_space(); show_header("ICMP: ", " MIP Advertisement Extensions ", len); show_space(); interpret_extensions(p, len, ADV); }
int interpret_pppoe(int flags, poep_t *poep, int len) { uint8_t code = poep->poep_code; uint8_t *payload; if (len < sizeof (poep_t)) return (len); payload = (uint8_t *)poep + sizeof (poep_t); if (flags & F_SUM) { (void) sprintf(get_sum_line(), "PPPoE %s", pppoe_codetoname(code, B_FALSE)); } else { /* flags & F_DTAIL */ show_header("PPPoE: ", "PPP Over Ethernet", len); show_space(); (void) sprintf(get_line(0, 0), "Version = %d", POE_VERS(poep->poep_version_type)); (void) sprintf(get_line(0, 0), "Type = %d", POE_TYPE(poep->poep_version_type)); (void) sprintf(get_line(0, 0), "Code = %d (%s)", code, pppoe_codetoname(code, B_TRUE)); (void) sprintf(get_line(0, 0), "Session Id = %d", ntohs(poep->poep_session_id)); (void) sprintf(get_line(0, 0), "Length = %d bytes", ntohs(poep->poep_length)); show_space(); len -= sizeof (poep_t); len = MIN(len, ntohs(poep->poep_length)); if (poep->poep_code != 0 && poep->poep_length > 0) { interpret_tags(payload, len); } } if (poep->poep_code == 0) { return (interpret_ppp(flags, payload, len)); } return (len); }
void MainWindow::show_tree(){ //expose all tree delete ui->treeWidget->takeTopLevelItem(0); show_space(); if(getRoot() == NULL) //if tree doesn`t exist { return; } QTreeWidgetItem * root_item = new QTreeWidgetItem(ui->treeWidget); //create item for expose tree space * wp = (space*)getRoot(); root_item->setText(0,wp->name); star** star_array = (star**)wp->sublvl; int star_count = wp->sublvl_count; if(star_count == 0 || star_array == NULL) { return; } for(int i_star = 0;i_star < star_count;i_star++) { star * p_star = star_array[i_star]; //expose star QTreeWidgetItem *s_item = new QTreeWidgetItem(root_item); s_item->setText(0,p_star->name); planet ** planet_array = (planet**)p_star->sublvl; int planet_count = p_star->sublvl_count; if(planet_array == NULL || planet_count == 0) { continue; } for(int i_planet = 0;i_planet < planet_count;i_planet++) { planet * p_planet = planet_array[i_planet]; //expose planet QTreeWidgetItem * p_item = new QTreeWidgetItem(s_item); p_item->setText(0,p_planet->name); satellite ** satellite_array = (satellite**)p_planet->sublvl; int satellite_count = p_planet->sublvl_count; if(satellite_array == NULL || satellite_count == 0) { continue; } for(int i_sat = 0; i_sat < satellite_count;i_sat++) { satellite * p_sat = satellite_array[i_sat]; //expose satellite QTreeWidgetItem *sat_item = new QTreeWidgetItem(p_item); sat_item->setText(0,p_sat->name); } } }ui->treeWidget->expandAll(); }
void MainWindow::on_treeWidget_clicked(const QModelIndex &index) { setButtonState(false,false); int lvl = selected_lvl(); space * wp = (space*)getRoot(); if(lvl == 0){ show_space(); }else if(lvl == 1){ int index_s = selected_index(0); star * p_star = (star*)wp->sublvl[index_s]; show_star(p_star); }else if(lvl == 2){ int index_s = selected_index(1); star * p_star = (star*)wp->sublvl[index_s]; int index_p = selected_index(0); planet * p_planet = (planet*)p_star->sublvl[index_p]; show_planet(p_planet); }else if(lvl == 3){ int index_s = selected_index(2); star * p_star = (star*)wp->sublvl[index_s]; int index_p = selected_index(1); planet * p_planet = (planet*)p_star->sublvl[index_p]; int index_sat = selected_index(0); satellite * p_sat = (satellite*)p_planet->sublvl[index_sat]; show_satellite(p_sat); } }
/* * interpret_tags() prints PPPoE Discovery Stage TAGs in detail. */ static void interpret_tags(uint8_t *payload, uint16_t length) { uint8_t *tagptr = payload; uint16_t tag_length; uint16_t tag_type; uint8_t *tag_value; taginfo_t *tinfo; while (length >= POET_HDRLEN) { tag_type = POET_GET_TYPE(tagptr); tag_length = POET_GET_LENG(tagptr); tinfo = pppoe_gettaginfo(tag_type); show_header("PPPoE: ", tinfo->tag_name, tag_length + POET_HDRLEN); (void) sprintf(get_line(0, 0), "Tag Type = %d", tag_type); (void) sprintf(get_line(0, 0), "Tag Length = %d bytes", tag_length); length -= POET_HDRLEN; if (tag_length > length) { (void) sprintf(get_line(0, 0), "Warning: Truncated Packet"); show_space(); break; } /* * unknown tags or tags which should always have 0 length * are not interpreted any further. */ tag_value = POET_DATA(tagptr); if (tag_length != 0 && tinfo->interpret_tagvalue != NULL) tinfo->interpret_tagvalue(tag_value, tag_length); show_space(); length -= tag_length; tagptr = POET_NEXT(tagptr); } }
/* ARGSUSED */ int interpret_esp(int flags, uint8_t *hdr, int iplen, int fraglen) { /* LINTED: alignment */ esph_t *esph = (esph_t *)hdr; esph_t *aligned_esph; esph_t storage; /* In case hdr isn't aligned. */ char *line; if (fraglen < sizeof (esph_t)) return (fraglen); /* incomplete header */ if (!IS_P2ALIGNED(hdr, 4)) { aligned_esph = &storage; bcopy(hdr, aligned_esph, sizeof (esph_t)); } else { aligned_esph = esph; } if (flags & F_SUM) { line = (char *)get_sum_line(); /* * sprintf() is safe because line guarantees us 80 columns, * and SPI and replay certainly won't exceed that. */ (void) sprintf(line, "ESP SPI=0x%x Replay=%u", ntohl(aligned_esph->esph_spi), ntohl(aligned_esph->esph_replay)); line += strlen(line); } if (flags & F_DTAIL) { show_header("ESP: ", "Encapsulating Security Payload", sizeof (esph_t)); show_space(); /* * sprintf() is safe because get_line guarantees us 80 columns, * and SPI and replay certainly won't exceed that. */ (void) sprintf(get_line((char *)&esph->esph_spi - dlc_header, 4), "SPI = 0x%x", ntohl(aligned_esph->esph_spi)); (void) sprintf(get_line((char *)&esph->esph_replay - dlc_header, 4), "Replay = %u", ntohl(aligned_esph->esph_replay)); (void) sprintf(get_line((char *)(esph + 1) - dlc_header, 4), " ....ENCRYPTED DATA...."); } return (sizeof (esph_t)); }
void interpret_nbp(int flags, struct nbp_hdr *nbp, int len) { uint8_t *data; int nbp_cnt = nbp->nbp_fun_cnt & 0xf; /* lower four bits */ int nbp_op = (nbp->nbp_fun_cnt >> 4) & 0xf; /* upper four bits */ data = (uint8_t *)(nbp + 1); if (flags & F_SUM) { if (len < sizeof (struct nbp_hdr)) { (void) snprintf(get_sum_line(), MAXLINE, "NBP (short packet)"); return; } (void) snprintf(get_sum_line(), MAXLINE, "NBP F=%s CNT=%d ID=%d", nbp_short[nbp_op], nbp_cnt, nbp->nbp_id); } if (flags & F_DTAIL) { show_header("NBP: ", "NBP Header", len); show_space(); if (len < sizeof (struct nbp_hdr)) { (void) snprintf(get_line(0, 0), get_line_remain(), "NBP (short packet)"); return; } (void) snprintf(get_line(0, 0), get_line_remain(), "Length = %d", len); (void) snprintf(get_line(0, 0), get_line_remain(), "Func = %d (%s)", nbp_op, nbp_short[nbp_op]); (void) snprintf(get_line(0, 0), get_line_remain(), "Tuple count = %d", nbp_cnt); (void) snprintf(get_line(0, 0), get_line_remain(), "Id = %d", nbp->nbp_id); show_nbp_tuples(data, nbp_cnt, ((uint8_t *)nbp) + len); } }
void interpret_aecho(int flags, struct ddp_hdr *ddp, int len) { char *data; data = (char *)ddp + DDPHDR_SIZE; if (flags & F_SUM) { if (len < DDPHDR_SIZE + 1) { (void) snprintf(get_sum_line(), MAXLINE, "AECHO (short packet)"); return; } (void) snprintf(get_sum_line(), MAXLINE, "AECHO F=%s LEN=%d", *data == AEP_REQ ? "Request" : "Reply", len); } if (flags & F_DTAIL) { if (len < DDPHDR_SIZE + 1) { (void) snprintf(get_line(0, 0), get_line_remain(), "AECHO (short packet)"); return; } show_header("AECHO: ", "AECHO Header", len); show_space(); (void) snprintf(get_line(0, 0), get_line_remain(), "Func = %d (%s)", data[0], data[0] == AEP_REQ ? "Request" : "Reply"); (void) snprintf(get_line(0, 0), get_line_remain(), "Length = %d", len); } }
uint_t interpret_ether(int flags, char *header, int elen, int origlen) { struct ether_header *e = (struct ether_header *)header; uchar_t *off, *ieeestart; int len; int ieee8023 = 0; extern char *dst_name; int ethertype; struct ether_vlan_extinfo *evx = NULL; int blen = MAX(origlen, ETHERMTU); boolean_t trillpkt = B_FALSE; uint16_t tci = 0; if (data != NULL && datalen != 0 && datalen < blen) { free(data); data = NULL; datalen = 0; } if (!data) { data = (char *)malloc(blen); if (!data) pr_err("Warning: malloc failure"); datalen = blen; } inner_pkt: if (origlen < 14) { if (flags & F_SUM) { (void) sprintf(get_sum_line(), "RUNT (short packet - %d bytes)", origlen); } if (flags & F_DTAIL) show_header("RUNT: ", "Short packet", origlen); return (elen); } if (elen < 14) return (elen); if (memcmp(&e->ether_dhost, ðer_broadcast, sizeof (struct ether_addr)) == 0) dst_name = "(broadcast)"; else if (e->ether_dhost.ether_addr_octet[0] & 1) dst_name = "(multicast)"; ethertype = ntohs(e->ether_type); /* * The 14 byte ether header screws up alignment * of the rest of the packet for 32 bit aligned * architectures like SPARC. Alas, we have to copy * the rest of the packet in order to align it. */ len = elen - sizeof (struct ether_header); off = (uchar_t *)(e + 1); if (ethertype == ETHERTYPE_VLAN) { if (origlen < sizeof (struct ether_vlan_header)) { if (flags & F_SUM) { (void) sprintf(get_sum_line(), "RUNT (short VLAN packet - %d bytes)", origlen); } if (flags & F_DTAIL) { show_header("RUNT: ", "Short VLAN packet", origlen); } return (elen); } if (len < sizeof (struct ether_vlan_extinfo)) return (elen); evx = (struct ether_vlan_extinfo *)off; off += sizeof (struct ether_vlan_extinfo); len -= sizeof (struct ether_vlan_extinfo); ethertype = ntohs(evx->ether_type); tci = ntohs(evx->ether_tci); } if (ethertype <= 1514) { /* * Fake out the IEEE 802.3 packets. * Should be DSAP=0xAA, SSAP=0xAA, control=0x03 * then three padding bytes of zero (OUI), * followed by a normal ethernet-type packet. */ ieee8023 = ethertype; ieeestart = off; if (off[0] == 0xAA && off[1] == 0xAA) { ethertype = ntohs(*(ushort_t *)(off + 6)); off += 8; len -= 8; } else { ethertype = 0; off += 3; len -= 3; } } if (flags & F_SUM) { /* * Set the flag that says don't display VLAN information. * If it needs to change, that will be done later if the * packet is VLAN tagged and if snoop is in its default * summary mode. */ set_vlan_id(0); if (evx == NULL) { if (ethertype == 0 && ieee8023 > 0) { (void) sprintf(get_sum_line(), "ETHER 802.3 SSAP %02X DSAP %02X, " "size=%d bytes", ieeestart[0], ieeestart[1], origlen); } else { (void) sprintf(get_sum_line(), "ETHER Type=%04X (%s), size=%d bytes", ethertype, print_ethertype(ethertype), origlen); } } else { if (ethertype == 0 && ieee8023 > 0) { (void) sprintf(get_sum_line(), "ETHER 802.3 SSAP %02X DSAP %02X, " "VLAN ID=%hu, size=%d bytes", ieeestart[0], ieeestart[1], VLAN_ID(tci), origlen); } else { (void) sprintf(get_sum_line(), "ETHER Type=%04X (%s), VLAN ID=%hu, " "size=%d bytes", ethertype, print_ethertype(ethertype), VLAN_ID(tci), origlen); } if (!(flags & F_ALLSUM)) set_vlan_id(VLAN_ID(tci)); } } if (flags & F_DTAIL) { show_header("ETHER: ", "Ether Header", elen); show_space(); if (!trillpkt) { (void) sprintf(get_line(0, 0), "Packet %d arrived at %d:%02d:%d.%05d", pi_frame, pi_time_hour, pi_time_min, pi_time_sec, pi_time_usec / 10); (void) sprintf(get_line(0, 0), "Packet size = %d bytes", elen, elen); } (void) sprintf(get_line(0, 6), "Destination = %s, %s", printether(&e->ether_dhost), print_etherinfo(&e->ether_dhost)); (void) sprintf(get_line(6, 6), "Source = %s, %s", printether(&e->ether_shost), print_etherinfo(&e->ether_shost)); if (evx != NULL) { (void) sprintf(get_line(0, 0), "VLAN ID = %hu", VLAN_ID(tci)); (void) sprintf(get_line(0, 0), "VLAN Priority = %hu", VLAN_PRI(tci)); } if (ieee8023 > 0) { (void) sprintf(get_line(12, 2), "IEEE 802.3 length = %d bytes", ieee8023); /* Print LLC only for non-TCP/IP packets */ if (ethertype == 0) { (void) snprintf(get_line(0, 0), get_line_remain(), "SSAP = %02X, DSAP = %02X, CTRL = %02X", ieeestart[0], ieeestart[1], ieeestart[2]); } } if (ethertype != 0 || ieee8023 == 0) (void) sprintf(get_line(12, 2), "Ethertype = %04X (%s)", ethertype, print_ethertype(ethertype)); show_space(); } /* * We cannot trust the length field in the header to be correct. * But we should continue to process the packet. Then user can * notice something funny in the header. * Go to the next protocol layer only if data have been * copied. */ if (len > 0 && (off + len <= (uchar_t *)e + elen)) { (void) memmove(data, off, len); if (!trillpkt && ethertype == ETHERTYPE_TRILL) { ethertype = interpret_trill(flags, &e, data, &len); /* Decode inner Ethernet frame */ if (ethertype != 0) { evx = NULL; trillpkt = B_TRUE; (void) memmove(data, e, len); e = (struct ether_header *)data; origlen = len; elen = len; goto inner_pkt; } } switch (ethertype) { case ETHERTYPE_IP: (void) interpret_ip(flags, (struct ip *)data, len); break; /* Just in case it is decided to add this type */ case ETHERTYPE_IPV6: (void) interpret_ipv6(flags, (ip6_t *)data, len); break; case ETHERTYPE_ARP: case ETHERTYPE_REVARP: interpret_arp(flags, (struct arphdr *)data, len); break; case ETHERTYPE_PPPOED: case ETHERTYPE_PPPOES: (void) interpret_pppoe(flags, (poep_t *)data, len); break; case ETHERTYPE_AARP: /* AppleTalk */ interpret_aarp(flags, data, len); break; case ETHERTYPE_AT: interpret_at(flags, (struct ddp_hdr *)data, len); break; case 0: if (ieee8023 == 0) break; switch (ieeestart[0]) { case 0xFE: interpret_isis(flags, data, len, memcmp(&e->ether_dhost, &all_isis_rbridges, sizeof (struct ether_addr)) == 0); break; case 0x42: interpret_bpdu(flags, data, len); break; } break; } } return (elen); }
uint_t interpret_fddi(int flags, caddr_t e, int elen, int origlen) { struct fddi_header fhdr, *f = &fhdr; char *off; int len; boolean_t data_copied = B_FALSE; extern char *dst_name, *src_name; int ethertype; int is_llc = 0, is_smt = 0, is_snap = 0; int blen = MAX(origlen, 4500); if (data != NULL && datalen != 0 && datalen < blen) { free(data); data = NULL; datalen = 0; } if (!data) { data = (char *)malloc(blen); if (!data) pr_err("Warning: malloc failure"); datalen = blen; } if (origlen < 13) { if (flags & F_SUM) { (void) sprintf(get_sum_line(), "RUNT (short packet - %d bytes)", origlen); } if (flags & F_DTAIL) show_header("RUNT: ", "Short packet", origlen); return (elen); } if (elen < 13) return (elen); (void) memcpy(&f->fc, e, sizeof (f->fc)); addr_copy_swap(&f->dhost, (struct ether_addr *)(e+1)); addr_copy_swap(&f->shost, (struct ether_addr *)(e+7)); if ((f->fc&0x50) == 0x50) { is_llc = 1; (void) memcpy(&f->dsap, e+13, sizeof (f->dsap)); (void) memcpy(&f->ssap, e+14, sizeof (f->ssap)); (void) memcpy(&f->ctl, e+15, sizeof (f->ctl)); if (f->dsap == 0xaa && f->ssap == 0xaa) { is_snap = 1; (void) memcpy(&f->proto_id, e+16, sizeof (f->proto_id)); (void) memcpy(&f->type, e+19, sizeof (f->type)); } } else { if ((f->fc&0x41) == 0x41 || (f->fc&0x4f) == 0x4f) { is_smt = 1; } } if (memcmp(&f->dhost, ðer_broadcast, sizeof (struct ether_addr)) == 0) dst_name = "(broadcast)"; else if (f->dhost.ether_addr_octet[0] & 0x01) dst_name = "(multicast)"; if (is_snap) ethertype = ntohs(f->type); else { src_name = print_etherinfo(&f->shost); dst_name = print_etherinfo(&f->dhost); } /* * The 14 byte ether header screws up alignment * of the rest of the packet for 32 bit aligned * architectures like SPARC. Alas, we have to copy * the rest of the packet in order to align it. */ if (is_llc) { if (is_snap) { len = elen - 21; off = (char *)(e + 21); } else { len = elen - 16; off = (char *)(e + 16); } } else { len = elen - 13; off = (char *)(e + 13); } if (len > 0 && (off + len <= (char *)e + elen)) { (void) memcpy(data, off, len); data_copied = B_TRUE; } if (flags & F_SUM) { if (is_llc) { if (is_snap) { (void) sprintf(get_sum_line(), "FDDI LLC Type=%04X (%s), size = %d bytes", ethertype, print_ethertype(ethertype), origlen); } else { (void) sprintf(get_sum_line(), "LLC, but no " "SNAP encoding, size = %d bytes", origlen); } } else if (is_smt) { (void) sprintf(get_sum_line(), "SMT Type=%02X (%s), " "Class = %02X (%s), size = %d bytes", *(uchar_t *)(data+1), print_smttype(*(data+1)), *data, print_smtclass(*data), origlen); } else { (void) sprintf(get_sum_line(), "FC=%02X (%s), size = %d bytes", f->fc, print_fc(f->fc), origlen); } } if (flags & F_DTAIL) { show_header("FDDI: ", "FDDI Header", elen); show_space(); (void) sprintf(get_line(0, 0), "Packet %d arrived at %d:%02d:%d.%05d", pi_frame, pi_time_hour, pi_time_min, pi_time_sec, pi_time_usec / 10); (void) sprintf(get_line(0, 0), "Packet size = %d bytes", elen, elen); (void) sprintf(get_line(0, 6), "Destination = %s, %s", printether(&f->dhost), print_etherinfo(&f->dhost)); (void) sprintf(get_line(6, 6), "Source = %s, %s", printether(&f->shost), print_etherinfo(&f->shost)); if (is_llc) { (void) sprintf(get_line(12, 2), "Frame Control = %02x (%s)", f->fc, print_fc(f->fc)); (void) sprintf(get_line(12, 2), "Dest Service Access Point = %02x", f->dsap); (void) sprintf(get_line(12, 2), "Source Service Access Point = %02x", f->ssap); (void) sprintf(get_line(12, 2), "Control = %02x", f->ctl); if (is_snap) { (void) sprintf(get_line(12, 2), "Protocol Id = %02x%02x%02x", f->proto_id[0], f->proto_id[1], f->proto_id[2]); } } else if (is_smt) { (void) sprintf(get_line(12, 2), "Frame Control = %02x (%s)", f->fc, print_fc(f->fc)); (void) sprintf(get_line(12, 2), "Class = %02x (%s)", (uchar_t)*data, print_smtclass(*data)); (void) sprintf(get_line(12, 2), "Type = %02x (%s)", *(uchar_t *)(data+1), print_smttype(*(data+1))); } else { (void) sprintf(get_line(12, 2), "FC=%02X (%s), size = %d bytes", f->fc, print_fc(f->fc), origlen); } if (is_snap) { (void) sprintf(get_line(12, 2), "LLC Type = %04X (%s)", ethertype, print_ethertype(ethertype)); } show_space(); } /* go to the next protocol layer */ if (is_llc && is_snap && f->ctl == 0x03 && data_copied) { switch (ethertype) { case ETHERTYPE_IP: (void) interpret_ip(flags, (struct ip *)data, len); break; /* Just in case it is decided to add this type */ case ETHERTYPE_IPV6: (void) interpret_ipv6(flags, (ip6_t *)data, len); break; case ETHERTYPE_ARP: case ETHERTYPE_REVARP: interpret_arp(flags, (struct arphdr *)data, len); break; default: break; } } return (elen); }
int interpret_rip6(int flags, struct rip6 *rip6, int fraglen) { char *p; struct netinfo6 *n; int len, count; struct in6_addr *dst; int notdefault = 0; char dststr[INET6_ADDRSTRLEN]; if (flags & F_SUM) { switch (rip6->rip6_cmd) { case RIPCMD6_REQUEST: p = "C"; break; case RIPCMD6_RESPONSE: p = "R"; break; default: p = "?"; break; } switch (rip6->rip6_cmd) { case RIPCMD6_REQUEST: case RIPCMD6_RESPONSE: len = fraglen - 4; count = 0; for (n = rip6->rip6_nets; len >= sizeof (struct netinfo6); n++) { count++; len -= sizeof (struct netinfo6); } (void) sprintf(get_sum_line(), "RIPng %s (%d destinations)", p, count); break; default: (void) sprintf(get_sum_line(), "RIPng %s", p); break; } } if (flags & F_DTAIL) { show_header("RIPng: ", "Routing Information Protocol for IPv6", fraglen); show_space(); (void) sprintf(get_line((char *)(uintptr_t)rip6->rip6_cmd - dlc_header, 1), "Opcode = %d (%s)", rip6->rip6_cmd, show_cmd6(rip6->rip6_cmd)); (void) sprintf(get_line((char *)(uintptr_t)rip6->rip6_vers - dlc_header, 1), "Version = %d", rip6->rip6_vers); switch (rip6->rip6_cmd) { case RIPCMD6_REQUEST: case RIPCMD6_RESPONSE: show_space(); (void) sprintf(get_line(0, 0), "Address" " Prefix Metric"); len = fraglen - 4; for (n = rip6->rip6_nets; len >= sizeof (struct netinfo6); n++) { if (rip6->rip6_vers > 0) { n->rip6_metric = n->rip6_metric; } dst = &n->rip6_prefix; notdefault = bcmp((caddr_t *)dst, (caddr_t *)&all_zeroes_addr, sizeof (*dst)); (void) inet_ntop(AF_INET6, (char *)dst, dststr, INET6_ADDRSTRLEN); (void) sprintf(get_line((char *)n - dlc_header, sizeof (struct netinfo6)), "%-30s %-10d %-5d %s", notdefault ? dststr : " (default)", n->rip6_prefix_length, n->rip6_metric, n->rip6_metric == 16 ? " (not reachable)":""); len -= sizeof (struct netinfo); } break; } } return (fraglen); }
/*ARGSUSED*/ void interpret_igmp(int flags, char *data, int iplen, int ilen) { const char *pt; char *line; struct igmp *igmp = (struct igmp *)data; char addrstr[INET_ADDRSTRLEN]; if (ilen < IGMP_MINLEN) { /* incomplete header */ line = get_sum_line(); (void) snprintf(line, MAXLINE, "Malformed IGMP packet"); return; } switch (igmp->igmp_type) { case IGMP_MEMBERSHIP_QUERY: if (ilen == IGMP_MINLEN) { if (igmp->igmp_code == 0) pt = "v1 membership query"; else pt = "v2 membership query"; } else if (ilen >= IGMP_V3_QUERY_MINLEN) { pt = "v3 membership query"; } else { pt = "Unknown membership query"; } break; case IGMP_V1_MEMBERSHIP_REPORT: pt = "v1 membership report"; break; case IGMP_V2_MEMBERSHIP_REPORT: pt = "v2 membership report"; break; case IGMP_V3_MEMBERSHIP_REPORT: pt = "v3 membership report"; break; case IGMP_V2_LEAVE_GROUP: pt = "v2 leave group"; break; default: pt = "Unknown"; break; } if (flags & F_SUM) { line = get_sum_line(); (void) snprintf(line, MAXLINE, "IGMP %s", pt); } if (flags & F_DTAIL) { show_header("IGMP: ", "IGMP Header", ilen); show_space(); (void) snprintf(get_line(0, 0), get_line_remain(), "Type = %d (%s)", igmp->igmp_type, pt); (void) snprintf(get_line(0, 0), get_line_remain(), "Max Response Time = %d", igmp->igmp_code); (void) snprintf(get_line(0, 0), get_line_remain(), "Checksum = %x", ntohs(igmp->igmp_cksum)); if (igmp->igmp_type == IGMP_MEMBERSHIP_QUERY && ilen >= IGMP_V3_QUERY_MINLEN) { interpret_igmpv3qry(igmp, ilen); } else if (igmp->igmp_type == IGMP_V3_MEMBERSHIP_REPORT) { interpret_igmpv3rpt(igmp, ilen); } else { (void) snprintf(get_line(0, 0), get_line_remain(), "Group = %s", inet_ntop(AF_INET, &igmp->igmp_group.s_addr, addrstr, INET_ADDRSTRLEN)); } show_space(); } }
void interpret_mip_cntrlmsg(int flags, uchar_t *msg, int fraglen) { char *pt, *pc = NULL; char *line; regreq_t rreq[1]; regrep_t rrep[1]; int regext_size; uchar_t *regext_data; struct in_addr addr_temp; /* First byte of the message should be the type */ switch (*msg) { case REG_TYPE_REQ: if (fraglen < sizeof (regreq_t)) return; pt = (flags & F_DTAIL ? "registration request ":"reg rqst "); (void) memcpy(rreq, msg, sizeof (*rreq)); regext_size = fraglen - sizeof (regreq_t); regext_data = msg + sizeof (*rreq); break; case REG_TYPE_REP: if (fraglen < sizeof (regrep_t)) return; pt = (flags & F_DTAIL ? "registration reply ":"reg reply "); (void) memcpy(rrep, msg, sizeof (*rrep)); regext_size = fraglen - sizeof (regrep_t); regext_data = msg + sizeof (*rrep); switch (rrep->code) { case REPLY_CODE_ACK: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL)) ? "OK" : "OK code 0"; break; case REPLY_CODE_ACK_NO_SIMULTANEOUS: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "OK simultaneous bindings" : "OK code 1"; break; case REPLY_CODE_FA_NACK_UNSPECIFIED: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: unspecified":"FA denial: code 64"; break; case REPLY_CODE_FA_NACK_PROHIBITED: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: prohibited":"FA denial: code 65"; break; case REPLY_CODE_FA_NACK_RESOURCES: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: no resources":"FA denial: code 66"; break; case REPLY_CODE_FA_NACK_MN_AUTH: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: MN auth failed":"FA denial: code 67"; break; case REPLY_CODE_FA_NACK_HA_AUTH: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: HA auth failed": "FA denial: code 68"; break; case REPLY_CODE_FA_NACK_LIFETIME: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: lifetime":"FA denial: code 69"; break; case REPLY_CODE_FA_NACK_BAD_REQUEST: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: bad request": "FA: code 70"; break; case REPLY_CODE_FA_NACK_BAD_REPLY: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: bad Reply":"FA denial: code 71"; break; case REPLY_CODE_FA_NACK_ENCAP_UNAVAILABLE: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: encapsulation":"FA denial: code 72"; break; case REPLY_CODE_FA_NACK_VJ_UNAVAILABLE: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: VJ compression":"FA denial: code 73"; break; case REPLY_CODE_FA_NACK_BIDIR_TUNNEL_UNAVAILABLE: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: reverse tunnel unavailable": "FA denial: code 74"; break; case REPLY_CODE_FA_NACK_BIDIR_TUNNEL_NO_TBIT: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: reverse tunnel: missing T-bit": "FA denial: code 75"; break; case REPLY_CODE_FA_NACK_BIDIR_TUNNEL_TOO_DISTANT: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: reverse tunnel: too distant": "FA denial: code 76"; break; case REPLY_CODE_FA_NACK_ICMP_HA_NET_UNREACHABLE: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: home network unreachable": "FA denial: code 80"; break; case REPLY_CODE_FA_NACK_ICMP_HA_HOST_UNREACHABLE: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: HA host unreachable": "FA denial: code 81"; break; case REPLY_CODE_FA_NACK_ICMP_HA_PORT_UNREACHABLE: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: HA port unreachable": "FA denial: code 82"; break; case REPLY_CODE_FA_NACK_ICMP_HA_UNREACHABLE: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: HA unreachable":"FA denial: code 88"; break; case REPLY_CODE_FA_NACK_UNIQUE_HOMEADDR_REQD: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: Unique Home Addr Required": "FA denial: code 96"; break; case REPLY_CODE_FA_NACK_MISSING_NAI: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: Missing NAI": "FA denial: code 97"; break; case REPLY_CODE_FA_NACK_MISSING_HOME_AGENT: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: Missing Home Agent": "FA denial: code 98"; break; case REPLY_CODE_FA_NACK_UNKNOWN_CHALLENGE: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: Unknown Challenge": "FA denial: code 104"; break; case REPLY_CODE_FA_NACK_MISSING_CHALLENGE: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: Missing Challenge": "FA denial: code 105"; break; case REPLY_CODE_FA_NACK_MISSING_MN_FA: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "FA denial: Missing Mobile-Foreign Key Extension": "FA denial: code 106"; break; case REPLY_CODE_HA_NACK_UNSPECIFIED: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "HA denial: unspecified":"HA denial: code 128"; break; case REPLY_CODE_HA_NACK_PROHIBITED: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "HA denial: prohibited":"HA denial: code 129"; break; case REPLY_CODE_HA_NACK_RESOURCES: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "HA denial: no resources":"HA denial: code 130"; break; case REPLY_CODE_HA_NACK_MN_AUTH: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "HA denial: MN auth failed":"HA denial: code 131"; break; case REPLY_CODE_HA_NACK_FA_AUTH: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "HA denial: FA auth failed":"HA denial: code 132"; break; case REPLY_CODE_HA_NACK_ID_MISMATCH: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "HA denial: ID mismatch":"HA denial: code 133"; break; case REPLY_CODE_HA_NACK_BAD_REQUEST: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "HA denial: bad request":"HA denial: code 134"; break; case REPLY_CODE_HA_NACK_TOO_MANY_BINDINGS: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "HA denial: too many bindings": "HA denial: code 135"; break; case REPLY_CODE_HA_NACK_BAD_HA_ADDRESS: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "HA denial: bad HA address":"HA denial: code 136"; break; case REPLY_CODE_HA_NACK_BIDIR_TUNNEL_UNAVAILABLE: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "HA denial: no reverse tunnel": "HA denial: code 137"; break; case REPLY_CODE_HA_NACK_BIDIR_TUNNEL_NO_TBIT: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "HA denial: reverse tunnel: no T-bit": "HA denial: code 138"; break; case REPLY_CODE_HA_NACK_BIDIR_ENCAP_UNAVAILABLE: pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? "HA denial: encapsulation unavailable": "HA denial: code 139"; break; default: pc = "?"; break; } break; default : break; } if (flags & F_SUM) { line = get_sum_line(); if (pc != NULL) (void) sprintf(line, "Mobile IP %s(%s)", pt, pc); else (void) sprintf(line, "Mobile IP %s", pt); } if (flags & F_DTAIL) { show_header("MIP: ", "Mobile IP Header", fraglen); show_space(); if (*msg == REG_TYPE_REQ) { (void) sprintf(get_line((char *)&rreq - dlc_header, 1), "Registration header type = %s", pt); (void) sprintf(get_line( (char *)(((uchar_t *)&rreq) + 1) - dlc_header, 1), "%d... .... = %s simultaneous bindings ", (rreq->Simultaneous_registration == 1)? 1 : 0, (rreq->Simultaneous_registration == 1)? "":"no"); (void) sprintf(get_line( (char *)(((uchar_t *)&rreq) + 1) - dlc_header, 1), ".%d.. .... = %s broadcast datagrams ", (rreq->Broadcasts_desired == 1) ? 1 : 0, (rreq->Broadcasts_desired == 1) ? "":"no"); (void) sprintf(get_line( (char *)(((uchar_t *)&rreq) + 1) - dlc_header, 1), "..%d. .... = %s decapsulation by MN", (rreq->Decapsulation_done_locally == 1) ? 1 : 0, (rreq->Decapsulation_done_locally == 1) ? "" : "no"); (void) sprintf(get_line( (char *)(((uchar_t *)&rreq) + 1) - dlc_header, 1), "...%d .... = %s minimum encapsulation ", (rreq->Minimal_encap_desired == 1) ? 1 : 0, (rreq->Minimal_encap_desired == 1) ? "" : "no"); (void) sprintf(get_line( (char *)(((uchar_t *)&rreq) + 1) - dlc_header, 1), ".... %d... = %s GRE encapsulation ", (rreq->GRE_encap_desired == 1) ? 1 : 0, (rreq->GRE_encap_desired == 1) ? "" : "no"); (void) sprintf(get_line( (char *)(((uchar_t *)&rreq) + 1) - dlc_header, 1), ".... .%d.. = %s VJ hdr Compression ", (rreq->VJ_compression_desired == 1) ? 1 : 0, (rreq->VJ_compression_desired == 1) ? "" : "no"); (void) sprintf(get_line( (char *)(((uchar_t *)&rreq) + 1) - dlc_header, 1), ".... ..%d. = %s reverse tunnel", (rreq->BiDirectional_Tunnel_desired == 1) ? 1 : 0, (rreq->BiDirectional_Tunnel_desired == 1) ? "" : "no"); if (ntohs(rreq->lifetime) == 0xffff) { (void) sprintf(get_line( (char *)&rreq->lifetime - dlc_header, 1), "Life Time = 0xFFFF (infinity)"); } else if (ntohs(rreq->lifetime) == 0) { (void) sprintf(get_line( (char *)&rreq->lifetime - dlc_header, 1), "Life Time = 0 " "(request for de-registration)"); } else { (void) sprintf(get_line( (char *)&rreq->lifetime - dlc_header, 1), "Life time = %d seconds", ntohs(rreq->lifetime)); } addr_temp.s_addr = rreq->home_addr; (void) sprintf(get_line( (char *)&rreq->home_addr - dlc_header, 1), "Home address = %s, %s", inet_ntoa(addr_temp), addrtoname(AF_INET, &addr_temp)); addr_temp.s_addr = rreq->home_agent_addr; (void) sprintf(get_line( (char *)&rreq->home_agent_addr - dlc_header, 1), "Home Agent address = %s, %s", inet_ntoa(addr_temp), addrtoname(AF_INET, &addr_temp)); addr_temp.s_addr = rreq->care_of_addr; (void) sprintf(get_line( (char *)&rreq->care_of_addr - dlc_header, 1), "Care of address = %s, %s", inet_ntoa(addr_temp), addrtoname(AF_INET, &addr_temp)); (void) sprintf(get_line( (char *)&rreq->identification - dlc_header, 1), "Identification = 0x%x-%x", ntohl(rreq->identification.high_bits), ntohl(rreq->identification.low_bits)); } else if (*msg == REG_TYPE_REP) { (void) sprintf( get_line((char *)&rrep->type - dlc_header, 1), "Registration header type = %d (%s)", (int)rrep->type, pt); (void) sprintf(get_line((char *)&rrep - dlc_header, 1), "Code = %d %s", (int)rrep->code, pc); if (ntohs(rrep->lifetime) == 0xffff) { (void) sprintf(get_line( (char *)&rrep->lifetime - dlc_header, 1), "Life time = 0xFFFF (infinity)"); } else if (ntohs(rrep->lifetime) == 0) { (void) sprintf(get_line( (char *)&rrep->lifetime - dlc_header, 1), ((rrep->code == REPLY_CODE_ACK) || (rrep->code == REPLY_CODE_ACK_NO_SIMULTANEOUS))? "Life time = 0 (de-registeration success)" : "Life time = 0 (de-registration failed)"); } else { (void) sprintf(get_line( (char *)&rrep->lifetime - dlc_header, 1), "Life time = %d seconds", ntohs(rrep->lifetime)); } addr_temp.s_addr = rrep->home_addr; (void) sprintf( get_line((char *)&rrep->home_addr - dlc_header, 1), "Home address = %s, %s", inet_ntoa(addr_temp), addrtoname(AF_INET, &addr_temp)); addr_temp.s_addr = rrep->home_agent_addr; (void) sprintf(get_line( (char *)&rrep->home_agent_addr - dlc_header, 1), "Home Agent address = %s, %s", inet_ntoa(addr_temp), addrtoname(AF_INET, &addr_temp)); (void) sprintf(get_line( (char *)&rrep->identification - dlc_header, 1), "Identification = 0x%x-%x", ntohl(rrep->identification.high_bits), ntohl(rrep->identification.low_bits)); } fraglen = interpret_extensions(regext_data, regext_size, REG); } }
/*ARGSUSED*/ void interpret_icmp(int flags, struct icmp *icmp, int iplen, int ilen) { char *pt, *pc, *px; char *line; char buff[67627]; /* Router adv. can have 256 routers .... */ /* Each router has a name 256 char long .. */ char extbuff[MAXHOSTNAMELEN + 1]; struct udphdr *orig_uhdr; int num_rtr_addrs = 0; extern char *prot_nest_prefix; if (ilen < ICMP_MINLEN) return; /* incomplete header */ pt = "Unknown"; pc = ""; px = ""; switch (icmp->icmp_type) { case ICMP_ECHOREPLY: pt = "Echo reply"; (void) sprintf(buff, "ID: %d Sequence number: %d", ntohs(icmp->icmp_id), ntohs(icmp->icmp_seq)); pc = buff; break; case ICMP_UNREACH: pt = "Destination unreachable"; switch (icmp->icmp_code) { case ICMP_UNREACH_NET: if (ilen >= ICMP_ADVLENMIN) { (void) sprintf(buff, "Net %s unreachable", addrtoname(AF_INET, &icmp->icmp_ip.ip_dst)); pc = buff; } else { pc = "Bad net"; } break; case ICMP_UNREACH_HOST: if (ilen >= ICMP_ADVLENMIN) { (void) sprintf(buff, "Host %s unreachable", addrtoname(AF_INET, &icmp->icmp_ip.ip_dst)); pc = buff; } else { pc = "Bad host"; } break; case ICMP_UNREACH_PROTOCOL: if (ilen >= ICMP_ADVLENMIN) { (void) sprintf(buff, "Bad protocol %d", icmp->icmp_ip.ip_p); pc = buff; } else { pc = "Bad protocol"; } break; case ICMP_UNREACH_PORT: if (ilen >= ICMP_ADVLENMIN) { orig_uhdr = (struct udphdr *)((uchar_t *)icmp + ICMP_MINLEN + icmp->icmp_ip.ip_hl * 4); switch (icmp->icmp_ip.ip_p) { case IPPROTO_TCP: (void) sprintf(buff, "TCP port %d" " unreachable", ntohs(orig_uhdr->uh_dport)); pc = buff; break; case IPPROTO_UDP: (void) sprintf(buff, "UDP port %d" " unreachable", ntohs(orig_uhdr->uh_dport)); pc = buff; break; default: pc = "Port unreachable"; break; } } else { pc = "Bad port"; } break; case ICMP_UNREACH_NEEDFRAG: if (ntohs(icmp->icmp_nextmtu) != 0) { (void) sprintf(buff, "Needed to fragment:" " next hop MTU = %d", ntohs(icmp->icmp_nextmtu)); pc = buff; } else { pc = "Needed to fragment"; } break; case ICMP_UNREACH_SRCFAIL: pc = "Source route failed"; break; case ICMP_UNREACH_NET_UNKNOWN: pc = "Unknown network"; break; case ICMP_UNREACH_HOST_UNKNOWN: pc = "Unknown host"; break; case ICMP_UNREACH_ISOLATED: pc = "Source host isolated"; break; case ICMP_UNREACH_NET_PROHIB: pc = "Net administratively prohibited"; break; case ICMP_UNREACH_HOST_PROHIB: pc = "Host administratively prohibited"; break; case ICMP_UNREACH_TOSNET: pc = "Net unreachable for this TOS"; break; case ICMP_UNREACH_TOSHOST: pc = "Host unreachable for this TOS"; break; case ICMP_UNREACH_FILTER_PROHIB: pc = "Communication administratively prohibited"; break; case ICMP_UNREACH_HOST_PRECEDENCE: pc = "Host precedence violation"; break; case ICMP_UNREACH_PRECEDENCE_CUTOFF: pc = "Precedence cutoff in effect"; break; default: break; } break; case ICMP_SOURCEQUENCH: pt = "Packet lost, slow down"; break; case ICMP_REDIRECT: pt = "Redirect"; switch (icmp->icmp_code) { case ICMP_REDIRECT_NET: pc = "for network"; break; case ICMP_REDIRECT_HOST: pc = "for host"; break; case ICMP_REDIRECT_TOSNET: pc = "for tos and net"; break; case ICMP_REDIRECT_TOSHOST: pc = "for tos and host"; break; default: break; } (void) sprintf(buff, "%s %s to %s", pc, addrtoname(AF_INET, &icmp->icmp_ip.ip_dst), addrtoname(AF_INET, &icmp->icmp_gwaddr)); pc = buff; break; case ICMP_ECHO: pt = "Echo request"; (void) sprintf(buff, "ID: %d Sequence number: %d", ntohs(icmp->icmp_id), ntohs(icmp->icmp_seq)); pc = buff; break; case ICMP_ROUTERADVERT: #define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs #define icmp_wpa icmp_hun.ih_rtradv.irt_wpa #define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime pt = "Router advertisement"; (void) sprintf(buff, "Lifetime %ds [%d]:", ntohs(icmp->icmp_lifetime), icmp->icmp_num_addrs); if (icmp->icmp_wpa == 2) { struct icmp_ra_addr *ra; char ra_buf[MAXHOSTNAMELEN + 32]; char ra_ext_buf[50]; struct in_addr sin; int icmp_ra_len; int i; /* Cannot trust anything from the network... */ num_rtr_addrs = MIN((ilen - ICMP_MINLEN) / 8, icmp->icmp_num_addrs); ra = (struct icmp_ra_addr *)icmp->icmp_data; for (i = 0; i < num_rtr_addrs; i++) { sin.s_addr = ra->addr; (void) snprintf(ra_buf, sizeof (ra_buf), " {%s %u}", addrtoname(AF_INET, &sin), ntohl(ra->preference)); if (strlcat(buff, ra_buf, sizeof (buff)) >= sizeof (buff)) { buff[sizeof (buff) - strlen("<Too Long>)")] = '\0'; (void) strlcat(buff, "<Too Long>", sizeof (buff)); break; } ra++; } icmp_ra_len = ICMP_MINLEN + num_rtr_addrs * sizeof (struct icmp_ra_addr); if (ilen > icmp_ra_len) { int curr_len = ilen - icmp_ra_len; int ocurr_len; exthdr_t *exthdr = (exthdr_t *)ra; extbuff[0] = '\0'; while (curr_len > 0) { /* Append Mobile-IP description */ (void) snprintf(ra_ext_buf, sizeof (ra_ext_buf), ", %s", get_mip_adv_desc(exthdr->type)); (void) strlcat(extbuff, ra_ext_buf, sizeof (extbuff)); /* Special case for padding */ if (exthdr->type == ICMP_ADV_MSG_PADDING_EXT) { curr_len--; exthdr = (exthdr_t *) ((char *)exthdr + 1); continue; } /* else normal extension */ ocurr_len = curr_len; curr_len -= sizeof (*exthdr) + exthdr->length; /* detect bad length */ if (ocurr_len < curr_len) break; exthdr = (exthdr_t *) ((char *)exthdr + sizeof (*exthdr) + exthdr->length); } px = extbuff; } pc = buff; } break; case ICMP_ROUTERSOLICIT: pt = "Router solicitation"; break; case ICMP_TIMXCEED: pt = "Time exceeded"; switch (icmp->icmp_code) { case ICMP_TIMXCEED_INTRANS: pc = "in transit"; break; case ICMP_TIMXCEED_REASS: pc = "in reassembly"; break; default: break; } break; case ICMP_PARAMPROB: pt = "IP parameter problem"; switch (icmp->icmp_code) { case ICMP_PARAMPROB_OPTABSENT: pc = "Required option missing"; break; case ICMP_PARAMPROB_BADLENGTH: pc = "Bad length"; break; case 0: /* Should this be the default? */ (void) sprintf(buff, "Problem at octet %d\n", icmp->icmp_pptr); pc = buff; default: break; } break; case ICMP_TSTAMP: pt = "Timestamp request"; break; case ICMP_TSTAMPREPLY: pt = "Timestamp reply"; break; case ICMP_IREQ: pt = "Information request"; break; case ICMP_IREQREPLY: pt = "Information reply"; break; case ICMP_MASKREQ: pt = "Address mask request"; break; case ICMP_MASKREPLY: pt = "Address mask reply"; (void) sprintf(buff, "Mask = 0x%x", ntohl(icmp->icmp_mask)); pc = buff; break; default: break; } if (flags & F_SUM) { line = get_sum_line(); if (*pc) { if (*px) { (void) sprintf(line, "ICMP %s (%s)%s", pt, pc, px); } else { (void) sprintf(line, "ICMP %s (%s)", pt, pc); } } else { (void) sprintf(line, "ICMP %s", pt); } } if (flags & F_DTAIL) { show_header("ICMP: ", "ICMP Header", ilen); show_space(); (void) sprintf(get_line(0, 0), "Type = %d (%s)", icmp->icmp_type, pt); if (*pc) { (void) sprintf(get_line(0, 0), "Code = %d (%s)", icmp->icmp_code, pc); } else { (void) sprintf(get_line(0, 0), "Code = %d", icmp->icmp_code); } (void) sprintf(get_line(0, 0), "Checksum = %x", ntohs(icmp->icmp_cksum)); if (icmp->icmp_type == ICMP_UNREACH || icmp->icmp_type == ICMP_REDIRECT) { if (ilen > 28) { show_space(); (void) sprintf(get_line(0, 0), "[ subject header follows ]"); show_space(); prot_nest_prefix = "ICMP:"; (void) interpret_ip(flags, (struct ip *)icmp->icmp_data, 28); prot_nest_prefix = ""; } } else if (icmp->icmp_type == ICMP_PARAMPROB) { if (ilen > 28) { show_space(); (void) sprintf(get_line(0, 0), "[ subject header follows ]"); show_space(); prot_nest_prefix = "ICMP:"; (void) interpret_ip(flags, (struct ip *)icmp->icmp_data, 28); prot_nest_prefix = ""; } } else if (icmp->icmp_type == ICMP_ROUTERADVERT) { if (icmp->icmp_wpa == 2) { int icmp_ra_len; show_space(); icmp_ra_len = ICMP_MINLEN + num_rtr_addrs * sizeof (struct icmp_ra_addr); prot_nest_prefix = ""; if (ilen > icmp_ra_len) { interpret_icmp_mip_ext( (uchar_t *)icmp + icmp_ra_len, ilen - icmp_ra_len); } } } show_space(); } }
static int v1_header(int flags, struct slpv1_hdr *slp, int fraglen) { extern int src_port, dst_port, curr_proto; char *prototag = (curr_proto == IPPROTO_TCP? "/tcp" : ""); if (flags & F_SUM) { char portflag = ' '; if (msglength < sizeof (*slp)) { sprintf(msgbuf, "SLP V1 [incomplete header]"); return (0); } if (slp->vers != 1) { if (curr_proto == IPPROTO_TCP) sprintf(msgbuf, "SLP [TCP Continuation]"); else sprintf(msgbuf, "SLP [unknown version %d]", slp->vers); return (0); } if (src_port != 427 && dst_port != 427) portflag = '-'; sprintf(msgbuf, "SLP V1%c%s [%d%s] ", portflag, slpv1_func(slp->function, B_TRUE), ntohs(slp->xid), prototag); msgend = msgbuf + strlen(msgbuf); msglength -= sizeof (*slp); p += sizeof (*slp); } else if (flags & F_DTAIL) { show_header("SLP: ", "Service Location Protocol (v1)", fraglen); show_space(); if (msglength < sizeof (*slp)) { sprintf(get_line(0, 0), "==> Incomplete SLP header"); return (0); } sprintf(get_line(0, 0), "Version = %d", slp->vers); if (slp->vers != 1) { if (curr_proto == IPPROTO_TCP) sprintf(get_line(0, 0), "==> TCP continuation"); else sprintf(get_line(0, 0), "==> Unexpected version number"); return (0); } sprintf(get_line(0, 0), "Function = %d, %s", slp->function, slpv1_func(slp->function, B_FALSE)); sprintf(get_line(0, 0), "Message length = %u", ntohs(slp->length)); /* flags */ sprintf(get_line(0, 0), "Flags = 0x%02x", slp->flags); sprintf(get_line(0, 0), " %s", getflag(slp->flags, V1_OVERFLOW, "overflow", "no overflow")); sprintf(get_line(0, 0), " %s", getflag(slp->flags, V1_MONOLINGUAL, "monolingual", "not monolingual")); sprintf(get_line(0, 0), " %s", getflag(slp->flags, V1_URL_AUTH, "url authentication", "no url authentication")); sprintf(get_line(0, 0), " %s", getflag(slp->flags, V1_ATTR_AUTH, "attribute authentication", "no attribute authentication")); sprintf(get_line(0, 0), " %s", getflag(slp->flags, V1_FRESH_REG, "fresh registration", "no fresh registration")); /* check reserved flags that must be zero */ if ((slp->flags & 7) != 0) { sprintf(get_line(0, 0), " .... .xxx = %d (reserved flags nonzero)", slp->flags & 7); } /* end of flags */ sprintf(get_line(0, 0), "Dialect = %u", slp->dialect); sprintf(get_line(0, 0), "Language = 0x%02x%02x, %c%c", slp->language[0], slp->language[1], slp->language[0], slp->language[1]); v1_charset = ntohs(slp->charset); sprintf(get_line(0, 0), "Character encoding = %u, %s", v1_charset, slpv1_charset(v1_charset)); sprintf(get_line(0, 0), "XID = %u", ntohs(slp->xid)); /* set msglength to remaining length of SLP message */ msglength -= sizeof (*slp); p += sizeof (*slp); } return (1); }
int interpret_rpc(int flags, char *rpc, int fraglen, int type) { ulong_t xid; int direction; struct cache_struct *x; int rpcvers, prog, vers, proc; int status, astat, rstat, why; char *lp; unsigned recmark; int markpos; extern int pi_frame; int lo, hi; xdr_init(rpc, fraglen); if (setjmp(xdr_err)) { if (flags & F_DTAIL) (void) sprintf(get_line(0, 0), "---- short frame ---"); return (fraglen); } if (type == IPPROTO_TCP) { /* record mark */ markpos = getxdr_pos(); recmark = getxdr_long(); } xid = getxdr_u_long(); direction = getxdr_long(); if (direction == CALL) { rpcvers = getxdr_long(); pos = getxdr_pos(); prog = getxdr_long(); vers = getxdr_long(); proc = getxdr_long(); stash_xid(xid, pi_frame, prog, vers, proc); if (!(flags & (F_SUM | F_DTAIL))) protoprint(flags, CALL, xid, prog, vers, proc, rpc, fraglen); } else { x = find_xid(xid); } if (flags & F_SUM) { switch (direction) { case CALL: (void) sprintf(get_sum_line(), "RPC C XID=%lu PROG=%d (%s) VERS=%d PROC=%d", xid, prog, nameof_prog(prog), vers, proc); if (getxdr_long() == RPCSEC_GSS) { /* Cred auth type */ extract_rpcsec_gss_cred_info(xid); /* RPCSEC_GSS cred auth data */ } else { xdr_skip(getxdr_long()); /* non RPCSEC_GSS cred auth data */ } xdr_skip(4); /* Verf auth type */ xdr_skip(RNDUP(getxdr_long())); /* Verf auth data */ protoprint(flags, CALL, xid, prog, vers, proc, rpc, fraglen); break; case REPLY: lp = get_sum_line(); if (x == NULL) (void) sprintf(lp, "RPC R XID=%lu", xid); else (void) sprintf(lp, "RPC R (#%d) XID=%lu", x->xid_frame, xid); lp += strlen(lp); status = getxdr_long(); switch (status) { case MSG_ACCEPTED: /* eat flavor and verifier */ (void) getxdr_long(); xdr_skip(RNDUP(getxdr_long())); astat = getxdr_long(); (void) sprintf(lp, " %s", nameof_astat(astat)); lp += strlen(lp); switch (astat) { case SUCCESS: if (x) { protoprint(flags, REPLY, xid, x->xid_prog, x->xid_vers, x->xid_proc, rpc, fraglen); } break; case PROG_UNAVAIL : case PROG_MISMATCH: case PROC_UNAVAIL : lo = getxdr_long(); hi = getxdr_long(); (void) sprintf(lp, " (low=%d, high=%d)", lo, hi); break; case GARBAGE_ARGS: case SYSTEM_ERR: default: ; } break; case MSG_DENIED: rstat = getxdr_long(); switch (rstat) { case RPC_MISMATCH: lo = getxdr_long(); hi = getxdr_long(); (void) sprintf(lp, " Vers mismatch (low=%d, high=%d)", lo, hi); break; case AUTH_ERROR: why = getxdr_u_long(); (void) sprintf(lp, " Can't authenticate (%s)", nameof_why(why)); break; } } break; } } if (flags & F_DTAIL) { show_header("RPC: ", "SUN RPC Header", fraglen); show_space(); if (type == IPPROTO_TCP) { /* record mark */ (void) sprintf(get_line(markpos, markpos+4), "Record Mark: %s fragment, length = %d", recmark & LAST_FRAG ? "last" : "", recmark & ~LAST_FRAG); } (void) sprintf(get_line(0, 0), "Transaction id = %lu", xid); (void) sprintf(get_line(0, 0), "Type = %d (%s)", direction, direction == CALL ? "Call":"Reply"); switch (direction) { case CALL: rpc_detail_call(flags, xid, rpcvers, prog, vers, proc, rpc, fraglen); break; case REPLY: rpc_detail_reply(flags, xid, x, rpc, fraglen); break; } } return (fraglen); }
uint_t interpret_tr(int flags, caddr_t e, int elen, int origlen) { struct tr_header *mh; struct tr_ri *rh; uchar_t fc; struct llc_snap_hdr *snaphdr; char *off; int maclen, len; boolean_t data_copied = B_FALSE; extern char *dst_name, *src_name; int ethertype; int is_llc = 0, is_snap = 0, source_routing = 0; int blen = MAX(origlen, 17800); if (data != NULL && datalen != 0 && datalen < blen) { free(data); data = NULL; datalen = 0; } if (!data) { data = (char *)malloc(blen); if (!data) pr_err("Warning: malloc failure"); datalen = blen; } if (origlen < ACFCDASA_LEN) { if (flags & F_SUM) { (void) sprintf(get_sum_line(), "RUNT (short packet - %d bytes)", origlen); } if (flags & F_DTAIL) show_header("RUNT: ", "Short packet", origlen); return (elen); } if (elen < ACFCDASA_LEN) return (elen); mh = (struct tr_header *)e; rh = (struct tr_ri *)&mh->ri; fc = mh->fc; if (is_llc = tr_machdr_len(e, &maclen, &source_routing)) { snaphdr = (struct llc_snap_hdr *)(e + maclen); if (snaphdr->d_lsap == LSAP_SNAP && snaphdr->s_lsap == LSAP_SNAP && snaphdr->control == CNTL_LLC_UI) { is_snap = 1; } } if (memcmp(&mh->dhost, ðer_broadcast, sizeof (struct ether_addr)) == 0) dst_name = "(broadcast)"; else if (memcmp(&mh->dhost, &tokenbroadcastaddr2, sizeof (struct ether_addr)) == 0) dst_name = "(mac broadcast)"; else if (mh->dhost.ether_addr_octet[0] & TR_FN_ADDR) dst_name = "(functional)"; if (is_snap) ethertype = ntohs(snaphdr->type); else { src_name = print_etherinfo(&mh->shost); dst_name = print_etherinfo(&mh->dhost); } /* * The 14 byte ether header screws up alignment * of the rest of the packet for 32 bit aligned * architectures like SPARC. Alas, we have to copy * the rest of the packet in order to align it. */ if (is_llc) { if (is_snap) { len = elen - (maclen + LLC_SNAP_HDR_LEN); off = (char *)(e + maclen + LLC_SNAP_HDR_LEN); } else { len = elen - (maclen + LLC_HDR1_LEN); off = (char *)(e + maclen + LLC_HDR1_LEN); } } else { len = elen - maclen; off = (char *)(e + maclen); } if (len > 0 && (off + len <= (char *)e + elen)) { (void) memcpy(data, off, len); data_copied = B_TRUE; } if (flags & F_SUM) { if (source_routing) sprintf(get_sum_line(), print_sr(rh)); if (is_llc) { if (is_snap) { (void) sprintf(get_sum_line(), "TR LLC w/SNAP " "Type=%04X (%s), size=%d bytes", ethertype, print_ethertype(ethertype), origlen); } else { (void) sprintf(get_sum_line(), "TR LLC, but no " "SNAP encoding, size = %d bytes", origlen); } } else { (void) sprintf(get_sum_line(), "TR MAC FC=%02X (%s), size = %d bytes", fc, print_fc(fc), origlen); } } if (flags & F_DTAIL) { show_header("TR: ", "TR Header", elen); show_space(); (void) sprintf(get_line(0, 0), "Packet %d arrived at %d:%02d:%d.%05d", pi_frame, pi_time_hour, pi_time_min, pi_time_sec, pi_time_usec / 10); (void) sprintf(get_line(0, 0), "Packet size = %d bytes", elen); (void) sprintf(get_line(0, 1), "Frame Control = %02x (%s)", fc, print_fc(fc)); (void) sprintf(get_line(2, 6), "Destination = %s, %s", printether(&mh->dhost), print_etherinfo(&mh->dhost)); (void) sprintf(get_line(8, 6), "Source = %s, %s", printether(&mh->shost), print_etherinfo(&mh->shost)); if (source_routing) sprintf(get_line(ACFCDASA_LEN, rh->len), print_sr(rh)); if (is_llc) { (void) sprintf(get_line(maclen, 1), "Dest Service Access Point = %02x", snaphdr->d_lsap); (void) sprintf(get_line(maclen+1, 1), "Source Service Access Point = %02x", snaphdr->s_lsap); (void) sprintf(get_line(maclen+2, 1), "Control = %02x", snaphdr->control); if (is_snap) { (void) sprintf(get_line(maclen+3, 3), "SNAP Protocol Id = %02x%02x%02x", snaphdr->org[0], snaphdr->org[1], snaphdr->org[2]); } } if (is_snap) { (void) sprintf(get_line(maclen+6, 2), "SNAP Type = %04X (%s)", ethertype, print_ethertype(ethertype)); } show_space(); } /* go to the next protocol layer */ if (is_snap && data_copied) { switch (ethertype) { case ETHERTYPE_IP: (void) interpret_ip(flags, (struct ip *)data, len); break; /* Just in case it is decided to add this type */ case ETHERTYPE_IPV6: (void) interpret_ipv6(flags, (ip6_t *)data, len); break; case ETHERTYPE_ARP: case ETHERTYPE_REVARP: interpret_arp(flags, (struct arphdr *)data, len); break; case ETHERTYPE_AARP: /* AppleTalk */ interpret_aarp(flags, data, len); break; case ETHERTYPE_AT: interpret_at(flags, (struct ddp_hdr *)data, len); break; default: break; } } return (elen); }
int interpret_ah(int flags, uint8_t *hdr, int iplen, int fraglen) { /* LINTED: alignment */ ah_t *ah = (ah_t *)hdr; ah_t *aligned_ah; ah_t storage; /* In case hdr isn't aligned. */ char *line, *buff; uint_t ahlen, auth_data_len; uint8_t *auth_data, *data; int new_iplen; uint8_t proto; if (fraglen < sizeof (ah_t)) return (fraglen); /* incomplete header */ if (!IS_P2ALIGNED(hdr, 4)) { aligned_ah = (ah_t *)&storage; bcopy(hdr, &storage, sizeof (ah_t)); } else { aligned_ah = ah; } /* * "+ 8" is for the "constant" part that's not included in the AH * length. * * The AH RFC specifies the length field in "length in 4-byte units, * not counting the first 8 bytes". So if an AH is 24 bytes long, * the length field will contain "4". (4 * 4 + 8 == 24). */ ahlen = (aligned_ah->ah_length << 2) + 8; fraglen -= ahlen; if (fraglen < 0) return (fraglen + ahlen); /* incomplete header */ auth_data_len = ahlen - sizeof (ah_t); auth_data = (uint8_t *)(ah + 1); data = auth_data + auth_data_len; if (flags & F_SUM) { line = (char *)get_sum_line(); (void) sprintf(line, "AH SPI=0x%x Replay=%u", ntohl(aligned_ah->ah_spi), ntohl(aligned_ah->ah_replay)); line += strlen(line); } if (flags & F_DTAIL) { show_header("AH: ", "Authentication Header", ahlen); show_space(); (void) sprintf(get_line((char *)&ah->ah_nexthdr - dlc_header, 1), "Next header = %d (%s)", aligned_ah->ah_nexthdr, getproto(aligned_ah->ah_nexthdr)); (void) sprintf(get_line((char *)&ah->ah_length - dlc_header, 1), "AH length = %d (%d bytes)", aligned_ah->ah_length, ahlen); (void) sprintf(get_line((char *)&ah->ah_reserved - dlc_header, 2), "<Reserved field = 0x%x>", ntohs(aligned_ah->ah_reserved)); (void) sprintf(get_line((char *)&ah->ah_spi - dlc_header, 4), "SPI = 0x%x", ntohl(aligned_ah->ah_spi)); (void) sprintf(get_line((char *)&ah->ah_replay - dlc_header, 4), "Replay = %u", ntohl(aligned_ah->ah_replay)); /* * 2 for two hex digits per auth_data byte. */ buff = malloc(auth_data_len * 2); if (buff != NULL) { int i; for (i = 0; i < auth_data_len; i++) sprintf(buff + i * 2, "%02x", auth_data[i]); } (void) sprintf(get_line((char *)auth_data - dlc_header, auth_data_len), "ICV = %s", (buff == NULL) ? "<out of memory>" : buff); /* malloc(3c) says I can call free even if buff == NULL */ free(buff); show_space(); } new_iplen = iplen - ahlen; proto = aligned_ah->ah_nexthdr; /* * Print IPv6 Extension Headers, or skip them in the summary case. */ if (proto == IPPROTO_HOPOPTS || proto == IPPROTO_DSTOPTS || proto == IPPROTO_ROUTING || proto == IPPROTO_FRAGMENT) { (void) print_ipv6_extensions(flags, &data, &proto, &iplen, &fraglen); } if (fraglen > 0) switch (proto) { case IPPROTO_ENCAP: /* LINTED: alignment */ (void) interpret_ip(flags, (struct ip *)data, new_iplen); break; case IPPROTO_IPV6: (void) interpret_ipv6(flags, (ip6_t *)data, new_iplen); break; case IPPROTO_ICMP: (void) interpret_icmp(flags, /* LINTED: alignment */ (struct icmp *)data, new_iplen, fraglen); break; case IPPROTO_ICMPV6: /* LINTED: alignment */ (void) interpret_icmpv6(flags, (icmp6_t *)data, new_iplen, fraglen); break; case IPPROTO_TCP: (void) interpret_tcp(flags, (struct tcphdr *)data, new_iplen, fraglen); break; case IPPROTO_ESP: (void) interpret_esp(flags, data, new_iplen, fraglen); break; case IPPROTO_AH: (void) interpret_ah(flags, data, new_iplen, fraglen); break; case IPPROTO_UDP: (void) interpret_udp(flags, (struct udphdr *)data, new_iplen, fraglen); break; /* default case is to not print anything else */ } return (ahlen); }
int interpret_udp(int flags, struct udphdr *udp, int iplen, int fraglen) { char *data; int udplen; int sunrpc; char *pname; char buff [32]; if (fraglen < sizeof (struct udphdr)) return (fraglen); /* incomplete header */ data = (char *)udp + sizeof (struct udphdr); udplen = ntohs((ushort_t)udp->uh_ulen) - sizeof (struct udphdr); fraglen -= sizeof (struct udphdr); if (fraglen > udplen) fraglen = udplen; if (flags & F_SUM) { (void) sprintf(get_sum_line(), "UDP D=%d S=%d LEN=%d", ntohs(udp->uh_dport), ntohs(udp->uh_sport), ntohs((ushort_t)udp->uh_ulen)); } sunrpc = !reservedport(IPPROTO_UDP, ntohs(udp->uh_dport)) && !reservedport(IPPROTO_UDP, ntohs(udp->uh_sport)) && valid_rpc(data, udplen); if (flags & F_DTAIL) { show_header("UDP: ", "UDP Header", udplen); show_space(); (void) sprintf(get_line((char *)(uintptr_t)udp->uh_sport - dlc_header, 1), "Source port = %d", ntohs(udp->uh_sport)); if (sunrpc) { pname = "(Sun RPC)"; } else { pname = getportname(IPPROTO_UDP, ntohs(udp->uh_dport)); if (pname == NULL) { pname = ""; } else { (void) sprintf(buff, "(%s)", pname); pname = buff; } } (void) sprintf(get_line((char *)(uintptr_t)udp->uh_dport - dlc_header, 1), "Destination port = %d %s", ntohs(udp->uh_dport), pname); (void) sprintf(get_line((char *)(uintptr_t)udp->uh_ulen - dlc_header, 1), "Length = %d %s", ntohs((ushort_t)udp->uh_ulen), udplen > fraglen ? "(Not all data contained in this fragment)" : ""); (void) sprintf(get_line((char *)(uintptr_t)udp->uh_sum - dlc_header, 1), "Checksum = %04X %s", ntohs(udp->uh_sum), udp->uh_sum == 0 ? "(no checksum)" : ""); show_space(); } /* go to the next protocol layer */ if (!interpret_reserved(flags, IPPROTO_UDP, ntohs(udp->uh_sport), ntohs(udp->uh_dport), data, fraglen)) { if (fraglen > 0 && sunrpc) interpret_rpc(flags, data, fraglen, IPPROTO_UDP); } return (fraglen); }
static uint_t interpret_ib(int flags, char *header, int elen, int origlen) { struct ipoib_header *hdr = (struct ipoib_header *)header; char *off; int len; unsigned short ethertype; int blen = MAX(origlen, 4096); if (data != NULL && datalen != 0 && datalen < blen) { free(data); data = NULL; datalen = 0; } if (data == NULL) { data = malloc(blen); if (data == NULL) pr_err("Warning: malloc failure"); datalen = blen; } if (origlen < IPOIB_HDRSIZE) { if (flags & F_SUM) (void) snprintf(get_sum_line(), MAXLINE, "RUNT (short packet - %d bytes)", origlen); if (flags & F_DTAIL) show_header("RUNT: ", "Short packet", origlen); return (elen); } if (elen < IPOIB_HDRSIZE) return (elen); /* * It is not possible to understand just by looking * at the header whether this was a broad/multi cast * packet; thus dst_name is not updated. */ ethertype = ntohs(hdr->ipoib_type); len = elen - IPOIB_HDRSIZE; off = (char *)(hdr + 1); (void) memcpy(data, off, len); if (flags & F_SUM) { (void) snprintf(get_sum_line(), MAXLINE, "IPIB Type=%04X (%s), size = %d bytes", ethertype, print_ethertype(ethertype), origlen); } if (flags & F_DTAIL) { show_header("IPIB: ", "IPIB Header", elen); show_space(); (void) snprintf(get_line(0, 0), get_line_remain(), "Packet %d arrived at %d:%02d:%d.%02d", pi_frame, pi_time_hour, pi_time_min, pi_time_sec, pi_time_usec / 10000); (void) snprintf(get_line(0, 0), get_line_remain(), "Packet size = %d bytes", elen, elen); (void) snprintf(get_line(0, 2), get_line_remain(), "Ethertype = %04X (%s)", ethertype, print_ethertype(ethertype)); show_space(); } /* Go to the next protocol layer */ switch (ethertype) { case ETHERTYPE_IP: (void) interpret_ip(flags, (struct ip *)data, len); break; case ETHERTYPE_IPV6: (void) interpret_ipv6(flags, (ip6_t *)data, len); break; case ETHERTYPE_ARP: case ETHERTYPE_REVARP: interpret_arp(flags, (struct arphdr *)data, len); break; } return (elen); }
static int interpret_extensions(uchar_t *ext, int regext_size, enum EXT_TYPE etype) { int curr_size = regext_size; /* remaining total for all exts */ exthdr_t *exthdr; gen_exthdr_t *gen_exthdr; const char *st; uchar_t *p; interpreter_f *f; uint8_t ext_type; uint16_t ext_len; uint_t ext_hdrlen; show_space(); exthdr = (exthdr_t *)ALIGN(ext); do { ext_type = exthdr->type; if (ext_type == GEN_AUTH) { gen_exthdr = (gen_exthdr_t *)exthdr; ext_hdrlen = sizeof (gen_exthdr_t); ext_len = ntohs(gen_exthdr->length); } else { ext_hdrlen = sizeof (exthdr_t); ext_len = exthdr->length; } if (!((etype == ADV && ext_type == ICMP_ADV_MSG_PADDING_EXT && curr_size >= 1) || curr_size >= ext_hdrlen + ext_len)) break; /* Print description for this extension */ if (etype == ADV) { st = get_desc(adv_desc, ext_type, ADV_TBL_LEN); } else /* REG */ { st = get_desc(reg_desc, ext_type, REG_TBL_LEN); } (void) sprintf(get_line((char *)exthdr-dlc_header, 1), "Extension header type = %d %s", ext_type, st); if (ext_type == GEN_AUTH) { st = get_desc(genauth_desc, gen_exthdr->subtype, GENAUTH_TBL_LEN); (void) sprintf(get_line((char *)exthdr-dlc_header, 1), "Subtype = %d %s", gen_exthdr->subtype, st); } /* Special case for 1-byte padding */ if (etype == ADV && ext_type == ICMP_ADV_MSG_PADDING_EXT) { exthdr = (exthdr_t *)((uchar_t *)exthdr + 1); curr_size--; continue; } (void) sprintf(get_line((char *)&exthdr->length-dlc_header, 1), "Length = %d", ext_len); /* Parse out the extension's payload */ p = (uchar_t *)exthdr + ext_hdrlen; curr_size -= (ext_hdrlen + ext_len); if (etype == ADV) { f = get_interpreter(adv_dispatch, ext_type, ADV_TBL_LEN); } else /* REG */ { f = get_interpreter(reg_dispatch, ext_type, REG_TBL_LEN); } f(ext_type, ext_len, p); show_space(); exthdr = (exthdr_t *)(p + ext_len); } while (B_TRUE); return (0); }
static uint_t interpret_ipnet(int flags, char *header, int elen, int origlen) { dl_ipnetinfo_t dl; size_t len = elen - sizeof (dl_ipnetinfo_t); char *off = (char *)header + sizeof (dl_ipnetinfo_t); int blen = MAX(origlen, 8252); char szone[MAX_UINT64_STR]; char dzone[MAX_UINT64_STR]; (void) memcpy(&dl, header, sizeof (dl)); if (data != NULL && datalen != 0 && datalen < blen) { free(data); data = NULL; datalen = 0; } if (data == NULL) { data = (char *)malloc(blen); if (!data) pr_err("Warning: malloc failure"); datalen = blen; } if (dl.dli_zsrc == ALL_ZONES) sprintf(szone, "Unknown"); else sprintf(szone, "%lu", BE_32(dl.dli_zsrc)); if (dl.dli_zdst == ALL_ZONES) sprintf(dzone, "Unknown"); else sprintf(dzone, "%lu", BE_32(dl.dli_zdst)); if (flags & F_SUM) { (void) snprintf(get_sum_line(), MAXLINE, "IPNET src zone %s dst zone %s", szone, dzone); } if (flags & F_DTAIL) { show_header("IPNET: ", "IPNET Header", elen); show_space(); (void) sprintf(get_line(0, 0), "Packet %d arrived at %d:%02d:%d.%05d", pi_frame, pi_time_hour, pi_time_min, pi_time_sec, pi_time_usec / 10); (void) sprintf(get_line(0, 0), "Packet size = %d bytes", elen); (void) snprintf(get_line(0, 0), get_line_remain(), "dli_version = %d", dl.dli_version); (void) snprintf(get_line(0, 0), get_line_remain(), "dli_family = %d", dl.dli_family); (void) snprintf(get_line(0, 2), get_line_remain(), "dli_zsrc = %s", szone); (void) snprintf(get_line(0, 2), get_line_remain(), "dli_zdst = %s", dzone); show_space(); } memcpy(data, off, len); switch (dl.dli_family) { case AF_INET: (void) interpret_ip(flags, (struct ip *)data, len); break; case AF_INET6: (void) interpret_ipv6(flags, (ip6_t *)data, len); break; default: break; } return (0); }
static int v2_header(int flags, struct slpv2_hdr *slp, int *totallen, int fraglen) { extern int curr_proto, dst_port; char *prototag = (curr_proto == IPPROTO_TCP ? "/tcp" : ""); if ((slp->flags & V2_OVERFLOW) == V2_OVERFLOW) overflow = B_TRUE; /* summary mode header parsing */ if (flags & F_SUM) { /* make sure we have at least a header */ if (msglength < sizeof (*slp)) { sprintf(get_sum_line(), "SLP V2 [Incomplete Header]"); return (0); } sprintf(msgbuf, "SLP V2 %s [%d%s] ", slpv2_func(slp->function, B_TRUE), ntohs(slp->xid), prototag); /* skip to end of header */ msgend = msgbuf + strlen(msgbuf); msglength -= sizeof (*slp); p += sizeof (*slp); /* skip language tag */ SKIPFIELD(FIELD_DEFAULT); } else if (flags & F_DTAIL) { char *lang; int len; /* detailed mode header parsing */ show_header("SLP: ", "Service Location Protocol (v2)", fraglen); show_space(); if (msglength < sizeof (*slp)) { sprintf(get_line(0, 0), "==> Incomplete SLP header"); return (0); } sprintf(get_line(0, 0), "Version = %d", slp->vers); sprintf(get_line(0, 0), "Function = %d, %s", slp->function, slpv2_func(slp->function, B_FALSE)); get_int24(&(slp->l1)); *totallen = netval; sprintf(get_line(0, 0), "Message length = %u", *totallen); /* check for TCP continuation */ if (curr_proto == IPPROTO_TCP && *totallen > msglength && !tcp_continuation) { tcp_continuation = B_TRUE; reg_tcp_cont((char *)slp, *totallen, msglength, dst_port); } if (!tcp_continuation && *totallen != msglength) { sprintf(get_line(0, 0), " (Stated and on-the-wire lengths differ)"); } /* flags */ sprintf(get_line(0, 0), "Flags = 0x%02x", slp->flags); sprintf(get_line(0, 0), " %s", getflag(slp->flags, V2_OVERFLOW, "overflow", "no overflow")); sprintf(get_line(0, 0), " %s", getflag(slp->flags, V2_FRESH, "fresh registration", "no fresh registration")); sprintf(get_line(0, 0), " %s", getflag(slp->flags, V2_MCAST, "request multicast / broadcast", "unicast")); /* check reserved flags that must be zero */ if ((slp->flags & 7) != 0) { sprintf(get_line(0, 0), " .... .xxx = %d (reserved flags nonzero)", slp->flags & 7); } /* end of flags */ /* language tag */ p = (char *)slp + sizeof (*slp); msglength -= sizeof (*slp); GETSHORT(len); if (len > msglength) { sprintf(get_line(0, 0), "Language Tag Length = %u [CORRUPT MESSAGE]", len); return (0); } lang = get_line(0, 0); strcpy(lang, "Language Tag = "); strncat(lang, p, len); sprintf(get_line(0, 0), "XID = %u", ntohs(slp->xid)); /* set msglength to remaining length of SLP message */ p += len; msglength -= len; } return (1); }
/* * This is called by snoop_netbios.c. * This is the external entry point. */ void interpret_smb(int flags, uchar_t *data, int len) { struct smb *smb; struct decode *decoder; char xtra[MAXLINE]; ushort_t smb_flags2; void (*func)(int, uchar_t *, int, char *, int); if (len < sizeof (struct smb)) return; smb = (struct smb *)data; decoder = &SMBtable[smb->com & 255]; smb_flags2 = get2(smb->flags2); xtra[0] = '\0'; /* * SMB Header description * [X/Open-SMB, Sec. 5.1] */ if (flags & F_DTAIL) { show_header("SMB: ", "SMB Header", len); show_space(); if (smb->flags & SERVER_RESPONSE) show_line("SERVER RESPONSE"); else show_line("CLIENT REQUEST"); if (decoder->name) show_printf("Command code = 0x%x (SMB%s)", smb->com, decoder->name); else show_printf("Command code = 0x%x", smb->com); /* * NT status or error class/code * [X/Open-SMB, Sec. 5.6] */ if (smb_flags2 & FLAGS2_NT_STATUS) { show_printf("NT Status = %x", get4(smb->err)); } else { /* Error classes [X/Open-SMB, Sec. 5.6] */ show_printf("Error class/code = %d/%d", smb->err[0], get2(&smb->err[2])); } show_printf("Flags summary = 0x%.2x", smb->flags); show_printf("Flags2 summary = 0x%.4x", smb_flags2); show_printf("Tree ID (TID) = 0x%.4x", get2(smb->tid)); show_printf("Proc. ID (PID) = 0x%.4x", get2(smb->pid)); show_printf("User ID (UID) = 0x%.4x", get2(smb->uid)); show_printf("Mux. ID (MID) = 0x%.4x", get2(smb->mid)); show_space(); } if ((func = decoder->func) == NULL) func = interpret_default; (*func)(flags, (uchar_t *)data, len, xtra, sizeof (xtra)); if (flags & F_SUM) { char *p; int sz, tl; /* Will advance p and decr. sz */ p = get_sum_line(); sz = MAXLINE; /* Call or Reply */ if (smb->flags & SERVER_RESPONSE) tl = snprintf(p, sz, "SMB R"); else tl = snprintf(p, sz, "SMB C"); p += tl; sz -= tl; /* The name, if known, else the cmd code */ if (decoder->name) { tl = snprintf(p, sz, " Cmd=SMB%s", decoder->name); } else { tl = snprintf(p, sz, " Cmd=0x%02X", smb->com); } p += tl; sz -= tl; /* * The "extra" (cmd-specific summary). * If non-null, has leading blank. */ if (xtra[0] != '\0') { tl = snprintf(p, sz, "%s", xtra); p += tl; sz -= tl; } /* * NT status or error class/code * [X/Open-SMB, Sec. 5.6] * * Only show for response, not call. */ if (smb->flags & SERVER_RESPONSE) { if (smb_flags2 & FLAGS2_NT_STATUS) { uint_t status = get4(smb->err); snprintf(p, sz, " Status=0x%x", status); } else { uchar_t errcl = smb->err[0]; ushort_t code = get2(&smb->err[2]); snprintf(p, sz, " Error=%d/%d", errcl, code); } } } if (flags & F_DTAIL) show_trailer(); }
int interpret_dhcpv6(int flags, const uint8_t *data, int len) { int olen = len; char *line, *lstart; dhcpv6_relay_t d6r; dhcpv6_message_t d6m; uint_t optlen; uint16_t statuscode; if (len <= 0) { (void) strlcpy(get_sum_line(), "DHCPv6?", MAXLINE); return (0); } if (flags & F_SUM) { uint_t ias; dhcpv6_option_t *d6o; in6_addr_t link, peer; char linkstr[INET6_ADDRSTRLEN]; char peerstr[INET6_ADDRSTRLEN]; line = lstart = get_sum_line(); line += snprintf(line, MAXLINE, "DHCPv6 %s", mtype_to_str(data[0])); if (data[0] == DHCPV6_MSG_RELAY_FORW || data[0] == DHCPV6_MSG_RELAY_REPL) { if (len < sizeof (d6r)) { (void) strlcpy(line, "?", MAXLINE - (line - lstart)); return (olen); } /* Not much in DHCPv6 is aligned. */ (void) memcpy(&d6r, data, sizeof (d6r)); (void) memcpy(&link, d6r.d6r_linkaddr, sizeof (link)); (void) memcpy(&peer, d6r.d6r_peeraddr, sizeof (peer)); line += snprintf(line, MAXLINE - (line - lstart), " HC=%d link=%s peer=%s", d6r.d6r_hop_count, inet_ntop(AF_INET6, &link, linkstr, sizeof (linkstr)), inet_ntop(AF_INET6, &peer, peerstr, sizeof (peerstr))); data += sizeof (d6r); len -= sizeof (d6r); } else { if (len < sizeof (d6m)) { (void) strlcpy(line, "?", MAXLINE - (line - lstart)); return (olen); } (void) memcpy(&d6m, data, sizeof (d6m)); line += snprintf(line, MAXLINE - (line - lstart), " xid=%x", DHCPV6_GET_TRANSID(&d6m)); data += sizeof (d6m); len -= sizeof (d6m); } ias = 0; d6o = NULL; while ((d6o = dhcpv6_find_option(data, len, d6o, DHCPV6_OPT_IA_NA, NULL)) != NULL) ias++; if (ias > 0) line += snprintf(line, MAXLINE - (line - lstart), " IAs=%u", ias); d6o = dhcpv6_find_option(data, len, NULL, DHCPV6_OPT_STATUS_CODE, &optlen); optlen -= sizeof (*d6o); if (d6o != NULL && optlen >= sizeof (statuscode)) { (void) memcpy(&statuscode, d6o + 1, sizeof (statuscode)); line += snprintf(line, MAXLINE - (line - lstart), " status=%u", ntohs(statuscode)); optlen -= sizeof (statuscode); if (optlen > 0) { line += snprintf(line, MAXLINE - (line - lstart), " \"%.*s\"", optlen, (char *)(d6o + 1) + 2); } } d6o = dhcpv6_find_option(data, len, NULL, DHCPV6_OPT_RELAY_MSG, &optlen); optlen -= sizeof (*d6o); if (d6o != NULL && optlen >= 1) { line += snprintf(line, MAXLINE - (line - lstart), " relay=%s", mtype_to_str(*(uint8_t *)(d6o + 1))); } } else if (flags & F_DTAIL) { show_header("DHCPv6: ", "Dynamic Host Configuration Protocol Version 6", len); show_space(); (void) snprintf(get_line(0, 0), get_line_remain(), "Message type (msg-type) = %u (%s)", data[0], mtype_to_str(data[0])); if (data[0] == DHCPV6_MSG_RELAY_FORW || data[0] == DHCPV6_MSG_RELAY_REPL) { if (len < sizeof (d6r)) { (void) strlcpy(get_line(0, 0), "Truncated", get_line_remain()); return (olen); } (void) memcpy(&d6r, data, sizeof (d6r)); (void) snprintf(get_line(0, 0), get_line_remain(), "Hop count = %u", d6r.d6r_hop_count); show_address("Link address", d6r.d6r_linkaddr); show_address("Peer address", d6r.d6r_peeraddr); data += sizeof (d6r); len -= sizeof (d6r); } else { if (len < sizeof (d6m)) { (void) strlcpy(get_line(0, 0), "Truncated", get_line_remain()); return (olen); } (void) memcpy(&d6m, data, sizeof (d6m)); (void) snprintf(get_line(0, 0), get_line_remain(), "Transaction ID = %x", DHCPV6_GET_TRANSID(&d6m)); data += sizeof (d6m); len -= sizeof (d6m); } show_space(); show_options(data, len); show_space(); } return (olen); }