func Hop(port, ttl int, IP_addr net.IP) (*Hop_ret, error) { ret_addr := net.IPv4(0, 0, 0, 0) success := false // make sockets send_udp_s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP) if err != nil { return nil, err } recv_icmp_s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP) if err != nil { return nil, err } //editing TTL value for outgoing IPv4 packets if err := syscall.SetsockoptInt(send_udp_s, syscall.SOL_IP, syscall.IP_TTL, ttl); err != nil { return nil, err } tv := syscall.NsecToTimeval(1000 * 1000 * TIME_OUT_MS) syscall.SetsockoptTimeval(recv_icmp_s, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv) defer syscall.Close(send_udp_s) defer syscall.Close(recv_icmp_s) //connect sockets if err := syscall.Bind(recv_icmp_s, &syscall.SockaddrInet4{Port: port, Addr: [4]byte{137, 224, 226, 47}}); err != nil { return nil, err } //send udp-packet var IP [4]byte copy(IP[:], IP_addr.To4()) if err := syscall.Sendto(send_udp_s, []byte{0x42, 0x42}, 0, &syscall.SockaddrInet4{Port: 1337, Addr: IP}); err != nil { return nil, err } //receive ICMP recv_buffer := make([]byte, 4096) _, _, err = syscall.Recvfrom(recv_icmp_s, recv_buffer, 0) if err == nil { header, err := ipv4.ParseHeader(recv_buffer) if err != nil { log.Errorf("%q", err) } success = true ret_addr = header.Src } else { //time out success = false ret_addr = net.IPv4(0, 0, 0, 0) //log.Errorf("%q", err) } //resolve (timeout) errors, retry or return false... return &Hop_ret{Addr: ret_addr, TTL: ttl, success: success}, nil }
func NewConnectionFromPacket(packet []byte) (Connection, error) { ipheader, err := ipv4.ParseHeader(packet) if err != nil { return Connection{}, err } tcpheader, err := tcp.ParseHeader(packet[ipheader.Len:]) if err != nil { return Connection{}, err } return NewConnectionFromPacketAndIPHeaderAndTCPHeader(packet, ipheader, tcpheader) }
func TestParseHeader(t *testing.T) { var wh []byte switch runtime.GOOS { case "linux", "openbsd": wh = wireHeaderFromKernel[:] default: wh = wireHeaderFromTradBSDKernel[:] } h, err := ipv4.ParseHeader(wh) if err != nil { t.Fatalf("ipv4.ParseHeader failed: %v", err) } if !reflect.DeepEqual(h, testHeader) { t.Fatalf("ipv4.ParseHeader failed: %#v not equal %#v", h, testHeader) } }
func (t *connectionManager) Process() error { var wg sync.WaitGroup for i := 0; i < t.configuration.Manager.Agents; i++ { wg.Add(1) go func() { defer wg.Done() for { message := <-t.reader.output ipheader, err := ipv4.ParseHeader(message) if err != nil { log.Println("Error: Parsing IPHeader:" + err.Error()) log.Printf("Message:%v\n", message) continue } if int(ipheader.Flags) < 2 { log.Printf("Warning: More Fragments Flag Is Set\n") } tcpheader, err := tcp.ParseHeader(message[ipheader.Len:]) if err != nil { log.Println("Error: Parsing TCPHeader:" + err.Error()) log.Printf("Message:%v\n", message) continue } connectionhelper, err := datastore.GetConnectionHelper() if err != nil { log.Printf("Error: Getting Connection Helper: %v\n", err.Error()) return } connectionhelper.Lock() connection, err := connectionhelper.GetConnection(ipheader.Src, tcpheader.SourcePort, ipheader.Dst, tcpheader.DestinationPort) if err != nil { log.Printf("Error: Getting Connection: %v\n", err.Error()) connectionhelper.Unlock() return } if bytes.Equal(connection.SourceIP(), net.IP{}) { //No connection found connection, err = datastore.NewConnectionFromPacketAndIPHeaderAndTCPHeader(message, ipheader, tcpheader) if err != nil { log.Printf("Error: Creating New Connection: %v\n", err.Error()) connectionhelper.Unlock() continue } err = connectionhelper.SetConnection(connection) if err != nil { log.Printf("Error: Saving New Connection: %v\n", err.Error()) connectionhelper.Unlock() continue } } else { //Connection found //We need to find out if the connection is still for this device and user devicehelper, err := datastore.GetDeviceHelper() if err != nil { log.Printf("Error: Getting Device Helper: %v\n", err.Error()) connectionhelper.Unlock() return } device, err := devicehelper.GetDeviceByIP(ipheader.Src) if err != nil { log.Printf("Error: Getting Source Device By IP(%v) \"%v\"\n", ipheader.Src.String(), err.Error()) } if bytes.Equal(device.MACAddress, net.HardwareAddr{}) { device, err = devicehelper.GetDeviceByIP(ipheader.Dst) if err != nil { log.Printf("Error: Getting Destination Device By IP(%v) \"%v\"\n", ipheader.Dst.String(), err.Error()) } } //If we have a device, is now or it's empty currentuser := "" if device.GetActiveUser() != nil { currentuser = device.GetActiveUser().Username } //Device, User or Number of In Memory Packets Breached... if !bytes.Equal(device.MACAddress, connection.DeviceID()) || (connection.Username() != currentuser) || connection.NumberOfPackets() >= t.configuration.Manager.MaxPackets { //Device or User has changed. err = connectionhelper.RemoveConnection(connection) if err != nil { log.Printf("Error: Removing Connection: %v\n", err.Error()) connectionhelper.Unlock() continue } //If a channel is registered and we had no errors closing it. if t.manager.output != nil { select { case t.manager.output <- connection: default: log.Println("Error: Manager Queue is full! Discarding Closed Connection..") } } //Create A New Connection connection, err := datastore.NewConnectionFromPacketAndIPHeaderAndTCPHeader(message, ipheader, tcpheader) if err != nil { log.Printf("Error: Creating New Connection After Remove: %v\n", err.Error()) connectionhelper.Unlock() continue } err = connectionhelper.SetConnection(connection) if err != nil { log.Printf("Error: Saving New Connection After Remove: %v\n", err.Error()) connectionhelper.Unlock() continue } } else { err = connection.AddPacket(message) if err != nil { log.Printf("Error: Adding Packet: %v\n", err.Error()) connectionhelper.Unlock() continue } err = connectionhelper.SetConnection(connection) if err != nil { log.Printf("Error: Saving Packet after adding packet: %v\n", err.Error()) connectionhelper.Unlock() continue } } } connectionhelper.Unlock() } }() } wg.Wait() log.Println("Error: We seem to be existing packet processing??") return errors.New("Error: Packet Processing Exited?") }