Пример #1
0
func (srv *HopServer) forwardFrames() {

	// packet map
	srv.pktHandle = map[byte](func(*udpPacket, *HopPacket)){
		HOP_FLG_PSH:               srv.handleKnock,
		HOP_FLG_PSH | HOP_FLG_ACK: srv.handleHeartbeatAck,
		HOP_FLG_HSH:               srv.handleHandshake,
		HOP_FLG_HSH | HOP_FLG_ACK: srv.handleHandshakeAck,
		HOP_FLG_DAT:               srv.handleDataPacket,
		HOP_FLG_DAT | HOP_FLG_MFR: srv.handleDataPacket,
		HOP_FLG_FIN:               srv.handleFinish,
	}

	for {
		select {
		case pack := <-srv.fromIface:
			// logger.Debug("New iface Frame")
			// first byte is left for opcode
			frame := pack[HOP_HDR_LEN:]
			dest := waterutil.IPv4Destination(frame).To4()
			mkey := ip4_uint64(dest)

			// logger.Debug("ip dest: %v", dest)
			if hpeer, found := srv.peers[mkey]; found {
				srv.bufferToClient(hpeer, pack)
			} else {
				logger.Warning("client peer with key %d not found", mkey)
			}

		case packet := <-srv.fromNet:
			srv.handlePacket(packet)
		}

	}
}
Пример #2
0
func main() {
	ifce, err := water.NewTAP("tap0")
	fmt.Printf("%v, %v\n\n", err, ifce)
	buffer := make([]byte, BUFFERSIZE)
	for {
		_, err = ifce.Read(buffer)
		if err != nil {
			fmt.Printf("err = %v\n", err)
			break
		}
		ethertype := waterutil.MACEthertype(buffer)
		fmt.Printf("ethertype = %#v\n", ethertype)
		if ethertype == waterutil.IPv4 {
			packet := waterutil.MACPayload(buffer)
			if waterutil.IsIPv4(packet) {
				fmt.Printf("IPv4 Source:      %v [%v]\n", waterutil.MACSource(buffer), waterutil.IPv4Source(packet))
				fmt.Printf("IPv4 Destination: %v [%v]\n", waterutil.MACDestination(buffer), waterutil.IPv4Destination(packet))
				fmt.Printf("IPv4 Protocol:    %v\n\n", waterutil.IPv4Protocol(packet))
			} else if waterutil.IsIPv6(packet) {
				fmt.Printf("IPv6 Source:      %v\n", waterutil.MACSource(buffer))
				fmt.Printf("IPv6 Destination: %v\n\n", waterutil.MACDestination(buffer))
			} else {
				fmt.Printf("unknow Source:      %v\n", waterutil.MACSource(buffer))
				fmt.Printf("unknow Destination: %v\n\n", waterutil.MACDestination(buffer))
			}
		}
	}
}
Пример #3
0
func updateChecksum(datagram []byte) {
	ipv4_hdr_len := 4 * (datagram[0] & 0x0F)

	datagram[ipv4_hdr_len+16] = 0
	datagram[ipv4_hdr_len+17] = 0

	csum := Csum(datagram[ipv4_hdr_len:],
		IPTo4le(waterutil.IPv4Source(datagram)),
		IPTo4le(waterutil.IPv4Destination(datagram)))

	datagram[ipv4_hdr_len+16] = (byte)(csum >> 8)
	datagram[ipv4_hdr_len+17] = (byte)(csum & 0xFF)
}
Пример #4
0
func TestBroadcast(t *testing.T) {
	var (
		self = net.IPv4(10, 0, 42, 1)
		mask = net.IPv4Mask(255, 255, 255, 0)
		brd  = net.IPv4(10, 0, 42, 255)
	)

	ifce, err := NewTAP("test")
	if err != nil {
		t.Fatalf("creating TAP error: %v\n", err)
	}

	setupIfce(t, net.IPNet{IP: self, Mask: mask}, ifce.Name())
	startBroadcast(t, brd)

	dataCh := make(chan []byte, 8)
	startRead(dataCh, ifce)

	timeout := time.NewTimer(8 * time.Second).C

readFrame:
	for {
		select {
		case buffer := <-dataCh:
			ethertype := waterutil.MACEthertype(buffer)
			if ethertype != waterutil.IPv4 {
				continue readFrame
			}
			if !waterutil.IsBroadcast(waterutil.MACDestination(buffer)) {
				continue readFrame
			}
			packet := waterutil.MACPayload(buffer)
			if !waterutil.IsIPv4(packet) {
				continue readFrame
			}
			if !waterutil.IPv4Source(packet).Equal(self) {
				continue readFrame
			}
			if !waterutil.IPv4Destination(packet).Equal(brd) {
				continue readFrame
			}
			if waterutil.IPv4Protocol(packet) != waterutil.ICMP {
				continue readFrame
			}
			t.Logf("received broadcast frame: %#v\n", buffer)
			break readFrame
		case <-timeout:
			t.Fatal("Waiting for broadcast packet timeout")
		}
	}
}
Пример #5
0
func HostProxy() {

	file, e := ioutil.ReadFile(*config_path)
	if e != nil {
		l_err.Printf("Config file open error: %v\n", e)
		os.Exit(1)
	}

	var config Config
	e_parse := json.Unmarshal(file, &config)
	if e_parse != nil {
		l_err.Printf("Config parse error: %v\n", e_parse)
		os.Exit(1)
	}

	// Get interface IP
	config_interface_ip := config.Proxy.SourceIP

	raw_sock, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_RAW)
	if err != nil {
		panic(err)
	}

	err = syscall.SetsockoptInt(raw_sock, syscall.IPPROTO_IP, syscall.IP_HDRINCL, 1)
	if err != nil {
		panic(err)
	}

	// Length byte order
	cmd_stdoutQueue := make(chan interface{}, 10)
	cmd_stdinQueue := make(chan interface{}, 10)
	SpawnNodeSubprocess(*config_path, cmd_stdoutQueue, cmd_stdinQueue)

	proxy := NewProxyState()

	go proxy.doListen(syscall.IPPROTO_TCP)
	go proxy.doListen(syscall.IPPROTO_UDP)

	go func() {
		for {
			datagram := <-proxy.messages_to_send

			waterutil.SetIPv4Source(datagram, config_interface_ip)

			updateChecksum(datagram)

			destinationIP := waterutil.IPv4Destination(datagram)

			// Reverse byte order of IP for host byte order
			destinationIP4 := destinationIP.To4()
			dstAddrHost := [4]byte{destinationIP4[3], destinationIP4[2], destinationIP4[1], destinationIP4[0]}
			dstAddr := syscall.SockaddrInet4{Addr: dstAddrHost}

			// Swap header length byte order, for host byte order
			{
				x := datagram[2]
				datagram[2] = datagram[3]
				datagram[3] = x
			}

			err = syscall.Sendto(raw_sock, datagram, 0, &dstAddr)
			if err != nil {
				fmt.Fprintf(os.Stderr, "Error on sendto(): %v\n", err)
			}
		}
	}()

	// Process messages coming from node
	for {
		select {
		case datagram := <-proxy.messages_received:
			{
				local_port := LocalPort{
					binary.BigEndian.Uint32(waterutil.IPv4Destination(datagram)),
					waterutil.IPv4DestinationPort(datagram),
					// TODO: UDP
					waterutil.TCP,
				}
				fmt.Fprintf(os.Stderr, "Main loop recvd from %v: %v\n", local_port, datagram)
				if source_port, exists := proxy.source_ports_by_local_ports[local_port]; exists {
					fmt.Fprintf(os.Stderr, "--- Exists\n")
					cmd_stdinQueue <- Stdin_SendBack{mesh.MeshMessage{source_port.SendId, source_port.ConnectedPeer, []byte{}}, datagram}
				}
			}
		case msg_out := <-cmd_stdoutQueue:
			{
				if reflect.TypeOf(msg_out) == reflect.TypeOf(Stdout_RecvMessage{}) {
					recv_msg := msg_out.(Stdout_RecvMessage)
					datagram := recv_msg.Contents
					protocol := waterutil.IPv4Protocol(datagram)
					if protocol == waterutil.TCP || protocol == waterutil.UDP {
						source := SourcePort{
							recv_msg.SendId,
							recv_msg.ConnectedPeer,
							waterutil.IPv4SourcePort(datagram),
							binary.BigEndian.Uint32(waterutil.IPv4Source(datagram)),
							protocol,
						}
						port := proxy.portForSource(source)

						destinationIP := waterutil.IPv4Destination(datagram)
						fmt.Fprintf(os.Stderr, "\n<<<<<<<<<<< recv from source: %v use port %v dst %s\n", source, port, destinationIP)

						waterutil.SetIPv4SourcePort(datagram, port.Port)
						srcIP := make([]byte, 4)
						binary.LittleEndian.PutUint32(srcIP, port.IP)
						waterutil.SetIPv4Source(datagram, srcIP)
						waterutil.ZeroIPv4Checksum(datagram)

						proxy.messages_to_send <- datagram
					}
				}
			}
		}

	}

}