github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/sentry/strace/socket.go (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package strace
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  
    21  	"github.com/SagerNet/gvisor/pkg/abi"
    22  	"github.com/SagerNet/gvisor/pkg/abi/linux"
    23  	"github.com/SagerNet/gvisor/pkg/bits"
    24  	"github.com/SagerNet/gvisor/pkg/hostarch"
    25  	"github.com/SagerNet/gvisor/pkg/marshal/primitive"
    26  	"github.com/SagerNet/gvisor/pkg/sentry/kernel"
    27  	"github.com/SagerNet/gvisor/pkg/sentry/socket"
    28  	"github.com/SagerNet/gvisor/pkg/sentry/socket/netlink"
    29  	slinux "github.com/SagerNet/gvisor/pkg/sentry/syscalls/linux"
    30  )
    31  
    32  // SocketFamily are the possible socket(2) families.
    33  var SocketFamily = abi.ValueSet{
    34  	linux.AF_UNSPEC:     "AF_UNSPEC",
    35  	linux.AF_UNIX:       "AF_UNIX",
    36  	linux.AF_INET:       "AF_INET",
    37  	linux.AF_AX25:       "AF_AX25",
    38  	linux.AF_IPX:        "AF_IPX",
    39  	linux.AF_APPLETALK:  "AF_APPLETALK",
    40  	linux.AF_NETROM:     "AF_NETROM",
    41  	linux.AF_BRIDGE:     "AF_BRIDGE",
    42  	linux.AF_ATMPVC:     "AF_ATMPVC",
    43  	linux.AF_X25:        "AF_X25",
    44  	linux.AF_INET6:      "AF_INET6",
    45  	linux.AF_ROSE:       "AF_ROSE",
    46  	linux.AF_DECnet:     "AF_DECnet",
    47  	linux.AF_NETBEUI:    "AF_NETBEUI",
    48  	linux.AF_SECURITY:   "AF_SECURITY",
    49  	linux.AF_KEY:        "AF_KEY",
    50  	linux.AF_NETLINK:    "AF_NETLINK",
    51  	linux.AF_PACKET:     "AF_PACKET",
    52  	linux.AF_ASH:        "AF_ASH",
    53  	linux.AF_ECONET:     "AF_ECONET",
    54  	linux.AF_ATMSVC:     "AF_ATMSVC",
    55  	linux.AF_RDS:        "AF_RDS",
    56  	linux.AF_SNA:        "AF_SNA",
    57  	linux.AF_IRDA:       "AF_IRDA",
    58  	linux.AF_PPPOX:      "AF_PPPOX",
    59  	linux.AF_WANPIPE:    "AF_WANPIPE",
    60  	linux.AF_LLC:        "AF_LLC",
    61  	linux.AF_IB:         "AF_IB",
    62  	linux.AF_MPLS:       "AF_MPLS",
    63  	linux.AF_CAN:        "AF_CAN",
    64  	linux.AF_TIPC:       "AF_TIPC",
    65  	linux.AF_BLUETOOTH:  "AF_BLUETOOTH",
    66  	linux.AF_IUCV:       "AF_IUCV",
    67  	linux.AF_RXRPC:      "AF_RXRPC",
    68  	linux.AF_ISDN:       "AF_ISDN",
    69  	linux.AF_PHONET:     "AF_PHONET",
    70  	linux.AF_IEEE802154: "AF_IEEE802154",
    71  	linux.AF_CAIF:       "AF_CAIF",
    72  	linux.AF_ALG:        "AF_ALG",
    73  	linux.AF_NFC:        "AF_NFC",
    74  	linux.AF_VSOCK:      "AF_VSOCK",
    75  }
    76  
    77  // SocketType are the possible socket(2) types.
    78  var SocketType = abi.ValueSet{
    79  	uint64(linux.SOCK_STREAM):    "SOCK_STREAM",
    80  	uint64(linux.SOCK_DGRAM):     "SOCK_DGRAM",
    81  	uint64(linux.SOCK_RAW):       "SOCK_RAW",
    82  	uint64(linux.SOCK_RDM):       "SOCK_RDM",
    83  	uint64(linux.SOCK_SEQPACKET): "SOCK_SEQPACKET",
    84  	uint64(linux.SOCK_DCCP):      "SOCK_DCCP",
    85  	uint64(linux.SOCK_PACKET):    "SOCK_PACKET",
    86  }
    87  
    88  // SocketFlagSet are the possible socket(2) flags.
    89  var SocketFlagSet = abi.FlagSet{
    90  	{
    91  		Flag: linux.SOCK_CLOEXEC,
    92  		Name: "SOCK_CLOEXEC",
    93  	},
    94  	{
    95  		Flag: linux.SOCK_NONBLOCK,
    96  		Name: "SOCK_NONBLOCK",
    97  	},
    98  }
    99  
   100  // ipProtocol are the possible socket(2) types for INET and INET6 sockets.
   101  var ipProtocol = abi.ValueSet{
   102  	linux.IPPROTO_IP:      "IPPROTO_IP",
   103  	linux.IPPROTO_ICMP:    "IPPROTO_ICMP",
   104  	linux.IPPROTO_IGMP:    "IPPROTO_IGMP",
   105  	linux.IPPROTO_IPIP:    "IPPROTO_IPIP",
   106  	linux.IPPROTO_TCP:     "IPPROTO_TCP",
   107  	linux.IPPROTO_EGP:     "IPPROTO_EGP",
   108  	linux.IPPROTO_PUP:     "IPPROTO_PUP",
   109  	linux.IPPROTO_UDP:     "IPPROTO_UDP",
   110  	linux.IPPROTO_IDP:     "IPPROTO_IDP",
   111  	linux.IPPROTO_TP:      "IPPROTO_TP",
   112  	linux.IPPROTO_DCCP:    "IPPROTO_DCCP",
   113  	linux.IPPROTO_IPV6:    "IPPROTO_IPV6",
   114  	linux.IPPROTO_RSVP:    "IPPROTO_RSVP",
   115  	linux.IPPROTO_GRE:     "IPPROTO_GRE",
   116  	linux.IPPROTO_ESP:     "IPPROTO_ESP",
   117  	linux.IPPROTO_AH:      "IPPROTO_AH",
   118  	linux.IPPROTO_MTP:     "IPPROTO_MTP",
   119  	linux.IPPROTO_BEETPH:  "IPPROTO_BEETPH",
   120  	linux.IPPROTO_ENCAP:   "IPPROTO_ENCAP",
   121  	linux.IPPROTO_PIM:     "IPPROTO_PIM",
   122  	linux.IPPROTO_COMP:    "IPPROTO_COMP",
   123  	linux.IPPROTO_SCTP:    "IPPROTO_SCTP",
   124  	linux.IPPROTO_UDPLITE: "IPPROTO_UDPLITE",
   125  	linux.IPPROTO_MPLS:    "IPPROTO_MPLS",
   126  	linux.IPPROTO_RAW:     "IPPROTO_RAW",
   127  }
   128  
   129  // SocketProtocol are the possible socket(2) protocols for each protocol family.
   130  var SocketProtocol = map[int32]abi.ValueSet{
   131  	linux.AF_INET:  ipProtocol,
   132  	linux.AF_INET6: ipProtocol,
   133  	linux.AF_NETLINK: {
   134  		linux.NETLINK_ROUTE:          "NETLINK_ROUTE",
   135  		linux.NETLINK_UNUSED:         "NETLINK_UNUSED",
   136  		linux.NETLINK_USERSOCK:       "NETLINK_USERSOCK",
   137  		linux.NETLINK_FIREWALL:       "NETLINK_FIREWALL",
   138  		linux.NETLINK_SOCK_DIAG:      "NETLINK_SOCK_DIAG",
   139  		linux.NETLINK_NFLOG:          "NETLINK_NFLOG",
   140  		linux.NETLINK_XFRM:           "NETLINK_XFRM",
   141  		linux.NETLINK_SELINUX:        "NETLINK_SELINUX",
   142  		linux.NETLINK_ISCSI:          "NETLINK_ISCSI",
   143  		linux.NETLINK_AUDIT:          "NETLINK_AUDIT",
   144  		linux.NETLINK_FIB_LOOKUP:     "NETLINK_FIB_LOOKUP",
   145  		linux.NETLINK_CONNECTOR:      "NETLINK_CONNECTOR",
   146  		linux.NETLINK_NETFILTER:      "NETLINK_NETFILTER",
   147  		linux.NETLINK_IP6_FW:         "NETLINK_IP6_FW",
   148  		linux.NETLINK_DNRTMSG:        "NETLINK_DNRTMSG",
   149  		linux.NETLINK_KOBJECT_UEVENT: "NETLINK_KOBJECT_UEVENT",
   150  		linux.NETLINK_GENERIC:        "NETLINK_GENERIC",
   151  		linux.NETLINK_SCSITRANSPORT:  "NETLINK_SCSITRANSPORT",
   152  		linux.NETLINK_ECRYPTFS:       "NETLINK_ECRYPTFS",
   153  		linux.NETLINK_RDMA:           "NETLINK_RDMA",
   154  		linux.NETLINK_CRYPTO:         "NETLINK_CRYPTO",
   155  	},
   156  }
   157  
   158  var controlMessageType = map[int32]string{
   159  	linux.SCM_RIGHTS:      "SCM_RIGHTS",
   160  	linux.SCM_CREDENTIALS: "SCM_CREDENTIALS",
   161  	linux.SO_TIMESTAMP:    "SO_TIMESTAMP",
   162  }
   163  
   164  func unmarshalControlMessageRights(src []byte) linux.ControlMessageRights {
   165  	count := len(src) / linux.SizeOfControlMessageRight
   166  	cmr := make(linux.ControlMessageRights, count)
   167  	for i, _ := range cmr {
   168  		cmr[i] = int32(hostarch.ByteOrder.Uint32(src[i*linux.SizeOfControlMessageRight:]))
   169  	}
   170  	return cmr
   171  }
   172  
   173  func cmsghdr(t *kernel.Task, addr hostarch.Addr, length uint64, maxBytes uint64) string {
   174  	if length > maxBytes {
   175  		return fmt.Sprintf("%#x (error decoding control: invalid length (%d))", addr, length)
   176  	}
   177  
   178  	buf := make([]byte, length)
   179  	if _, err := t.CopyInBytes(addr, buf); err != nil {
   180  		return fmt.Sprintf("%#x (error decoding control: %v)", addr, err)
   181  	}
   182  
   183  	var strs []string
   184  
   185  	for i := 0; i < len(buf); {
   186  		if i+linux.SizeOfControlMessageHeader > len(buf) {
   187  			strs = append(strs, "{invalid control message (too short)}")
   188  			break
   189  		}
   190  
   191  		var h linux.ControlMessageHeader
   192  		h.UnmarshalUnsafe(buf[i : i+linux.SizeOfControlMessageHeader])
   193  
   194  		var skipData bool
   195  		level := "SOL_SOCKET"
   196  		if h.Level != linux.SOL_SOCKET {
   197  			skipData = true
   198  			level = fmt.Sprint(h.Level)
   199  		}
   200  
   201  		typ, ok := controlMessageType[h.Type]
   202  		if !ok {
   203  			skipData = true
   204  			typ = fmt.Sprint(h.Type)
   205  		}
   206  
   207  		if h.Length > uint64(len(buf)-i) {
   208  			strs = append(strs, fmt.Sprintf(
   209  				"{level=%s, type=%s, length=%d, content extends beyond buffer}",
   210  				level,
   211  				typ,
   212  				h.Length,
   213  			))
   214  			break
   215  		}
   216  
   217  		i += linux.SizeOfControlMessageHeader
   218  		width := t.Arch().Width()
   219  		length := int(h.Length) - linux.SizeOfControlMessageHeader
   220  		if length < 0 {
   221  			strs = append(strs, fmt.Sprintf(
   222  				"{level=%s, type=%s, length=%d, content too short}",
   223  				level,
   224  				typ,
   225  				h.Length,
   226  			))
   227  			break
   228  		}
   229  
   230  		if skipData {
   231  			strs = append(strs, fmt.Sprintf("{level=%s, type=%s, length=%d}", level, typ, h.Length))
   232  			i += bits.AlignUp(length, width)
   233  			continue
   234  		}
   235  
   236  		switch h.Type {
   237  		case linux.SCM_RIGHTS:
   238  			rightsSize := bits.AlignDown(length, linux.SizeOfControlMessageRight)
   239  			fds := unmarshalControlMessageRights(buf[i : i+rightsSize])
   240  			rights := make([]string, 0, len(fds))
   241  			for _, fd := range fds {
   242  				rights = append(rights, fmt.Sprint(fd))
   243  			}
   244  
   245  			strs = append(strs, fmt.Sprintf(
   246  				"{level=%s, type=%s, length=%d, content: %s}",
   247  				level,
   248  				typ,
   249  				h.Length,
   250  				strings.Join(rights, ","),
   251  			))
   252  
   253  		case linux.SCM_CREDENTIALS:
   254  			if length < linux.SizeOfControlMessageCredentials {
   255  				strs = append(strs, fmt.Sprintf(
   256  					"{level=%s, type=%s, length=%d, content too short}",
   257  					level,
   258  					typ,
   259  					h.Length,
   260  				))
   261  				break
   262  			}
   263  
   264  			var creds linux.ControlMessageCredentials
   265  			creds.UnmarshalUnsafe(buf[i : i+linux.SizeOfControlMessageCredentials])
   266  
   267  			strs = append(strs, fmt.Sprintf(
   268  				"{level=%s, type=%s, length=%d, pid: %d, uid: %d, gid: %d}",
   269  				level,
   270  				typ,
   271  				h.Length,
   272  				creds.PID,
   273  				creds.UID,
   274  				creds.GID,
   275  			))
   276  
   277  		case linux.SO_TIMESTAMP:
   278  			if length < linux.SizeOfTimeval {
   279  				strs = append(strs, fmt.Sprintf(
   280  					"{level=%s, type=%s, length=%d, content too short}",
   281  					level,
   282  					typ,
   283  					h.Length,
   284  				))
   285  				break
   286  			}
   287  
   288  			var tv linux.Timeval
   289  			tv.UnmarshalUnsafe(buf[i : i+linux.SizeOfTimeval])
   290  
   291  			strs = append(strs, fmt.Sprintf(
   292  				"{level=%s, type=%s, length=%d, Sec: %d, Usec: %d}",
   293  				level,
   294  				typ,
   295  				h.Length,
   296  				tv.Sec,
   297  				tv.Usec,
   298  			))
   299  
   300  		default:
   301  			panic("unreachable")
   302  		}
   303  		i += bits.AlignUp(length, width)
   304  	}
   305  
   306  	return fmt.Sprintf("%#x %s", addr, strings.Join(strs, ", "))
   307  }
   308  
   309  func msghdr(t *kernel.Task, addr hostarch.Addr, printContent bool, maxBytes uint64) string {
   310  	var msg slinux.MessageHeader64
   311  	if _, err := msg.CopyIn(t, addr); err != nil {
   312  		return fmt.Sprintf("%#x (error decoding msghdr: %v)", addr, err)
   313  	}
   314  	s := fmt.Sprintf(
   315  		"%#x {name=%#x, namelen=%d, iovecs=%s",
   316  		addr,
   317  		msg.Name,
   318  		msg.NameLen,
   319  		iovecs(t, hostarch.Addr(msg.Iov), int(msg.IovLen), printContent, maxBytes),
   320  	)
   321  	if printContent {
   322  		s = fmt.Sprintf("%s, control={%s}", s, cmsghdr(t, hostarch.Addr(msg.Control), msg.ControlLen, maxBytes))
   323  	} else {
   324  		s = fmt.Sprintf("%s, control=%#x, control_len=%d", s, msg.Control, msg.ControlLen)
   325  	}
   326  	return fmt.Sprintf("%s, flags=%d}", s, msg.Flags)
   327  }
   328  
   329  func sockAddr(t *kernel.Task, addr hostarch.Addr, length uint32) string {
   330  	if addr == 0 {
   331  		return "null"
   332  	}
   333  
   334  	b, err := slinux.CaptureAddress(t, addr, length)
   335  	if err != nil {
   336  		return fmt.Sprintf("%#x {error reading address: %v}", addr, err)
   337  	}
   338  
   339  	// Extract address family.
   340  	if len(b) < 2 {
   341  		return fmt.Sprintf("%#x {address too short: %d bytes}", addr, len(b))
   342  	}
   343  	family := hostarch.ByteOrder.Uint16(b)
   344  
   345  	familyStr := SocketFamily.Parse(uint64(family))
   346  
   347  	switch family {
   348  	case linux.AF_INET, linux.AF_INET6, linux.AF_UNIX:
   349  		fa, _, err := socket.AddressAndFamily(b)
   350  		if err != nil {
   351  			return fmt.Sprintf("%#x {Family: %s, error extracting address: %v}", addr, familyStr, err)
   352  		}
   353  
   354  		if family == linux.AF_UNIX {
   355  			return fmt.Sprintf("%#x {Family: %s, Addr: %q}", addr, familyStr, string(fa.Addr))
   356  		}
   357  
   358  		return fmt.Sprintf("%#x {Family: %s, Addr: %v, Port: %d}", addr, familyStr, fa.Addr, fa.Port)
   359  	case linux.AF_NETLINK:
   360  		sa, err := netlink.ExtractSockAddr(b)
   361  		if err != nil {
   362  			return fmt.Sprintf("%#x {Family: %s, error extracting address: %v}", addr, familyStr, err)
   363  		}
   364  		return fmt.Sprintf("%#x {Family: %s, PortID: %d, Groups: %d}", addr, familyStr, sa.PortID, sa.Groups)
   365  	default:
   366  		return fmt.Sprintf("%#x {Family: %s, family addr format unknown}", addr, familyStr)
   367  	}
   368  }
   369  
   370  func postSockAddr(t *kernel.Task, addr hostarch.Addr, lengthPtr hostarch.Addr) string {
   371  	if addr == 0 {
   372  		return "null"
   373  	}
   374  
   375  	if lengthPtr == 0 {
   376  		return fmt.Sprintf("%#x {length null}", addr)
   377  	}
   378  
   379  	l, err := copySockLen(t, lengthPtr)
   380  	if err != nil {
   381  		return fmt.Sprintf("%#x {error reading length: %v}", addr, err)
   382  	}
   383  
   384  	return sockAddr(t, addr, l)
   385  }
   386  
   387  func copySockLen(t *kernel.Task, addr hostarch.Addr) (uint32, error) {
   388  	// socklen_t is 32-bits.
   389  	var l primitive.Uint32
   390  	_, err := l.CopyIn(t, addr)
   391  	return uint32(l), err
   392  }
   393  
   394  func sockLenPointer(t *kernel.Task, addr hostarch.Addr) string {
   395  	if addr == 0 {
   396  		return "null"
   397  	}
   398  	l, err := copySockLen(t, addr)
   399  	if err != nil {
   400  		return fmt.Sprintf("%#x {error reading length: %v}", addr, err)
   401  	}
   402  	return fmt.Sprintf("%#x {length=%v}", addr, l)
   403  }
   404  
   405  func sockType(stype int32) string {
   406  	s := SocketType.Parse(uint64(stype & linux.SOCK_TYPE_MASK))
   407  	if flags := SocketFlagSet.Parse(uint64(stype &^ linux.SOCK_TYPE_MASK)); flags != "" {
   408  		s += "|" + flags
   409  	}
   410  	return s
   411  }
   412  
   413  func sockProtocol(family, protocol int32) string {
   414  	protocols, ok := SocketProtocol[family]
   415  	if !ok {
   416  		return fmt.Sprintf("%#x", protocol)
   417  	}
   418  	return protocols.Parse(uint64(protocol))
   419  }
   420  
   421  func sockFlags(flags int32) string {
   422  	if flags == 0 {
   423  		return "0"
   424  	}
   425  	return SocketFlagSet.Parse(uint64(flags))
   426  }
   427  
   428  func getSockOptVal(t *kernel.Task, level, optname uint64, optVal hostarch.Addr, optLen hostarch.Addr, maximumBlobSize uint, rval uintptr) string {
   429  	if int(rval) < 0 {
   430  		return hexNum(uint64(optVal))
   431  	}
   432  	if optVal == 0 {
   433  		return "null"
   434  	}
   435  	l, err := copySockLen(t, optLen)
   436  	if err != nil {
   437  		return fmt.Sprintf("%#x {error reading length: %v}", optLen, err)
   438  	}
   439  	return sockOptVal(t, level, optname, optVal, uint64(l), maximumBlobSize)
   440  }
   441  
   442  func sockOptVal(t *kernel.Task, level, optname uint64, optVal hostarch.Addr, optLen uint64, maximumBlobSize uint) string {
   443  	switch optLen {
   444  	case 1:
   445  		var v primitive.Uint8
   446  		_, err := v.CopyIn(t, optVal)
   447  		if err != nil {
   448  			return fmt.Sprintf("%#x {error reading optval: %v}", optVal, err)
   449  		}
   450  		return fmt.Sprintf("%#x {value=%v}", optVal, v)
   451  	case 2:
   452  		var v primitive.Uint16
   453  		_, err := v.CopyIn(t, optVal)
   454  		if err != nil {
   455  			return fmt.Sprintf("%#x {error reading optval: %v}", optVal, err)
   456  		}
   457  		return fmt.Sprintf("%#x {value=%v}", optVal, v)
   458  	case 4:
   459  		var v primitive.Uint32
   460  		_, err := v.CopyIn(t, optVal)
   461  		if err != nil {
   462  			return fmt.Sprintf("%#x {error reading optval: %v}", optVal, err)
   463  		}
   464  		return fmt.Sprintf("%#x {value=%v}", optVal, v)
   465  	default:
   466  		return dump(t, optVal, uint(optLen), maximumBlobSize)
   467  	}
   468  }
   469  
   470  var sockOptLevels = abi.ValueSet{
   471  	linux.SOL_IP:      "SOL_IP",
   472  	linux.SOL_SOCKET:  "SOL_SOCKET",
   473  	linux.SOL_TCP:     "SOL_TCP",
   474  	linux.SOL_UDP:     "SOL_UDP",
   475  	linux.SOL_IPV6:    "SOL_IPV6",
   476  	linux.SOL_ICMPV6:  "SOL_ICMPV6",
   477  	linux.SOL_RAW:     "SOL_RAW",
   478  	linux.SOL_PACKET:  "SOL_PACKET",
   479  	linux.SOL_NETLINK: "SOL_NETLINK",
   480  }
   481  
   482  var sockOptNames = map[uint64]abi.ValueSet{
   483  	linux.SOL_IP: {
   484  		linux.IP_TTL:                    "IP_TTL",
   485  		linux.IP_MULTICAST_TTL:          "IP_MULTICAST_TTL",
   486  		linux.IP_MULTICAST_IF:           "IP_MULTICAST_IF",
   487  		linux.IP_MULTICAST_LOOP:         "IP_MULTICAST_LOOP",
   488  		linux.IP_TOS:                    "IP_TOS",
   489  		linux.IP_RECVTOS:                "IP_RECVTOS",
   490  		linux.IPT_SO_GET_INFO:           "IPT_SO_GET_INFO",
   491  		linux.IPT_SO_GET_ENTRIES:        "IPT_SO_GET_ENTRIES",
   492  		linux.IP_ADD_MEMBERSHIP:         "IP_ADD_MEMBERSHIP",
   493  		linux.IP_DROP_MEMBERSHIP:        "IP_DROP_MEMBERSHIP",
   494  		linux.MCAST_JOIN_GROUP:          "MCAST_JOIN_GROUP",
   495  		linux.IP_ADD_SOURCE_MEMBERSHIP:  "IP_ADD_SOURCE_MEMBERSHIP",
   496  		linux.IP_BIND_ADDRESS_NO_PORT:   "IP_BIND_ADDRESS_NO_PORT",
   497  		linux.IP_BLOCK_SOURCE:           "IP_BLOCK_SOURCE",
   498  		linux.IP_CHECKSUM:               "IP_CHECKSUM",
   499  		linux.IP_DROP_SOURCE_MEMBERSHIP: "IP_DROP_SOURCE_MEMBERSHIP",
   500  		linux.IP_FREEBIND:               "IP_FREEBIND",
   501  		linux.IP_HDRINCL:                "IP_HDRINCL",
   502  		linux.IP_IPSEC_POLICY:           "IP_IPSEC_POLICY",
   503  		linux.IP_MINTTL:                 "IP_MINTTL",
   504  		linux.IP_MSFILTER:               "IP_MSFILTER",
   505  		linux.IP_MTU_DISCOVER:           "IP_MTU_DISCOVER",
   506  		linux.IP_MULTICAST_ALL:          "IP_MULTICAST_ALL",
   507  		linux.IP_NODEFRAG:               "IP_NODEFRAG",
   508  		linux.IP_OPTIONS:                "IP_OPTIONS",
   509  		linux.IP_PASSSEC:                "IP_PASSSEC",
   510  		linux.IP_PKTINFO:                "IP_PKTINFO",
   511  		linux.IP_RECVERR:                "IP_RECVERR",
   512  		linux.IP_RECVFRAGSIZE:           "IP_RECVFRAGSIZE",
   513  		linux.IP_RECVOPTS:               "IP_RECVOPTS",
   514  		linux.IP_RECVORIGDSTADDR:        "IP_RECVORIGDSTADDR",
   515  		linux.IP_RECVTTL:                "IP_RECVTTL",
   516  		linux.IP_RETOPTS:                "IP_RETOPTS",
   517  		linux.IP_TRANSPARENT:            "IP_TRANSPARENT",
   518  		linux.IP_UNBLOCK_SOURCE:         "IP_UNBLOCK_SOURCE",
   519  		linux.IP_UNICAST_IF:             "IP_UNICAST_IF",
   520  		linux.IP_XFRM_POLICY:            "IP_XFRM_POLICY",
   521  		linux.MCAST_BLOCK_SOURCE:        "MCAST_BLOCK_SOURCE",
   522  		linux.MCAST_JOIN_SOURCE_GROUP:   "MCAST_JOIN_SOURCE_GROUP",
   523  		linux.MCAST_LEAVE_GROUP:         "MCAST_LEAVE_GROUP",
   524  		linux.MCAST_LEAVE_SOURCE_GROUP:  "MCAST_LEAVE_SOURCE_GROUP",
   525  		linux.MCAST_MSFILTER:            "MCAST_MSFILTER",
   526  		linux.MCAST_UNBLOCK_SOURCE:      "MCAST_UNBLOCK_SOURCE",
   527  		linux.IP_ROUTER_ALERT:           "IP_ROUTER_ALERT",
   528  		linux.IP_PKTOPTIONS:             "IP_PKTOPTIONS",
   529  		linux.IP_MTU:                    "IP_MTU",
   530  		linux.SO_ORIGINAL_DST:           "SO_ORIGINAL_DST",
   531  	},
   532  	linux.SOL_SOCKET: {
   533  		linux.SO_ERROR:        "SO_ERROR",
   534  		linux.SO_PEERCRED:     "SO_PEERCRED",
   535  		linux.SO_PASSCRED:     "SO_PASSCRED",
   536  		linux.SO_SNDBUF:       "SO_SNDBUF",
   537  		linux.SO_RCVBUF:       "SO_RCVBUF",
   538  		linux.SO_REUSEADDR:    "SO_REUSEADDR",
   539  		linux.SO_REUSEPORT:    "SO_REUSEPORT",
   540  		linux.SO_BINDTODEVICE: "SO_BINDTODEVICE",
   541  		linux.SO_BROADCAST:    "SO_BROADCAST",
   542  		linux.SO_KEEPALIVE:    "SO_KEEPALIVE",
   543  		linux.SO_LINGER:       "SO_LINGER",
   544  		linux.SO_SNDTIMEO:     "SO_SNDTIMEO",
   545  		linux.SO_RCVTIMEO:     "SO_RCVTIMEO",
   546  		linux.SO_OOBINLINE:    "SO_OOBINLINE",
   547  		linux.SO_TIMESTAMP:    "SO_TIMESTAMP",
   548  	},
   549  	linux.SOL_TCP: {
   550  		linux.TCP_NODELAY:              "TCP_NODELAY",
   551  		linux.TCP_CORK:                 "TCP_CORK",
   552  		linux.TCP_QUICKACK:             "TCP_QUICKACK",
   553  		linux.TCP_MAXSEG:               "TCP_MAXSEG",
   554  		linux.TCP_KEEPIDLE:             "TCP_KEEPIDLE",
   555  		linux.TCP_KEEPINTVL:            "TCP_KEEPINTVL",
   556  		linux.TCP_USER_TIMEOUT:         "TCP_USER_TIMEOUT",
   557  		linux.TCP_INFO:                 "TCP_INFO",
   558  		linux.TCP_CC_INFO:              "TCP_CC_INFO",
   559  		linux.TCP_NOTSENT_LOWAT:        "TCP_NOTSENT_LOWAT",
   560  		linux.TCP_ZEROCOPY_RECEIVE:     "TCP_ZEROCOPY_RECEIVE",
   561  		linux.TCP_CONGESTION:           "TCP_CONGESTION",
   562  		linux.TCP_LINGER2:              "TCP_LINGER2",
   563  		linux.TCP_DEFER_ACCEPT:         "TCP_DEFER_ACCEPT",
   564  		linux.TCP_REPAIR_OPTIONS:       "TCP_REPAIR_OPTIONS",
   565  		linux.TCP_INQ:                  "TCP_INQ",
   566  		linux.TCP_FASTOPEN:             "TCP_FASTOPEN",
   567  		linux.TCP_FASTOPEN_CONNECT:     "TCP_FASTOPEN_CONNECT",
   568  		linux.TCP_FASTOPEN_KEY:         "TCP_FASTOPEN_KEY",
   569  		linux.TCP_FASTOPEN_NO_COOKIE:   "TCP_FASTOPEN_NO_COOKIE",
   570  		linux.TCP_KEEPCNT:              "TCP_KEEPCNT",
   571  		linux.TCP_QUEUE_SEQ:            "TCP_QUEUE_SEQ",
   572  		linux.TCP_REPAIR:               "TCP_REPAIR",
   573  		linux.TCP_REPAIR_QUEUE:         "TCP_REPAIR_QUEUE",
   574  		linux.TCP_REPAIR_WINDOW:        "TCP_REPAIR_WINDOW",
   575  		linux.TCP_SAVED_SYN:            "TCP_SAVED_SYN",
   576  		linux.TCP_SAVE_SYN:             "TCP_SAVE_SYN",
   577  		linux.TCP_SYNCNT:               "TCP_SYNCNT",
   578  		linux.TCP_THIN_DUPACK:          "TCP_THIN_DUPACK",
   579  		linux.TCP_THIN_LINEAR_TIMEOUTS: "TCP_THIN_LINEAR_TIMEOUTS",
   580  		linux.TCP_TIMESTAMP:            "TCP_TIMESTAMP",
   581  		linux.TCP_ULP:                  "TCP_ULP",
   582  		linux.TCP_WINDOW_CLAMP:         "TCP_WINDOW_CLAMP",
   583  	},
   584  	linux.SOL_IPV6: {
   585  		linux.IPV6_V6ONLY:              "IPV6_V6ONLY",
   586  		linux.IPV6_PATHMTU:             "IPV6_PATHMTU",
   587  		linux.IPV6_TCLASS:              "IPV6_TCLASS",
   588  		linux.IPV6_ADD_MEMBERSHIP:      "IPV6_ADD_MEMBERSHIP",
   589  		linux.IPV6_DROP_MEMBERSHIP:     "IPV6_DROP_MEMBERSHIP",
   590  		linux.IPV6_IPSEC_POLICY:        "IPV6_IPSEC_POLICY",
   591  		linux.IPV6_JOIN_ANYCAST:        "IPV6_JOIN_ANYCAST",
   592  		linux.IPV6_LEAVE_ANYCAST:       "IPV6_LEAVE_ANYCAST",
   593  		linux.IPV6_PKTINFO:             "IPV6_PKTINFO",
   594  		linux.IPV6_ROUTER_ALERT:        "IPV6_ROUTER_ALERT",
   595  		linux.IPV6_XFRM_POLICY:         "IPV6_XFRM_POLICY",
   596  		linux.MCAST_BLOCK_SOURCE:       "MCAST_BLOCK_SOURCE",
   597  		linux.MCAST_JOIN_GROUP:         "MCAST_JOIN_GROUP",
   598  		linux.MCAST_JOIN_SOURCE_GROUP:  "MCAST_JOIN_SOURCE_GROUP",
   599  		linux.MCAST_LEAVE_GROUP:        "MCAST_LEAVE_GROUP",
   600  		linux.MCAST_LEAVE_SOURCE_GROUP: "MCAST_LEAVE_SOURCE_GROUP",
   601  		linux.MCAST_UNBLOCK_SOURCE:     "MCAST_UNBLOCK_SOURCE",
   602  		linux.IPV6_2292DSTOPTS:         "IPV6_2292DSTOPTS",
   603  		linux.IPV6_2292HOPLIMIT:        "IPV6_2292HOPLIMIT",
   604  		linux.IPV6_2292HOPOPTS:         "IPV6_2292HOPOPTS",
   605  		linux.IPV6_2292PKTINFO:         "IPV6_2292PKTINFO",
   606  		linux.IPV6_2292PKTOPTIONS:      "IPV6_2292PKTOPTIONS",
   607  		linux.IPV6_2292RTHDR:           "IPV6_2292RTHDR",
   608  		linux.IPV6_ADDR_PREFERENCES:    "IPV6_ADDR_PREFERENCES",
   609  		linux.IPV6_AUTOFLOWLABEL:       "IPV6_AUTOFLOWLABEL",
   610  		linux.IPV6_DONTFRAG:            "IPV6_DONTFRAG",
   611  		linux.IPV6_DSTOPTS:             "IPV6_DSTOPTS",
   612  		linux.IPV6_FLOWINFO:            "IPV6_FLOWINFO",
   613  		linux.IPV6_FLOWINFO_SEND:       "IPV6_FLOWINFO_SEND",
   614  		linux.IPV6_FLOWLABEL_MGR:       "IPV6_FLOWLABEL_MGR",
   615  		linux.IPV6_FREEBIND:            "IPV6_FREEBIND",
   616  		linux.IPV6_HOPOPTS:             "IPV6_HOPOPTS",
   617  		linux.IPV6_MINHOPCOUNT:         "IPV6_MINHOPCOUNT",
   618  		linux.IPV6_MTU:                 "IPV6_MTU",
   619  		linux.IPV6_MTU_DISCOVER:        "IPV6_MTU_DISCOVER",
   620  		linux.IPV6_MULTICAST_ALL:       "IPV6_MULTICAST_ALL",
   621  		linux.IPV6_MULTICAST_HOPS:      "IPV6_MULTICAST_HOPS",
   622  		linux.IPV6_MULTICAST_IF:        "IPV6_MULTICAST_IF",
   623  		linux.IPV6_MULTICAST_LOOP:      "IPV6_MULTICAST_LOOP",
   624  		linux.IPV6_RECVDSTOPTS:         "IPV6_RECVDSTOPTS",
   625  		linux.IPV6_RECVERR:             "IPV6_RECVERR",
   626  		linux.IPV6_RECVFRAGSIZE:        "IPV6_RECVFRAGSIZE",
   627  		linux.IPV6_RECVHOPLIMIT:        "IPV6_RECVHOPLIMIT",
   628  		linux.IPV6_RECVHOPOPTS:         "IPV6_RECVHOPOPTS",
   629  		linux.IPV6_RECVORIGDSTADDR:     "IPV6_RECVORIGDSTADDR",
   630  		linux.IPV6_RECVPATHMTU:         "IPV6_RECVPATHMTU",
   631  		linux.IPV6_RECVPKTINFO:         "IPV6_RECVPKTINFO",
   632  		linux.IPV6_RECVRTHDR:           "IPV6_RECVRTHDR",
   633  		linux.IPV6_RECVTCLASS:          "IPV6_RECVTCLASS",
   634  		linux.IPV6_RTHDR:               "IPV6_RTHDR",
   635  		linux.IPV6_RTHDRDSTOPTS:        "IPV6_RTHDRDSTOPTS",
   636  		linux.IPV6_TRANSPARENT:         "IPV6_TRANSPARENT",
   637  		linux.IPV6_UNICAST_HOPS:        "IPV6_UNICAST_HOPS",
   638  		linux.IPV6_UNICAST_IF:          "IPV6_UNICAST_IF",
   639  		linux.MCAST_MSFILTER:           "MCAST_MSFILTER",
   640  		linux.IPV6_ADDRFORM:            "IPV6_ADDRFORM",
   641  		linux.IP6T_SO_GET_INFO:         "IP6T_SO_GET_INFO",
   642  		linux.IP6T_SO_GET_ENTRIES:      "IP6T_SO_GET_ENTRIES",
   643  	},
   644  	linux.SOL_NETLINK: {
   645  		linux.NETLINK_BROADCAST_ERROR:  "NETLINK_BROADCAST_ERROR",
   646  		linux.NETLINK_CAP_ACK:          "NETLINK_CAP_ACK",
   647  		linux.NETLINK_DUMP_STRICT_CHK:  "NETLINK_DUMP_STRICT_CHK",
   648  		linux.NETLINK_EXT_ACK:          "NETLINK_EXT_ACK",
   649  		linux.NETLINK_LIST_MEMBERSHIPS: "NETLINK_LIST_MEMBERSHIPS",
   650  		linux.NETLINK_NO_ENOBUFS:       "NETLINK_NO_ENOBUFS",
   651  		linux.NETLINK_PKTINFO:          "NETLINK_PKTINFO",
   652  	},
   653  }