func main() {
	// Open device
	handle, err = pcap.OpenLive(device, snapshot_len, promiscuous, timeout)
	if err != nil {
		log.Fatal(err)
	}
	defer handle.Close()

	// Send raw bytes over wire
	rawBytes := []byte{10, 20, 30}
	err = handle.WritePacketData(rawBytes)
	if err != nil {
		log.Fatal(err)
	}

	// Create a properly formed packet, just with
	// empty details. Should fill out MAC addresses,
	// IP addresses, etc.
	buffer = gopacket.NewSerializeBuffer()
	gopacket.SerializeLayers(buffer, options,
		&layers.Ethernet{},
		&layers.IPv4{},
		&layers.TCP{},
		gopacket.Payload(rawBytes),
	)
	outgoingPacket := buffer.Bytes()
	// Send our packet
	err = handle.WritePacketData(outgoingPacket)
	if err != nil {
		log.Fatal(err)
	}

	// This time lets fill out some information
	ipLayer := &layers.IPv4{
		SrcIP: net.IP{127, 0, 0, 1},
		DstIP: net.IP{8, 8, 8, 8},
	}
	ethernetLayer := &layers.Ethernet{
		SrcMAC: net.HardwareAddr{0xFF, 0xAA, 0xFA, 0xAA, 0xFF, 0xAA, 0xFA, 0xAA},
		DstMAC: net.HardwareAddr{0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD},
	}
	tcpLayer := &layers.TCP{
		SrcPort: layers.TCPPort(4321),
		DstPort: layers.TCPPort(80),
	}
	// And create the packet with the layers
	buffer = gopacket.NewSerializeBuffer()
	gopacket.SerializeLayers(buffer, options,
		ethernetLayer,
		ipLayer,
		tcpLayer,
		gopacket.Payload(rawBytes),
	)
	outgoingPacket = buffer.Bytes()
}
Exemple #2
0
func (sender *RawUDPSender) Send(msg []byte) error {
	payload := gopacket.Payload(msg)
	sender.udpHeader.DstPort = layers.UDPPort(sender.conn.RemoteUDPAddr().Port)

	err := gopacket.SerializeLayers(sender.ipBuf, sender.opts, sender.udpHeader, &payload)
	if err != nil {
		return err
	}
	packet := sender.ipBuf.Bytes()
	_, err = sender.socket.Write(packet)
	if err == nil || PosixError(err) != syscall.EMSGSIZE {
		return err
	}
	f, err := sender.socket.File()
	if err != nil {
		return err
	}
	defer f.Close()
	fd := int(f.Fd())
	log.Println("EMSGSIZE on send, expecting PMTU update (IP packet was",
		len(packet), "bytes, payload was", len(msg), "bytes)")
	pmtu, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_MTU)
	if err != nil {
		return err
	}
	return MsgTooBigError{PMTU: pmtu}
}
Exemple #3
0
func newIcmpData(src, dest *net.IPAddr, typeCode, offSet, ttl int) (data []byte) {
	ip := &layers.IPv4{}
	ip.Version = 4
	ip.Protocol = layers.IPProtocolICMPv4
	ip.SrcIP = src.IP
	ip.DstIP = dest.IP
	ip.Length = 20
	ip.TTL = uint8(ttl)

	icmp := &layers.ICMPv4{}
	icmp.TypeCode = layers.ICMPv4TypeCode(uint16(typeCode) << 8)
	icmp.Id = pid
	icmp.Seq = 1
	icmp.Checksum = 0

	opts := gopacket.SerializeOptions{}
	opts.ComputeChecksums = true
	opts.FixLengths = true

	now := time.Now().UnixNano()
	var payload = make([]byte, 8)
	binary.LittleEndian.PutUint64(payload, uint64(now))

	buf := gopacket.NewSerializeBuffer()
	gopacket.SerializeLayers(buf, opts, ip, icmp, gopacket.Payload(payload))

	return buf.Bytes()
}
Exemple #4
0
func TestSetupPan(t *testing.T) {
	/*
		packetManifest := types.PacketManifest{
			Timestamp: time.Now(),
			Flow:      nil,
			RawPacket: nil,
			IP:        ip,
			TCP:       tcp,
			Payload:   payload,
		}
	*/

	buf := gopacket.NewSerializeBuffer()
	opts := gopacket.SerializeOptions{}
	ip0 := net.ParseIP("127.0.0.100")
	ip1 := net.ParseIP("127.0.0.1")
	gopacket.SerializeLayers(buf, opts,
		&layers.Ethernet{},
		&layers.IPv4{SrcIP: ip0, DstIP: ip1},
		&layers.TCP{},
		gopacket.Payload([]byte{1, 2, 3, 4, 5}))
	packetData := buf.Bytes()
	assert.NotEqual(t, packetData, nil)

}
Exemple #5
0
func forgeEthIPTCP(t *testing.T, seed int64) *gopacket.Packet {
	var options gopacket.SerializeOptions
	rnd := rand.New(rand.NewSource(seed))

	rawBytes := []byte{10, 20, 30}
	ethernetLayer := &layers.Ethernet{
		SrcMAC: net.HardwareAddr{0x00, 0x0F, 0xAA, 0xFA, 0xAA, byte(rnd.Intn(0x100))},
		DstMAC: net.HardwareAddr{0x00, 0x0D, 0xBD, 0xBD, byte(rnd.Intn(0x100)), 0xBD},
	}
	ipLayer := &layers.IPv4{
		SrcIP: net.IP{127, 0, 0, byte(rnd.Intn(0x100))},
		DstIP: net.IP{byte(rnd.Intn(0x100)), 8, 8, 8},
	}
	tcpLayer := &layers.TCP{
		SrcPort: layers.TCPPort(byte(rnd.Intn(0x10000))),
		DstPort: layers.TCPPort(byte(rnd.Intn(0x10000))),
	}
	// And create the packet with the layers
	buffer := gopacket.NewSerializeBuffer()
	err := gopacket.SerializeLayers(buffer, options,
		ethernetLayer,
		ipLayer,
		tcpLayer,
		gopacket.Payload(rawBytes),
	)
	if err != nil {
		t.Fail()
	}

	gpacket := gopacket.NewPacket(buffer.Bytes(), layers.LayerTypeEthernet, gopacket.Default)
	return &gpacket

}
Exemple #6
0
func (dec *EthernetDecoder) sendICMPFragNeeded(mtu int, sendFrame func([]byte) error) error {
	buf := gopacket.NewSerializeBuffer()
	opts := gopacket.SerializeOptions{
		FixLengths:       true,
		ComputeChecksums: true}
	ipHeaderSize := int(dec.IP.IHL) * 4 // IHL is the number of 32-byte words in the header
	payload := gopacket.Payload(dec.IP.BaseLayer.Contents[:ipHeaderSize+8])
	err := gopacket.SerializeLayers(buf, opts,
		&layers.Ethernet{
			SrcMAC:       dec.Eth.DstMAC,
			DstMAC:       dec.Eth.SrcMAC,
			EthernetType: dec.Eth.EthernetType},
		&layers.IPv4{
			Version:    4,
			TOS:        dec.IP.TOS,
			Id:         0,
			Flags:      0,
			FragOffset: 0,
			TTL:        64,
			Protocol:   layers.IPProtocolICMPv4,
			DstIP:      dec.IP.SrcIP,
			SrcIP:      dec.IP.DstIP},
		&layers.ICMPv4{
			TypeCode: 0x304,
			Id:       0,
			Seq:      uint16(mtu)},
		&payload)
	if err != nil {
		return err
	}

	Log.Printf("Sending ICMP 3,4 (%v -> %v): PMTU= %v\n", dec.IP.DstIP, dec.IP.SrcIP, mtu)
	return sendFrame(buf.Bytes())
}
Exemple #7
0
func main() {
	// If we don't have a handle to a device or a file, but we have a bunch
	// of raw bytes, we can try to decode them in to packet information

	// NewPacket() takes the raw bytes that make up the packet as the first parameter
	// The second parameter is the lowest level layer you want to decode. It will
	// decode that layer and all layers on top of it. The third layer
	// is the type of decoding: default(all at once), lazy(on demand), and NoCopy
	// which will not create a copy of the buffer

	// Create an packet with ethernet, IP, TCP, and payload layers
	// We are creating one we know will be decoded properly but
	// your byte source could be anything. If any of the packets
	// come back as nil, that means it could not decode it in to
	// the proper layer (malformed or incorrect packet type)
	payload := []byte{2, 4, 6}
	options := gopacket.SerializeOptions{}
	buffer := gopacket.NewSerializeBuffer()
	gopacket.SerializeLayers(buffer, options,
		&layers.Ethernet{},
		&layers.IPv4{},
		&layers.TCP{},
		gopacket.Payload(payload),
	)
	rawBytes := buffer.Bytes()

	// Decode an ethernet packet
	ethPacket :=
		gopacket.NewPacket(
			rawBytes,
			layers.LayerTypeEthernet,
			gopacket.Default,
		)

	// with Lazy decoding it will only decode what it needs when it needs it
	// This is not concurrency safe. If using concurrency, use default
	ipPacket :=
		gopacket.NewPacket(
			rawBytes,
			layers.LayerTypeIPv4,
			gopacket.Lazy,
		)

	// With the NoCopy option, the underlying slices are referenced
	// directly and not copied. If the underlying bytes change so will
	// the packet
	tcpPacket :=
		gopacket.NewPacket(
			rawBytes,
			layers.LayerTypeTCP,
			gopacket.NoCopy,
		)

	fmt.Println(ethPacket)
	fmt.Println(ipPacket)
	fmt.Println(tcpPacket)
}
Exemple #8
0
/* protos must contain a UDP or TCP layer on top of IPv4 */
func forgeTestPacket(t *testing.T, seed int64, protos ...ProtocolType) *gopacket.Packet {
	rnd := rand.New(rand.NewSource(seed))

	rawBytes := []byte{10, 20, 30}
	var protoStack []gopacket.SerializableLayer

	for i, proto := range protos {
		switch proto {
		case ETH:
			ethernetLayer := &layers.Ethernet{
				SrcMAC:       net.HardwareAddr{0x00, 0x0F, 0xAA, 0xFA, 0xAA, byte(rnd.Intn(0x100))},
				DstMAC:       net.HardwareAddr{0x00, 0x0D, 0xBD, 0xBD, byte(rnd.Intn(0x100)), 0xBD},
				EthernetType: layers.EthernetTypeIPv4,
			}
			protoStack = append(protoStack, ethernetLayer)
		case IPv4:
			ipv4Layer := &layers.IPv4{
				SrcIP: net.IP{127, 0, 0, byte(rnd.Intn(0x100))},
				DstIP: net.IP{byte(rnd.Intn(0x100)), 8, 8, 8},
			}
			switch protos[i+1] {
			case TCP:
				ipv4Layer.Protocol = layers.IPProtocolTCP
			case UDP:
				ipv4Layer.Protocol = layers.IPProtocolUDP
			}
			protoStack = append(protoStack, ipv4Layer)
		case TCP:
			tcpLayer := &layers.TCP{
				SrcPort: layers.TCPPort(byte(rnd.Intn(0x10000))),
				DstPort: layers.TCPPort(byte(rnd.Intn(0x10000))),
			}
			protoStack = append(protoStack, tcpLayer)
		case UDP:
			udpLayer := &layers.UDP{
				SrcPort: layers.UDPPort(byte(rnd.Intn(0x10000))),
				DstPort: layers.UDPPort(byte(rnd.Intn(0x10000))),
			}
			protoStack = append(protoStack, udpLayer)
		default:
			t.Log("forgeTestPacket : Unsupported protocol ", proto)
		}
	}
	protoStack = append(protoStack, gopacket.Payload(rawBytes))

	buffer := gopacket.NewSerializeBuffer()
	options := gopacket.SerializeOptions{FixLengths: true}
	err := gopacket.SerializeLayers(buffer, options, protoStack...)

	if err != nil {
		t.Fail()
	}

	gpacket := gopacket.NewPacket(buffer.Bytes(), layers.LayerTypeEthernet, gopacket.Default)
	return &gpacket
}
Exemple #9
0
func fragment(eth layers.Ethernet, ip layers.IPv4, mtu int,
	forward func([]byte)) error {
	// We are not doing any sort of NAT, so we don't need to worry
	// about checksums of IP payload (eg UDP checksum).
	headerSize := int(ip.IHL) * 4
	// &^ is bit clear (AND NOT). So here we're clearing the lowest 3
	// bits.
	maxSegmentSize := (mtu - headerSize) &^ 7
	opts := gopacket.SerializeOptions{
		FixLengths:       false,
		ComputeChecksums: true}
	payloadSize := int(ip.Length) - headerSize
	payload := ip.BaseLayer.Payload[:payloadSize]
	offsetBase := int(ip.FragOffset) << 3
	origFlags := ip.Flags
	ip.Flags = ip.Flags | layers.IPv4MoreFragments
	ip.Length = uint16(headerSize + maxSegmentSize)
	if eth.EthernetType == layers.EthernetTypeLLC {
		// using LLC, so must set eth length correctly. eth length
		// is just the length of the payload
		eth.Length = ip.Length
	} else {
		eth.Length = 0
	}
	for offset := 0; offset < payloadSize; offset += maxSegmentSize {
		var segmentPayload []byte
		if len(payload) <= maxSegmentSize {
			// last one
			segmentPayload = payload
			ip.Length = uint16(len(payload) + headerSize)
			ip.Flags = origFlags
			if eth.EthernetType == layers.EthernetTypeLLC {
				eth.Length = ip.Length
			} else {
				eth.Length = 0
			}
		} else {
			segmentPayload = payload[:maxSegmentSize]
			payload = payload[maxSegmentSize:]
		}
		ip.FragOffset = uint16((offset + offsetBase) >> 3)
		buf := gopacket.NewSerializeBuffer()
		segPayload := gopacket.Payload(segmentPayload)
		err := gopacket.SerializeLayers(buf, opts, &eth, &ip,
			&segPayload)
		if err != nil {
			return err
		}

		forward(buf.Bytes())
	}
	return nil
}
Exemple #10
0
func TestIPv6JumbogramUDPChecksum(t *testing.T) {
	var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 4)
	var u *UDP
	var err error

	ip6 := &IPv6{}
	ip6.Version = 6
	ip6.NextHeader = IPProtocolUDP
	ip6.HopLimit = 64
	ip6.SrcIP = net.ParseIP("2001:db8::1")
	ip6.DstIP = net.ParseIP("2001:db8::2")
	serialize = append(serialize, ip6)

	udp := &UDP{}
	udp.SrcPort = UDPPort(12345)
	udp.DstPort = UDPPort(9999)
	udp.SetNetworkLayerForChecksum(ip6)
	serialize = append(serialize, udp)

	payload := make([]byte, ipv6MaxPayloadLength+1)
	for i := range payload {
		payload[i] = 0xfe
	}
	serialize = append(serialize, gopacket.Payload(payload))

	buf := gopacket.NewSerializeBuffer()
	opts := gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}
	err = gopacket.SerializeLayers(buf, opts, serialize...)
	if err != nil {
		t.Fatal(err)
	}

	p := gopacket.NewPacket(buf.Bytes(), LinkTypeRaw, gopacket.Default)
	if p.ErrorLayer() != nil {
		t.Fatal("Failed to decode packet:", p.ErrorLayer().Error())
	}
	checkLayers(p, []gopacket.LayerType{LayerTypeIPv6, LayerTypeIPv6HopByHop, LayerTypeUDP, gopacket.LayerTypePayload}, t)

	if l, ok := p.Layer(LayerTypeUDP).(*UDP); !ok {
		t.Fatal("No UDP layer type found in packet")
	} else {
		u = l
	}
	got := u.Checksum
	want := ipv6UDPChecksumJumbogram
	if got != want {
		t.Errorf("Bad checksum:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want)
	}
}
func TestGetOverlapRingsWithZeroRings(t *testing.T) {
	ip := layers.IPv4{
		SrcIP:    net.IP{1, 2, 3, 4},
		DstIP:    net.IP{2, 3, 4, 5},
		Version:  4,
		TTL:      64,
		Protocol: layers.IPProtocolTCP,
	}
	tcp := layers.TCP{
		SYN:     true,
		SrcPort: 1,
		DstPort: 2,
	}
	tcp.SetNetworkLayerForChecksum(&ip)
	payload := gopacket.Payload([]byte{1, 2, 3, 4})
	p := types.PacketManifest{
		IP:      ip,
		TCP:     tcp,
		Payload: payload,
	}
	options := ConnectionOptions{
		MaxBufferedPagesTotal:         0,
		MaxBufferedPagesPerConnection: 0,
		MaxRingPackets:                40,
		PageCache:                     nil,
		LogDir:                        "fake-log-dir",
	}

	f := &DefaultConnFactory{}
	conn := f.Build(options).(*Connection)

	ipFlow, _ := gopacket.FlowFromEndpoints(layers.NewIPEndpoint(net.IPv4(1, 2, 3, 4)), layers.NewIPEndpoint(net.IPv4(2, 3, 4, 5)))
	tcpFlow, _ := gopacket.FlowFromEndpoints(layers.NewTCPPortEndpoint(layers.TCPPort(1)), layers.NewTCPPortEndpoint(layers.TCPPort(2)))
	serverFlow := types.NewTcpIpFlowFromFlows(ipFlow, tcpFlow)
	clientFlow := serverFlow.Reverse()
	conn.serverFlow = serverFlow
	conn.clientFlow = clientFlow

	head, tail := getOverlapRings(&p, serverFlow, conn.ClientStreamRing)
	if head == nil || tail == nil {
		return
	} else {
		t.Fail()
	}
	return
}
Exemple #12
0
func sendPacket(handle *pcap.Handle, sMac, dMac net.HardwareAddr, sIp, dIp net.IP, sPort, dPort layers.TCPPort, IpId uint16, IpTtl uint8, TcpSeq, ack uint32, WindowsSize uint16, data []byte) error {
	eth := layers.Ethernet{
		SrcMAC:       sMac,
		DstMAC:       dMac,
		EthernetType: layers.EthernetTypeIPv4,
	}
	ip4 := layers.IPv4{
		SrcIP:    sIp,
		DstIP:    dIp,
		Id:       IpId,
		Flags:    layers.IPv4DontFragment,
		Version:  4,
		TTL:      IpTtl,
		Protocol: layers.IPProtocolTCP,
	}
	tcp := layers.TCP{
		SrcPort: sPort,
		DstPort: dPort,
		Seq:     TcpSeq,
		ACK:     true,
		Ack:     ack,
		Window:  WindowsSize,
		PSH:     true, // 立刻处理
	}

	if len(data) == 0 {
		tcp.RST = true
	}

	tcp.SetNetworkLayerForChecksum(&ip4)

	buf := gopacket.NewSerializeBuffer()
	opts := gopacket.SerializeOptions{
		FixLengths:       true,
		ComputeChecksums: true,
	}

	payload := gopacket.Payload(data)

	if err := gopacket.SerializeLayers(buf, opts, &eth, &ip4, &tcp, payload); err != nil {
		return err
	}

	return handle.WritePacketData(buf.Bytes())
}
Exemple #13
0
/*
   FUNCTION: craftPacket(data []byte, ip string, port uint16, payload []byte) []byte
   RETURNS: []byte, byte array containing packet data created
   ARGUMENTS:
             []byte data - data to be placed in the source port
             string ip   - address to place in the dst ip of the ip layer
             uint16 port - destination port of udp header
             []byte payload - udp payload to be passed in

   ABOUT:
   Crafts a packet with a IP, ethernet and UDP header. Covertly inserts data into
   the source port and appends the specified payload.
*/
func craftPacket(data []byte, ip string, port uint16, payload []byte) []byte {

	ethernetLayer := &layers.Ethernet{
		SrcMAC:       localmac,
		DstMAC:       destmac,
		EthernetType: layers.EthernetTypeIPv4,
	}

	ipLayer := &layers.IPv4{
		Version:    4,
		IHL:        5,
		TOS:        0,
		Length:     20,
		Id:         2,
		Flags:      layers.IPv4DontFragment,
		FragOffset: 0,
		TTL:        255,
		Protocol:   layers.IPProtocolUDP,
		Checksum:   0,
		SrcIP:      localip,
		DstIP:      net.ParseIP(ip),
	}

	val := binary.BigEndian.Uint16(data)
	udpLayer := &layers.UDP{
		SrcPort: layers.UDPPort(MAX_PORT - val),
		DstPort: layers.UDPPort(port),
		Length:  16,
	}

	err := udpLayer.SetNetworkLayerForChecksum(ipLayer)
	checkError(err)

	buf := gopacket.NewSerializeBuffer()
	opts := gopacket.SerializeOptions{
		FixLengths:       true,
		ComputeChecksums: true,
	}

	err = gopacket.SerializeLayers(buf, opts, ethernetLayer, ipLayer, udpLayer, gopacket.Payload(payload))
	checkError(err)

	return buf.Bytes()
}
func main() {
	// Open device
	handle, err = pcap.OpenLive(device, snapshot_len, promiscuous, timeout)
	if err != nil {
		log.Fatal(err)
	}
	defer handle.Close()

	// Create the layers
	ethernetLayer := &layers.Ethernet{
		SrcMAC:       net.HardwareAddr{0xFF, 0xAA, 0xFA, 0xAA, 0xFF, 0xAA},
		DstMAC:       net.HardwareAddr{0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD},
		EthernetType: layers.EthernetTypeIPv4,
	}
	ipLayer := &layers.IPv4{
		SrcIP:   net.IP{192, 168, 1, 3},
		DstIP:   net.IP{8, 8, 8, 8},
		Version: 4,
		IHL:     5, // 20 bytes standard header size
		Length:  24,
	}
	tcpLayer := &layers.TCP{
		SrcPort: layers.TCPPort(4321),
		DstPort: layers.TCPPort(80),
	}
	payload := []byte{10, 20, 30, 40}

	// Serialize the layers
	buffer = gopacket.NewSerializeBuffer()
	gopacket.SerializeLayers(buffer, options,
		ethernetLayer,
		ipLayer,
		tcpLayer,
		gopacket.Payload(payload),
	)
	outgoingPacket := buffer.Bytes()

	// Send packet over the wire (or air)
	err = handle.WritePacketData(outgoingPacket)
	if err != nil {
		log.Fatal(err)
	}
}
Exemple #15
0
func (vnet *VNET) handleICMPv4EchoRequest(pkt *Packet) {
	host := vnet.hosts.GetTable().LookupByIPv4(pkt.IPv4.DstIP)
	if host == nil {
		log.Printf("ICMPv4: DST: %s (unknown)\n", pkt.IPv4.DstIP)
		return
	}
	if !host.Up {
		log.Printf("ICMPv4: DST: %s (down)\n", pkt.IPv4.DstIP)
		return
	}
	if len(host.IPv4Addrs) == 0 {
		log.Printf("ICMPv4: DST: %s (unknown)\n", pkt.IPv4.DstIP)
		return
	}
	log.Printf("ICMPv4: DST: %s (up)\n", pkt.IPv4.DstIP)

	err := vnet.writePacket(
		&layers.Ethernet{
			SrcMAC:       vnet.system.ControllerMAC(),
			DstMAC:       pkt.Eth.SrcMAC,
			EthernetType: layers.EthernetTypeIPv4,
		},
		&layers.IPv4{
			SrcIP:    pkt.IPv4.DstIP,
			DstIP:    pkt.IPv4.SrcIP,
			Version:  4,
			Protocol: layers.IPProtocolICMPv4,
			TTL:      64,
		},
		&layers.ICMPv4{
			TypeCode: layers.ICMPv4TypeEchoReply << 8,
			Seq:      pkt.ICMPv4.Seq,
			Id:       pkt.ICMPv4.Id,
			BaseLayer: layers.BaseLayer{
				Contents: pkt.ICMPv4.Contents,
			},
		},
		gopacket.Payload(pkt.ICMPv4.Payload))
	if err != nil {
		log.Printf("DCHP/error: %s", err)
		return
	}
}
Exemple #16
0
func (r *RawSocketServer) injectPacketFromDst(tcpLayer *layers.TCP, rawBytes []byte) error {
	// Preparing ipLayer.
	ipLayer := &layers.IPv4{
		SrcIP:    r.dst.ip,
		DstIP:    r.src.ip,
		Version:  4,
		TTL:      64,
		Protocol: layers.IPProtocolTCP,
	}

	options := gopacket.SerializeOptions{
		ComputeChecksums: true,
		FixLengths:       true,
	}

	tcpLayer.SrcPort = r.dst.port
	tcpLayer.DstPort = r.src.port
	tcpLayer.Window = r.window

	tcpLayer.Ack = r.ack
	tcpLayer.Seq = r.seq

	tcpLayer.SetNetworkLayerForChecksum(ipLayer)

	// And create the packet with the layers
	buffer := gopacket.NewSerializeBuffer()
	gopacket.SerializeLayers(buffer, options,
		ipLayer,
		tcpLayer,
		gopacket.Payload(rawBytes),
	)

	outgoingPacket := buffer.Bytes()

	p := tuntap.Packet{
		Protocol:  0x800,
		Truncated: false,
		Packet:    outgoingPacket,
	}

	return r.iface.WritePacket(&p)
}
Exemple #17
0
func packet(raddr net.IP) []byte {
	ip := &layers.IPv4{
		Version:           0x4,
		TOS:               0x0,
		TTL:               0x40,
		Protocol:          layers.IPProtocolUDP,
		SrcIP:             net.ParseIP(os.Args[2]),
		DstIP:             raddr,
		WithRawINETSocket: true,
	}
	udp := &layers.UDP{
		SrcPort: 0xaa47,
		DstPort: 0x50,
	}
	udp.SetNetworkLayerForChecksum(ip)
	buf := gopacket.NewSerializeBuffer()
	opts := gopacket.SerializeOptions{true, true}
	check(gopacket.SerializeLayers(buf, opts, ip, udp, gopacket.Payload([]byte("gg ez"))))
	return buf.Bytes()
}
Exemple #18
0
func (sender *udpSenderDF) send(msg []byte, raddr *net.UDPAddr) error {
	// Ensure we have a socket sending to the right IP address
	if sender.socket == nil || !bytes.Equal(sender.remoteIP, raddr.IP) {
		sender.remoteIP = raddr.IP
		if err := sender.dial(); err != nil {
			return err
		}
	}

	sender.udpHeader.DstPort = layers.UDPPort(raddr.Port)
	payload := gopacket.Payload(msg)
	err := gopacket.SerializeLayers(sender.ipBuf, sender.opts,
		sender.udpHeader, &payload)
	if err != nil {
		return err
	}

	packet := sender.ipBuf.Bytes()
	_, err = sender.socket.Write(packet)
	if err == nil || PosixError(err) != syscall.EMSGSIZE {
		return err
	}

	f, err := sender.socket.File()
	if err != nil {
		return err
	}
	defer f.Close()

	log.Print("EMSGSIZE on send, expecting PMTU update (IP packet was ",
		len(packet), " bytes, payload was ", len(msg), " bytes)")
	pmtu, err := syscall.GetsockoptInt(int(f.Fd()), syscall.IPPROTO_IP,
		syscall.IP_MTU)
	if err != nil {
		return err
	}

	return msgTooBigError{underlayPMTU: pmtu}
}
Exemple #19
0
func TestIPv6JumbogramSerialize(t *testing.T) {
	var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 2)
	var err error

	ip6 := &IPv6{}
	ip6.Version = 6
	ip6.NextHeader = IPProtocolNoNextHeader
	ip6.HopLimit = 64
	ip6.SrcIP = net.ParseIP("2001:db8::1")
	ip6.DstIP = net.ParseIP("2001:db8::2")
	serialize = append(serialize, ip6)

	payload := make([]byte, ipv6MaxPayloadLength+1)
	for i := range payload {
		payload[i] = 0xfe
	}
	serialize = append(serialize, gopacket.Payload(payload))

	buf := gopacket.NewSerializeBuffer()
	opts := gopacket.SerializeOptions{FixLengths: true}
	err = gopacket.SerializeLayers(buf, opts, serialize...)
	if err != nil {
		t.Fatal(err)
	}

	got := buf.Bytes()
	w := new(bytes.Buffer)
	w.Write(testPacketIPv6JumbogramHeader)
	w.Write(payload)
	want := w.Bytes()

	if !bytes.Equal(got, want) {
		t.Errorf("IPv6 Jumbogram serialize failed:\ngot:\n%v\n\nwant:\n%v\n\n",
			gopacket.LongBytesGoString(got), gopacket.LongBytesGoString(want))
	}
}
Exemple #20
0
/* protos must contain a UDP or TCP layer on top of IPv4 */
func forgeTestPacket(t *testing.T, seed int64, swap bool, protos ...ProtocolType) *gopacket.Packet {
	rnd := rand.New(rand.NewSource(seed))
	rawBytes := []byte{10, 20, 30}
	var protoStack []gopacket.SerializableLayer

	for i, proto := range protos {
		switch proto {
		case GRE:
			greLayer := &layers.GRE{}
			switch protos[i+1] {
			case IPv4:
				greLayer.Protocol = layers.EthernetTypeIPv4
			case IPv6:
				greLayer.Protocol = layers.EthernetTypeIPv6
			default:
				t.Error(fmt.Sprintf("Protocol %s can not be encapsulated in GRE", protos[i+1]))
			}
			protoStack = append(protoStack, greLayer)
		case ETH:
			ethernetLayer := &layers.Ethernet{
				SrcMAC:       net.HardwareAddr{0x00, 0x0F, 0xAA, 0xFA, 0xAA, byte(rnd.Intn(0x100))},
				DstMAC:       net.HardwareAddr{0x00, 0x0D, 0xBD, 0xBD, byte(rnd.Intn(0x100)), 0xBD},
				EthernetType: layers.EthernetTypeIPv4,
			}
			if swap {
				ethernetLayer.SrcMAC, ethernetLayer.DstMAC = ethernetLayer.DstMAC, ethernetLayer.SrcMAC
			}
			protoStack = append(protoStack, ethernetLayer)
		case IPv4:
			ipv4Layer := &layers.IPv4{
				SrcIP: net.IP{127, 0, 0, byte(rnd.Intn(0x100))},
				DstIP: net.IP{byte(rnd.Intn(0x100)), 8, 8, 8},
			}
			switch protos[i+1] {
			case TCP:
				ipv4Layer.Protocol = layers.IPProtocolTCP
			case UDP:
				ipv4Layer.Protocol = layers.IPProtocolUDP
			case GRE:
				ipv4Layer.Protocol = layers.IPProtocolGRE
			}
			if swap {
				ipv4Layer.SrcIP, ipv4Layer.DstIP = ipv4Layer.DstIP, ipv4Layer.SrcIP
			}
			protoStack = append(protoStack, ipv4Layer)
		case TCP:
			tcpLayer := &layers.TCP{
				SrcPort: layers.TCPPort(uint16(1024 + rnd.Intn(0x10000-1024))),
				DstPort: layers.TCPPort(uint16(1024 + rnd.Intn(0x10000-1024))),
			}
			if swap {
				tcpLayer.SrcPort, tcpLayer.DstPort = tcpLayer.DstPort, tcpLayer.SrcPort
			}
			protoStack = append(protoStack, tcpLayer)
		case UDP:
			udpLayer := &layers.UDP{
				SrcPort: layers.UDPPort(uint16(1024 + rnd.Intn(0x10000-1024))),
				DstPort: layers.UDPPort(uint16(1024 + rnd.Intn(0x10000-1024))),
			}
			if swap {
				udpLayer.SrcPort, udpLayer.DstPort = udpLayer.DstPort, udpLayer.SrcPort
			}
			protoStack = append(protoStack, udpLayer)
		default:
			t.Log("forgeTestPacket : Unsupported protocol ", proto)
		}
	}
	protoStack = append(protoStack, gopacket.Payload(rawBytes))

	buffer := gopacket.NewSerializeBuffer()
	options := gopacket.SerializeOptions{FixLengths: true}
	err := gopacket.SerializeLayers(buffer, options, protoStack...)

	if err != nil {
		t.Fail()
	}

	firstLayerType := layers.LayerTypeEthernet
	switch protos[0] {
	case IPv4:
		firstLayerType = layers.LayerTypeIPv4
	case IPv6:
		firstLayerType = layers.LayerTypeIPv6
	}
	gpacket := gopacket.NewPacket(buffer.Bytes(), firstLayerType, gopacket.Default)
	return &gpacket
}
Exemple #21
0
func (vnet *VNET) handleUDPForward(pkt *Packet, now time.Time) {
	defer pkt.Release()
	// fmt.Printf("UDP: %08x %s\n", pkt.Flags, pkt.String())

	var err error

	if bytes.Equal(pkt.Eth.DstMAC, layers.EthernetBroadcast[:]) {
		// ignore
		return
	}

	if pkt.DstHost == nil {
		// ignore
		return
	}
	if !pkt.DstHost.Up {
		log.Printf("destination is down: %s", pkt.DstHost.Name)
		// ignore
		return
	}

	var (
		srcIP   net.IP
		dstIP   net.IP
		srcPort = uint16(pkt.UDP.SrcPort)
		dstPort = uint16(pkt.UDP.DstPort)
	)

	if pkt.IPv4 != nil {
		srcIP = CloneIP(pkt.IPv4.SrcIP.To16())
		dstIP = CloneIP(pkt.IPv4.DstIP.To16())
	} else if pkt.IPv6 != nil {
		srcIP = CloneIP(pkt.IPv6.SrcIP.To16())
		dstIP = CloneIP(pkt.IPv6.DstIP.To16())
	} else {
		log.Printf("invalid protocol")
		// ignore
		return
	}

	route := vnet.routes.GetTable().Lookup(
		protocols.UDP,
		srcIP, dstIP, srcPort, dstPort)

	if route == nil {
		rule, found := vnet.rules.GetTable().Lookup(protocols.UDP, pkt.DstHost.ID, dstPort)
		if !found {
			log.Printf("no rule")
			// ignore
			return
		}

		var ruleDstIP = rule.DstIP

		if ruleDstIP == nil {
			gateway := vnet.hosts.GetTable().LookupByName("gateway")
			if gateway == nil || !gateway.Up {
				log.Printf("no gateway")
				// ignore
				return
			}

			if dstIP.To4() != nil {
				if len(gateway.IPv4Addrs) > 0 {
					ruleDstIP = gateway.IPv4Addrs[0]
				}
			} else {
				if len(gateway.IPv6Addrs) > 0 {
					ruleDstIP = gateway.IPv6Addrs[0]
				}
			}
		}
		if ruleDstIP == nil {
			log.Printf("no destination ip")
			// ignore
			return
		}

		var r routes.Route
		r.Protocol = protocols.UDP
		r.HostID = pkt.DstHost.ID
		r.SetInboundSource(srcIP, srcPort)
		r.SetInboundDestination(dstIP, dstPort)
		r.SetOutboundDestination(ruleDstIP, rule.DstPort)
		route, err = vnet.routes.AddRoute(&r)
		if err != nil {
			// ignore
			log.Printf("UDP/error: %s", err)
			return
		}
	}

	if route == nil {
		log.Printf("no route")
		// ignore
		return
	}

	var (
		eth layers.Ethernet
		udp layers.UDP
	)

	eth = *pkt.Eth
	eth.SrcMAC, eth.DstMAC = eth.DstMAC, eth.SrcMAC

	udp = *pkt.UDP
	udp.SrcPort = layers.UDPPort(route.Outbound.SrcPort)
	udp.DstPort = layers.UDPPort(route.Outbound.DstPort)

	if route.Outbound.DstIP.To4() != nil {
		ip := layers.IPv4{
			SrcIP:    route.Outbound.SrcIP.To4(),
			DstIP:    route.Outbound.DstIP.To4(),
			Version:  4,
			Protocol: layers.IPProtocolUDP,
			TTL:      64,
		}

		udp.SetNetworkLayerForChecksum(&ip)

		err = vnet.writePacket(
			&eth,
			&ip,
			&udp,
			gopacket.Payload(pkt.UDP.Payload))
		if err != nil {
			log.Printf("UDP/error: %s", err)
			return
		}

	} else {
		ip := layers.IPv6{
			SrcIP:      route.Outbound.SrcIP.To16(),
			DstIP:      route.Outbound.DstIP.To16(),
			Version:    4,
			NextHeader: layers.IPProtocolUDP,
		}

		udp.SetNetworkLayerForChecksum(&ip)

		err = vnet.writePacket(
			&eth,
			&ip,
			&udp,
			gopacket.Payload(pkt.UDP.Payload))
		if err != nil {
			log.Printf("UDP/error: %s", err)
			return
		}
	}

	route.RoutedPacket(now, len(pkt.buf))
}
//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
}
func InjectPacket(pp *PacketParams, g *graph.Graph) error {
	srcdata := pp.SrcNode.Metadata()
	dstdata := pp.DstNode.Metadata()

	if _, ok := srcdata["IPV4"]; !ok {
		return errors.New("Source Node doesn't have an IP")
	}

	srcIP := getIP(srcdata["IPV4"].(string))
	if srcIP == nil {
		return errors.New("Source Node doesn't have proper IP")
	}

	if _, ok := dstdata["IPV4"]; !ok {
		return errors.New("Destination Node doesn't have an IP")
	}

	dstIP := getIP(dstdata["IPV4"].(string))
	if dstIP == nil {
		return errors.New("Destination Node doesn't have proper IP")
	}

	srcMAC, err := net.ParseMAC(srcdata["MAC"].(string))
	if err != nil || srcMAC == nil {
		return errors.New("Source Node doesn't have proper MAC")
	}

	dstMAC, err := net.ParseMAC(dstdata["MAC"].(string))
	if err != nil || dstMAC == nil {
		return errors.New("Destination Node doesn't have proper MAC")
	}

	//create packet
	buffer := gopacket.NewSerializeBuffer()
	ipLayer := &layers.IPv4{Version: 4, SrcIP: srcIP, DstIP: dstIP}
	ethLayer := &layers.Ethernet{EthernetType: layers.EthernetTypeIPv4, SrcMAC: srcMAC, DstMAC: dstMAC}

	switch pp.Type {
	case "icmp":
		ipLayer.Protocol = layers.IPProtocolICMPv4
		gopacket.SerializeLayers(buffer, options,
			ethLayer,
			ipLayer,
			&layers.ICMPv4{
				TypeCode: layers.CreateICMPv4TypeCode(layers.ICMPv4TypeEchoRequest, 0),
			},
			gopacket.Payload([]byte(pp.Payload)),
		)
	default:
		return fmt.Errorf("Unsupported traffic type '%s'", pp.Type)
	}

	g.RLock()

	srcNode := g.GetNode(pp.SrcNode.ID)
	if srcNode == nil {
		g.RUnlock()
		return errors.New("Unable to find source node")
	}

	nscontext, err := topology.NewNetNSContextByNode(g, srcNode)
	defer nscontext.Close()

	g.RUnlock()

	if err != nil {
		return err
	}

	handle, err := pcap.OpenLive(srcdata["Name"].(string), 1024, false, 2000)
	if err != nil {
		return fmt.Errorf("Unable to open the source node: %s", err.Error())
	}
	defer handle.Close()

	packet := buffer.Bytes()
	for i := 0; i < pp.Count; i++ {
		if err := handle.WritePacketData(packet); err != nil {
			return fmt.Errorf("Write error: %s", err.Error())
		}
	}

	return nil
}
Exemple #24
0
//sendPacket generates & sends a packet of arbitrary size to a specific destination.
//The size specified should be larger then 40bytes.
func sendPacket(sourceIP string, destinationIP string, size int, message string, appID int, chanID int, icmpType layers.ICMPv4TypeCode) []byte {

	var payloadSize int
	if size < 28 {
		//Unable to create smaller packets.
		payloadSize = 0
	} else {
		payloadSize = size - 28
	}

	//Convert IP to 4bit representation
	srcIP := net.ParseIP(sourceIP).To4()
	dstIP := net.ParseIP(destinationIP).To4()

	//IP Layer
	ip := layers.IPv4{
		SrcIP:    srcIP,
		DstIP:    dstIP,
		Version:  4,
		TTL:      64,
		Protocol: layers.IPProtocolICMPv4,
	}

	icmp := layers.ICMPv4{
		TypeCode: icmpType,
	}

	opts := gopacket.SerializeOptions{
		FixLengths:       true,
		ComputeChecksums: true,
	}

	ipHeaderBuf := gopacket.NewSerializeBuffer()

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

	//Set "Don't Fragment"-Flag in Header
	ipHeader, err := ipv4.ParseHeader(ipHeaderBuf.Bytes())
	ipHeader.Flags |= ipv4.DontFragment
	if err != nil {
		panic(err)
	}

	payloadBuf := gopacket.NewSerializeBuffer()

	//Influence the payload size
	payload := gopacket.Payload(generatePayload(payloadSize, ","+strconv.Itoa(appID)+","+strconv.Itoa(chanID)+","+message+","))
	err = gopacket.SerializeLayers(payloadBuf, opts, &icmp, payload)
	if err != nil {
		panic(err)
	}

	//Send packet
	var packetConn net.PacketConn
	var rawConn *ipv4.RawConn

	packetConn, err = net.ListenPacket("ip4:icmp", srcIP.String())
	if err != nil {
		panic(err)
	}
	rawConn, err = ipv4.NewRawConn(packetConn)
	if err != nil {
		panic(err)
	}

	err = rawConn.WriteTo(ipHeader, payloadBuf.Bytes(), nil)

	return append(ipHeaderBuf.Bytes(), payloadBuf.Bytes()...)
}
Exemple #25
0
func (vnet *VNET) handleDHCPOffer(pkt *Packet, offer *dhcp.Message) {
	if offer.YourIPAddress == nil {
		return
	}

	msg := &dhcp.Message{}

	msg.ClientMAC = vnet.system.ControllerMAC()

	msg.Type = dhcp.MessageTypeRequest
	msg.HardwareType = dhcp.MessageHardwareTypeEthernet
	msg.HardwareAddressLength = 6
	msg.Hops = 0
	msg.TransactionID = offer.TransactionID
	msg.Options = map[uint8]*dhcp.Option{

		dhcp.OptionCodeDHCPMessageType: {
			Value: []byte{dhcp.DHCPMessageTypeRequest},
		},

		dhcp.OptionCodeDHCPClientidentifier: {
			Value: append([]byte{1}, msg.ClientMAC[:6]...),
		},

		dhcp.OptionCodeDHCPRequestedIPAddress: {
			Value: offer.YourIPAddress.To4(),
		},

		dhcp.OptionCodeDHCPServerIdentifier: offer.Options[dhcp.OptionCodeDHCPServerIdentifier],

		dhcp.OptionCodeDHCPMaximumMessageSize: {
			Value: []byte{2, 64}, // 576
		},

		dhcp.OptionCodeDHCPParameterRequestList: {
			Value: []byte{
				dhcp.OptionCodeSubnetMask,
				dhcp.OptionCodeRouter,
				dhcp.OptionCodeDomainNameServer,
				dhcp.OptionCodeHostName,
				dhcp.OptionCodeDomainName,
				dhcp.OptionCodeBroadcastAddress,
				dhcp.OptionCodeNetworkTimeProtocolServers,
			},
		},

		dhcp.OptionCodeDHCPVendorclassidentifier: {
			Value: []byte("swtchbrd 1.23.1"),
		},

		dhcp.OptionCodeEnd: {},
	}

	ipv4 := &layers.IPv4{
		SrcIP:    net.IPv4(0, 0, 0, 0),
		DstIP:    net.IPv4(255, 255, 255, 255),
		Version:  4,
		Protocol: layers.IPProtocolUDP,
		TTL:      64,
	}

	udp := &layers.UDP{
		SrcPort: layers.UDPPort(68),
		DstPort: layers.UDPPort(67),
	}

	udp.SetNetworkLayerForChecksum(ipv4)

	err := vnet.writePacket(
		&layers.Ethernet{
			SrcMAC:       msg.ClientMAC,
			DstMAC:       layers.EthernetBroadcast,
			EthernetType: layers.EthernetTypeIPv4,
		},
		ipv4,
		udp,
		gopacket.Payload(writeDHCPMessage(msg)))
	if err != nil {
		log.Printf("DCHP/error: %s", err)
		return
	}

	return
}
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, &eth, &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)
}
Exemple #27
0
// Given an EvePacket, convert the payload to a PCAP faking out the
// headers as best we can.
//
// A buffer containing the 1 packet pcap file will be returned.
func EvePayloadToPcap(event *EveEvent) ([]byte, error) {
	buffer := gopacket.NewSerializeBuffer()
	options := gopacket.SerializeOptions{
		FixLengths:       true,
		ComputeChecksums: true,
	}

	payloadLayer := gopacket.Payload(event.Payload.Bytes())
	payloadLayer.SerializeTo(buffer, options)

	srcIp := net.ParseIP(event.SrcIP)
	if srcIp == nil {
		return nil, fmt.Errorf("Failed to parse IP address %s.", event.SrcIP)
	}
	dstIp := net.ParseIP(event.DstIP)
	if dstIp == nil {
		return nil, fmt.Errorf("Failed to parse IP address %s.", event.DstIP)
	}

	proto, err := ProtoNumber(event.Proto)
	if err != nil {
		return nil, err
	}

	switch proto {
	case layers.IPProtocolTCP:
		// Could probably fake up a better TCP layer here.
		tcpLayer := layers.TCP{
			SrcPort: layers.TCPPort(event.SrcPort),
			DstPort: layers.TCPPort(event.DstPort),
		}
		tcpLayer.SerializeTo(buffer, options)
		break
	case layers.IPProtocolUDP:
		udpLayer := layers.UDP{
			SrcPort: layers.UDPPort(event.SrcPort),
			DstPort: layers.UDPPort(event.DstPort),
		}
		udpLayer.SerializeTo(buffer, options)
		break
	case layers.IPProtocolICMPv4:
		icmpLayer := layers.ICMPv4{
			TypeCode: layers.CreateICMPv4TypeCode(
				event.IcmpType, event.IcmpCode),
			Id:  0,
			Seq: 0,
		}
		icmpLayer.SerializeTo(buffer, options)
		break
	case layers.IPProtocolICMPv6:
		icmp6Layer := layers.ICMPv6{
			TypeCode: layers.CreateICMPv6TypeCode(
				event.IcmpType, event.IcmpCode),
		}
		icmp6Layer.SerializeTo(buffer, options)
		break
	default:
		return nil, fmt.Errorf("Unsupported protocol %d.", proto)
	}

	isIp6 := dstIp.To4() == nil

	if !isIp6 {
		ipLayer := layers.IPv4{
			SrcIP:    srcIp,
			DstIP:    dstIp,
			Version:  4,
			Protocol: proto,
			TTL:      64,
		}
		ipLayer.SerializeTo(buffer, options)
	} else {
		ip6Layer := layers.IPv6{
			Version: 6,
			SrcIP:   srcIp,
			DstIP:   dstIp,
		}
		ip6Layer.SerializeTo(buffer, options)
	}

	return pcap.CreatePcap(event.Timestamp.Time,
		buffer.Bytes(), layers.LinkTypeRaw)
}