mirror of
				https://github.com/yggdrasil-network/water.git
				synced 2025-10-26 06:45:09 +03:00 
			
		
		
		
	initial commit
This commit is contained in:
		
							parent
							
								
									a9977e0a62
								
							
						
					
					
						commit
						4a028c3fe3
					
				
					 7 changed files with 377 additions and 0 deletions
				
			
		
							
								
								
									
										71
									
								
								if.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								if.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,71 @@ | ||||||
|  | package water | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"os" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Interface is a TUN/TAP interface. | ||||||
|  | type Interface struct { | ||||||
|  | 	isTAP bool | ||||||
|  | 	file  *os.File | ||||||
|  | 	name  string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Create a new TAP interface whose name is ifName. | ||||||
|  | // If ifName is empty, a default name (tap0, tap1, ... ) will be assigned. | ||||||
|  | // ifName should not exceed 16 bytes. | ||||||
|  | func NewTAP(ifName string) (ifce *Interface, err error) { | ||||||
|  | 	file, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	name, err := createInterface(file.Fd(), ifName, cIFF_TAP|cIFF_NO_PI) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	ifce = &Interface{isTAP: true, file: file, name: name} | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Create a new TUN interface whose name is ifName. | ||||||
|  | // If ifName is empty, a default name (tap0, tap1, ... ) will be assigned. | ||||||
|  | // ifName should not exceed 16 bytes. | ||||||
|  | func NewTUN(ifName string) (ifce *Interface, err error) { | ||||||
|  | 	file, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	name, err := createInterface(file.Fd(), ifName, cIFF_TUN|cIFF_NO_PI) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	ifce = &Interface{isTAP: false, file: file, name: name} | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Returns true if ifce is a TUN interface, otherwise returns false; | ||||||
|  | func (ifce *Interface) IsTUN() bool { | ||||||
|  | 	return !ifce.isTAP | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Returns true if ifce is a TAP interface, otherwise returns false; | ||||||
|  | func (ifce *Interface) IsTAP() bool { | ||||||
|  | 	return ifce.isTAP | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Returns the interface name of ifce, e.g. tun0, tap1, etc.. | ||||||
|  | func (ifce *Interface) Name() string { | ||||||
|  | 	return ifce.name | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Implement io.Writer interface. | ||||||
|  | func (ifce *Interface) Write(p []byte) (n int, err error) { | ||||||
|  | 	n, err = ifce.file.Write(p) | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Implement io.Reader interface. | ||||||
|  | func (ifce *Interface) Read(p []byte) (n int, err error) { | ||||||
|  | 	n, err = ifce.file.Read(p) | ||||||
|  | 	return | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								syscalls_linux.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								syscalls_linux.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | ||||||
|  | // +build linux | ||||||
|  | 
 | ||||||
|  | package water | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"strings" | ||||||
|  | 	"syscall" | ||||||
|  | 	"unsafe" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	cIFF_TUN   = 0x0001 | ||||||
|  | 	cIFF_TAP   = 0x0002 | ||||||
|  | 	cIFF_NO_PI = 0x1000 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type ifReq struct { | ||||||
|  | 	Name  [0x10]byte | ||||||
|  | 	Flags uint16 | ||||||
|  | 	pad   [0x28 - 0x10 - 2]byte | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func createInterface(fd uintptr, ifName string, flags uint16) (createdIFName string, err error) { | ||||||
|  | 	var req ifReq | ||||||
|  | 	req.Flags = flags | ||||||
|  | 	copy(req.Name[:], ifName) | ||||||
|  | 	_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TUNSETIFF), uintptr(unsafe.Pointer(&req))) | ||||||
|  | 	if errno != 0 { | ||||||
|  | 		err = errno | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	createdIFName = strings.Trim(string(req.Name[:]), "\x00") | ||||||
|  | 	return | ||||||
|  | } | ||||||
							
								
								
									
										46
									
								
								waterutil/ethertypes.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								waterutil/ethertypes.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,46 @@ | ||||||
|  | package waterutil | ||||||
|  | 
 | ||||||
|  | type Ethertype [2]byte | ||||||
|  | 
 | ||||||
|  | // Ethertype values. From: http://en.wikipedia.org/wiki/Ethertype | ||||||
|  | var ( | ||||||
|  | 	IPv4                = Ethertype{0x08, 0x00} | ||||||
|  | 	ARP                 = Ethertype{0x08, 0x06} | ||||||
|  | 	WakeOnLAN           = Ethertype{0x08, 0x42} | ||||||
|  | 	TRILL               = Ethertype{0x22, 0xF3} | ||||||
|  | 	DECnetPhase4        = Ethertype{0x60, 0x03} | ||||||
|  | 	RARP                = Ethertype{0x80, 0x35} | ||||||
|  | 	AppleTalk           = Ethertype{0x80, 0x9B} | ||||||
|  | 	AARP                = Ethertype{0x80, 0xF3} | ||||||
|  | 	IPX1                = Ethertype{0x81, 0x37} | ||||||
|  | 	IPX2                = Ethertype{0x81, 0x38} | ||||||
|  | 	QNXQnet             = Ethertype{0x82, 0x04} | ||||||
|  | 	IPv6                = Ethertype{0x86, 0xDD} | ||||||
|  | 	EthernetFlowControl = Ethertype{0x88, 0x08} | ||||||
|  | 	IEEE802_3           = Ethertype{0x88, 0x09} | ||||||
|  | 	CobraNet            = Ethertype{0x88, 0x19} | ||||||
|  | 	MPLSUnicast         = Ethertype{0x88, 0x47} | ||||||
|  | 	MPLSMulticast       = Ethertype{0x88, 0x48} | ||||||
|  | 	PPPoEDiscovery      = Ethertype{0x88, 0x63} | ||||||
|  | 	PPPoESession        = Ethertype{0x88, 0x64} | ||||||
|  | 	JumboFrames         = Ethertype{0x88, 0x70} | ||||||
|  | 	HomePlug1_0MME      = Ethertype{0x88, 0x7B} | ||||||
|  | 	IEEE802_1X          = Ethertype{0x88, 0x8E} | ||||||
|  | 	PROFINET            = Ethertype{0x88, 0x92} | ||||||
|  | 	HyperSCSI           = Ethertype{0x88, 0x9A} | ||||||
|  | 	AoE                 = Ethertype{0x88, 0xA2} | ||||||
|  | 	EtherCAT            = Ethertype{0x88, 0xA4} | ||||||
|  | 	EthernetPowerlink   = Ethertype{0x88, 0xAB} | ||||||
|  | 	LLDP                = Ethertype{0x88, 0xCC} | ||||||
|  | 	SERCOS3             = Ethertype{0x88, 0xCD} | ||||||
|  | 	HomePlugAVMME       = Ethertype{0x88, 0xE1} | ||||||
|  | 	MRP                 = Ethertype{0x88, 0xE3} | ||||||
|  | 	IEEE802_1AE         = Ethertype{0x88, 0xE5} | ||||||
|  | 	IEEE1588            = Ethertype{0x88, 0xF7} | ||||||
|  | 	IEEE802_1ag         = Ethertype{0x89, 0x02} | ||||||
|  | 	FCoE                = Ethertype{0x89, 0x06} | ||||||
|  | 	FCoEInit            = Ethertype{0x89, 0x14} | ||||||
|  | 	RoCE                = Ethertype{0x89, 0x15} | ||||||
|  | 	CTP                 = Ethertype{0x90, 0x00} | ||||||
|  | 	VeritasLLT          = Ethertype{0xCA, 0xFE} | ||||||
|  | ) | ||||||
							
								
								
									
										139
									
								
								waterutil/ip_protocols.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								waterutil/ip_protocols.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,139 @@ | ||||||
|  | package waterutil | ||||||
|  | 
 | ||||||
|  | type IPProtocol byte | ||||||
|  | 
 | ||||||
|  | // IP Protocols. From: http://en.wikipedia.org/wiki/List_of_IP_protocol_numbers | ||||||
|  | const ( | ||||||
|  | 	HOPOPT            = 0x00 | ||||||
|  | 	ICMP              = 0x01 | ||||||
|  | 	IGMP              = 0x02 | ||||||
|  | 	GGP               = 0x03 | ||||||
|  | 	IPv4Encapsulation = 0x04 | ||||||
|  | 	ST                = 0x05 | ||||||
|  | 	TCP               = 0x06 | ||||||
|  | 	CBT               = 0x07 | ||||||
|  | 	EGP               = 0x08 | ||||||
|  | 	IGP               = 0x09 | ||||||
|  | 	BBN_RCC_MON       = 0x0A | ||||||
|  | 	NVP_II            = 0x0B | ||||||
|  | 	PUP               = 0x0C | ||||||
|  | 	ARGUS             = 0x0D | ||||||
|  | 	EMCON             = 0x0E | ||||||
|  | 	XNET              = 0x0F | ||||||
|  | 	CHAOS             = 0x10 | ||||||
|  | 	UDP               = 0x11 | ||||||
|  | 	MUX               = 0x12 | ||||||
|  | 	DCN_MEAS          = 0x13 | ||||||
|  | 	HMP               = 0x14 | ||||||
|  | 	PRM               = 0x15 | ||||||
|  | 	XNS_IDP           = 0x16 | ||||||
|  | 	TRUNK_1           = 0x17 | ||||||
|  | 	TRUNK_2           = 0x18 | ||||||
|  | 	LEAF_1            = 0x19 | ||||||
|  | 	LEAF_2            = 0x1A | ||||||
|  | 	RDP               = 0x1B | ||||||
|  | 	IRTP              = 0x1C | ||||||
|  | 	ISO_TP4           = 0x1D | ||||||
|  | 	NETBLT            = 0x1E | ||||||
|  | 	MFE_NSP           = 0x1F | ||||||
|  | 	MERIT_INP         = 0x20 | ||||||
|  | 	DCCP              = 0x21 | ||||||
|  | 	ThirdPC           = 0x22 | ||||||
|  | 	IDPR              = 0x23 | ||||||
|  | 	XTP               = 0x24 | ||||||
|  | 	DDP               = 0x25 | ||||||
|  | 	IDPR_CMTP         = 0x26 | ||||||
|  | 	TPxx              = 0x27 | ||||||
|  | 	IL                = 0x28 | ||||||
|  | 	IPv6Encapsulation = 0x29 | ||||||
|  | 	SDRP              = 0x2A | ||||||
|  | 	IPv6_Route        = 0x2B | ||||||
|  | 	IPv6_Frag         = 0x2C | ||||||
|  | 	IDRP              = 0x2D | ||||||
|  | 	RSVP              = 0x2E | ||||||
|  | 	GRE               = 0x2F | ||||||
|  | 	MHRP              = 0x30 | ||||||
|  | 	BNA               = 0x31 | ||||||
|  | 	ESP               = 0x32 | ||||||
|  | 	AH                = 0x33 | ||||||
|  | 	I_NLSP            = 0x34 | ||||||
|  | 	SWIPE             = 0x35 | ||||||
|  | 	NARP              = 0x36 | ||||||
|  | 	MOBILE            = 0x37 | ||||||
|  | 	TLSP              = 0x38 | ||||||
|  | 	SKIP              = 0x39 | ||||||
|  | 	IPv6_ICMP         = 0x3A | ||||||
|  | 	IPv6_NoNxt        = 0x3B | ||||||
|  | 	IPv6_Opts         = 0x3C | ||||||
|  | 	CFTP              = 0x3E | ||||||
|  | 	SAT_EXPAK         = 0x40 | ||||||
|  | 	KRYPTOLAN         = 0x41 | ||||||
|  | 	RVD               = 0x42 | ||||||
|  | 	IPPC              = 0x43 | ||||||
|  | 	SAT_MON           = 0x45 | ||||||
|  | 	VISA              = 0x46 | ||||||
|  | 	IPCV              = 0x47 | ||||||
|  | 	CPNX              = 0x48 | ||||||
|  | 	CPHB              = 0x49 | ||||||
|  | 	WSN               = 0x4A | ||||||
|  | 	PVP               = 0x4B | ||||||
|  | 	BR_SAT_MON        = 0x4C | ||||||
|  | 	SUN_ND            = 0x4D | ||||||
|  | 	WB_MON            = 0x4E | ||||||
|  | 	WB_EXPAK          = 0x4F | ||||||
|  | 	ISO_IP            = 0x50 | ||||||
|  | 	VMTP              = 0x51 | ||||||
|  | 	SECURE_VMTP       = 0x52 | ||||||
|  | 	VINES             = 0x53 | ||||||
|  | 	TTP               = 0x54 | ||||||
|  | 	IPTM              = 0x54 | ||||||
|  | 	NSFNET_IGP        = 0x55 | ||||||
|  | 	DGP               = 0x56 | ||||||
|  | 	TCF               = 0x57 | ||||||
|  | 	EIGRP             = 0x58 | ||||||
|  | 	OSPF              = 0x59 | ||||||
|  | 	Sprite_RPC        = 0x5A | ||||||
|  | 	LARP              = 0x5B | ||||||
|  | 	MTP               = 0x5C | ||||||
|  | 	AX_25             = 0x5D | ||||||
|  | 	IPIP              = 0x5E | ||||||
|  | 	MICP              = 0x5F | ||||||
|  | 	SCC_SP            = 0x60 | ||||||
|  | 	ETHERIP           = 0x61 | ||||||
|  | 	ENCAP             = 0x62 | ||||||
|  | 	GMTP              = 0x64 | ||||||
|  | 	IFMP              = 0x65 | ||||||
|  | 	PNNI              = 0x66 | ||||||
|  | 	PIM               = 0x67 | ||||||
|  | 	ARIS              = 0x68 | ||||||
|  | 	SCPS              = 0x69 | ||||||
|  | 	QNX               = 0x6A | ||||||
|  | 	A_N               = 0x6B | ||||||
|  | 	IPComp            = 0x6C | ||||||
|  | 	SNP               = 0x6D | ||||||
|  | 	Compaq_Peer       = 0x6E | ||||||
|  | 	IPX_in_IP         = 0x6F | ||||||
|  | 	VRRP              = 0x70 | ||||||
|  | 	PGM               = 0x71 | ||||||
|  | 	L2TP              = 0x73 | ||||||
|  | 	DDX               = 0x74 | ||||||
|  | 	IATP              = 0x75 | ||||||
|  | 	STP               = 0x76 | ||||||
|  | 	SRP               = 0x77 | ||||||
|  | 	UTI               = 0x78 | ||||||
|  | 	SMP               = 0x79 | ||||||
|  | 	SM                = 0x7A | ||||||
|  | 	PTP               = 0x7B | ||||||
|  | 	FIRE              = 0x7D | ||||||
|  | 	CRTP              = 0x7E | ||||||
|  | 	CRUDP             = 0x7F | ||||||
|  | 	SSCOPMCE          = 0x80 | ||||||
|  | 	IPLT              = 0x81 | ||||||
|  | 	SPS               = 0x82 | ||||||
|  | 	PIPE              = 0x83 | ||||||
|  | 	SCTP              = 0x84 | ||||||
|  | 	FC                = 0x85 | ||||||
|  | 	manet             = 0x8A | ||||||
|  | 	HIP               = 0x8B | ||||||
|  | 	Shim6             = 0x8C | ||||||
|  | ) | ||||||
							
								
								
									
										40
									
								
								waterutil/tap.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								waterutil/tap.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | ||||||
|  | package waterutil | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"net" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type Tagging int | ||||||
|  | 
 | ||||||
|  | // Indicating whether/how a MAC frame is tagged. The value is number of bytes taken by tagging. | ||||||
|  | const ( | ||||||
|  | 	NotTagged    Tagging = 0 | ||||||
|  | 	Tagged       Tagging = 4 | ||||||
|  | 	DoubleTagged Tagging = 8 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func MACDestination(macFrame []byte) net.HardwareAddr { | ||||||
|  | 	return net.HardwareAddr(macFrame[:6]) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func MACSource(macFrame []byte) net.HardwareAddr { | ||||||
|  | 	return net.HardwareAddr(macFrame[6:12]) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func MACTagging(macFrame []byte) Tagging { | ||||||
|  | 	if macFrame[12] == 0x81 && macFrame[13] == 0x00 { | ||||||
|  | 		return Tagged | ||||||
|  | 	} else if macFrame[12] == 0x88 && macFrame[13] == 0xa8 { | ||||||
|  | 		return DoubleTagged | ||||||
|  | 	} | ||||||
|  | 	return NotTagged | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func MACEthertype(macFrame []byte) Ethertype { | ||||||
|  | 	ethertypePos := 12 + MACTagging(macFrame) | ||||||
|  | 	return Ethertype{macFrame[ethertypePos], macFrame[ethertypePos+1]} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func MACPayload(macFrame []byte) []byte { | ||||||
|  | 	return macFrame[12+MACTagging(macFrame)+2:] | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								waterutil/tun.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								waterutil/tun.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | ||||||
|  | package waterutil | ||||||
|  | 
 | ||||||
|  | func IsIPv4(packet []byte) bool { | ||||||
|  | 	return 4 == (packet[0] >> 4) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func IsIPv6(packet []byte) bool { | ||||||
|  | 	return 6 == (packet[0] >> 4) | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								waterutil/tun_ipv4.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								waterutil/tun_ipv4.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,38 @@ | ||||||
|  | package waterutil | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"net" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func IPv4DSCP(packet []byte) byte { | ||||||
|  | 	return packet[1] >> 2 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func IPv4ECN(packet []byte) byte { | ||||||
|  | 	return packet[1] & 0x03 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func IPv4Identification(packet []byte) [2]byte { | ||||||
|  | 	return [2]byte{packet[4], packet[5]} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func IPv4TTL(packet []byte) byte { | ||||||
|  | 	return packet[8] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func IPv4Protocol(packet []byte) IPProtocol { | ||||||
|  | 	return IPProtocol(packet[9]) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func IPv4Source(packet []byte) net.IP { | ||||||
|  | 	return net.IPv4(packet[12], packet[13], packet[14], packet[15]) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func IPv4Destination(packet []byte) net.IP { | ||||||
|  | 	return net.IPv4(packet[16], packet[17], packet[18], packet[19]) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func IPv4Payload(packet []byte) []byte { | ||||||
|  | 	ihl := packet[0] & 0x0F | ||||||
|  | 	return packet[ihl*4:] | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Song Gao
						Song Gao