637 lines
21 KiB
Go
637 lines
21 KiB
Go
// Copyright 2018 The gVisor Authors.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package strace
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"gvisor.dev/gvisor/pkg/abi"
|
|
"gvisor.dev/gvisor/pkg/abi/linux"
|
|
"gvisor.dev/gvisor/pkg/binary"
|
|
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
|
"gvisor.dev/gvisor/pkg/sentry/socket/control"
|
|
"gvisor.dev/gvisor/pkg/sentry/socket/netlink"
|
|
"gvisor.dev/gvisor/pkg/sentry/socket/netstack"
|
|
slinux "gvisor.dev/gvisor/pkg/sentry/syscalls/linux"
|
|
"gvisor.dev/gvisor/pkg/usermem"
|
|
)
|
|
|
|
// SocketFamily are the possible socket(2) families.
|
|
var SocketFamily = abi.ValueSet{
|
|
linux.AF_UNSPEC: "AF_UNSPEC",
|
|
linux.AF_UNIX: "AF_UNIX",
|
|
linux.AF_INET: "AF_INET",
|
|
linux.AF_AX25: "AF_AX25",
|
|
linux.AF_IPX: "AF_IPX",
|
|
linux.AF_APPLETALK: "AF_APPLETALK",
|
|
linux.AF_NETROM: "AF_NETROM",
|
|
linux.AF_BRIDGE: "AF_BRIDGE",
|
|
linux.AF_ATMPVC: "AF_ATMPVC",
|
|
linux.AF_X25: "AF_X25",
|
|
linux.AF_INET6: "AF_INET6",
|
|
linux.AF_ROSE: "AF_ROSE",
|
|
linux.AF_DECnet: "AF_DECnet",
|
|
linux.AF_NETBEUI: "AF_NETBEUI",
|
|
linux.AF_SECURITY: "AF_SECURITY",
|
|
linux.AF_KEY: "AF_KEY",
|
|
linux.AF_NETLINK: "AF_NETLINK",
|
|
linux.AF_PACKET: "AF_PACKET",
|
|
linux.AF_ASH: "AF_ASH",
|
|
linux.AF_ECONET: "AF_ECONET",
|
|
linux.AF_ATMSVC: "AF_ATMSVC",
|
|
linux.AF_RDS: "AF_RDS",
|
|
linux.AF_SNA: "AF_SNA",
|
|
linux.AF_IRDA: "AF_IRDA",
|
|
linux.AF_PPPOX: "AF_PPPOX",
|
|
linux.AF_WANPIPE: "AF_WANPIPE",
|
|
linux.AF_LLC: "AF_LLC",
|
|
linux.AF_IB: "AF_IB",
|
|
linux.AF_MPLS: "AF_MPLS",
|
|
linux.AF_CAN: "AF_CAN",
|
|
linux.AF_TIPC: "AF_TIPC",
|
|
linux.AF_BLUETOOTH: "AF_BLUETOOTH",
|
|
linux.AF_IUCV: "AF_IUCV",
|
|
linux.AF_RXRPC: "AF_RXRPC",
|
|
linux.AF_ISDN: "AF_ISDN",
|
|
linux.AF_PHONET: "AF_PHONET",
|
|
linux.AF_IEEE802154: "AF_IEEE802154",
|
|
linux.AF_CAIF: "AF_CAIF",
|
|
linux.AF_ALG: "AF_ALG",
|
|
linux.AF_NFC: "AF_NFC",
|
|
linux.AF_VSOCK: "AF_VSOCK",
|
|
}
|
|
|
|
// SocketType are the possible socket(2) types.
|
|
var SocketType = abi.ValueSet{
|
|
uint64(linux.SOCK_STREAM): "SOCK_STREAM",
|
|
uint64(linux.SOCK_DGRAM): "SOCK_DGRAM",
|
|
uint64(linux.SOCK_RAW): "SOCK_RAW",
|
|
uint64(linux.SOCK_RDM): "SOCK_RDM",
|
|
uint64(linux.SOCK_SEQPACKET): "SOCK_SEQPACKET",
|
|
uint64(linux.SOCK_DCCP): "SOCK_DCCP",
|
|
uint64(linux.SOCK_PACKET): "SOCK_PACKET",
|
|
}
|
|
|
|
// SocketFlagSet are the possible socket(2) flags.
|
|
var SocketFlagSet = abi.FlagSet{
|
|
{
|
|
Flag: linux.SOCK_CLOEXEC,
|
|
Name: "SOCK_CLOEXEC",
|
|
},
|
|
{
|
|
Flag: linux.SOCK_NONBLOCK,
|
|
Name: "SOCK_NONBLOCK",
|
|
},
|
|
}
|
|
|
|
// ipProtocol are the possible socket(2) types for INET and INET6 sockets.
|
|
var ipProtocol = abi.ValueSet{
|
|
linux.IPPROTO_IP: "IPPROTO_IP",
|
|
linux.IPPROTO_ICMP: "IPPROTO_ICMP",
|
|
linux.IPPROTO_IGMP: "IPPROTO_IGMP",
|
|
linux.IPPROTO_IPIP: "IPPROTO_IPIP",
|
|
linux.IPPROTO_TCP: "IPPROTO_TCP",
|
|
linux.IPPROTO_EGP: "IPPROTO_EGP",
|
|
linux.IPPROTO_PUP: "IPPROTO_PUP",
|
|
linux.IPPROTO_UDP: "IPPROTO_UDP",
|
|
linux.IPPROTO_IDP: "IPPROTO_IDP",
|
|
linux.IPPROTO_TP: "IPPROTO_TP",
|
|
linux.IPPROTO_DCCP: "IPPROTO_DCCP",
|
|
linux.IPPROTO_IPV6: "IPPROTO_IPV6",
|
|
linux.IPPROTO_RSVP: "IPPROTO_RSVP",
|
|
linux.IPPROTO_GRE: "IPPROTO_GRE",
|
|
linux.IPPROTO_ESP: "IPPROTO_ESP",
|
|
linux.IPPROTO_AH: "IPPROTO_AH",
|
|
linux.IPPROTO_MTP: "IPPROTO_MTP",
|
|
linux.IPPROTO_BEETPH: "IPPROTO_BEETPH",
|
|
linux.IPPROTO_ENCAP: "IPPROTO_ENCAP",
|
|
linux.IPPROTO_PIM: "IPPROTO_PIM",
|
|
linux.IPPROTO_COMP: "IPPROTO_COMP",
|
|
linux.IPPROTO_SCTP: "IPPROTO_SCTP",
|
|
linux.IPPROTO_UDPLITE: "IPPROTO_UDPLITE",
|
|
linux.IPPROTO_MPLS: "IPPROTO_MPLS",
|
|
linux.IPPROTO_RAW: "IPPROTO_RAW",
|
|
}
|
|
|
|
// SocketProtocol are the possible socket(2) protocols for each protocol family.
|
|
var SocketProtocol = map[int32]abi.ValueSet{
|
|
linux.AF_INET: ipProtocol,
|
|
linux.AF_INET6: ipProtocol,
|
|
linux.AF_NETLINK: {
|
|
linux.NETLINK_ROUTE: "NETLINK_ROUTE",
|
|
linux.NETLINK_UNUSED: "NETLINK_UNUSED",
|
|
linux.NETLINK_USERSOCK: "NETLINK_USERSOCK",
|
|
linux.NETLINK_FIREWALL: "NETLINK_FIREWALL",
|
|
linux.NETLINK_SOCK_DIAG: "NETLINK_SOCK_DIAG",
|
|
linux.NETLINK_NFLOG: "NETLINK_NFLOG",
|
|
linux.NETLINK_XFRM: "NETLINK_XFRM",
|
|
linux.NETLINK_SELINUX: "NETLINK_SELINUX",
|
|
linux.NETLINK_ISCSI: "NETLINK_ISCSI",
|
|
linux.NETLINK_AUDIT: "NETLINK_AUDIT",
|
|
linux.NETLINK_FIB_LOOKUP: "NETLINK_FIB_LOOKUP",
|
|
linux.NETLINK_CONNECTOR: "NETLINK_CONNECTOR",
|
|
linux.NETLINK_NETFILTER: "NETLINK_NETFILTER",
|
|
linux.NETLINK_IP6_FW: "NETLINK_IP6_FW",
|
|
linux.NETLINK_DNRTMSG: "NETLINK_DNRTMSG",
|
|
linux.NETLINK_KOBJECT_UEVENT: "NETLINK_KOBJECT_UEVENT",
|
|
linux.NETLINK_GENERIC: "NETLINK_GENERIC",
|
|
linux.NETLINK_SCSITRANSPORT: "NETLINK_SCSITRANSPORT",
|
|
linux.NETLINK_ECRYPTFS: "NETLINK_ECRYPTFS",
|
|
linux.NETLINK_RDMA: "NETLINK_RDMA",
|
|
linux.NETLINK_CRYPTO: "NETLINK_CRYPTO",
|
|
},
|
|
}
|
|
|
|
var controlMessageType = map[int32]string{
|
|
linux.SCM_RIGHTS: "SCM_RIGHTS",
|
|
linux.SCM_CREDENTIALS: "SCM_CREDENTIALS",
|
|
linux.SO_TIMESTAMP: "SO_TIMESTAMP",
|
|
}
|
|
|
|
func cmsghdr(t *kernel.Task, addr usermem.Addr, length uint64, maxBytes uint64) string {
|
|
if length > maxBytes {
|
|
return fmt.Sprintf("%#x (error decoding control: invalid length (%d))", addr, length)
|
|
}
|
|
|
|
buf := make([]byte, length)
|
|
if _, err := t.CopyIn(addr, &buf); err != nil {
|
|
return fmt.Sprintf("%#x (error decoding control: %v)", addr, err)
|
|
}
|
|
|
|
var strs []string
|
|
|
|
for i := 0; i < len(buf); {
|
|
if i+linux.SizeOfControlMessageHeader > len(buf) {
|
|
strs = append(strs, "{invalid control message (too short)}")
|
|
break
|
|
}
|
|
|
|
var h linux.ControlMessageHeader
|
|
binary.Unmarshal(buf[i:i+linux.SizeOfControlMessageHeader], usermem.ByteOrder, &h)
|
|
|
|
var skipData bool
|
|
level := "SOL_SOCKET"
|
|
if h.Level != linux.SOL_SOCKET {
|
|
skipData = true
|
|
level = fmt.Sprint(h.Level)
|
|
}
|
|
|
|
typ, ok := controlMessageType[h.Type]
|
|
if !ok {
|
|
skipData = true
|
|
typ = fmt.Sprint(h.Type)
|
|
}
|
|
|
|
if h.Length > uint64(len(buf)-i) {
|
|
strs = append(strs, fmt.Sprintf(
|
|
"{level=%s, type=%s, length=%d, content extends beyond buffer}",
|
|
level,
|
|
typ,
|
|
h.Length,
|
|
))
|
|
break
|
|
}
|
|
|
|
i += linux.SizeOfControlMessageHeader
|
|
width := t.Arch().Width()
|
|
length := int(h.Length) - linux.SizeOfControlMessageHeader
|
|
if length < 0 {
|
|
strs = append(strs, fmt.Sprintf(
|
|
"{level=%s, type=%s, length=%d, content too short}",
|
|
level,
|
|
typ,
|
|
h.Length,
|
|
))
|
|
break
|
|
}
|
|
|
|
if skipData {
|
|
strs = append(strs, fmt.Sprintf("{level=%s, type=%s, length=%d}", level, typ, h.Length))
|
|
i += control.AlignUp(length, width)
|
|
continue
|
|
}
|
|
|
|
switch h.Type {
|
|
case linux.SCM_RIGHTS:
|
|
rightsSize := control.AlignDown(length, linux.SizeOfControlMessageRight)
|
|
|
|
numRights := rightsSize / linux.SizeOfControlMessageRight
|
|
fds := make(linux.ControlMessageRights, numRights)
|
|
binary.Unmarshal(buf[i:i+rightsSize], usermem.ByteOrder, &fds)
|
|
|
|
rights := make([]string, 0, len(fds))
|
|
for _, fd := range fds {
|
|
rights = append(rights, fmt.Sprint(fd))
|
|
}
|
|
|
|
strs = append(strs, fmt.Sprintf(
|
|
"{level=%s, type=%s, length=%d, content: %s}",
|
|
level,
|
|
typ,
|
|
h.Length,
|
|
strings.Join(rights, ","),
|
|
))
|
|
|
|
case linux.SCM_CREDENTIALS:
|
|
if length < linux.SizeOfControlMessageCredentials {
|
|
strs = append(strs, fmt.Sprintf(
|
|
"{level=%s, type=%s, length=%d, content too short}",
|
|
level,
|
|
typ,
|
|
h.Length,
|
|
))
|
|
break
|
|
}
|
|
|
|
var creds linux.ControlMessageCredentials
|
|
binary.Unmarshal(buf[i:i+linux.SizeOfControlMessageCredentials], usermem.ByteOrder, &creds)
|
|
|
|
strs = append(strs, fmt.Sprintf(
|
|
"{level=%s, type=%s, length=%d, pid: %d, uid: %d, gid: %d}",
|
|
level,
|
|
typ,
|
|
h.Length,
|
|
creds.PID,
|
|
creds.UID,
|
|
creds.GID,
|
|
))
|
|
|
|
case linux.SO_TIMESTAMP:
|
|
if length < linux.SizeOfTimeval {
|
|
strs = append(strs, fmt.Sprintf(
|
|
"{level=%s, type=%s, length=%d, content too short}",
|
|
level,
|
|
typ,
|
|
h.Length,
|
|
))
|
|
break
|
|
}
|
|
|
|
var tv linux.Timeval
|
|
binary.Unmarshal(buf[i:i+linux.SizeOfTimeval], usermem.ByteOrder, &tv)
|
|
|
|
strs = append(strs, fmt.Sprintf(
|
|
"{level=%s, type=%s, length=%d, Sec: %d, Usec: %d}",
|
|
level,
|
|
typ,
|
|
h.Length,
|
|
tv.Sec,
|
|
tv.Usec,
|
|
))
|
|
|
|
default:
|
|
panic("unreachable")
|
|
}
|
|
i += control.AlignUp(length, width)
|
|
}
|
|
|
|
return fmt.Sprintf("%#x %s", addr, strings.Join(strs, ", "))
|
|
}
|
|
|
|
func msghdr(t *kernel.Task, addr usermem.Addr, printContent bool, maxBytes uint64) string {
|
|
var msg slinux.MessageHeader64
|
|
if err := slinux.CopyInMessageHeader64(t, addr, &msg); err != nil {
|
|
return fmt.Sprintf("%#x (error decoding msghdr: %v)", addr, err)
|
|
}
|
|
s := fmt.Sprintf(
|
|
"%#x {name=%#x, namelen=%d, iovecs=%s",
|
|
addr,
|
|
msg.Name,
|
|
msg.NameLen,
|
|
iovecs(t, usermem.Addr(msg.Iov), int(msg.IovLen), printContent, maxBytes),
|
|
)
|
|
if printContent {
|
|
s = fmt.Sprintf("%s, control={%s}", s, cmsghdr(t, usermem.Addr(msg.Control), msg.ControlLen, maxBytes))
|
|
} else {
|
|
s = fmt.Sprintf("%s, control=%#x, control_len=%d", s, msg.Control, msg.ControlLen)
|
|
}
|
|
return fmt.Sprintf("%s, flags=%d}", s, msg.Flags)
|
|
}
|
|
|
|
func sockAddr(t *kernel.Task, addr usermem.Addr, length uint32) string {
|
|
if addr == 0 {
|
|
return "null"
|
|
}
|
|
|
|
b, err := slinux.CaptureAddress(t, addr, length)
|
|
if err != nil {
|
|
return fmt.Sprintf("%#x {error reading address: %v}", addr, err)
|
|
}
|
|
|
|
// Extract address family.
|
|
if len(b) < 2 {
|
|
return fmt.Sprintf("%#x {address too short: %d bytes}", addr, len(b))
|
|
}
|
|
family := usermem.ByteOrder.Uint16(b)
|
|
|
|
familyStr := SocketFamily.Parse(uint64(family))
|
|
|
|
switch family {
|
|
case linux.AF_INET, linux.AF_INET6, linux.AF_UNIX:
|
|
fa, _, err := netstack.AddressAndFamily(b)
|
|
if err != nil {
|
|
return fmt.Sprintf("%#x {Family: %s, error extracting address: %v}", addr, familyStr, err)
|
|
}
|
|
|
|
if family == linux.AF_UNIX {
|
|
return fmt.Sprintf("%#x {Family: %s, Addr: %q}", addr, familyStr, string(fa.Addr))
|
|
}
|
|
|
|
return fmt.Sprintf("%#x {Family: %s, Addr: %v, Port: %d}", addr, familyStr, fa.Addr, fa.Port)
|
|
case linux.AF_NETLINK:
|
|
sa, err := netlink.ExtractSockAddr(b)
|
|
if err != nil {
|
|
return fmt.Sprintf("%#x {Family: %s, error extracting address: %v}", addr, familyStr, err)
|
|
}
|
|
return fmt.Sprintf("%#x {Family: %s, PortID: %d, Groups: %d}", addr, familyStr, sa.PortID, sa.Groups)
|
|
default:
|
|
return fmt.Sprintf("%#x {Family: %s, family addr format unknown}", addr, familyStr)
|
|
}
|
|
}
|
|
|
|
func postSockAddr(t *kernel.Task, addr usermem.Addr, lengthPtr usermem.Addr) string {
|
|
if addr == 0 {
|
|
return "null"
|
|
}
|
|
|
|
if lengthPtr == 0 {
|
|
return fmt.Sprintf("%#x {length null}", addr)
|
|
}
|
|
|
|
l, err := copySockLen(t, lengthPtr)
|
|
if err != nil {
|
|
return fmt.Sprintf("%#x {error reading length: %v}", addr, err)
|
|
}
|
|
|
|
return sockAddr(t, addr, l)
|
|
}
|
|
|
|
func copySockLen(t *kernel.Task, addr usermem.Addr) (uint32, error) {
|
|
// socklen_t is 32-bits.
|
|
var l uint32
|
|
_, err := t.CopyIn(addr, &l)
|
|
return l, err
|
|
}
|
|
|
|
func sockLenPointer(t *kernel.Task, addr usermem.Addr) string {
|
|
if addr == 0 {
|
|
return "null"
|
|
}
|
|
l, err := copySockLen(t, addr)
|
|
if err != nil {
|
|
return fmt.Sprintf("%#x {error reading length: %v}", addr, err)
|
|
}
|
|
return fmt.Sprintf("%#x {length=%v}", addr, l)
|
|
}
|
|
|
|
func sockType(stype int32) string {
|
|
s := SocketType.Parse(uint64(stype & linux.SOCK_TYPE_MASK))
|
|
if flags := SocketFlagSet.Parse(uint64(stype &^ linux.SOCK_TYPE_MASK)); flags != "" {
|
|
s += "|" + flags
|
|
}
|
|
return s
|
|
}
|
|
|
|
func sockProtocol(family, protocol int32) string {
|
|
protocols, ok := SocketProtocol[family]
|
|
if !ok {
|
|
return fmt.Sprintf("%#x", protocol)
|
|
}
|
|
return protocols.Parse(uint64(protocol))
|
|
}
|
|
|
|
func sockFlags(flags int32) string {
|
|
if flags == 0 {
|
|
return "0"
|
|
}
|
|
return SocketFlagSet.Parse(uint64(flags))
|
|
}
|
|
|
|
func getSockOptVal(t *kernel.Task, level, optname uint64, optVal usermem.Addr, optLen usermem.Addr, maximumBlobSize uint, rval uintptr) string {
|
|
if int(rval) < 0 {
|
|
return hexNum(uint64(optVal))
|
|
}
|
|
if optVal == 0 {
|
|
return "null"
|
|
}
|
|
l, err := copySockLen(t, optLen)
|
|
if err != nil {
|
|
return fmt.Sprintf("%#x {error reading length: %v}", optLen, err)
|
|
}
|
|
return sockOptVal(t, level, optname, optVal, uint64(l), maximumBlobSize)
|
|
}
|
|
|
|
func sockOptVal(t *kernel.Task, level, optname uint64, optVal usermem.Addr, optLen uint64, maximumBlobSize uint) string {
|
|
switch optLen {
|
|
case 1:
|
|
var v uint8
|
|
_, err := t.CopyIn(optVal, &v)
|
|
if err != nil {
|
|
return fmt.Sprintf("%#x {error reading optval: %v}", optVal, err)
|
|
}
|
|
return fmt.Sprintf("%#x {value=%v}", optVal, v)
|
|
case 2:
|
|
var v uint16
|
|
_, err := t.CopyIn(optVal, &v)
|
|
if err != nil {
|
|
return fmt.Sprintf("%#x {error reading optval: %v}", optVal, err)
|
|
}
|
|
return fmt.Sprintf("%#x {value=%v}", optVal, v)
|
|
case 4:
|
|
var v uint32
|
|
_, err := t.CopyIn(optVal, &v)
|
|
if err != nil {
|
|
return fmt.Sprintf("%#x {error reading optval: %v}", optVal, err)
|
|
}
|
|
return fmt.Sprintf("%#x {value=%v}", optVal, v)
|
|
default:
|
|
return dump(t, optVal, uint(optLen), maximumBlobSize)
|
|
}
|
|
}
|
|
|
|
var sockOptLevels = abi.ValueSet{
|
|
linux.SOL_IP: "SOL_IP",
|
|
linux.SOL_SOCKET: "SOL_SOCKET",
|
|
linux.SOL_TCP: "SOL_TCP",
|
|
linux.SOL_UDP: "SOL_UDP",
|
|
linux.SOL_IPV6: "SOL_IPV6",
|
|
linux.SOL_ICMPV6: "SOL_ICMPV6",
|
|
linux.SOL_RAW: "SOL_RAW",
|
|
linux.SOL_PACKET: "SOL_PACKET",
|
|
linux.SOL_NETLINK: "SOL_NETLINK",
|
|
}
|
|
|
|
var sockOptNames = map[uint64]abi.ValueSet{
|
|
linux.SOL_IP: {
|
|
linux.IP_TTL: "IP_TTL",
|
|
linux.IP_MULTICAST_TTL: "IP_MULTICAST_TTL",
|
|
linux.IP_MULTICAST_IF: "IP_MULTICAST_IF",
|
|
linux.IP_MULTICAST_LOOP: "IP_MULTICAST_LOOP",
|
|
linux.IP_TOS: "IP_TOS",
|
|
linux.IP_RECVTOS: "IP_RECVTOS",
|
|
linux.IPT_SO_GET_INFO: "IPT_SO_GET_INFO",
|
|
linux.IPT_SO_GET_ENTRIES: "IPT_SO_GET_ENTRIES",
|
|
linux.IP_ADD_MEMBERSHIP: "IP_ADD_MEMBERSHIP",
|
|
linux.IP_DROP_MEMBERSHIP: "IP_DROP_MEMBERSHIP",
|
|
linux.MCAST_JOIN_GROUP: "MCAST_JOIN_GROUP",
|
|
linux.IP_ADD_SOURCE_MEMBERSHIP: "IP_ADD_SOURCE_MEMBERSHIP",
|
|
linux.IP_BIND_ADDRESS_NO_PORT: "IP_BIND_ADDRESS_NO_PORT",
|
|
linux.IP_BLOCK_SOURCE: "IP_BLOCK_SOURCE",
|
|
linux.IP_CHECKSUM: "IP_CHECKSUM",
|
|
linux.IP_DROP_SOURCE_MEMBERSHIP: "IP_DROP_SOURCE_MEMBERSHIP",
|
|
linux.IP_FREEBIND: "IP_FREEBIND",
|
|
linux.IP_HDRINCL: "IP_HDRINCL",
|
|
linux.IP_IPSEC_POLICY: "IP_IPSEC_POLICY",
|
|
linux.IP_MINTTL: "IP_MINTTL",
|
|
linux.IP_MSFILTER: "IP_MSFILTER",
|
|
linux.IP_MTU_DISCOVER: "IP_MTU_DISCOVER",
|
|
linux.IP_MULTICAST_ALL: "IP_MULTICAST_ALL",
|
|
linux.IP_NODEFRAG: "IP_NODEFRAG",
|
|
linux.IP_OPTIONS: "IP_OPTIONS",
|
|
linux.IP_PASSSEC: "IP_PASSSEC",
|
|
linux.IP_PKTINFO: "IP_PKTINFO",
|
|
linux.IP_RECVERR: "IP_RECVERR",
|
|
linux.IP_RECVFRAGSIZE: "IP_RECVFRAGSIZE",
|
|
linux.IP_RECVOPTS: "IP_RECVOPTS",
|
|
linux.IP_RECVORIGDSTADDR: "IP_RECVORIGDSTADDR",
|
|
linux.IP_RECVTTL: "IP_RECVTTL",
|
|
linux.IP_RETOPTS: "IP_RETOPTS",
|
|
linux.IP_TRANSPARENT: "IP_TRANSPARENT",
|
|
linux.IP_UNBLOCK_SOURCE: "IP_UNBLOCK_SOURCE",
|
|
linux.IP_UNICAST_IF: "IP_UNICAST_IF",
|
|
linux.IP_XFRM_POLICY: "IP_XFRM_POLICY",
|
|
linux.MCAST_BLOCK_SOURCE: "MCAST_BLOCK_SOURCE",
|
|
linux.MCAST_JOIN_SOURCE_GROUP: "MCAST_JOIN_SOURCE_GROUP",
|
|
linux.MCAST_LEAVE_GROUP: "MCAST_LEAVE_GROUP",
|
|
linux.MCAST_LEAVE_SOURCE_GROUP: "MCAST_LEAVE_SOURCE_GROUP",
|
|
linux.MCAST_MSFILTER: "MCAST_MSFILTER",
|
|
linux.MCAST_UNBLOCK_SOURCE: "MCAST_UNBLOCK_SOURCE",
|
|
linux.IP_ROUTER_ALERT: "IP_ROUTER_ALERT",
|
|
linux.IP_PKTOPTIONS: "IP_PKTOPTIONS",
|
|
linux.IP_MTU: "IP_MTU",
|
|
},
|
|
linux.SOL_SOCKET: {
|
|
linux.SO_ERROR: "SO_ERROR",
|
|
linux.SO_PEERCRED: "SO_PEERCRED",
|
|
linux.SO_PASSCRED: "SO_PASSCRED",
|
|
linux.SO_SNDBUF: "SO_SNDBUF",
|
|
linux.SO_RCVBUF: "SO_RCVBUF",
|
|
linux.SO_REUSEADDR: "SO_REUSEADDR",
|
|
linux.SO_REUSEPORT: "SO_REUSEPORT",
|
|
linux.SO_BINDTODEVICE: "SO_BINDTODEVICE",
|
|
linux.SO_BROADCAST: "SO_BROADCAST",
|
|
linux.SO_KEEPALIVE: "SO_KEEPALIVE",
|
|
linux.SO_LINGER: "SO_LINGER",
|
|
linux.SO_SNDTIMEO: "SO_SNDTIMEO",
|
|
linux.SO_RCVTIMEO: "SO_RCVTIMEO",
|
|
linux.SO_OOBINLINE: "SO_OOBINLINE",
|
|
linux.SO_TIMESTAMP: "SO_TIMESTAMP",
|
|
},
|
|
linux.SOL_TCP: {
|
|
linux.TCP_NODELAY: "TCP_NODELAY",
|
|
linux.TCP_CORK: "TCP_CORK",
|
|
linux.TCP_QUICKACK: "TCP_QUICKACK",
|
|
linux.TCP_MAXSEG: "TCP_MAXSEG",
|
|
linux.TCP_KEEPIDLE: "TCP_KEEPIDLE",
|
|
linux.TCP_KEEPINTVL: "TCP_KEEPINTVL",
|
|
linux.TCP_USER_TIMEOUT: "TCP_USER_TIMEOUT",
|
|
linux.TCP_INFO: "TCP_INFO",
|
|
linux.TCP_CC_INFO: "TCP_CC_INFO",
|
|
linux.TCP_NOTSENT_LOWAT: "TCP_NOTSENT_LOWAT",
|
|
linux.TCP_ZEROCOPY_RECEIVE: "TCP_ZEROCOPY_RECEIVE",
|
|
linux.TCP_CONGESTION: "TCP_CONGESTION",
|
|
linux.TCP_LINGER2: "TCP_LINGER2",
|
|
linux.TCP_DEFER_ACCEPT: "TCP_DEFER_ACCEPT",
|
|
linux.TCP_REPAIR_OPTIONS: "TCP_REPAIR_OPTIONS",
|
|
linux.TCP_INQ: "TCP_INQ",
|
|
linux.TCP_FASTOPEN: "TCP_FASTOPEN",
|
|
linux.TCP_FASTOPEN_CONNECT: "TCP_FASTOPEN_CONNECT",
|
|
linux.TCP_FASTOPEN_KEY: "TCP_FASTOPEN_KEY",
|
|
linux.TCP_FASTOPEN_NO_COOKIE: "TCP_FASTOPEN_NO_COOKIE",
|
|
linux.TCP_KEEPCNT: "TCP_KEEPCNT",
|
|
linux.TCP_QUEUE_SEQ: "TCP_QUEUE_SEQ",
|
|
linux.TCP_REPAIR: "TCP_REPAIR",
|
|
linux.TCP_REPAIR_QUEUE: "TCP_REPAIR_QUEUE",
|
|
linux.TCP_REPAIR_WINDOW: "TCP_REPAIR_WINDOW",
|
|
linux.TCP_SAVED_SYN: "TCP_SAVED_SYN",
|
|
linux.TCP_SAVE_SYN: "TCP_SAVE_SYN",
|
|
linux.TCP_SYNCNT: "TCP_SYNCNT",
|
|
linux.TCP_THIN_DUPACK: "TCP_THIN_DUPACK",
|
|
linux.TCP_THIN_LINEAR_TIMEOUTS: "TCP_THIN_LINEAR_TIMEOUTS",
|
|
linux.TCP_TIMESTAMP: "TCP_TIMESTAMP",
|
|
linux.TCP_ULP: "TCP_ULP",
|
|
linux.TCP_WINDOW_CLAMP: "TCP_WINDOW_CLAMP",
|
|
},
|
|
linux.SOL_IPV6: {
|
|
linux.IPV6_V6ONLY: "IPV6_V6ONLY",
|
|
linux.IPV6_PATHMTU: "IPV6_PATHMTU",
|
|
linux.IPV6_TCLASS: "IPV6_TCLASS",
|
|
linux.IPV6_ADD_MEMBERSHIP: "IPV6_ADD_MEMBERSHIP",
|
|
linux.IPV6_DROP_MEMBERSHIP: "IPV6_DROP_MEMBERSHIP",
|
|
linux.IPV6_IPSEC_POLICY: "IPV6_IPSEC_POLICY",
|
|
linux.IPV6_JOIN_ANYCAST: "IPV6_JOIN_ANYCAST",
|
|
linux.IPV6_LEAVE_ANYCAST: "IPV6_LEAVE_ANYCAST",
|
|
linux.IPV6_PKTINFO: "IPV6_PKTINFO",
|
|
linux.IPV6_ROUTER_ALERT: "IPV6_ROUTER_ALERT",
|
|
linux.IPV6_XFRM_POLICY: "IPV6_XFRM_POLICY",
|
|
linux.MCAST_BLOCK_SOURCE: "MCAST_BLOCK_SOURCE",
|
|
linux.MCAST_JOIN_GROUP: "MCAST_JOIN_GROUP",
|
|
linux.MCAST_JOIN_SOURCE_GROUP: "MCAST_JOIN_SOURCE_GROUP",
|
|
linux.MCAST_LEAVE_GROUP: "MCAST_LEAVE_GROUP",
|
|
linux.MCAST_LEAVE_SOURCE_GROUP: "MCAST_LEAVE_SOURCE_GROUP",
|
|
linux.MCAST_UNBLOCK_SOURCE: "MCAST_UNBLOCK_SOURCE",
|
|
linux.IPV6_2292DSTOPTS: "IPV6_2292DSTOPTS",
|
|
linux.IPV6_2292HOPLIMIT: "IPV6_2292HOPLIMIT",
|
|
linux.IPV6_2292HOPOPTS: "IPV6_2292HOPOPTS",
|
|
linux.IPV6_2292PKTINFO: "IPV6_2292PKTINFO",
|
|
linux.IPV6_2292PKTOPTIONS: "IPV6_2292PKTOPTIONS",
|
|
linux.IPV6_2292RTHDR: "IPV6_2292RTHDR",
|
|
linux.IPV6_ADDR_PREFERENCES: "IPV6_ADDR_PREFERENCES",
|
|
linux.IPV6_AUTOFLOWLABEL: "IPV6_AUTOFLOWLABEL",
|
|
linux.IPV6_DONTFRAG: "IPV6_DONTFRAG",
|
|
linux.IPV6_DSTOPTS: "IPV6_DSTOPTS",
|
|
linux.IPV6_FLOWINFO: "IPV6_FLOWINFO",
|
|
linux.IPV6_FLOWINFO_SEND: "IPV6_FLOWINFO_SEND",
|
|
linux.IPV6_FLOWLABEL_MGR: "IPV6_FLOWLABEL_MGR",
|
|
linux.IPV6_FREEBIND: "IPV6_FREEBIND",
|
|
linux.IPV6_HOPOPTS: "IPV6_HOPOPTS",
|
|
linux.IPV6_MINHOPCOUNT: "IPV6_MINHOPCOUNT",
|
|
linux.IPV6_MTU: "IPV6_MTU",
|
|
linux.IPV6_MTU_DISCOVER: "IPV6_MTU_DISCOVER",
|
|
linux.IPV6_MULTICAST_ALL: "IPV6_MULTICAST_ALL",
|
|
linux.IPV6_MULTICAST_HOPS: "IPV6_MULTICAST_HOPS",
|
|
linux.IPV6_MULTICAST_IF: "IPV6_MULTICAST_IF",
|
|
linux.IPV6_MULTICAST_LOOP: "IPV6_MULTICAST_LOOP",
|
|
linux.IPV6_RECVDSTOPTS: "IPV6_RECVDSTOPTS",
|
|
linux.IPV6_RECVERR: "IPV6_RECVERR",
|
|
linux.IPV6_RECVFRAGSIZE: "IPV6_RECVFRAGSIZE",
|
|
linux.IPV6_RECVHOPLIMIT: "IPV6_RECVHOPLIMIT",
|
|
linux.IPV6_RECVHOPOPTS: "IPV6_RECVHOPOPTS",
|
|
linux.IPV6_RECVORIGDSTADDR: "IPV6_RECVORIGDSTADDR",
|
|
linux.IPV6_RECVPATHMTU: "IPV6_RECVPATHMTU",
|
|
linux.IPV6_RECVPKTINFO: "IPV6_RECVPKTINFO",
|
|
linux.IPV6_RECVRTHDR: "IPV6_RECVRTHDR",
|
|
linux.IPV6_RECVTCLASS: "IPV6_RECVTCLASS",
|
|
linux.IPV6_RTHDR: "IPV6_RTHDR",
|
|
linux.IPV6_RTHDRDSTOPTS: "IPV6_RTHDRDSTOPTS",
|
|
linux.IPV6_TRANSPARENT: "IPV6_TRANSPARENT",
|
|
linux.IPV6_UNICAST_HOPS: "IPV6_UNICAST_HOPS",
|
|
linux.IPV6_UNICAST_IF: "IPV6_UNICAST_IF",
|
|
linux.MCAST_MSFILTER: "MCAST_MSFILTER",
|
|
linux.IPV6_ADDRFORM: "IPV6_ADDRFORM",
|
|
},
|
|
}
|