func main() { // Open device handle, err = pcap.OpenLive(device, snapshot_len, promiscuous, timeout) if err != nil { log.Fatal(err) } defer handle.Close() // Send raw bytes over wire rawBytes := []byte{10, 20, 30} err = handle.WritePacketData(rawBytes) if err != nil { log.Fatal(err) } // Create a properly formed packet, just with // empty details. Should fill out MAC addresses, // IP addresses, etc. buffer = gopacket.NewSerializeBuffer() gopacket.SerializeLayers(buffer, options, &layers.Ethernet{}, &layers.IPv4{}, &layers.TCP{}, gopacket.Payload(rawBytes), ) outgoingPacket := buffer.Bytes() // Send our packet err = handle.WritePacketData(outgoingPacket) if err != nil { log.Fatal(err) } // This time lets fill out some information ipLayer := &layers.IPv4{ SrcIP: net.IP{127, 0, 0, 1}, DstIP: net.IP{8, 8, 8, 8}, } ethernetLayer := &layers.Ethernet{ SrcMAC: net.HardwareAddr{0xFF, 0xAA, 0xFA, 0xAA, 0xFF, 0xAA, 0xFA, 0xAA}, DstMAC: net.HardwareAddr{0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD}, } tcpLayer := &layers.TCP{ SrcPort: layers.TCPPort(4321), DstPort: layers.TCPPort(80), } // And create the packet with the layers buffer = gopacket.NewSerializeBuffer() gopacket.SerializeLayers(buffer, options, ethernetLayer, ipLayer, tcpLayer, gopacket.Payload(rawBytes), ) outgoingPacket = buffer.Bytes() }
func getGratuitousArp(mac net.HardwareAddr, ip net.IP) []byte { // Set up all the layers' fields we can. eth := layers.Ethernet{ SrcMAC: mac, DstMAC: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, EthernetType: layers.EthernetTypeARP, } arp := layers.ARP{ AddrType: layers.LinkTypeEthernet, Protocol: layers.EthernetTypeIPv4, HwAddressSize: 6, ProtAddressSize: 4, Operation: layers.ARPReply, SourceHwAddress: mac, SourceProtAddress: ip.To4(), DstHwAddress: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, DstProtAddress: ip.To4(), } // Set up buffer and options for serialization. buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } // Send one packet for every address. gopacket.SerializeLayers(buf, opts, ð, &arp) return buf.Bytes() }
func getSerializeBuffer() gopacket.SerializeBuffer { buf, _ := serializeBufferPool.Get().(gopacket.SerializeBuffer) if buf != nil { return buf } return gopacket.NewSerializeBuffer() }
func TestPacketIPv6Destination0Serialize(t *testing.T) { var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 2) var err error ip6 := &IPv6{} ip6.Version = 6 ip6.NextHeader = IPProtocolIPv6Destination ip6.HopLimit = 64 ip6.SrcIP = net.ParseIP("2001:db8::1") ip6.DstIP = net.ParseIP("2001:db8::2") serialize = append(serialize, ip6) tlv := &IPv6DestinationOption{} tlv.OptionType = 0x01 //PadN tlv.OptionData = []byte{0x00, 0x00, 0x00, 0x00} dst := &IPv6Destination{} dst.Options = append(dst.Options, *tlv) dst.NextHeader = IPProtocolNoNextHeader serialize = append(serialize, dst) buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true} err = gopacket.SerializeLayers(buf, opts, serialize...) if err != nil { t.Fatal(err) } got := buf.Bytes() want := testPacketIPv6Destination0 if !reflect.DeepEqual(got, want) { t.Errorf("IPv6Destination serialize failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) } }
func newIcmpData(src, dest *net.IPAddr, typeCode, offSet, ttl int) (data []byte) { ip := &layers.IPv4{} ip.Version = 4 ip.Protocol = layers.IPProtocolICMPv4 ip.SrcIP = src.IP ip.DstIP = dest.IP ip.Length = 20 ip.TTL = uint8(ttl) icmp := &layers.ICMPv4{} icmp.TypeCode = layers.ICMPv4TypeCode(uint16(typeCode) << 8) icmp.Id = pid icmp.Seq = 1 icmp.Checksum = 0 opts := gopacket.SerializeOptions{} opts.ComputeChecksums = true opts.FixLengths = true now := time.Now().UnixNano() var payload = make([]byte, 8) binary.LittleEndian.PutUint64(payload, uint64(now)) buf := gopacket.NewSerializeBuffer() gopacket.SerializeLayers(buf, opts, ip, icmp, gopacket.Payload(payload)) return buf.Bytes() }
func v4Defrag(v4frag chan gopacket.Packet, normalPack chan gopacket.Packet) error { defragger := ip4defrag.NewIPv4Defragmenter() for { fragpack := <-v4frag layer := fragpack.Layer(layers.LayerTypeIPv4).(*layers.IPv4) in, err := defragger.DefragIPv4(layer) if err != nil { return err //error handle } else if in == nil { //part of fragment continue continue } else { b := gopacket.NewSerializeBuffer() ops := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } // it should be remebered that you should copy the payload in when you use SerializeTo ip_payload, _ := b.PrependBytes(len(in.Payload)) copy(ip_payload, in.Payload) in.SerializeTo(b, ops) resultPack := gopacket.NewPacket(b.Bytes(), layers.LayerTypeIPv4, gopacket.Default) err := resultPack.ErrorLayer() if err != nil { fmt.Println("Error decoding some part of the packet:", err) //need error handle here //return continue } resultPack.Metadata().CaptureLength = len(resultPack.Data()) resultPack.Metadata().Length = len(resultPack.Data()) fmt.Println("defrag a package") normalPack <- resultPack } } return nil }
func makeTestPacket() []byte { var testSeq uint32 = 12345 buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } eth := layers.Ethernet{ SrcMAC: net.HardwareAddr{0xde, 0xad, 0xbe, 0xee, 0xee, 0xff}, DstMAC: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, } ip := layers.IPv4{ SrcIP: net.IP{1, 2, 3, 4}, DstIP: net.IP{2, 3, 4, 5}, Version: 4, TTL: 64, Protocol: layers.IPProtocolTCP, } tcp := layers.TCP{ SYN: true, SrcPort: 1, DstPort: 2, Seq: testSeq, BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3}}, } tcp.SetNetworkLayerForChecksum(&ip) gopacket.SerializeLayers(buf, opts, ð, &ip, &tcp) packetData := buf.Bytes() return packetData }
func TestSetupPan(t *testing.T) { /* packetManifest := types.PacketManifest{ Timestamp: time.Now(), Flow: nil, RawPacket: nil, IP: ip, TCP: tcp, Payload: payload, } */ buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{} ip0 := net.ParseIP("127.0.0.100") ip1 := net.ParseIP("127.0.0.1") gopacket.SerializeLayers(buf, opts, &layers.Ethernet{}, &layers.IPv4{SrcIP: ip0, DstIP: ip1}, &layers.TCP{}, gopacket.Payload([]byte{1, 2, 3, 4, 5})) packetData := buf.Bytes() assert.NotEqual(t, packetData, nil) }
func packet(raddr net.IP) []byte { ip := &layers.IPv4{ Version: 0x4, TOS: 0x0, TTL: 0x40, Protocol: layers.IPProtocolTCP, SrcIP: net.ParseIP(os.Args[2]), DstIP: raddr, WithRawINETSocket: true, } rand.Seed(time.Now().UnixNano()) tcp := &layers.TCP{ SrcPort: layers.TCPPort(rand.Uint32()), DstPort: 0x50, Seq: rand.Uint32(), DataOffset: 0x5, SYN: true, Window: 0xaaaa, } tcp.SetNetworkLayerForChecksum(ip) buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{true, true} check(gopacket.SerializeLayers(buf, opts, ip, tcp)) return buf.Bytes() }
func TestDNSEncodeQuery(t *testing.T) { dns := &DNS{ID: 1234, OpCode: DNSOpCodeQuery, RD: true} dns.Questions = append(dns.Questions, DNSQuestion{ Name: []byte("example1.com"), Type: DNSTypeA, Class: DNSClassIN, }) dns.Questions = append(dns.Questions, DNSQuestion{ Name: []byte("example2.com"), Type: DNSTypeA, Class: DNSClassIN, }) buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{FixLengths: true} err := gopacket.SerializeLayers(buf, opts, dns) if err != nil { t.Fatal(err) } if int(dns.QDCount) != len(dns.Questions) { t.Errorf("fix lengths did not adjust QDCount, expected %d got %d", len(dns.Questions), dns.QDCount) } p2 := gopacket.NewPacket(buf.Bytes(), LayerTypeDNS, testDecodeOptions) dns2 := p2.Layer(LayerTypeDNS).(*DNS) testDNSEqual(t, dns, dns2) }
func TestGREChecksum(t *testing.T) { buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ ComputeChecksums: true, FixLengths: true, } for cksum, packet := range testGREChecksum { buf.Clear() if err := setNetworkLayer(packet); err != nil { t.Errorf("Failed to set network layer: %v", err) continue } if err := gopacket.SerializeLayers(buf, opts, packet...); err != nil { t.Errorf("Failed to serialize packet: %v", err) continue } p := gopacket.NewPacket(buf.Bytes(), LinkTypeEthernet, gopacket.Default) t.Log(p) if p.ErrorLayer() != nil { t.Error("Failed to decode packet:", p.ErrorLayer().Error()) continue } if got, ok := p.Layer(LayerTypeGRE).(*GRE); ok { if got.Checksum != cksum { t.Errorf("Incorrect checksum calculated for GRE packet: want %v, got %v", cksum, got.Checksum) } } } }
func (dec *EthernetDecoder) sendICMPFragNeeded(mtu int, sendFrame func([]byte) error) error { buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true} ipHeaderSize := int(dec.IP.IHL) * 4 // IHL is the number of 32-byte words in the header payload := gopacket.Payload(dec.IP.BaseLayer.Contents[:ipHeaderSize+8]) err := gopacket.SerializeLayers(buf, opts, &layers.Ethernet{ SrcMAC: dec.Eth.DstMAC, DstMAC: dec.Eth.SrcMAC, EthernetType: dec.Eth.EthernetType}, &layers.IPv4{ Version: 4, TOS: dec.IP.TOS, Id: 0, Flags: 0, FragOffset: 0, TTL: 64, Protocol: layers.IPProtocolICMPv4, DstIP: dec.IP.SrcIP, SrcIP: dec.IP.DstIP}, &layers.ICMPv4{ TypeCode: 0x304, Id: 0, Seq: uint16(mtu)}, &payload) if err != nil { return err } Log.Printf("Sending ICMP 3,4 (%v -> %v): PMTU= %v\n", dec.IP.DstIP, dec.IP.SrcIP, mtu) return sendFrame(buf.Bytes()) }
func TestPacketIPv6HopByHop0Serialize(t *testing.T) { var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 2) var err error ip6 := &IPv6{} ip6.Version = 6 ip6.NextHeader = IPProtocolIPv6HopByHop ip6.HopLimit = 64 ip6.SrcIP = net.ParseIP("2001:db8::1") ip6.DstIP = net.ParseIP("2001:db8::2") serialize = append(serialize, ip6) tlv := &IPv6HopByHopOption{} tlv.OptionType = 0x01 //PadN tlv.OptionData = []byte{0x00, 0x00, 0x00, 0x00} hop := &IPv6HopByHop{} hop.Options = append(hop.Options, tlv) hop.NextHeader = IPProtocolNoNextHeader ip6.HopByHop = hop buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{FixLengths: true} err = gopacket.SerializeLayers(buf, opts, serialize...) if err != nil { t.Fatal(err) } got := buf.Bytes() want := testPacketIPv6HopByHop0 if !bytes.Equal(got, want) { t.Errorf("IPv6HopByHop serialize failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) } }
// Serialised returns []byte representation of this frame. You should treat this as frozen data and // should not modify the contents of returned slice. func (self *Frame) Serialized() ([]byte, error) { if len(self.layers) != 0 { ls := make([]gopacket.SerializableLayer, len(self.layers)) var network gopacket.NetworkLayer for i, layer := range self.layers { switch l := layer.(type) { case *layers.IPv4: network = l case *layers.IPv6: network = l case *layers.TCP: l.SetNetworkLayerForChecksum(network) case *layers.UDP: l.SetNetworkLayerForChecksum(network) case *layers.ICMPv6: l.SetNetworkLayerForChecksum(network) } if t, ok := layer.(gopacket.SerializableLayer); ok { ls[i] = t } else { // XXX: gopacket known issues: // XXX: IPv6 with hop-by-hop header return nil, fmt.Errorf("non serializableLayer %v", layer) } } buf := gopacket.NewSerializeBuffer() if err := gopacket.SerializeLayers(buf, gopacket.SerializeOptions{ComputeChecksums: true, FixLengths: true}, ls...); err != nil { return nil, err } self.layers = self.layers[:0] self.serialized = buf.Bytes() } return self.serialized, nil }
func TestDHCPv4EncodeResponse(t *testing.T) { dhcp := &DHCPv4{Operation: DHCPOpReply, HardwareType: LinkTypeEthernet, Xid: 0x12345678, ClientIP: net.IP{0, 0, 0, 0}, YourClientIP: net.IP{192, 168, 0, 123}, NextServerIP: net.IP{192, 168, 0, 1}, RelayAgentIP: net.IP{0, 0, 0, 0}, ClientHWAddr: net.HardwareAddr{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}, ServerName: make([]byte, 64), File: make([]byte, 128)} dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptMessageType, []byte{byte(DHCPMsgTypeOffer)})) dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptSubnetMask, []byte{255, 255, 255, 0})) dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptT1, []byte{0x00, 0x00, 0x0e, 0x10})) dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptT2, []byte{0x00, 0x00, 0x0e, 0x10})) dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptLeaseTime, []byte{0x00, 0x00, 0x0e, 0x10})) dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptServerID, []byte{192, 168, 0, 1})) buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{FixLengths: true} err := gopacket.SerializeLayers(buf, opts, dhcp) if err != nil { t.Fatal(err) } p2 := gopacket.NewPacket(buf.Bytes(), LayerTypeDHCPv4, testDecodeOptions) dhcp2 := p2.Layer(LayerTypeDHCPv4).(*DHCPv4) testDHCPEqual(t, dhcp, dhcp2) fmt.Print(p2) }
func TestDHCPv4EncodeRequest(t *testing.T) { dhcp := &DHCPv4{Operation: DHCPOpRequest, HardwareType: LinkTypeEthernet, Xid: 0x12345678, ClientIP: net.IP{0, 0, 0, 0}, YourClientIP: net.IP{0, 0, 0, 0}, NextServerIP: net.IP{0, 0, 0, 0}, RelayAgentIP: net.IP{0, 0, 0, 0}, ClientHWAddr: net.HardwareAddr{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}, ServerName: make([]byte, 64), File: make([]byte, 128)} dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptMessageType, []byte{byte(DHCPMsgTypeDiscover)})) dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptHostname, []byte{'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'})) dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptParamsRequest, []byte{byte(DHCPOptSubnetMask), byte(DHCPOptBroadcastAddr), byte(DHCPOptTimeOffset), byte(DHCPOptRouter), byte(DHCPOptDomainName), byte(DHCPOptDNS), byte(DHCPOptDomainSearch), byte(DHCPOptHostname), byte(DHCPOptNetBIOSTCPNS), byte(DHCPOptInterfaceMTU), byte(DHCPOptClasslessStaticRoute), byte(DHCPOptNTPServers)})) buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{FixLengths: true} err := gopacket.SerializeLayers(buf, opts, dhcp) if err != nil { t.Fatal(err) } p2 := gopacket.NewPacket(buf.Bytes(), LayerTypeDHCPv4, testDecodeOptions) dhcp2 := p2.Layer(LayerTypeDHCPv4).(*DHCPv4) testDHCPEqual(t, dhcp, dhcp2) }
// writeARP writes an ARP request for each address on our local network to the // pcap handle. func writeARP(handle *pcap.Handle, iface *net.Interface, addr *net.IPNet) error { // Set up all the layers' fields we can. eth := layers.Ethernet{ SrcMAC: iface.HardwareAddr, DstMAC: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, EthernetType: layers.EthernetTypeARP, } arp := layers.ARP{ AddrType: layers.LinkTypeEthernet, Protocol: layers.EthernetTypeIPv4, HwAddressSize: 6, ProtAddressSize: 4, Operation: layers.ARPRequest, SourceHwAddress: []byte(iface.HardwareAddr), SourceProtAddress: []byte(addr.IP), DstHwAddress: []byte{0, 0, 0, 0, 0, 0}, } // Set up buffer and options for serialization. buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } // Send one packet for every address. for _, ip := range ips(addr) { arp.DstProtAddress = []byte(ip) gopacket.SerializeLayers(buf, opts, ð, &arp) if err := handle.WritePacketData(buf.Bytes()); err != nil { return err } } return nil }
func forgeEthIPTCP(t *testing.T, seed int64) *gopacket.Packet { var options gopacket.SerializeOptions rnd := rand.New(rand.NewSource(seed)) rawBytes := []byte{10, 20, 30} ethernetLayer := &layers.Ethernet{ SrcMAC: net.HardwareAddr{0x00, 0x0F, 0xAA, 0xFA, 0xAA, byte(rnd.Intn(0x100))}, DstMAC: net.HardwareAddr{0x00, 0x0D, 0xBD, 0xBD, byte(rnd.Intn(0x100)), 0xBD}, } ipLayer := &layers.IPv4{ SrcIP: net.IP{127, 0, 0, byte(rnd.Intn(0x100))}, DstIP: net.IP{byte(rnd.Intn(0x100)), 8, 8, 8}, } tcpLayer := &layers.TCP{ SrcPort: layers.TCPPort(byte(rnd.Intn(0x10000))), DstPort: layers.TCPPort(byte(rnd.Intn(0x10000))), } // And create the packet with the layers buffer := gopacket.NewSerializeBuffer() err := gopacket.SerializeLayers(buffer, options, ethernetLayer, ipLayer, tcpLayer, gopacket.Payload(rawBytes), ) if err != nil { t.Fail() } gpacket := gopacket.NewPacket(buffer.Bytes(), layers.LayerTypeEthernet, gopacket.Default) return &gpacket }
// newScanner creates a new scanner for a given destination IP address, using // router to determine how to route packets to that IP. func newScanner(ip net.IP, router routing.Router) (*scanner, error) { s := &scanner{ dst: ip, opts: gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, }, buf: gopacket.NewSerializeBuffer(), } // Figure out the route to the IP. iface, gw, src, err := router.Route(ip) if err != nil { return nil, err } log.Printf("scanning ip %v with interface %v, gateway %v, src %v", ip, iface.Name, gw, src) s.gw, s.src, s.iface = gw, src, iface // Open the handle for reading/writing. // Note we could very easily add some BPF filtering here to greatly // decrease the number of packets we have to look at when getting back // scan results. handle, err := pcap.OpenLive(iface.Name, 65536, true, pcap.BlockForever) if err != nil { return nil, err } s.handle = handle return s, nil }
//need work func (f *fragmentList) build(in gopacket.Packet) (gopacket.Packet, error) { var final []byte var currentOffset uint16 = 0 debug.Printf("defrag: building the datagram \n") for e := f.List.Front(); e != nil; e = e.Next() { pack, _ := e.Value.(gopacket.Packet) frag := pack.Layer(layers.LayerTypeIPv6Fragment).(*layers.IPv6Fragment) ip := pack.Layer(layers.LayerTypeIPv6).(*layers.IPv6) if frag.FragmentOffset*8 == currentOffset { debug.Printf("defrag: building - adding %d\n", frag.FragmentOffset*8) final = append(final, frag.Payload...) currentOffset = currentOffset + ip.Length - 8 } else if frag.FragmentOffset*8 < currentOffset { // overlapping fragment - let's take only what we need startAt := currentOffset - frag.FragmentOffset*8 debug.Printf("defrag: building - overlapping, starting at %d\n", startAt) if startAt > ip.Length-8 { return nil, fmt.Errorf("defrag: building - invalid fragment") } final = append(final, frag.Payload[startAt:]...) currentOffset = currentOffset + frag.FragmentOffset*8 } else { // Houston - we have an hole ! debug.Printf("defrag: hole found while building, " + "stopping the defrag process\n") return nil, fmt.Errorf("defrag: building - hole found") } debug.Printf("defrag: building - next is %d\n", currentOffset) } final_ipv6 := in.Layer(layers.LayerTypeIPv6).(*layers.IPv6) final_frag := in.Layer(layers.LayerTypeIPv6Fragment).(*layers.IPv6Fragment) // TODO recompute IP Checksum out := &layers.IPv6{ Version: final_ipv6.Version, TrafficClass: final_ipv6.TrafficClass, FlowLabel: final_ipv6.FlowLabel, Length: f.Highest, NextHeader: final_frag.NextHeader, HopLimit: final_ipv6.HopLimit, SrcIP: final_ipv6.SrcIP, DstIP: final_ipv6.DstIP, HopByHop: final_ipv6.HopByHop, } out.Payload = final v6SerailizeBuffer := gopacket.NewSerializeBuffer() v6Buffer, _ := v6SerailizeBuffer.PrependBytes(len(final)) copy(v6Buffer, final) ops := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } out.SerializeTo(v6SerailizeBuffer, ops) outPacket := gopacket.NewPacket(v6SerailizeBuffer.Bytes(), layers.LayerTypeIPv6, gopacket.Default) outPacket.Metadata().CaptureLength = len(outPacket.Data()) outPacket.Metadata().Length = len(outPacket.Data()) return outPacket, nil }
func main() { // If we don't have a handle to a device or a file, but we have a bunch // of raw bytes, we can try to decode them in to packet information // NewPacket() takes the raw bytes that make up the packet as the first parameter // The second parameter is the lowest level layer you want to decode. It will // decode that layer and all layers on top of it. The third layer // is the type of decoding: default(all at once), lazy(on demand), and NoCopy // which will not create a copy of the buffer // Create an packet with ethernet, IP, TCP, and payload layers // We are creating one we know will be decoded properly but // your byte source could be anything. If any of the packets // come back as nil, that means it could not decode it in to // the proper layer (malformed or incorrect packet type) payload := []byte{2, 4, 6} options := gopacket.SerializeOptions{} buffer := gopacket.NewSerializeBuffer() gopacket.SerializeLayers(buffer, options, &layers.Ethernet{}, &layers.IPv4{}, &layers.TCP{}, gopacket.Payload(payload), ) rawBytes := buffer.Bytes() // Decode an ethernet packet ethPacket := gopacket.NewPacket( rawBytes, layers.LayerTypeEthernet, gopacket.Default, ) // with Lazy decoding it will only decode what it needs when it needs it // This is not concurrency safe. If using concurrency, use default ipPacket := gopacket.NewPacket( rawBytes, layers.LayerTypeIPv4, gopacket.Lazy, ) // With the NoCopy option, the underlying slices are referenced // directly and not copied. If the underlying bytes change so will // the packet tcpPacket := gopacket.NewPacket( rawBytes, layers.LayerTypeTCP, gopacket.NoCopy, ) fmt.Println(ethPacket) fmt.Println(ipPacket) fmt.Println(tcpPacket) }
/* protos must contain a UDP or TCP layer on top of IPv4 */ func forgeTestPacket(t *testing.T, seed int64, protos ...ProtocolType) *gopacket.Packet { rnd := rand.New(rand.NewSource(seed)) rawBytes := []byte{10, 20, 30} var protoStack []gopacket.SerializableLayer for i, proto := range protos { switch proto { case ETH: ethernetLayer := &layers.Ethernet{ SrcMAC: net.HardwareAddr{0x00, 0x0F, 0xAA, 0xFA, 0xAA, byte(rnd.Intn(0x100))}, DstMAC: net.HardwareAddr{0x00, 0x0D, 0xBD, 0xBD, byte(rnd.Intn(0x100)), 0xBD}, EthernetType: layers.EthernetTypeIPv4, } protoStack = append(protoStack, ethernetLayer) case IPv4: ipv4Layer := &layers.IPv4{ SrcIP: net.IP{127, 0, 0, byte(rnd.Intn(0x100))}, DstIP: net.IP{byte(rnd.Intn(0x100)), 8, 8, 8}, } switch protos[i+1] { case TCP: ipv4Layer.Protocol = layers.IPProtocolTCP case UDP: ipv4Layer.Protocol = layers.IPProtocolUDP } protoStack = append(protoStack, ipv4Layer) case TCP: tcpLayer := &layers.TCP{ SrcPort: layers.TCPPort(byte(rnd.Intn(0x10000))), DstPort: layers.TCPPort(byte(rnd.Intn(0x10000))), } protoStack = append(protoStack, tcpLayer) case UDP: udpLayer := &layers.UDP{ SrcPort: layers.UDPPort(byte(rnd.Intn(0x10000))), DstPort: layers.UDPPort(byte(rnd.Intn(0x10000))), } protoStack = append(protoStack, udpLayer) default: t.Log("forgeTestPacket : Unsupported protocol ", proto) } } protoStack = append(protoStack, gopacket.Payload(rawBytes)) buffer := gopacket.NewSerializeBuffer() options := gopacket.SerializeOptions{FixLengths: true} err := gopacket.SerializeLayers(buffer, options, protoStack...) if err != nil { t.Fail() } gpacket := gopacket.NewPacket(buffer.Bytes(), layers.LayerTypeEthernet, gopacket.Default) return &gpacket }
/* FUNCTION: writePoison(arpPacket layers.ARP, etherPacket layers.Ethernet){ RETURNS: Nothing ARGUMENTS: *layers.ARP arpPacket - the arp packet to write to the line *layers.Ethernet etherPacket - the ethernet packet to write to the line ABOUT: Actually writes the arp and ethernet packets used in poisoning to the global handle. */ func writePoison(arpPacket layers.ARP, etherPacket layers.Ethernet) { buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{} gopacket.SerializeLayers(buf, opts, ðerPacket, &arpPacket) packetData := buf.Bytes() err := handle.WritePacketData(packetData[:42]) checkError(err) }
func BenchmarkEncodePacketEthernetOverGRE(b *testing.B) { buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ ComputeChecksums: true, FixLengths: true, } for i := 0; i < b.N; i++ { gopacket.SerializeLayers(buf, opts, testEthernetOverGRE...) buf.Clear() } }
func fragment(eth layers.Ethernet, ip layers.IPv4, mtu int, forward func([]byte)) error { // We are not doing any sort of NAT, so we don't need to worry // about checksums of IP payload (eg UDP checksum). headerSize := int(ip.IHL) * 4 // &^ is bit clear (AND NOT). So here we're clearing the lowest 3 // bits. maxSegmentSize := (mtu - headerSize) &^ 7 opts := gopacket.SerializeOptions{ FixLengths: false, ComputeChecksums: true} payloadSize := int(ip.Length) - headerSize payload := ip.BaseLayer.Payload[:payloadSize] offsetBase := int(ip.FragOffset) << 3 origFlags := ip.Flags ip.Flags = ip.Flags | layers.IPv4MoreFragments ip.Length = uint16(headerSize + maxSegmentSize) if eth.EthernetType == layers.EthernetTypeLLC { // using LLC, so must set eth length correctly. eth length // is just the length of the payload eth.Length = ip.Length } else { eth.Length = 0 } for offset := 0; offset < payloadSize; offset += maxSegmentSize { var segmentPayload []byte if len(payload) <= maxSegmentSize { // last one segmentPayload = payload ip.Length = uint16(len(payload) + headerSize) ip.Flags = origFlags if eth.EthernetType == layers.EthernetTypeLLC { eth.Length = ip.Length } else { eth.Length = 0 } } else { segmentPayload = payload[:maxSegmentSize] payload = payload[maxSegmentSize:] } ip.FragOffset = uint16((offset + offsetBase) >> 3) buf := gopacket.NewSerializeBuffer() segPayload := gopacket.Payload(segmentPayload) err := gopacket.SerializeLayers(buf, opts, ð, &ip, &segPayload) if err != nil { return err } forward(buf.Bytes()) } return nil }
/* FUNCTION: craftAnswer(ethernetLayer *layers.Ethernet, ipLayer *layers.IPv4, dnsLayer *layers.DNS, udpLayer *layers.UDP) []byte{ RETURNS: Byte array containing the spoofed response DNS packet data ARGUMENTS: *layers.Ethernet ethernetLayer - the ethernet part of the packet recieved *layers.DNS dnsLayer - the dns part of the packet recieved *layers.IPv4 ipLayer - the ip part of the packet recieved *layers.UDP udpLayer - the udp part of the packet recieved ABOUT: Crafts a spoofed dns packet using the incoming query. */ func craftAnswer(ethernetLayer *layers.Ethernet, ipLayer *layers.IPv4, dnsLayer *layers.DNS, udpLayer *layers.UDP) []byte { //if not a question return if dnsLayer.QR || ipLayer.SrcIP.String() != target { return nil } //must build every layer to send DNS packets ethMac := ethernetLayer.DstMAC ethernetLayer.DstMAC = ethernetLayer.SrcMAC ethernetLayer.SrcMAC = ethMac ipSrc := ipLayer.SrcIP ipLayer.SrcIP = ipLayer.DstIP ipLayer.DstIP = ipSrc srcPort := udpLayer.SrcPort udpLayer.SrcPort = udpLayer.DstPort udpLayer.DstPort = srcPort err = udpLayer.SetNetworkLayerForChecksum(ipLayer) checkError(err) var answer layers.DNSResourceRecord answer.Type = layers.DNSTypeA answer.Class = layers.DNSClassIN answer.TTL = 200 answer.IP = ipAddr dnsLayer.QR = true for _, q := range dnsLayer.Questions { if q.Type != layers.DNSTypeA || q.Class != layers.DNSClassIN { continue } answer.Name = q.Name dnsLayer.Answers = append(dnsLayer.Answers, answer) dnsLayer.ANCount = dnsLayer.ANCount + 1 } buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } err = gopacket.SerializeLayers(buf, opts, ethernetLayer, ipLayer, udpLayer, dnsLayer) checkError(err) return buf.Bytes() }
func SentPacket(layers ...gopacket.SerializableLayer) error { // Set up buffer and options for serialization. buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } if err := gopacket.SerializeLayers(buf, opts, layers...); err != nil { return err } return pcapHandle.WritePacketData(buf.Bytes()) }
func TestIPv6JumbogramUDPChecksum(t *testing.T) { var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 4) var u *UDP var err error ip6 := &IPv6{} ip6.Version = 6 ip6.NextHeader = IPProtocolUDP ip6.HopLimit = 64 ip6.SrcIP = net.ParseIP("2001:db8::1") ip6.DstIP = net.ParseIP("2001:db8::2") serialize = append(serialize, ip6) udp := &UDP{} udp.SrcPort = UDPPort(12345) udp.DstPort = UDPPort(9999) udp.SetNetworkLayerForChecksum(ip6) serialize = append(serialize, udp) payload := make([]byte, ipv6MaxPayloadLength+1) for i := range payload { payload[i] = 0xfe } serialize = append(serialize, gopacket.Payload(payload)) buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true} err = gopacket.SerializeLayers(buf, opts, serialize...) if err != nil { t.Fatal(err) } p := gopacket.NewPacket(buf.Bytes(), LinkTypeRaw, gopacket.Default) if p.ErrorLayer() != nil { t.Fatal("Failed to decode packet:", p.ErrorLayer().Error()) } checkLayers(p, []gopacket.LayerType{LayerTypeIPv6, LayerTypeIPv6HopByHop, LayerTypeUDP, gopacket.LayerTypePayload}, t) if l, ok := p.Layer(LayerTypeUDP).(*UDP); !ok { t.Fatal("No UDP layer type found in packet") } else { u = l } got := u.Checksum want := ipv6UDPChecksumJumbogram if got != want { t.Errorf("Bad checksum:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) } }
func (i *TCPStreamInjector) Write() error { i.tcp.SetNetworkLayerForChecksum(&i.ip) i.tcpPayloadBuf = gopacket.NewSerializeBuffer() // packetPayload := gopacket.Payload(i.Payload) packetPayload := i.Payload opts := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } err := gopacket.SerializeLayers(i.tcpPayloadBuf, opts, &i.tcp, packetPayload) if err != nil { return err } err = i.rawConn.WriteTo(i.ipHeader, i.tcpPayloadBuf.Bytes(), nil) return err }
func newUDPSenderDF(localIP net.IP, localPort int) *udpSenderDF { return &udpSenderDF{ ipBuf: gopacket.NewSerializeBuffer(), opts: gopacket.SerializeOptions{ FixLengths: true, // UDP header is calculated with a phantom IP // header. Yes, it's totally nuts. Thankfully, // for UDP over IPv4, the checksum is // optional. It's not optional for IPv6, but // we'll ignore that for now. TODO ComputeChecksums: false, }, udpHeader: &layers.UDP{SrcPort: layers.UDPPort(localPort)}, localIP: localIP, } }