void capture_raw(const guchar *pd, int len, packet_counts *ld) { /* So far, the only time we get raw connection types are with Linux and * Irix PPP connections. We can't tell what type of data is coming down * the line, so our safest bet is IP. - GCC */ /* Currently, the Linux 2.1.xxx PPP driver passes back some of the header * sometimes. This check should be removed when 2.2 is out. */ if (BYTES_ARE_IN_FRAME(0,len,2) && pd[0] == 0xff && pd[1] == 0x03) { capture_ppp_hdlc(pd, 0, len, ld); } /* The Linux ISDN driver sends a fake MAC address before the PPP header * on its ippp interfaces... */ else if (BYTES_ARE_IN_FRAME(0,len,8) && pd[6] == 0xff && pd[7] == 0x03) { capture_ppp_hdlc(pd, 6, len, ld); } /* ...except when it just puts out one byte before the PPP header... */ else if (BYTES_ARE_IN_FRAME(0,len,3) && pd[1] == 0xff && pd[2] == 0x03) { capture_ppp_hdlc(pd, 1, len, ld); } /* ...and if the connection is currently down, it sends 10 bytes of zeroes * instead of a fake MAC address and PPP header. */ else if (BYTES_ARE_IN_FRAME(0,len,10) && memcmp(pd, zeroes, 10) == 0) { capture_ip(pd, 10, len, ld); } else { /* * OK, is this IPv4 or IPv6? */ if (BYTES_ARE_IN_FRAME(0,len,1)) { switch (pd[0] & 0xF0) { case 0x40: /* IPv4 */ capture_ip(pd, 0, len, ld); break; #if 0 case 0x60: /* IPv6 */ capture_ipv6(pd, 0, len, ld); break; #endif } } } }
void capture_ethertype(guint16 etype, const guchar *pd, int offset, int len, packet_counts *ld) { switch (etype) { case ETHERTYPE_ARP: ld->arp++; break; case ETHERTYPE_IP: capture_ip(pd, offset, len, ld); break; case ETHERTYPE_IPv6: capture_ipv6(pd, offset, len, ld); break; case ETHERTYPE_IPX: capture_ipx(ld); break; case ETHERTYPE_VLAN: capture_vlan(pd, offset, len, ld); break; case ETHERTYPE_IEEE_802_1AD: case ETHERTYPE_IEEE_802_1AH: capture_ieee8021ah(pd, offset, len, ld); break; case ETHERTYPE_VINES_IP: case ETHERTYPE_VINES_ECHO: capture_vines(ld); break; default: ld->other++; break; } }
gboolean capture_chdlc( const guchar *pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header) { if (!BYTES_ARE_IN_FRAME(offset, len, 4)) return FALSE; switch (pntoh16(&pd[offset + 2])) { case ETHERTYPE_IP: return capture_ip(pd, offset + 4, len, cpinfo, pseudo_header); } return FALSE; }
void capture_chdlc( const guchar *pd, int offset, int len, packet_counts *ld ) { if (!BYTES_ARE_IN_FRAME(offset, len, 4)) { ld->other++; return; } switch (pntoh16(&pd[offset + 2])) { case ETHERTYPE_IP: capture_ip(pd, offset + 4, len, ld); break; default: ld->other++; break; } }
void capture_arcnet (const guchar *pd, int len, packet_counts *ld, gboolean has_offset, gboolean has_exception) { int offset = has_offset ? 4 : 2; if (!BYTES_ARE_IN_FRAME(offset, len, 1)) { ld->other++; return; } switch (pd[offset]) { case ARCNET_PROTO_IP_1051: /* No fragmentation stuff in the header */ capture_ip(pd, offset + 1, len, ld); break; case ARCNET_PROTO_IP_1201: /* * There's fragmentation stuff in the header. * * XXX - on at least some versions of NetBSD, it appears that we * might we get ARCNET frames, not reassembled packets; we should * perhaps bump "ld->other" for all but the first frame of a packet. * * XXX - but on FreeBSD it appears that we get reassembled packets * on input (but apparently we get frames on output - or maybe * we get the packet *and* all its frames!); how to tell the * difference? It looks from the FreeBSD reassembly code as if * the reassembled packet arrives with the header for the first * frame. It also looks as if, on output, we first get the * full packet, with a header containing none of the fragmentation * stuff, and then get the frames. * * On Linux, we get only reassembled packets, and the exception * frame stuff is hidden - there's a split flag and sequence * number, but it appears that it will never have the exception * frame stuff. * * XXX - what about OpenBSD? And, for that matter, what about * Windows? (I suspect Windows supplies reassembled frames, * as WinPcap, like PF_PACKET sockets, taps into the networking * stack just as other protocols do.) */ offset++; if (!BYTES_ARE_IN_FRAME(offset, len, 1)) { ld->other++; return; } if (has_exception && pd[offset] == 0xff) { /* This is an exception packet. The flag value there is the "this is an exception flag" packet; the next two bytes after it are padding, and another copy of the packet type appears after the padding. */ offset += 4; } capture_ip(pd, offset + 3, len, ld); break; case ARCNET_PROTO_ARP_1051: case ARCNET_PROTO_ARP_1201: /* * XXX - do we have to worry about fragmentation for ARP? */ ld->arp++; break; case ARCNET_PROTO_IPX: ld->ipx++; break; default: ld->other++; break; } }
void capture_llc(const guchar *pd, int offset, int len, packet_counts *ld) { int is_snap; guint16 control; int llc_header_len; if (!BYTES_ARE_IN_FRAME(offset, len, 2)) { ld->other++; return; } is_snap = (pd[offset] == SAP_SNAP) && (pd[offset+1] == SAP_SNAP); llc_header_len = 2; /* DSAP + SSAP */ /* * XXX - the page referred to in the comment above about the * Command/Response bit also implies that LLC Type 2 always * uses extended operation, so we don't need to determine * whether it's basic or extended operation; is that the case? */ control = get_xdlc_control(pd, offset+2, pd[offset+1] & SSAP_CR_BIT); llc_header_len += XDLC_CONTROL_LEN(control, TRUE); if (!BYTES_ARE_IN_FRAME(offset, len, llc_header_len)) { ld->other++; return; } if (!XDLC_IS_INFORMATION(control)) { ld->other++; return; } if (is_snap) capture_snap(pd, offset+llc_header_len, len, ld); else { /* non-SNAP */ switch (pd[offset]) { case SAP_IP: capture_ip(pd, offset + llc_header_len, len, ld); break; case SAP_NETWARE1: case SAP_NETWARE2: capture_ipx(ld); break; case SAP_NETBIOS: capture_netbios(ld); break; case SAP_VINES1: case SAP_VINES2: capture_vines(ld); break; default: ld->other++; break; } } }
void capture_clip( const guchar *pd, int len, packet_counts *ld ) { capture_ip(pd, 0, len, ld); }