github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/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/nicocha30/gvisor-ligolo/pkg/abi"
    22  	"github.com/nicocha30/gvisor-ligolo/pkg/abi/linux"
    23  	"github.com/nicocha30/gvisor-ligolo/pkg/bits"
    24  	"github.com/nicocha30/gvisor-ligolo/pkg/hostarch"
    25  	"github.com/nicocha30/gvisor-ligolo/pkg/marshal/primitive"
    26  	"github.com/nicocha30/gvisor-ligolo/pkg/sentry/kernel"
    27  	"github.com/nicocha30/gvisor-ligolo/pkg/sentry/socket"
    28  	"github.com/nicocha30/gvisor-ligolo/pkg/sentry/socket/netlink"
    29  	slinux "github.com/nicocha30/gvisor-ligolo/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_ICMPV6:  "IPPROTO_ICMPV6",
   105  	linux.IPPROTO_IGMP:    "IPPROTO_IGMP",
   106  	linux.IPPROTO_IPIP:    "IPPROTO_IPIP",
   107  	linux.IPPROTO_TCP:     "IPPROTO_TCP",
   108  	linux.IPPROTO_EGP:     "IPPROTO_EGP",
   109  	linux.IPPROTO_PUP:     "IPPROTO_PUP",
   110  	linux.IPPROTO_UDP:     "IPPROTO_UDP",
   111  	linux.IPPROTO_IDP:     "IPPROTO_IDP",
   112  	linux.IPPROTO_TP:      "IPPROTO_TP",
   113  	linux.IPPROTO_DCCP:    "IPPROTO_DCCP",
   114  	linux.IPPROTO_IPV6:    "IPPROTO_IPV6",
   115  	linux.IPPROTO_RSVP:    "IPPROTO_RSVP",
   116  	linux.IPPROTO_GRE:     "IPPROTO_GRE",
   117  	linux.IPPROTO_ESP:     "IPPROTO_ESP",
   118  	linux.IPPROTO_AH:      "IPPROTO_AH",
   119  	linux.IPPROTO_MTP:     "IPPROTO_MTP",
   120  	linux.IPPROTO_BEETPH:  "IPPROTO_BEETPH",
   121  	linux.IPPROTO_ENCAP:   "IPPROTO_ENCAP",
   122  	linux.IPPROTO_PIM:     "IPPROTO_PIM",
   123  	linux.IPPROTO_COMP:    "IPPROTO_COMP",
   124  	linux.IPPROTO_SCTP:    "IPPROTO_SCTP",
   125  	linux.IPPROTO_UDPLITE: "IPPROTO_UDPLITE",
   126  	linux.IPPROTO_MPLS:    "IPPROTO_MPLS",
   127  	linux.IPPROTO_RAW:     "IPPROTO_RAW",
   128  }
   129  
   130  // SocketProtocol are the possible socket(2) protocols for each protocol family.
   131  var SocketProtocol = map[int32]abi.ValueSet{
   132  	linux.AF_INET:  ipProtocol,
   133  	linux.AF_INET6: ipProtocol,
   134  	linux.AF_NETLINK: {
   135  		linux.NETLINK_ROUTE:          "NETLINK_ROUTE",
   136  		linux.NETLINK_UNUSED:         "NETLINK_UNUSED",
   137  		linux.NETLINK_USERSOCK:       "NETLINK_USERSOCK",
   138  		linux.NETLINK_FIREWALL:       "NETLINK_FIREWALL",
   139  		linux.NETLINK_SOCK_DIAG:      "NETLINK_SOCK_DIAG",
   140  		linux.NETLINK_NFLOG:          "NETLINK_NFLOG",
   141  		linux.NETLINK_XFRM:           "NETLINK_XFRM",
   142  		linux.NETLINK_SELINUX:        "NETLINK_SELINUX",
   143  		linux.NETLINK_ISCSI:          "NETLINK_ISCSI",
   144  		linux.NETLINK_AUDIT:          "NETLINK_AUDIT",
   145  		linux.NETLINK_FIB_LOOKUP:     "NETLINK_FIB_LOOKUP",
   146  		linux.NETLINK_CONNECTOR:      "NETLINK_CONNECTOR",
   147  		linux.NETLINK_NETFILTER:      "NETLINK_NETFILTER",
   148  		linux.NETLINK_IP6_FW:         "NETLINK_IP6_FW",
   149  		linux.NETLINK_DNRTMSG:        "NETLINK_DNRTMSG",
   150  		linux.NETLINK_KOBJECT_UEVENT: "NETLINK_KOBJECT_UEVENT",
   151  		linux.NETLINK_GENERIC:        "NETLINK_GENERIC",
   152  		linux.NETLINK_SCSITRANSPORT:  "NETLINK_SCSITRANSPORT",
   153  		linux.NETLINK_ECRYPTFS:       "NETLINK_ECRYPTFS",
   154  		linux.NETLINK_RDMA:           "NETLINK_RDMA",
   155  		linux.NETLINK_CRYPTO:         "NETLINK_CRYPTO",
   156  	},
   157  }
   158  
   159  var controlMessageType = map[int32]string{
   160  	linux.SCM_RIGHTS:      "SCM_RIGHTS",
   161  	linux.SCM_CREDENTIALS: "SCM_CREDENTIALS",
   162  	linux.SO_TIMESTAMP:    "SO_TIMESTAMP",
   163  }
   164  
   165  func unmarshalControlMessageRights(src []byte) []primitive.Int32 {
   166  	count := len(src) / linux.SizeOfControlMessageRight
   167  	cmr := make([]primitive.Int32, count)
   168  	primitive.UnmarshalUnsafeInt32Slice(cmr, src)
   169  	return cmr
   170  }
   171  
   172  func cmsghdr(t *kernel.Task, addr hostarch.Addr, length uint64, maxBytes uint64) string {
   173  	if length > maxBytes {
   174  		return fmt.Sprintf("%#x (error decoding control: invalid length (%d))", addr, length)
   175  	}
   176  
   177  	buf := make([]byte, length)
   178  	if _, err := t.CopyInBytes(addr, buf); err != nil {
   179  		return fmt.Sprintf("%#x (error decoding control: %v)", addr, err)
   180  	}
   181  
   182  	var strs []string
   183  
   184  	for len(buf) > 0 {
   185  		if linux.SizeOfControlMessageHeader > len(buf) {
   186  			strs = append(strs, "{invalid control message (too short)}")
   187  			break
   188  		}
   189  
   190  		var h linux.ControlMessageHeader
   191  		buf = h.UnmarshalUnsafe(buf)
   192  
   193  		var skipData bool
   194  		level := "SOL_SOCKET"
   195  		if h.Level != linux.SOL_SOCKET {
   196  			skipData = true
   197  			level = fmt.Sprint(h.Level)
   198  		}
   199  
   200  		typ, ok := controlMessageType[h.Type]
   201  		if !ok {
   202  			skipData = true
   203  			typ = fmt.Sprint(h.Type)
   204  		}
   205  
   206  		width := t.Arch().Width()
   207  		length := int(h.Length) - linux.SizeOfControlMessageHeader
   208  		if length > len(buf) {
   209  			strs = append(strs, fmt.Sprintf(
   210  				"{level=%s, type=%s, length=%d, content extends beyond buffer}",
   211  				level,
   212  				typ,
   213  				h.Length,
   214  			))
   215  			break
   216  		}
   217  
   218  		if length < 0 {
   219  			strs = append(strs, fmt.Sprintf(
   220  				"{level=%s, type=%s, length=%d, content too short}",
   221  				level,
   222  				typ,
   223  				h.Length,
   224  			))
   225  			break
   226  		}
   227  
   228  		if skipData {
   229  			strs = append(strs, fmt.Sprintf("{level=%s, type=%s, length=%d}", level, typ, h.Length))
   230  		} else {
   231  			switch h.Type {
   232  			case linux.SCM_RIGHTS:
   233  				rightsSize := bits.AlignDown(length, linux.SizeOfControlMessageRight)
   234  				fds := unmarshalControlMessageRights(buf[:rightsSize])
   235  				rights := make([]string, 0, len(fds))
   236  				for _, fd := range fds {
   237  					rights = append(rights, fmt.Sprint(fd))
   238  				}
   239  
   240  				strs = append(strs, fmt.Sprintf(
   241  					"{level=%s, type=%s, length=%d, content: %s}",
   242  					level,
   243  					typ,
   244  					h.Length,
   245  					strings.Join(rights, ","),
   246  				))
   247  
   248  			case linux.SCM_CREDENTIALS:
   249  				if length < linux.SizeOfControlMessageCredentials {
   250  					strs = append(strs, fmt.Sprintf(
   251  						"{level=%s, type=%s, length=%d, content too short}",
   252  						level,
   253  						typ,
   254  						h.Length,
   255  					))
   256  					break
   257  				}
   258  
   259  				var creds linux.ControlMessageCredentials
   260  				creds.UnmarshalUnsafe(buf)
   261  
   262  				strs = append(strs, fmt.Sprintf(
   263  					"{level=%s, type=%s, length=%d, pid: %d, uid: %d, gid: %d}",
   264  					level,
   265  					typ,
   266  					h.Length,
   267  					creds.PID,
   268  					creds.UID,
   269  					creds.GID,
   270  				))
   271  
   272  			case linux.SO_TIMESTAMP:
   273  				if length < linux.SizeOfTimeval {
   274  					strs = append(strs, fmt.Sprintf(
   275  						"{level=%s, type=%s, length=%d, content too short}",
   276  						level,
   277  						typ,
   278  						h.Length,
   279  					))
   280  					break
   281  				}
   282  
   283  				var tv linux.Timeval
   284  				tv.UnmarshalUnsafe(buf)
   285  
   286  				strs = append(strs, fmt.Sprintf(
   287  					"{level=%s, type=%s, length=%d, Sec: %d, Usec: %d}",
   288  					level,
   289  					typ,
   290  					h.Length,
   291  					tv.Sec,
   292  					tv.Usec,
   293  				))
   294  
   295  			default:
   296  				panic("unreachable")
   297  			}
   298  		}
   299  		if shift := bits.AlignUp(length, width); shift > len(buf) {
   300  			buf = buf[:0]
   301  		} else {
   302  			buf = buf[shift:]
   303  		}
   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.AsSlice()))
   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, true /* content */)
   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  		linux.SO_ACCEPTCONN:   "SO_ACCEPTCONN",
   549  	},
   550  	linux.SOL_TCP: {
   551  		linux.TCP_NODELAY:              "TCP_NODELAY",
   552  		linux.TCP_CORK:                 "TCP_CORK",
   553  		linux.TCP_QUICKACK:             "TCP_QUICKACK",
   554  		linux.TCP_MAXSEG:               "TCP_MAXSEG",
   555  		linux.TCP_KEEPIDLE:             "TCP_KEEPIDLE",
   556  		linux.TCP_KEEPINTVL:            "TCP_KEEPINTVL",
   557  		linux.TCP_USER_TIMEOUT:         "TCP_USER_TIMEOUT",
   558  		linux.TCP_INFO:                 "TCP_INFO",
   559  		linux.TCP_CC_INFO:              "TCP_CC_INFO",
   560  		linux.TCP_NOTSENT_LOWAT:        "TCP_NOTSENT_LOWAT",
   561  		linux.TCP_ZEROCOPY_RECEIVE:     "TCP_ZEROCOPY_RECEIVE",
   562  		linux.TCP_CONGESTION:           "TCP_CONGESTION",
   563  		linux.TCP_LINGER2:              "TCP_LINGER2",
   564  		linux.TCP_DEFER_ACCEPT:         "TCP_DEFER_ACCEPT",
   565  		linux.TCP_REPAIR_OPTIONS:       "TCP_REPAIR_OPTIONS",
   566  		linux.TCP_INQ:                  "TCP_INQ",
   567  		linux.TCP_FASTOPEN:             "TCP_FASTOPEN",
   568  		linux.TCP_FASTOPEN_CONNECT:     "TCP_FASTOPEN_CONNECT",
   569  		linux.TCP_FASTOPEN_KEY:         "TCP_FASTOPEN_KEY",
   570  		linux.TCP_FASTOPEN_NO_COOKIE:   "TCP_FASTOPEN_NO_COOKIE",
   571  		linux.TCP_KEEPCNT:              "TCP_KEEPCNT",
   572  		linux.TCP_QUEUE_SEQ:            "TCP_QUEUE_SEQ",
   573  		linux.TCP_REPAIR:               "TCP_REPAIR",
   574  		linux.TCP_REPAIR_QUEUE:         "TCP_REPAIR_QUEUE",
   575  		linux.TCP_REPAIR_WINDOW:        "TCP_REPAIR_WINDOW",
   576  		linux.TCP_SAVED_SYN:            "TCP_SAVED_SYN",
   577  		linux.TCP_SAVE_SYN:             "TCP_SAVE_SYN",
   578  		linux.TCP_SYNCNT:               "TCP_SYNCNT",
   579  		linux.TCP_THIN_DUPACK:          "TCP_THIN_DUPACK",
   580  		linux.TCP_THIN_LINEAR_TIMEOUTS: "TCP_THIN_LINEAR_TIMEOUTS",
   581  		linux.TCP_TIMESTAMP:            "TCP_TIMESTAMP",
   582  		linux.TCP_ULP:                  "TCP_ULP",
   583  		linux.TCP_WINDOW_CLAMP:         "TCP_WINDOW_CLAMP",
   584  	},
   585  	linux.SOL_IPV6: {
   586  		linux.IPV6_V6ONLY:              "IPV6_V6ONLY",
   587  		linux.IPV6_PATHMTU:             "IPV6_PATHMTU",
   588  		linux.IPV6_TCLASS:              "IPV6_TCLASS",
   589  		linux.IPV6_ADD_MEMBERSHIP:      "IPV6_ADD_MEMBERSHIP",
   590  		linux.IPV6_DROP_MEMBERSHIP:     "IPV6_DROP_MEMBERSHIP",
   591  		linux.IPV6_IPSEC_POLICY:        "IPV6_IPSEC_POLICY",
   592  		linux.IPV6_JOIN_ANYCAST:        "IPV6_JOIN_ANYCAST",
   593  		linux.IPV6_LEAVE_ANYCAST:       "IPV6_LEAVE_ANYCAST",
   594  		linux.IPV6_PKTINFO:             "IPV6_PKTINFO",
   595  		linux.IPV6_ROUTER_ALERT:        "IPV6_ROUTER_ALERT",
   596  		linux.IPV6_XFRM_POLICY:         "IPV6_XFRM_POLICY",
   597  		linux.MCAST_BLOCK_SOURCE:       "MCAST_BLOCK_SOURCE",
   598  		linux.MCAST_JOIN_GROUP:         "MCAST_JOIN_GROUP",
   599  		linux.MCAST_JOIN_SOURCE_GROUP:  "MCAST_JOIN_SOURCE_GROUP",
   600  		linux.MCAST_LEAVE_GROUP:        "MCAST_LEAVE_GROUP",
   601  		linux.MCAST_LEAVE_SOURCE_GROUP: "MCAST_LEAVE_SOURCE_GROUP",
   602  		linux.MCAST_UNBLOCK_SOURCE:     "MCAST_UNBLOCK_SOURCE",
   603  		linux.IPV6_2292DSTOPTS:         "IPV6_2292DSTOPTS",
   604  		linux.IPV6_2292HOPLIMIT:        "IPV6_2292HOPLIMIT",
   605  		linux.IPV6_2292HOPOPTS:         "IPV6_2292HOPOPTS",
   606  		linux.IPV6_2292PKTINFO:         "IPV6_2292PKTINFO",
   607  		linux.IPV6_2292PKTOPTIONS:      "IPV6_2292PKTOPTIONS",
   608  		linux.IPV6_2292RTHDR:           "IPV6_2292RTHDR",
   609  		linux.IPV6_ADDR_PREFERENCES:    "IPV6_ADDR_PREFERENCES",
   610  		linux.IPV6_AUTOFLOWLABEL:       "IPV6_AUTOFLOWLABEL",
   611  		linux.IPV6_DONTFRAG:            "IPV6_DONTFRAG",
   612  		linux.IPV6_DSTOPTS:             "IPV6_DSTOPTS",
   613  		linux.IPV6_FLOWINFO:            "IPV6_FLOWINFO",
   614  		linux.IPV6_FLOWINFO_SEND:       "IPV6_FLOWINFO_SEND",
   615  		linux.IPV6_FLOWLABEL_MGR:       "IPV6_FLOWLABEL_MGR",
   616  		linux.IPV6_FREEBIND:            "IPV6_FREEBIND",
   617  		linux.IPV6_HOPOPTS:             "IPV6_HOPOPTS",
   618  		linux.IPV6_MINHOPCOUNT:         "IPV6_MINHOPCOUNT",
   619  		linux.IPV6_MTU:                 "IPV6_MTU",
   620  		linux.IPV6_MTU_DISCOVER:        "IPV6_MTU_DISCOVER",
   621  		linux.IPV6_MULTICAST_ALL:       "IPV6_MULTICAST_ALL",
   622  		linux.IPV6_MULTICAST_HOPS:      "IPV6_MULTICAST_HOPS",
   623  		linux.IPV6_MULTICAST_IF:        "IPV6_MULTICAST_IF",
   624  		linux.IPV6_MULTICAST_LOOP:      "IPV6_MULTICAST_LOOP",
   625  		linux.IPV6_RECVDSTOPTS:         "IPV6_RECVDSTOPTS",
   626  		linux.IPV6_RECVERR:             "IPV6_RECVERR",
   627  		linux.IPV6_RECVFRAGSIZE:        "IPV6_RECVFRAGSIZE",
   628  		linux.IPV6_RECVHOPLIMIT:        "IPV6_RECVHOPLIMIT",
   629  		linux.IPV6_RECVHOPOPTS:         "IPV6_RECVHOPOPTS",
   630  		linux.IPV6_RECVORIGDSTADDR:     "IPV6_RECVORIGDSTADDR",
   631  		linux.IPV6_RECVPATHMTU:         "IPV6_RECVPATHMTU",
   632  		linux.IPV6_RECVPKTINFO:         "IPV6_RECVPKTINFO",
   633  		linux.IPV6_RECVRTHDR:           "IPV6_RECVRTHDR",
   634  		linux.IPV6_RECVTCLASS:          "IPV6_RECVTCLASS",
   635  		linux.IPV6_RTHDR:               "IPV6_RTHDR",
   636  		linux.IPV6_RTHDRDSTOPTS:        "IPV6_RTHDRDSTOPTS",
   637  		linux.IPV6_TRANSPARENT:         "IPV6_TRANSPARENT",
   638  		linux.IPV6_UNICAST_HOPS:        "IPV6_UNICAST_HOPS",
   639  		linux.IPV6_UNICAST_IF:          "IPV6_UNICAST_IF",
   640  		linux.MCAST_MSFILTER:           "MCAST_MSFILTER",
   641  		linux.IPV6_ADDRFORM:            "IPV6_ADDRFORM",
   642  		linux.IP6T_SO_GET_INFO:         "IP6T_SO_GET_INFO",
   643  		linux.IP6T_SO_GET_ENTRIES:      "IP6T_SO_GET_ENTRIES",
   644  	},
   645  	linux.SOL_NETLINK: {
   646  		linux.NETLINK_BROADCAST_ERROR:  "NETLINK_BROADCAST_ERROR",
   647  		linux.NETLINK_CAP_ACK:          "NETLINK_CAP_ACK",
   648  		linux.NETLINK_DUMP_STRICT_CHK:  "NETLINK_DUMP_STRICT_CHK",
   649  		linux.NETLINK_EXT_ACK:          "NETLINK_EXT_ACK",
   650  		linux.NETLINK_LIST_MEMBERSHIPS: "NETLINK_LIST_MEMBERSHIPS",
   651  		linux.NETLINK_NO_ENOBUFS:       "NETLINK_NO_ENOBUFS",
   652  		linux.NETLINK_PKTINFO:          "NETLINK_PKTINFO",
   653  	},
   654  }