func testSerialization(t *testing.T, p gopacket.Packet, data []byte) { // Test re-serialization. slayers := []gopacket.SerializableLayer{} for _, l := range p.Layers() { slayers = append(slayers, l.(gopacket.SerializableLayer)) if h, ok := l.(canSetNetLayer); ok { if err := h.SetNetworkLayerForChecksum(p.NetworkLayer()); err != nil { t.Fatal("can't set network layer:", err) } } } for _, opts := range []gopacket.SerializeOptions{ gopacket.SerializeOptions{}, gopacket.SerializeOptions{FixLengths: true}, gopacket.SerializeOptions{ComputeChecksums: true}, gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}, } { buf := gopacket.NewSerializeBuffer() err := gopacket.SerializeLayers(buf, opts, slayers...) if err != nil { t.Errorf("unable to reserialize layers with opts %#v: %v", opts, err) } else if !bytes.Equal(buf.Bytes(), data) { t.Errorf("serialization failure with opts %#v:\n---want---\n%v\n---got---\n%v\nBASH-colorized diff, want->got:\n%v", opts, hex.Dump(data), hex.Dump(buf.Bytes()), diffString(data, buf.Bytes())) } } }
// readARP watches a handle for incoming ARP responses we might care about, and prints them. // // readARP loops until 'stop' is closed. func readARP(handle *pcap.Handle, iface *net.Interface, stop chan struct{}) { src := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet) in := src.Packets() for { var packet gopacket.Packet select { case <-stop: return case packet = <-in: arpLayer := packet.Layer(layers.LayerTypeARP) if arpLayer == nil { continue } arp := arpLayer.(*layers.ARP) if arp.Operation != layers.ARPReply || bytes.Equal([]byte(iface.HardwareAddr), arp.SourceHwAddress) { // This is a packet I sent. continue } // Note: we might get some packets here that aren't responses to ones we've sent, // if for example someone else sends US an ARP request. Doesn't much matter, though... // all information is good information :) log.Printf("IP %v is at %v", net.IP(arp.SourceProtAddress), net.HardwareAddr(arp.SourceHwAddress)) } } }
func checkLayers(p gopacket.Packet, want []gopacket.LayerType, t *testing.T) { layers := p.Layers() t.Log("Checking packet layers, want", want) for _, l := range layers { t.Logf(" Got layer %v, %d bytes, payload of %d bytes", l.LayerType(), len(l.LayerContents()), len(l.LayerPayload())) } t.Log(p) if len(layers) != len(want) { t.Errorf(" Number of layers mismatch: got %d want %d", len(layers), len(want)) return } for i, l := range layers { if l.LayerType() != want[i] { t.Errorf(" Layer %d mismatch: got %v want %v", i, l.LayerType(), want[i]) } } }
func handlePacket(p gopacket.Packet) { ap := AP{} // extract beacon // extract Ssid for _, l := range p.Layers() { switch l.LayerType() { case layers.LayerTypeDot11MgmtBeacon: beacon, ok := p.Layer(layers.LayerTypeDot11MgmtBeacon).(*layers.Dot11MgmtBeacon) if !ok { log.Println("Could not marshal layer thing") continue } pack := gopacket.NewPacket(beacon.LayerContents(), layers.LayerTypeDot11MgmtBeacon, gopacket.Default) for _, subpack := range pack.Layers() { info, ok := subpack.(*layers.Dot11InformationElement) if !ok { continue } if info.ID == layers.Dot11InformationElementIDSSID { ap.Ssid = fmt.Sprintf("%s", info.Info) break } } case layers.LayerTypeDot11: base, ok := p.Layer(layers.LayerTypeDot11).(*layers.Dot11) if !ok { continue } ap.Bssid = base.Address2 continue case layers.LayerTypeRadioTap: radio, ok := p.Layer(layers.LayerTypeRadioTap).(*layers.RadioTap) if !ok { continue } ap.Channel = radio.ChannelFrequency continue } } APList[ap.Ssid] = ap }
func handlePacket(packet gopacket.Packet, counter chan *PacketCount) { appLayer := packet.ApplicationLayer() if appLayer == nil { return } if networkLayer := packet.NetworkLayer(); networkLayer != nil { srcIP := networkLayer.NetworkFlow().Src().String() dstIP := networkLayer.NetworkFlow().Dst().String() meta := packet.Metadata() counter <- &PacketCount{ src: srcIP, dst: dstIP, size: uint64(meta.Length), } } }
// Packet information digestion ------------------------------------------------------ // function that takes the raw packet and creates a GPPacket structure from it. Initial // sanity checking has been performed in the function above, so we can now check whether // the packet can be decoded directly func (g *GPCapture) handlePacket(curPack gopacket.Packet) (*GPPacket, error) { // process metadata var numBytes uint16 = uint16(curPack.Metadata().CaptureInfo.Length) // read the direction from which the packet entered the interface isInboundTraffic := false if curPack.Metadata().CaptureInfo.Inbound == 1 { isInboundTraffic = true } // initialize vars (GO ensures that all variables are initialized with their // respective zero element) var ( src, dst []byte = zeroip, zeroip sp, dp []byte = zeroport, zeroport // the default value is reserved by IANA and thus will never occur unless // the protocol could not be correctly identified proto byte = 0xff fragBits byte = 0x00 fragOffset uint16 TCPflags uint8 l7payload []byte = zeropayload l7payloadSize uint16 // size helper vars nlHeaderSize uint16 tpHeaderSize uint16 ) // decode rest of packet if curPack.NetworkLayer() != nil { nw_l := curPack.NetworkLayer().LayerContents() nlHeaderSize = uint16(len(nw_l)) // exit if layer is available but the bytes aren't captured by the layer // contents if nlHeaderSize == 0 { return nil, errors.New("Network layer header not available") } // get ip info ipsrc, ipdst := curPack.NetworkLayer().NetworkFlow().Endpoints() src = ipsrc.Raw() dst = ipdst.Raw() // read out the next layer protocol switch curPack.NetworkLayer().LayerType() { case layers.LayerTypeIPv4: proto = nw_l[9] // check for IP fragmentation fragBits = (0xe0 & nw_l[6]) >> 5 fragOffset = (uint16(0x1f & nw_l[6]) << 8) | uint16(nw_l[7]) // return decoding error if the packet carries anything other than the // first fragment, i.e. if the packet lacks a transport layer header if fragOffset != 0 { return nil, errors.New("Fragmented IP packet: offset: "+strconv.FormatUint(uint64(fragOffset), 10)+" flags: "+strconv.FormatUint(uint64(fragBits), 10)) } case layers.LayerTypeIPv6: proto = nw_l[6] } if curPack.TransportLayer() != nil { // get layer contents tp_l := curPack.TransportLayer().LayerContents() tpHeaderSize = uint16(len(tp_l)) if tpHeaderSize == 0 { return nil, errors.New("Transport layer header not available") } // get port bytes psrc, dsrc := curPack.TransportLayer().TransportFlow().Endpoints() // only get raw bytes if we actually have TCP or UDP if proto == 6 || proto == 17 { sp = psrc.Raw() dp = dsrc.Raw() } // if the protocol is TCP, grab the flag information if proto == 6 { if tpHeaderSize < 14 { return nil, errors.New("Incomplete TCP header: "+string(tp_l)) } TCPflags = tp_l[13] // we are primarily interested in SYN, ACK and FIN } // grab the next layer payload's first 4 bytes and calculate // the layer 7 payload size if the application layer could // be correctly decoded if curPack.ApplicationLayer() != nil { pl := curPack.ApplicationLayer().Payload() lenPayload := len(pl) if lenPayload >= 4 { l7payload = pl[0:4] } else { for i := 0; i < lenPayload; i++ { l7payload[i] = pl[i] } } } l7payloadSize = numBytes - tpHeaderSize - nlHeaderSize } } else { return nil, errors.New("network layer decoding failed") } return NewGPPacket(src, dst, sp, dp, l7payload, l7payloadSize, proto, numBytes, TCPflags, isInboundTraffic), nil }
func originalSize(packet gopacket.Packet) int { return len(packet.NetworkLayer().LayerPayload()) + len(packet.NetworkLayer().LayerContents()) }
//Returns both the source & destination IP. func getSrcDstIP(packet gopacket.Packet) (net.IP, net.IP) { ipLayer := packet.Layer(layers.LayerTypeIPv4) // Get IP data from this layer ip, _ := ipLayer.(*layers.IPv4) return ip.SrcIP, ip.DstIP }