def iterPcapFile(fd, reuse=False): h = PCAP_FILE_HEADER() b = fd.read(len(h)) h.vsParse(b, fast=True) linktype = h.linktype if linktype not in (PCAP_LINKTYPE_ETHER, PCAP_LINKTYPE_RAW): raise Exeption('PCAP Link Type %d Not Supported Yet!' % linktype) pkt = PCAP_PACKET_HEADER() eII = vs_inet.ETHERII() pktsize = len(pkt) eIIsize = len(eII) ipv4 = vs_inet.IPv4() tcp_hdr = vs_inet.TCP() udp_hdr = vs_inet.UDP() go = True while go: hdr = fd.read(pktsize) if len(hdr) != pktsize: break pkt.vsParse(hdr, fast=True) b = fd.read(pkt.caplen) offset = 0 if linktype == PCAP_LINKTYPE_ETHER: if len(b) < eIIsize: continue eII.vsParse(b, 0, fast=True) # No support for non-ip protocol yet... if eII.etype not in (vs_inet.ETH_P_IP, vs_inet.ETH_P_VLAN): continue offset += eIIsize if eII.etype == vs_inet.ETH_P_VLAN: offset += 4 elif linktype == PCAP_LINKTYPE_RAW: pass #print eII.tree() if not reuse: ipv4 = vs_inet.IPv4() ipv4.vsParse(b, offset, fast=True) # Make b *only* the IP datagram bytes... b = b[offset:offset + ipv4.totlen] offset = 0 offset += len(ipv4) tsize = len(b) - offset if ipv4.proto == vs_inet.IPPROTO_TCP: if tsize < 20: continue if not reuse: tcp_hdr = vs_inet.TCP() tcp_hdr.vsParse(b, offset, fast=True) offset += len(tcp_hdr) pdata = b[offset:] yield pkt, ipv4, tcp_hdr, pdata elif ipv4.proto == vs_inet.IPPROTO_UDP: if tsize < 8: continue if not reuse: udp_hdr = vs_inet.UDP() udp_hdr.vsParse(b, offset, fast=True) offset += len(udp_hdr) pdata = b[offset:] yield pkt, ipv4, udp_hdr, pdata else: pass
def _parsePcapngPacketBytes(linktype, pkt): ''' pkt is either a parsed PCAPNG_SIMPLE_PACKET_BLOCK or PCAPNG_ENHANCED_PACKET_BLOCK On success Returns tuple (pcapng_pkt, ipv4_vstruct, transport_vstruc, pdata) Returns None if the packet can't be parsed ''' if linktype not in (PCAP_LINKTYPE_ETHER, PCAP_LINKTYPE_RAW): raise Exception('PCAP Link Type %d Not Supported Yet!' % linktype) #pkt = PCAP_PACKET_HEADER() eII = vs_inet.ETHERII() eIIsize = len(eII) offset = 0 if linktype == PCAP_LINKTYPE_ETHER: if len(pkt.data) < eIIsize: return None eII.vsParse(pkt.data, 0, fast=True) # No support for non-ip protocol yet... if eII.etype not in (vs_inet.ETH_P_IP, vs_inet.ETH_P_VLAN): return None offset += eIIsize if eII.etype == vs_inet.ETH_P_VLAN: offset += 4 elif linktype == PCAP_LINKTYPE_RAW: pass ipv4 = vs_inet.IPv4() if (len(pkt.data) - offset) < len(ipv4): return None ipv4.vsParse(pkt.data, offset, fast=True) # Make b *only* the IP datagram bytes... b = pkt.data[offset:offset + ipv4.totlen] offset = 0 offset += len(ipv4) tsize = len(b) - offset if ipv4.proto == vs_inet.IPPROTO_TCP: if tsize < 20: return None tcp_hdr = vs_inet.TCP() tcp_hdr.vsParse(b, offset, fast=True) offset += len(tcp_hdr) pdata = b[offset:] return pkt, ipv4, tcp_hdr, pdata elif ipv4.proto == vs_inet.IPPROTO_UDP: if tsize < 8: return None udp_hdr = vs_inet.UDP() udp_hdr.vsParse(b, offset, fast=True) offset += len(udp_hdr) pdata = b[offset:] return pkt, ipv4, udp_hdr, pdata elif ipv4.proto == vs_inet.IPPROTO_ICMP: if tsize < 4: return None icmp_hdr = vs_inet.ICMP() icmp_hdr.vsParse(b, offset, fast=True) offset += len(icmp_hdr) pdata = b[offset:] return pkt, ipv4, icmp_hdr, pdata else: logger.warning('UNHANDLED IP PROTOCOL: %d', ipv4.proto) return None