func (h *dnsStream) creatPacket(msg_buf []byte, nomalPack chan gopacket.Packet) { var sourcePort, DesPort int16 //read the port from tranport flow b_buf := bytes.NewBuffer(h.transport.Src().Raw()) binary.Read(b_buf, binary.BigEndian, &sourcePort) b_buf = bytes.NewBuffer(h.transport.Dst().Raw()) binary.Read(b_buf, binary.BigEndian, &DesPort) //new a UDP layer udpLayer := layers.UDP{ BaseLayer: layers.BaseLayer{ Contents: []byte{}, Payload: msg_buf, }, SrcPort: layers.UDPPort(sourcePort), DstPort: layers.UDPPort(DesPort), Length: 1024, Checksum: 30026, } UDPNewSerializBuffer := gopacket.NewSerializeBuffer() // this buffer could be used as a payload of IP layer udpBuffer, _ := UDPNewSerializBuffer.PrependBytes(len(msg_buf)) copy(udpBuffer, msg_buf) ops := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } if h.net.EndpointType() == layers.EndpointIPv4 { ip_checksum := layers.IPv4{} ip_checksum.Version = 4 ip_checksum.TTL = 0 ip_checksum.SrcIP = h.net.Src().Raw() ip_checksum.DstIP = h.net.Dst().Raw() udpLayer.SetNetworkLayerForChecksum(&ip_checksum) } else { ip6_checksum := layers.IPv6{} ip6_checksum.Version = 6 ip6_checksum.NextHeader = layers.IPProtocolNoNextHeader ip6_checksum.HopLimit = 0 ip6_checksum.SrcIP = h.net.Src().Raw() ip6_checksum.DstIP = h.net.Dst().Raw() udpLayer.SetNetworkLayerForChecksum(&ip6_checksum) } err := udpLayer.SerializeTo(UDPNewSerializBuffer, ops) if err != nil { fmt.Print("error in create udp Layer") return //err = nil // need err handle there } fmt.Println("finished creat udplayer, the length is ", udpLayer.Length) if h.net.EndpointType() == layers.EndpointIPv4 { // if it is from ipv4, construct a ipv4 layer ip := layers.IPv4{ BaseLayer: layers.BaseLayer{ Contents: []byte{}, Payload: UDPNewSerializBuffer.Bytes(), }, Version: 4, IHL: 0, TOS: 0, Length: 0, Id: 0, Flags: 0, FragOffset: 0, TTL: 0, Protocol: layers.IPProtocolUDP, Checksum: 0, SrcIP: h.net.Src().Raw(), DstIP: h.net.Dst().Raw(), Options: []layers.IPv4Option{}, Padding: []byte{}, } //serialize it and use the serilize buffer to new packet IPserializeBuffer := gopacket.NewSerializeBuffer() ipBuffer, _ := IPserializeBuffer.PrependBytes(len(UDPNewSerializBuffer.Bytes())) copy(ipBuffer, UDPNewSerializBuffer.Bytes()) err = ip.SerializeTo(IPserializeBuffer, ops) if err != nil { fmt.Print("error in create ipv4 Layer") return //err = nil // need err handle there } fmt.Println("finished creat ip, the length is ", ip.Length) resultPack := gopacket.NewPacket(IPserializeBuffer.Bytes(), layers.LayerTypeIPv4, gopacket.Default) resultPack.Metadata().CaptureLength = len(resultPack.Data()) resultPack.Metadata().Length = len(resultPack.Data()) //seems the capture length is 0 so the pcapwrite cannot write it, try to give them a write value nomalPack <- resultPack return } else if h.net.EndpointType() == layers.EndpointIPv6 { // if it is in IPV6 contruct ipv6 packet ip := layers.IPv6{ BaseLayer: layers.BaseLayer{ Contents: []byte{}, Payload: UDPNewSerializBuffer.Bytes(), }, Version: 6, TrafficClass: 0, FlowLabel: 0, Length: 0, NextHeader: layers.IPProtocolNoNextHeader, //no sure what next header should be used there HopLimit: 0, SrcIP: h.net.Src().Raw(), DstIP: h.net.Dst().Raw(), HopByHop: nil, // hbh will be pointed to by HopByHop if that layer exists. } IPserializeBuffer := gopacket.NewSerializeBuffer() err := ip.SerializeTo(IPserializeBuffer, ops) if err != nil { fmt.Printf("error in creat IPV6 Layer") return } fmt.Println("finished creat ip, the length is ", ip.Length) resultPack := gopacket.NewPacket(IPserializeBuffer.Bytes(), layers.LayerTypeIPv6, gopacket.Default) resultPack.Metadata().CaptureLength = len(resultPack.Data()) resultPack.Metadata().Length = len(resultPack.Data()) //seems the capture length is 0 so the pcapwrite cannot write it, try to give them a write value nomalPack <- resultPack return } else { return //unknown network just return? } }