socket_linux.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  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.
  160. func SocketDiagTCPInfo(family uint8) ([]*InetDiagTCPInfoResp, error) {
  161. s, err := nl.Subscribe(unix.NETLINK_INET_DIAG)
  162. if err != nil {
  163. return nil, err
  164. }
  165. defer s.Close()
  166. req := nl.NewNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, unix.NLM_F_DUMP)
  167. req.AddData(&socketRequest{
  168. Family: family,
  169. Protocol: unix.IPPROTO_TCP,
  170. Ext: (1 << (INET_DIAG_VEGASINFO - 1)) | (1 << (INET_DIAG_INFO - 1)),
  171. States: uint32(0xfff), // All TCP states
  172. })
  173. s.Send(req)
  174. var result []*InetDiagTCPInfoResp
  175. loop:
  176. for {
  177. msgs, from, err := s.Receive()
  178. if err != nil {
  179. return nil, err
  180. }
  181. if from.Pid != nl.PidKernel {
  182. return nil, fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel)
  183. }
  184. if len(msgs) == 0 {
  185. return nil, errors.New("no message nor error from netlink")
  186. }
  187. for _, m := range msgs {
  188. switch m.Header.Type {
  189. case unix.NLMSG_DONE:
  190. break loop
  191. case unix.NLMSG_ERROR:
  192. native := nl.NativeEndian()
  193. error := int32(native.Uint32(m.Data[0:4]))
  194. return nil, syscall.Errno(-error)
  195. }
  196. sockInfo := &Socket{}
  197. if err := sockInfo.deserialize(m.Data); err != nil {
  198. return nil, err
  199. }
  200. attrs, err := nl.ParseRouteAttr(m.Data[sizeofSocket:])
  201. if err != nil {
  202. return nil, err
  203. }
  204. res, err := attrsToInetDiagTCPInfoResp(attrs, sockInfo)
  205. if err != nil {
  206. return nil, err
  207. }
  208. result = append(result, res)
  209. }
  210. }
  211. return result, nil
  212. }
  213. func attrsToInetDiagTCPInfoResp(attrs []syscall.NetlinkRouteAttr, sockInfo *Socket) (*InetDiagTCPInfoResp, error) {
  214. var tcpInfo *TCPInfo
  215. var tcpBBRInfo *TCPBBRInfo
  216. for _, a := range attrs {
  217. if a.Attr.Type == INET_DIAG_INFO {
  218. tcpInfo = &TCPInfo{}
  219. if err := tcpInfo.deserialize(a.Value); err != nil {
  220. return nil, err
  221. }
  222. continue
  223. }
  224. if a.Attr.Type == INET_DIAG_BBRINFO {
  225. tcpBBRInfo = &TCPBBRInfo{}
  226. if err := tcpBBRInfo.deserialize(a.Value); err != nil {
  227. return nil, err
  228. }
  229. continue
  230. }
  231. }
  232. return &InetDiagTCPInfoResp{
  233. InetDiagMsg: sockInfo,
  234. TCPInfo: tcpInfo,
  235. TCPBBRInfo: tcpBBRInfo,
  236. }, nil
  237. }