socket_linux.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. package netlink
  2. import (
  3. "errors"
  4. "fmt"
  5. "net"
  6. "syscall"
  7. "github.com/vishvananda/netlink/nl"
  8. "golang.org/x/sys/unix"
  9. )
  10. const (
  11. sizeofSocketID = 0x30
  12. sizeofSocketRequest = sizeofSocketID + 0x8
  13. sizeofSocket = sizeofSocketID + 0x18
  14. )
  15. type socketRequest struct {
  16. Family uint8
  17. Protocol uint8
  18. Ext uint8
  19. pad uint8
  20. States uint32
  21. ID SocketID
  22. }
  23. type writeBuffer struct {
  24. Bytes []byte
  25. pos int
  26. }
  27. func (b *writeBuffer) Write(c byte) {
  28. b.Bytes[b.pos] = c
  29. b.pos++
  30. }
  31. func (b *writeBuffer) Next(n int) []byte {
  32. s := b.Bytes[b.pos : b.pos+n]
  33. b.pos += n
  34. return s
  35. }
  36. func (r *socketRequest) Serialize() []byte {
  37. b := writeBuffer{Bytes: make([]byte, sizeofSocketRequest)}
  38. b.Write(r.Family)
  39. b.Write(r.Protocol)
  40. b.Write(r.Ext)
  41. b.Write(r.pad)
  42. native.PutUint32(b.Next(4), r.States)
  43. networkOrder.PutUint16(b.Next(2), r.ID.SourcePort)
  44. networkOrder.PutUint16(b.Next(2), r.ID.DestinationPort)
  45. if r.Family == unix.AF_INET6 {
  46. copy(b.Next(16), r.ID.Source)
  47. copy(b.Next(16), r.ID.Destination)
  48. } else {
  49. copy(b.Next(4), r.ID.Source.To4())
  50. b.Next(12)
  51. copy(b.Next(4), r.ID.Destination.To4())
  52. b.Next(12)
  53. }
  54. native.PutUint32(b.Next(4), r.ID.Interface)
  55. native.PutUint32(b.Next(4), r.ID.Cookie[0])
  56. native.PutUint32(b.Next(4), r.ID.Cookie[1])
  57. return b.Bytes
  58. }
  59. func (r *socketRequest) Len() int { return sizeofSocketRequest }
  60. type readBuffer struct {
  61. Bytes []byte
  62. pos int
  63. }
  64. func (b *readBuffer) Read() byte {
  65. c := b.Bytes[b.pos]
  66. b.pos++
  67. return c
  68. }
  69. func (b *readBuffer) Next(n int) []byte {
  70. s := b.Bytes[b.pos : b.pos+n]
  71. b.pos += n
  72. return s
  73. }
  74. func (s *Socket) deserialize(b []byte) error {
  75. if len(b) < sizeofSocket {
  76. return fmt.Errorf("socket data short read (%d); want %d", len(b), sizeofSocket)
  77. }
  78. rb := readBuffer{Bytes: b}
  79. s.Family = rb.Read()
  80. s.State = rb.Read()
  81. s.Timer = rb.Read()
  82. s.Retrans = rb.Read()
  83. s.ID.SourcePort = networkOrder.Uint16(rb.Next(2))
  84. s.ID.DestinationPort = networkOrder.Uint16(rb.Next(2))
  85. if s.Family == unix.AF_INET6 {
  86. s.ID.Source = net.IP(rb.Next(16))
  87. s.ID.Destination = net.IP(rb.Next(16))
  88. } else {
  89. s.ID.Source = net.IPv4(rb.Read(), rb.Read(), rb.Read(), rb.Read())
  90. rb.Next(12)
  91. s.ID.Destination = net.IPv4(rb.Read(), rb.Read(), rb.Read(), rb.Read())
  92. rb.Next(12)
  93. }
  94. s.ID.Interface = native.Uint32(rb.Next(4))
  95. s.ID.Cookie[0] = native.Uint32(rb.Next(4))
  96. s.ID.Cookie[1] = native.Uint32(rb.Next(4))
  97. s.Expires = native.Uint32(rb.Next(4))
  98. s.RQueue = native.Uint32(rb.Next(4))
  99. s.WQueue = native.Uint32(rb.Next(4))
  100. s.UID = native.Uint32(rb.Next(4))
  101. s.INode = native.Uint32(rb.Next(4))
  102. return nil
  103. }
  104. // SocketGet returns the Socket identified by its local and remote addresses.
  105. func SocketGet(local, remote net.Addr) (*Socket, error) {
  106. localTCP, ok := local.(*net.TCPAddr)
  107. if !ok {
  108. return nil, ErrNotImplemented
  109. }
  110. remoteTCP, ok := remote.(*net.TCPAddr)
  111. if !ok {
  112. return nil, ErrNotImplemented
  113. }
  114. localIP := localTCP.IP.To4()
  115. if localIP == nil {
  116. return nil, ErrNotImplemented
  117. }
  118. remoteIP := remoteTCP.IP.To4()
  119. if remoteIP == nil {
  120. return nil, ErrNotImplemented
  121. }
  122. s, err := nl.Subscribe(unix.NETLINK_INET_DIAG)
  123. if err != nil {
  124. return nil, err
  125. }
  126. defer s.Close()
  127. req := nl.NewNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, 0)
  128. req.AddData(&socketRequest{
  129. Family: unix.AF_INET,
  130. Protocol: unix.IPPROTO_TCP,
  131. ID: SocketID{
  132. SourcePort: uint16(localTCP.Port),
  133. DestinationPort: uint16(remoteTCP.Port),
  134. Source: localIP,
  135. Destination: remoteIP,
  136. Cookie: [2]uint32{nl.TCPDIAG_NOCOOKIE, nl.TCPDIAG_NOCOOKIE},
  137. },
  138. })
  139. s.Send(req)
  140. msgs, from, err := s.Receive()
  141. if err != nil {
  142. return nil, err
  143. }
  144. if from.Pid != nl.PidKernel {
  145. return nil, fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel)
  146. }
  147. if len(msgs) == 0 {
  148. return nil, errors.New("no message nor error from netlink")
  149. }
  150. if len(msgs) > 2 {
  151. return nil, fmt.Errorf("multiple (%d) matching sockets", len(msgs))
  152. }
  153. sock := &Socket{}
  154. if err := sock.deserialize(msgs[0].Data); err != nil {
  155. return nil, err
  156. }
  157. return sock, nil
  158. }
  159. // SocketDiagTCPInfo requests INET_DIAG_INFO for TCP protocol for specified family type and return with extension TCP info.
  160. func SocketDiagTCPInfo(family uint8) ([]*InetDiagTCPInfoResp, error) {
  161. var result []*InetDiagTCPInfoResp
  162. err := socketDiagTCPExecutor(family, func(m syscall.NetlinkMessage) error {
  163. sockInfo := &Socket{}
  164. if err := sockInfo.deserialize(m.Data); err != nil {
  165. return err
  166. }
  167. attrs, err := nl.ParseRouteAttr(m.Data[sizeofSocket:])
  168. if err != nil {
  169. return err
  170. }
  171. res, err := attrsToInetDiagTCPInfoResp(attrs, sockInfo)
  172. if err != nil {
  173. return err
  174. }
  175. result = append(result, res)
  176. return nil
  177. })
  178. if err != nil {
  179. return nil, err
  180. }
  181. return result, nil
  182. }
  183. // SocketDiagTCP requests INET_DIAG_INFO for TCP protocol for specified family type and return related socket.
  184. func SocketDiagTCP(family uint8) ([]*Socket, error) {
  185. var result []*Socket
  186. err := socketDiagTCPExecutor(family, func(m syscall.NetlinkMessage) error {
  187. sockInfo := &Socket{}
  188. if err := sockInfo.deserialize(m.Data); err != nil {
  189. return err
  190. }
  191. result = append(result, sockInfo)
  192. return nil
  193. })
  194. if err != nil {
  195. return nil, err
  196. }
  197. return result, nil
  198. }
  199. // socketDiagTCPExecutor requests INET_DIAG_INFO for TCP protocol for specified family type.
  200. func socketDiagTCPExecutor(family uint8, receiver func(syscall.NetlinkMessage) error) error {
  201. s, err := nl.Subscribe(unix.NETLINK_INET_DIAG)
  202. if err != nil {
  203. return err
  204. }
  205. defer s.Close()
  206. req := nl.NewNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, unix.NLM_F_DUMP)
  207. req.AddData(&socketRequest{
  208. Family: family,
  209. Protocol: unix.IPPROTO_TCP,
  210. Ext: (1 << (INET_DIAG_VEGASINFO - 1)) | (1 << (INET_DIAG_INFO - 1)),
  211. States: uint32(0xfff), // All TCP states
  212. })
  213. s.Send(req)
  214. loop:
  215. for {
  216. msgs, from, err := s.Receive()
  217. if err != nil {
  218. return err
  219. }
  220. if from.Pid != nl.PidKernel {
  221. return fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel)
  222. }
  223. if len(msgs) == 0 {
  224. return errors.New("no message nor error from netlink")
  225. }
  226. for _, m := range msgs {
  227. switch m.Header.Type {
  228. case unix.NLMSG_DONE:
  229. break loop
  230. case unix.NLMSG_ERROR:
  231. error := int32(native.Uint32(m.Data[0:4]))
  232. return syscall.Errno(-error)
  233. }
  234. if err := receiver(m); err != nil {
  235. return err
  236. }
  237. }
  238. }
  239. return nil
  240. }
  241. func attrsToInetDiagTCPInfoResp(attrs []syscall.NetlinkRouteAttr, sockInfo *Socket) (*InetDiagTCPInfoResp, error) {
  242. var tcpInfo *TCPInfo
  243. var tcpBBRInfo *TCPBBRInfo
  244. for _, a := range attrs {
  245. if a.Attr.Type == INET_DIAG_INFO {
  246. tcpInfo = &TCPInfo{}
  247. if err := tcpInfo.deserialize(a.Value); err != nil {
  248. return nil, err
  249. }
  250. continue
  251. }
  252. if a.Attr.Type == INET_DIAG_BBRINFO {
  253. tcpBBRInfo = &TCPBBRInfo{}
  254. if err := tcpBBRInfo.deserialize(a.Value); err != nil {
  255. return nil, err
  256. }
  257. continue
  258. }
  259. }
  260. return &InetDiagTCPInfoResp{
  261. InetDiagMsg: sockInfo,
  262. TCPInfo: tcpInfo,
  263. TCPBBRInfo: tcpBBRInfo,
  264. }, nil
  265. }