Ejemplo n.º 1
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}
}
Ejemplo n.º 2
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
}
Ejemplo n.º 3
0
func NewRawUDPSender(conn *LocalConnection) (*RawUDPSender, error) {
	ipSocket, err := dialIP(conn)
	if err != nil {
		return nil, err
	}
	udpHeader := &layers.UDP{SrcPort: layers.UDPPort(Port)}
	ipBuf := gopacket.NewSerializeBuffer()
	opts := gopacket.SerializeOptions{
		FixLengths: true,
		// UDP header is calculated with a phantom IP
		// header. Yes, it's totally nuts. Thankfully, for UDP
		// over IPv4, the checksum is optional. It's not
		// optional for IPv6, but we'll ignore that for
		// now. TODO
		ComputeChecksums: false}

	return &RawUDPSender{
		ipBuf:     ipBuf,
		opts:      opts,
		udpHeader: udpHeader,
		socket:    ipSocket,
		conn:      conn}, nil
}
Ejemplo n.º 4
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
}