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 Testv4Defrag(t *testing.T) { v4defragger := ip4defrag.NewIPv4Defragmenter() pack1 := gopacket.NewPacket(testPing1Frag1, layers.LinkTypeEthernet, gopacket.Default) pack2 := gopacket.NewPacket(testPing1Frag2, layers.LinkTypeEthernet, gopacket.Default) pack3 := gopacket.NewPacket(testPing1Frag3, layers.LinkTypeEthernet, gopacket.Default) pack4 := gopacket.NewPacket(testPing1Frag4, layers.LinkTypeEthernet, gopacket.Default) result, err := v4defragger.DefragIPv4(pack1.Layer(layers.LayerTypeIPv4).(*layers.IPv4)) if err != nil { t.Fatalf("error defragmenting pack1") } if result != nil { t.Fatalf("unexpected defragmented packet after pack1") } result, err = v4defragger.DefragIPv4(pack2.Layer(layers.LayerTypeIPv4).(*layers.IPv4)) if err != nil { t.Fatalf("error defragmenting pack2") } if result != nil { t.Fatalf("unexpected defragmented packet after pack2") } result, err = v4defragger.DefragIPv4(pack3.Layer(layers.LayerTypeIPv4).(*layers.IPv4)) if err != nil { t.Fatalf("error defragmenting pack3") } if result != nil { t.Fatalf("unexpected defragmented packet after pack3") } result, err = v4defragger.DefragIPv4(pack4.Layer(layers.LayerTypeIPv4).(*layers.IPv4)) if err != nil { t.Fatalf("error defragmenting pack4") } if result == nil { t.Fatalf("missing defragmented packet after pack4") } ip := result // TEST if the ip matches expectation if ip == nil { t.Errorf("defrag does not return IPV4 LAYER") } if len(ip.LayerPayload()) != 4508 { t.Fatalf("defrag: expecting a packet of 4508 bytes, got %d", len(ip.LayerPayload())) } validPayload := append(testPing1Frag1[34:], testPing1Frag2[34:]...) validPayload = append(validPayload, testPing1Frag3[34:]...) validPayload = append(validPayload, testPing1Frag4[34:]...) if bytes.Compare(validPayload, ip.LayerPayload()) != 0 { fmt.Println(bytediff.BashOutput.String( bytediff.Diff(validPayload, ip.LayerPayload()))) t.Errorf("defrag: payload is not correctly defragmented") } }
func TestnotFrag(t *testing.T) { ip := layers.IPv4{ Version: 4, TTL: 220, SrcIP: net.IPv4(1, 1, 1, 1), DstIP: net.IPv4(2, 2, 2, 2), Flags: layers.IPv4DontFragment, } v4defragger := ip4defrag.NewIPv4Defragmenter() b := gopacket.NewSerializeBuffer() ops := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } ip.SerializeTo(b, ops) pack := gopacket.NewPacket(b.Bytes(), layers.LinkTypeIPv4, gopacket.Default) _, err := v4defragger.DefragIPv4(pack.Layer(layers.LayerTypeIPv4).(*layers.IPv4)) if err != nil { t.Errorf("v4defrag do not return err when no frag pack is in") } }
func Run(src gopacket.PacketDataSource) { if !flag.Parsed() { log.Fatalln("Run called without flags.Parse() being called") } var dec gopacket.Decoder var ok bool if dec, ok = gopacket.DecodersByLayerName[*decoder]; !ok { log.Fatalln("No decoder named", *decoder) } source := gopacket.NewPacketSource(src, dec) source.Lazy = *lazy source.NoCopy = true fmt.Fprintln(os.Stderr, "Starting to read packets") count := 0 bytes := int64(0) start := time.Now() errors := 0 truncated := 0 layertypes := map[gopacket.LayerType]int{} defragger := ip4defrag.NewIPv4Defragmenter() for packet := range source.Packets() { count++ bytes += int64(len(packet.Data())) // defrag the IPv4 packet if required if *defrag { ip4Layer := packet.Layer(layers.LayerTypeIPv4) if ip4Layer == nil { continue } ip4 := ip4Layer.(*layers.IPv4) l := ip4.Length newip4, err := defragger.DefragIPv4(ip4) if err != nil { log.Fatalln("Error while de-fragmenting", err) } else if newip4 == nil { continue // packet fragment, we don't have whole packet yet. } if newip4.Length != l { fmt.Printf("Decoding re-assembled packet: %s\n", newip4.NextLayerType()) pb, ok := packet.(gopacket.PacketBuilder) if !ok { panic("Not a PacketBuilder") } nextDecoder := newip4.NextLayerType() nextDecoder.Decode(newip4.Payload, pb) } } if *dump { fmt.Println(packet.Dump()) } else if *print { fmt.Println(packet) } if !*lazy || *print || *dump { // if we've already decoded all layers... for _, layer := range packet.Layers() { layertypes[layer.LayerType()]++ } if packet.Metadata().Truncated { truncated++ } if errLayer := packet.ErrorLayer(); errLayer != nil { errors++ if *printErrors { fmt.Println("Error:", errLayer.Error()) fmt.Println("--- Packet ---") fmt.Println(packet.Dump()) } } } done := *maxcount > 0 && count >= *maxcount if count%*statsevery == 0 || done { fmt.Fprintf(os.Stderr, "Processed %v packets (%v bytes) in %v, %v errors and %v truncated packets\n", count, bytes, time.Since(start), errors, truncated) if len(layertypes) > 0 { fmt.Fprintf(os.Stderr, "Layer types seen: %+v\n", layertypes) } } if done { break } } }