func main() { opened := 0 closed := 0 udpAddr, _ := net.ResolveUDPAddr("udp", ":6343") conn, err := net.ListenUDP("udp", udpAddr) fmt.Println(err) buf := make([]byte, 65535) for { n, _, err := conn.ReadFromUDP(buf) if err == nil { datagram := sflow.Decode(buf[0:n]) for _, sample := range datagram.Samples { switch sample.SampleType() { case sflow.TypeFlowSample: fs := sample.(sflow.FlowSample) for _, record := range fs.Records { if record.RecordType() == sflow.TypeRawPacketFlow { r := record.(sflow.RawPacketFlowRecord) _, ipHdr, protoHdr := ethernetdecode.Decode(r.Header) if ipHdr != nil && ipHdr.IpVersion() == 4 { ipv4 := ipHdr.(ethernetdecode.Ipv4Header) switch protoHdr.Protocol() { case ethernetdecode.ProtocolTcp: tcp := protoHdr.(ethernetdecode.TcpHeader) // SYN+ACK flags if tcp.Flags&3 == 2 { opened++ } // FIN+ACK flags if tcp.Flags&17 != 0 { closed++ } case ethernetdecode.ProtocolUdp: } fmt.Printf("src: %v => dst: %v\n", net.IP(ipv4.Source[:]), net.IP(ipv4.Destination[:])) fmt.Printf("TCP connections opened: %d, closed: %d\n", opened, closed) } } } default: } } } else { fmt.Println(err) } } }
func analyzeFlowRecord(r sflow.RawPacketFlowRecord) { _, ipHdr, _ := ethernetdecode.Decode(r.Header) if ipHdr == nil { return } switch ipHdr.IpVersion() { case 4: ipv4 := ipHdr.(ethernetdecode.Ipv4Header) analyzeIpv4Header(ipv4) case 6: ipv6 := ipHdr.(ethernetdecode.Ipv6Header) analyzeIpv6Header(ipv6) } }
func main() { log.SetOutput(os.Stdout) tcpPort := flag.Uint64("port", 3306, "destination/source TCP port to sniff") flag.Parse() // open a raw socket for sniffing fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, htons(syscall.ETH_P_ALL)) if err != nil { log.Fatal(err, " - are you running as root?") } // much larger than MTU, just to be safe buf := make([]byte, 65536) for { n, _, err := syscall.Recvfrom(fd, buf, 0) if err != nil { log.Fatal(err) } // decode the Ethernet packet and save the protocol header _, iphdr, protohdr := ethernetdecode.Decode(buf[:n]) // check for a TCP header tcphdr, ok := protohdr.(ethernetdecode.TcpHeader) if ok { var source net.IP var dest net.IP switch iphdr.(type) { case ethernetdecode.Ipv4Header: ipBytes := iphdr.(ethernetdecode.Ipv4Header).Source source = net.IPv4(ipBytes[0], ipBytes[1], ipBytes[2], ipBytes[3]) ipBytes = iphdr.(ethernetdecode.Ipv4Header).Destination dest = net.IPv4(ipBytes[0], ipBytes[1], ipBytes[2], ipBytes[3]) case ethernetdecode.Ipv6Header: ipBytes := iphdr.(ethernetdecode.Ipv6Header).Source source = net.IP(ipBytes[:]) ipBytes = iphdr.(ethernetdecode.Ipv6Header).Destination dest = net.IP(ipBytes[:]) } // now for the magic. if tcphdr.DestinationPort == uint16(*tcpPort) || tcphdr.SourcePort == uint16(*tcpPort) { log.Println("---") if tcphdr.DestinationPort == uint16(*tcpPort) { log.Printf("%v:%d => %v:%d", source, tcphdr.SourcePort, dest, tcphdr.DestinationPort) } else { log.Printf("%v:%d <= %v:%d", dest, tcphdr.DestinationPort, source, tcphdr.SourcePort) } // SYN flag, but not ACK if tcphdr.Flags&3 == 2 { // we're seeing a connection being opened log.Print("Connection opened.") continue } // FIN + ACK if tcphdr.Flags&17 == 17 { // we're seeing a connection being opened log.Print("Connection closed.") continue } fmt.Printf("Payload length = %d\n\n%s", len(tcphdr.Payload), tcphdr.Payload) } } } }