Example #1
0
func (t *Nat) In(p Packet) (b []byte) {
	//ioutil.WriteFile("/tmp/b.pkt", pkt.Data(), 0777)

	var k uint16
	var srcPort uint16
	if p.tcp != nil {
		srcPort = uint16(p.tcp.SrcPort)
	} else {
		srcPort = uint16(p.udp.SrcPort)
	}
	k = t.Hash(p.ip, srcPort)

	log.Println("socket <<<", p)

	c, _ := t.table[k]
	if ((p.tcp != nil && p.tcp.SYN) || p.udp != nil) && c == nil {
		log.Println("nat new", k)
		c = &natConn{
			Ts:      time.Now(),
			SrcPort: srcPort,
			SrcIP:   p.ip.SrcIP,
			SrcMAC:  p.eth.SrcMAC,
			DstMAC:  p.eth.DstMAC,
		}
		t.table[k] = c
	}

	p.ip.SrcIP = myip
	p.eth.SrcMAC = mymac
	p.eth.DstMAC = gwmac

	if p.tcp != nil {
		p.tcp.SrcPort = layers.TCPPort(k)
	} else {
		p.udp.SrcPort = layers.UDPPort(k)
	}

	UpdatePkt(&p)
	log.Println("wire >>>", p)

	return p.data
}
Example #2
0
func (t *Nat) Out(p Packet) (b []byte) {
	var k uint16
	if p.tcp != nil {
		k = uint16(p.tcp.DstPort)
	} else {
		k = uint16(p.udp.DstPort)
	}
	c, _ := t.table[k]
	if c == nil {
		return
	}

	log.Println("wire <<<", p)

	p.eth.SrcMAC = c.DstMAC
	p.eth.DstMAC = c.SrcMAC

	p.ip.DstIP = c.SrcIP

	if p.tcp != nil {
		p.tcp.DstPort = layers.TCPPort(c.SrcPort)
		if p.tcp.FIN || p.tcp.RST {
			log.Println("nat del", k)
			delete(t.table, k)
		}
	} else {
		p.udp.DstPort = layers.UDPPort(c.SrcPort)
	}

	UpdatePkt(&p)
	c.Ts = time.Now()

	log.Println("socket >>>", p)

	return p.data
}
Example #3
0
func main() {
	flag.Parse()
	args := flag.Args()
	if len(args) != 2 {
		fmt.Printf("Usage: %s <ip> <port>\n", os.Args[0])
		os.Exit(-1)
	}

	// parse the destination host and port from the command line args
	dstip := net.ParseIP(args[0]).To4()
	dport_, err := strconv.ParseInt(args[1], 10, 16)
	if err != nil {
		panic(err)
	}
	dport := layers.TCPPort(dport_)

	// get our local ip.
	srcip, err := localIP(dstip)
	if err != nil {
		panic(err)
	}

	// Our IPv4 header
	ip := &layers.IPv4{
		Version:    4,
		IHL:        5,
		TOS:        0,
		Length:     0, // FIX
		Id:         12345,
		FragOffset: 16384,
		TTL:        64,
		Protocol:   layers.IPProtocolTCP,
		Checksum:   0,
		SrcIP:      srcip,
		DstIP:      dstip,
	}

	// Our TCP header
	tcp := &layers.TCP{
		SrcPort:  45677,
		DstPort:  dport,
		Seq:      1105024978,
		Ack:      0,
		SYN:      true,
		Window:   14600,
		Checksum: 0,
		Urgent:   0,
	}
	tcp.DataOffset = uint8(unsafe.Sizeof(tcp))
	tcp.SetNetworkLayerForChecksum(ip)

	buf := gopacket.NewSerializeBuffer()
	opts := gopacket.SerializeOptions{
		ComputeChecksums: true, // automatically compute checksums
	}

	err = ip.SerializeTo(buf, opts)
	if err != nil {
		panic(err)
	}

	err = tcp.SerializeTo(buf, opts)
	if err != nil {
		panic(err)
	}

	conn, err := net.ListenPacket("ip4:tcp", "0.0.0.0")
	if err != nil {
		panic(err)
	}

	_, err = conn.WriteTo(buf.Bytes(), &net.IPAddr{IP: dstip})
	if err != nil {
		panic(err)
	}

	var b []byte
	b = make([]byte, 152)
	n, addr, err := conn.ReadFrom(b)
	if err != nil {
		panic(err)
	}

	if addr.String() == dstip.String() {
		// Decode a packet
		packet := gopacket.NewPacket(b[:n], layers.LayerTypeTCP, gopacket.Default)
		// Get the TCP layer from this packet
		if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
			tcp, _ := tcpLayer.(*layers.TCP)

			//fmt.Printf("SYN: %v, ACK: %v, RST: %v\n", tcp.SYN, tcp.ACK, tcp.RST)
			if tcp.SYN && tcp.ACK {
				fmt.Printf("Port %d is OPEN\n", dport)
			} else {
				fmt.Printf("Port %d is CLOSED\n", dport)
			}
		}
	}
}
Example #4
0
func main() {
	flag.Parse()
	args := flag.Args()
	if len(args) != 2 {
		log.Printf("Usage: %s <ip> <port>\n", os.Args[0])
		os.Exit(-1)
	}

	// parse the destination host and port from the command line args
	dstip := net.ParseIP(args[0]).To4()
	dport_, err := strconv.ParseInt(args[1], 10, 16)
	if err != nil {
		log.Fatal(err)
	}
	dport := layers.TCPPort(dport_)
	sport := layers.TCPPort(5000)

	// get our local ip.
	srcip, err := localIP(dstip)
	if err != nil {
		log.Fatal(err)
	}

	devs, err := pcap.FindAllDevs()
	if err != nil {
		log.Fatal(err)
	}

	dev := ""
	for _, d := range devs {
		for _, a := range d.Addresses {
			if bytes.Equal(a.IP, srcip) {
				dev = d.Name
			}
		}
		// if d.Description == "Realtek PCIe GBE Family Controller" {
		//   fmt.Println(d.Name)
		//   dev = d.Name
		// }

		// fmt.Println(dev.Description)
	}

	if dev == "" {
		log.Fatal("Could not find the appropriate adapter device")
	}

	srcmac, err := localMac(dev)
	if err != nil {
		log.Fatal(err)
	}

	dstmac, err := remoteMac(dev, srcmac, srcip, dstip)
	if err != nil {
		log.Fatal(err)
	}

	eth := &layers.Ethernet{
		SrcMAC:       srcmac,
		DstMAC:       dstmac,
		EthernetType: layers.EthernetTypeIPv4,
	}

	// Our IPv4 header
	ip := &layers.IPv4{
		Version:    4,
		IHL:        5,
		TOS:        0,
		Length:     20, // FIX
		Id:         2,
		Flags:      layers.IPv4DontFragment,
		FragOffset: 0, //16384,
		TTL:        3, //64,
		Protocol:   layers.IPProtocolTCP,
		Checksum:   0,
		SrcIP:      srcip,
		DstIP:      dstip,
	}

	// Our TCP header
	tcp := &layers.TCP{
		SrcPort:  sport,
		DstPort:  dport,
		Seq:      0,
		Ack:      0,
		SYN:      true,
		Window:   64240,
		Checksum: 0,
		Urgent:   0,
	}
	tcp.DataOffset = 5 // uint8(unsafe.Sizeof(tcp))
	tcp.SetNetworkLayerForChecksum(ip)

	buf := gopacket.NewSerializeBuffer()
	err = gopacket.SerializeLayers(
		buf,
		gopacket.SerializeOptions{
			ComputeChecksums: true, // automatically compute checksums
			FixLengths:       true,
		},
		eth, ip, tcp,
	)
	if err != nil {
		log.Fatal(err)
	}

	handle, err := pcap.OpenLive(`rpcap://`+dev, 65535, true, time.Second*1)
	if err != nil {
		log.Fatal(err)
	}
	defer handle.Close()

	var wg sync.WaitGroup

	handle.SetBPFFilter(fmt.Sprintf("tcp and host %s and host %s and port %d and port %d", srcip.String(), dstip.String(), sport, dport))
	packetSource := gopacket.NewPacketSource(handle, handle.LinkType())

	wg.Add(1)
	go func() {
		stop := false

		go func() {
			<-time.After(time.Second * 2)
			stop = true
		}()

		for {
			if stop {
				break
			}

			packet, err := packetSource.NextPacket()
			if err == io.EOF {
				break
			} else if err != nil {
				//log.Println("Error:", err)
				continue
			}

			if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
				tcp, _ := tcpLayer.(*layers.TCP)
				if tcp.SrcPort == dport && tcp.DstPort == sport {
					if tcp.SYN && tcp.ACK {
						fmt.Printf("Port %d is OPEN\n", dport_)
					} else {
						fmt.Printf("Port %d is CLOSED\n", dport_)
					}
					break
				}
				//fmt.Printf("From src port %d to dst port %d\n", tcp.SrcPort, tcp.DstPort)
			}
		}

		wg.Done()
	}()

	err = handle.WritePacketData(buf.Bytes())
	if err != nil {
		log.Fatal(err)
	}

	wg.Wait()
}
Example #5
0
//Detectinitcwnd attempts to detect the initial congession window of an http endpoint.
//First does a 3 way tcp handshake, sends GET request and then does not ack any response while measuring the packets received. This allows us to see how much data the server can send without acknowledgement.
func Detectinitcwnd(host, url string, dstip net.IP) (pkt_count, payload_size int, fullpayload []byte, err error) {
	pldata := []byte(fmt.Sprintf("GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", url, host))
	var dstport layers.TCPPort

	dstport = layers.TCPPort(80)

	srcip, sport := localIPPort(dstip)
	srcport := layers.TCPPort(sport)
	log.Printf("using srcip: %v", srcip.String())
	log.Printf("using dstip: %v", dstip.String())

	// Our IP header... not used, but necessary for TCP checksumming.
	ip := &layers.IPv4{
		SrcIP:    srcip,
		DstIP:    dstip,
		Protocol: layers.IPProtocolTCP,
	}
	//layers.TCPOption{3, 3, []byte{7}} maybe for window scaling... dunno
	tcpopts := []layers.TCPOption{layers.TCPOption{2, 4, []byte{5, 172}}} //Set MSS 1452
	// Our TCP header
	tcp := &layers.TCP{
		SrcPort: srcport,
		DstPort: dstport,
		Seq:     1105024978,
		SYN:     true,
		Window:  65535,
		Options: tcpopts,
	}
	tcp.SetNetworkLayerForChecksum(ip)

	// Serialize.  Note:  we only serialize the TCP layer, because the
	// socket we get with net.ListenPacket wraps our data in IPv4 packets
	// already.  We do still need the IP layer to compute checksums
	// correctly, though.
	buf := gopacket.NewSerializeBuffer()
	opts := gopacket.SerializeOptions{
		ComputeChecksums: true,
		FixLengths:       true,
	}
	err = gopacket.SerializeLayers(buf, opts, tcp)
	if err != nil {
		return
	}
	var out1 bytes.Buffer
	iptset := exec.Command("iptables", "-A", "OUTPUT", "-p", "tcp", "--tcp-flags", "RST", "RST", "-s", srcip.String(), "--sport", porttoint(srcport), "--dport", porttoint(dstport), "-j", "DROP")
	iptset.Stderr = &out1
	log.Println(iptset)
	err = iptset.Run()
	if err != nil {
		return
	}
	log.Println(out1.String())
	iptrem := exec.Command("iptables", "-D", "OUTPUT", "-p", "tcp", "--tcp-flags", "RST", "RST", "-s", srcip.String(), "--sport", porttoint(srcport), "--dport", porttoint(dstport), "-j", "DROP")
	conn, err := net.ListenPacket("ip4:tcp", "0.0.0.0")
	if err != nil {
		return
	}
	defer func() {
		fmt.Println(iptrem)
		var out bytes.Buffer
		iptrem.Stderr = &out
		err = iptrem.Run()
		if err != nil {
			log.Println(err)
		}
		fmt.Printf(out.String())
		log.Println("Removed iptable rule")
		//Now RST should be allowed... send it
		rst_pkt := &layers.TCP{
			SrcPort: srcport,
			DstPort: dstport,
			Seq:     1105024980,
			Window:  65535,
			RST:     true,
		}
		rst_pkt.SetNetworkLayerForChecksum(ip)
		if err := gopacket.SerializeLayers(buf, opts, rst_pkt); err != nil {
			//Shadowing err since we dont care
			log.Println(err)
		}
		if _, err := conn.WriteTo(buf.Bytes(), &net.IPAddr{IP: dstip}); err != nil {
			//Shadowing err since we dont care
			log.Println(err)
		}

	}()
	log.Println("writing request")
	_, err = conn.WriteTo(buf.Bytes(), &net.IPAddr{IP: dstip})
	if err != nil {
		return
	}

	// Set deadline so we don't wait forever.
	err = conn.SetDeadline(time.Now().Add(15 * time.Second))
	if err != nil {
		return
	}
	//Capture synack from our syn, return the ack value
	ack, err := getack(conn, srcport, dstip.String())
	if err != nil {
		log.Println(err)
		return
	} else {
		//Prepare http request, ack the synack
		payload := &layers.TCP{
			SrcPort: srcport,
			DstPort: dstport,
			Seq:     1105024979,
			ACK:     true,
			Window:  65535,
			Ack:     ack + 1,
		}
		payload.SetNetworkLayerForChecksum(ip)
		if err := gopacket.SerializeLayers(buf, opts, payload, gopacket.Payload(pldata)); err != nil {
			log.Fatal(err)
		}
		if _, err := conn.WriteTo(buf.Bytes(), &net.IPAddr{IP: dstip}); err != nil {
			log.Fatal(err)
		}
		pkt_count, payload_size, fullpayload = listenandcount(conn, dstip.String(), srcport)
		log.Println("Initcwnd: ", pkt_count)
		log.Println("Data: ", payload_size)

		return
	}
	return
}