link_tap.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. package handler
  2. import (
  3. "fmt"
  4. "io"
  5. "net"
  6. "github.com/bjdgyc/anylink/base"
  7. "github.com/bjdgyc/anylink/pkg/arpdis"
  8. "github.com/bjdgyc/anylink/sessdata"
  9. "github.com/google/gopacket"
  10. "github.com/google/gopacket/layers"
  11. "github.com/songgao/packets/ethernet"
  12. "github.com/songgao/water"
  13. "github.com/songgao/water/waterutil"
  14. )
  15. const bridgeName = "anylink0"
  16. var (
  17. // 网关mac地址
  18. gatewayHw net.HardwareAddr
  19. )
  20. type LinkDriver interface {
  21. io.ReadWriteCloser
  22. Name() string
  23. }
  24. func _setGateway() {
  25. dstAddr := arpdis.Lookup(sessdata.IpPool.Ipv4Gateway, false)
  26. gatewayHw = dstAddr.HardwareAddr
  27. // 设置为静态地址映射
  28. dstAddr.Type = arpdis.TypeStatic
  29. arpdis.Add(dstAddr)
  30. }
  31. func _checkTapIp(ifName string) {
  32. iFace, err := net.InterfaceByName(ifName)
  33. if err != nil {
  34. base.Fatal("testTap err: ", err)
  35. }
  36. var ifIp net.IP
  37. addrs, err := iFace.Addrs()
  38. if err != nil {
  39. base.Fatal("testTap err: ", err)
  40. }
  41. for _, addr := range addrs {
  42. ip, _, err := net.ParseCIDR(addr.String())
  43. if err != nil || ip.To4() == nil {
  44. continue
  45. }
  46. ifIp = ip
  47. }
  48. if !sessdata.IpPool.Ipv4IPNet.Contains(ifIp) {
  49. base.Fatal("tapIp or Ip network err")
  50. }
  51. }
  52. func checkTap() {
  53. _setGateway()
  54. _checkTapIp(bridgeName)
  55. }
  56. // 创建tap网卡
  57. func LinkTap(cSess *sessdata.ConnSession) error {
  58. cfg := water.Config{
  59. DeviceType: water.TAP,
  60. }
  61. ifce, err := water.New(cfg)
  62. if err != nil {
  63. base.Error(err)
  64. return err
  65. }
  66. cSess.SetIfName(ifce.Name())
  67. cmdstr1 := fmt.Sprintf("ip link set dev %s up mtu %d multicast on", ifce.Name(), cSess.Mtu)
  68. cmdstr2 := fmt.Sprintf("ip link set dev %s master %s", ifce.Name(), bridgeName)
  69. err = execCmd([]string{cmdstr1, cmdstr2})
  70. if err != nil {
  71. base.Error(err)
  72. _ = ifce.Close()
  73. return err
  74. }
  75. cmdstr3 := fmt.Sprintf("sysctl -w net.ipv6.conf.%s.disable_ipv6=1", ifce.Name())
  76. execCmd([]string{cmdstr3})
  77. go allTapRead(ifce, cSess)
  78. go allTapWrite(ifce, cSess)
  79. return nil
  80. }
  81. // ========================通用代码===========================
  82. func allTapWrite(ifce LinkDriver, cSess *sessdata.ConnSession) {
  83. defer func() {
  84. base.Debug("LinkTap return", cSess.IpAddr)
  85. cSess.Close()
  86. ifce.Close()
  87. }()
  88. var (
  89. err error
  90. dstHw net.HardwareAddr
  91. pl *sessdata.Payload
  92. frame = make(ethernet.Frame, BufferSize)
  93. ipDst = net.IPv4(1, 2, 3, 4)
  94. )
  95. for {
  96. frame.Resize(BufferSize)
  97. select {
  98. case pl = <-cSess.PayloadIn:
  99. case <-cSess.CloseChan:
  100. return
  101. }
  102. // var frame ethernet.Frame
  103. switch pl.LType {
  104. default:
  105. // log.Println(payload)
  106. case sessdata.LTypeEthernet:
  107. copy(frame, pl.Data)
  108. frame = frame[:len(pl.Data)]
  109. // packet := gopacket.NewPacket(frame, layers.LayerTypeEthernet, gopacket.Default)
  110. // fmt.Println("wirteArp:", packet)
  111. case sessdata.LTypeIPData: // 需要转换成 Ethernet 数据
  112. ipSrc := waterutil.IPv4Source(pl.Data)
  113. if !ipSrc.Equal(cSess.IpAddr) {
  114. // 非分配给客户端ip,直接丢弃
  115. continue
  116. }
  117. if waterutil.IsIPv6(pl.Data) {
  118. // 过滤掉IPv6的数据
  119. continue
  120. }
  121. // packet := gopacket.NewPacket(pl.Data, layers.LayerTypeIPv4, gopacket.Default)
  122. // fmt.Println("get:", packet)
  123. // 手动设置ipv4地址
  124. ipDst[12] = pl.Data[16]
  125. ipDst[13] = pl.Data[17]
  126. ipDst[14] = pl.Data[18]
  127. ipDst[15] = pl.Data[19]
  128. dstHw = gatewayHw
  129. if sessdata.IpPool.Ipv4IPNet.Contains(ipDst) {
  130. dstAddr := arpdis.Lookup(ipDst, true)
  131. // fmt.Println("dstAddr", dstAddr)
  132. if dstAddr != nil {
  133. dstHw = dstAddr.HardwareAddr
  134. }
  135. }
  136. // fmt.Println("Gateway", ipSrc, ipDst, dstHw)
  137. frame.Prepare(dstHw, cSess.MacHw, ethernet.NotTagged, ethernet.IPv4, len(pl.Data))
  138. copy(frame[12+2:], pl.Data)
  139. }
  140. // packet := gopacket.NewPacket(frame, layers.LayerTypeEthernet, gopacket.Default)
  141. // fmt.Println("write:", packet)
  142. _, err = ifce.Write(frame)
  143. if err != nil {
  144. base.Error("tap Write err", err)
  145. return
  146. }
  147. putPayloadInBefore(cSess, pl)
  148. }
  149. }
  150. func allTapRead(ifce LinkDriver, cSess *sessdata.ConnSession) {
  151. defer func() {
  152. base.Debug("tapRead return", cSess.IpAddr)
  153. ifce.Close()
  154. }()
  155. var (
  156. err error
  157. n int
  158. data []byte
  159. frame = make(ethernet.Frame, BufferSize)
  160. )
  161. for {
  162. frame.Resize(BufferSize)
  163. n, err = ifce.Read(frame)
  164. if err != nil {
  165. base.Error("tap Read err", n, err)
  166. return
  167. }
  168. frame = frame[:n]
  169. switch frame.Ethertype() {
  170. default:
  171. continue
  172. case ethernet.IPv6:
  173. continue
  174. case ethernet.IPv4:
  175. // 发送IP数据
  176. data = frame.Payload()
  177. ip_dst := waterutil.IPv4Destination(data)
  178. if !ip_dst.Equal(cSess.IpAddr) {
  179. // 过滤非本机地址
  180. // log.Println(ip_dst, sess.Ip)
  181. continue
  182. }
  183. // packet := gopacket.NewPacket(data, layers.LayerTypeIPv4, gopacket.Default)
  184. // fmt.Println("put:", packet)
  185. pl := getPayload()
  186. // 拷贝数据到pl
  187. copy(pl.Data, data)
  188. // 更新切片长度
  189. pl.Data = pl.Data[:len(data)]
  190. if payloadOut(cSess, pl) {
  191. return
  192. }
  193. case ethernet.ARP:
  194. // 暂时仅实现了ARP协议
  195. packet := gopacket.NewPacket(frame, layers.LayerTypeEthernet, gopacket.NoCopy)
  196. layer := packet.Layer(layers.LayerTypeARP)
  197. arpReq := layer.(*layers.ARP)
  198. if !cSess.IpAddr.Equal(arpReq.DstProtAddress) {
  199. // 过滤非本机地址
  200. continue
  201. }
  202. // fmt.Println("arp", time.Now(), net.IP(arpReq.SourceProtAddress), cSess.IpAddr)
  203. // fmt.Println(packet)
  204. // 返回ARP数据
  205. src := &arpdis.Addr{IP: cSess.IpAddr, HardwareAddr: cSess.MacHw}
  206. dst := &arpdis.Addr{IP: arpReq.SourceProtAddress, HardwareAddr: arpReq.SourceHwAddress}
  207. data, err = arpdis.NewARPReply(src, dst)
  208. if err != nil {
  209. base.Error(err)
  210. return
  211. }
  212. // 从接受的arp信息添加arp地址
  213. addr := &arpdis.Addr{
  214. IP: append([]byte{}, dst.IP...),
  215. HardwareAddr: append([]byte{}, dst.HardwareAddr...),
  216. }
  217. arpdis.Add(addr)
  218. pl := getPayload()
  219. // 设置为二层数据类型
  220. pl.LType = sessdata.LTypeEthernet
  221. // 拷贝数据到pl
  222. copy(pl.Data, data)
  223. // 更新切片长度
  224. pl.Data = pl.Data[:len(data)]
  225. if payloadIn(cSess, pl) {
  226. return
  227. }
  228. }
  229. }
  230. }