github.com/mergetb/u-root@v4.0.1-0.20190719191109-b70b86b73e5b+incompatible/pkg/abi/abi_unix.go (about)

     1  // Copyright 2018 Google LLC.
     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 abi
    16  
    17  import (
    18  	"fmt"
    19  	"syscall"
    20  
    21  	"github.com/u-root/u-root/pkg/binary"
    22  	"golang.org/x/sys/unix"
    23  )
    24  
    25  // OpenMode represents the mode to open(2) a file.
    26  var OpenMode = FlagSet{
    27  	&Value{
    28  		Value: syscall.O_RDWR,
    29  		Name:  "O_RDWR",
    30  	},
    31  	&Value{
    32  		Value: syscall.O_WRONLY,
    33  		Name:  "O_WRONLY",
    34  	},
    35  	&Value{
    36  		Value: syscall.O_RDONLY,
    37  		Name:  "O_RDONLY",
    38  	},
    39  }
    40  
    41  // OpenFlagSet is the set of open(2) flags.
    42  var OpenFlagSet = FlagSet{
    43  	&BitFlag{
    44  		Value: syscall.O_APPEND,
    45  		Name:  "O_APPEND",
    46  	},
    47  	&BitFlag{
    48  		Value: syscall.O_ASYNC,
    49  		Name:  "O_ASYNC",
    50  	},
    51  	&BitFlag{
    52  		Value: syscall.O_CLOEXEC,
    53  		Name:  "O_CLOEXEC",
    54  	},
    55  	&BitFlag{
    56  		Value: syscall.O_CREAT,
    57  		Name:  "O_CREAT",
    58  	},
    59  	&BitFlag{
    60  		Value: syscall.O_DIRECT,
    61  		Name:  "O_DIRECT",
    62  	},
    63  	&BitFlag{
    64  		Value: syscall.O_DIRECTORY,
    65  		Name:  "O_DIRECTORY",
    66  	},
    67  	&BitFlag{
    68  		Value: syscall.O_EXCL,
    69  		Name:  "O_EXCL",
    70  	},
    71  	&BitFlag{
    72  		Value: syscall.O_NOATIME,
    73  		Name:  "O_NOATIME",
    74  	},
    75  	&BitFlag{
    76  		Value: syscall.O_NOCTTY,
    77  		Name:  "O_NOCTTY",
    78  	},
    79  	&BitFlag{
    80  		Value: syscall.O_NOFOLLOW,
    81  		Name:  "O_NOFOLLOW",
    82  	},
    83  	&BitFlag{
    84  		Value: syscall.O_NONBLOCK,
    85  		Name:  "O_NONBLOCK",
    86  	},
    87  	&BitFlag{
    88  		Value: 0x200000, // O_PATH
    89  		Name:  "O_PATH",
    90  	},
    91  	&BitFlag{
    92  		Value: syscall.O_SYNC,
    93  		Name:  "O_SYNC",
    94  	},
    95  	&BitFlag{
    96  		Value: syscall.O_TRUNC,
    97  		Name:  "O_TRUNC",
    98  	},
    99  }
   100  
   101  func Open(val uint64) string {
   102  	s := OpenMode.Parse(val & syscall.O_ACCMODE)
   103  	if flags := OpenFlagSet.Parse(val &^ syscall.O_ACCMODE); flags != "" {
   104  		s += "|" + flags
   105  	}
   106  	return s
   107  }
   108  
   109  // socket
   110  
   111  // SocketFamily are the possible socket(2) families.
   112  var SocketFamily = FlagSet{
   113  	&Value{
   114  		Value: unix.AF_UNSPEC,
   115  		Name:  "AF_UNSPEC",
   116  	},
   117  	&Value{
   118  		Value: unix.AF_UNIX,
   119  		Name:  "AF_UNIX",
   120  	},
   121  	&Value{
   122  		Value: unix.AF_INET,
   123  		Name:  "AF_INET",
   124  	},
   125  	&Value{
   126  		Value: unix.AF_AX25,
   127  		Name:  "AF_AX25",
   128  	},
   129  	&Value{
   130  		Value: unix.AF_IPX,
   131  		Name:  "AF_IPX",
   132  	},
   133  	&Value{
   134  		Value: unix.AF_APPLETALK,
   135  		Name:  "AF_APPLETALK",
   136  	},
   137  	&Value{
   138  		Value: unix.AF_NETROM,
   139  		Name:  "AF_NETROM",
   140  	},
   141  	&Value{
   142  		Value: unix.AF_BRIDGE,
   143  		Name:  "AF_BRIDGE",
   144  	},
   145  	&Value{
   146  		Value: unix.AF_ATMPVC,
   147  		Name:  "AF_ATMPVC",
   148  	},
   149  	&Value{
   150  		Value: unix.AF_X25,
   151  		Name:  "AF_X25",
   152  	},
   153  	&Value{
   154  		Value: unix.AF_INET6,
   155  		Name:  "AF_INET6",
   156  	},
   157  	&Value{
   158  		Value: unix.AF_ROSE,
   159  		Name:  "AF_ROSE",
   160  	},
   161  	&Value{
   162  		Value: unix.AF_DECnet,
   163  		Name:  "AF_DECnet",
   164  	},
   165  	&Value{
   166  		Value: unix.AF_NETBEUI,
   167  		Name:  "AF_NETBEUI",
   168  	},
   169  	&Value{
   170  		Value: unix.AF_SECURITY,
   171  		Name:  "AF_SECURITY",
   172  	},
   173  	&Value{
   174  		Value: unix.AF_KEY,
   175  		Name:  "AF_KEY",
   176  	},
   177  	&Value{
   178  		Value: unix.AF_NETLINK,
   179  		Name:  "AF_NETLINK",
   180  	},
   181  	&Value{
   182  		Value: unix.AF_PACKET,
   183  		Name:  "AF_PACKET",
   184  	},
   185  	&Value{
   186  		Value: unix.AF_ASH,
   187  		Name:  "AF_ASH",
   188  	},
   189  	&Value{
   190  		Value: unix.AF_ECONET,
   191  		Name:  "AF_ECONET",
   192  	},
   193  	&Value{
   194  		Value: unix.AF_ATMSVC,
   195  		Name:  "AF_ATMSVC",
   196  	},
   197  	&Value{
   198  		Value: unix.AF_RDS,
   199  		Name:  "AF_RDS",
   200  	},
   201  	&Value{
   202  		Value: unix.AF_SNA,
   203  		Name:  "AF_SNA",
   204  	},
   205  	&Value{
   206  		Value: unix.AF_IRDA,
   207  		Name:  "AF_IRDA",
   208  	},
   209  	&Value{
   210  		Value: unix.AF_PPPOX,
   211  		Name:  "AF_PPPOX",
   212  	},
   213  	&Value{
   214  		Value: unix.AF_WANPIPE,
   215  		Name:  "AF_WANPIPE",
   216  	},
   217  	&Value{
   218  		Value: unix.AF_LLC,
   219  		Name:  "AF_LLC",
   220  	},
   221  	&Value{
   222  		Value: unix.AF_IB,
   223  		Name:  "AF_IB",
   224  	},
   225  	&Value{
   226  		Value: unix.AF_MPLS,
   227  		Name:  "AF_MPLS",
   228  	},
   229  	&Value{
   230  		Value: unix.AF_CAN,
   231  		Name:  "AF_CAN",
   232  	},
   233  	&Value{
   234  		Value: unix.AF_TIPC,
   235  		Name:  "AF_TIPC",
   236  	},
   237  	&Value{
   238  		Value: unix.AF_BLUETOOTH,
   239  		Name:  "AF_BLUETOOTH",
   240  	},
   241  	&Value{
   242  		Value: unix.AF_IUCV,
   243  		Name:  "AF_IUCV",
   244  	},
   245  	&Value{
   246  		Value: unix.AF_RXRPC,
   247  		Name:  "AF_RXRPC",
   248  	},
   249  	&Value{
   250  		Value: unix.AF_ISDN,
   251  		Name:  "AF_ISDN",
   252  	},
   253  	&Value{
   254  		Value: unix.AF_PHONET,
   255  		Name:  "AF_PHONET",
   256  	},
   257  	&Value{
   258  		Value: unix.AF_IEEE802154,
   259  		Name:  "AF_IEEE802154",
   260  	},
   261  	&Value{
   262  		Value: unix.AF_CAIF,
   263  		Name:  "AF_CAIF",
   264  	},
   265  	&Value{
   266  		Value: unix.AF_ALG,
   267  		Name:  "AF_ALG",
   268  	},
   269  	&Value{
   270  		Value: unix.AF_NFC,
   271  		Name:  "AF_NFC",
   272  	},
   273  	&Value{
   274  		Value: unix.AF_VSOCK,
   275  		Name:  "AF_VSOCK",
   276  	},
   277  }
   278  
   279  // SocketType are the possible socket(2) types.
   280  var SocketType = FlagSet{
   281  	&Value{
   282  		Value: unix.SOCK_STREAM,
   283  		Name:  "SOCK_STREAM",
   284  	},
   285  	&Value{
   286  		Value: unix.SOCK_DGRAM,
   287  		Name:  "SOCK_DGRAM",
   288  	},
   289  	&Value{
   290  		Value: unix.SOCK_RAW,
   291  		Name:  "SOCK_RAW",
   292  	},
   293  	&Value{
   294  		Value: unix.SOCK_RDM,
   295  		Name:  "SOCK_RDM",
   296  	},
   297  	&Value{
   298  		Value: unix.SOCK_SEQPACKET,
   299  		Name:  "SOCK_SEQPACKET",
   300  	},
   301  	&Value{
   302  		Value: unix.SOCK_DCCP,
   303  		Name:  "SOCK_DCCP",
   304  	},
   305  	&Value{
   306  		Value: unix.SOCK_PACKET,
   307  		Name:  "SOCK_PACKET",
   308  	},
   309  }
   310  
   311  // SocketFlagSet are the possible socket(2) flags.
   312  var SocketFlagSet = FlagSet{
   313  	&BitFlag{
   314  		Value: unix.SOCK_CLOEXEC,
   315  		Name:  "SOCK_CLOEXEC",
   316  	},
   317  	&BitFlag{
   318  		Value: unix.SOCK_NONBLOCK,
   319  		Name:  "SOCK_NONBLOCK",
   320  	},
   321  }
   322  
   323  // ipProtocol are the possible socket(2) types for INET and INET6 sockets.
   324  var ipProtocol = FlagSet{
   325  	&Value{
   326  		Value: unix.IPPROTO_IP,
   327  		Name:  "IPPROTO_IP",
   328  	},
   329  	&Value{
   330  		Value: unix.IPPROTO_ICMP,
   331  		Name:  "IPPROTO_ICMP",
   332  	},
   333  	&Value{
   334  		Value: unix.IPPROTO_IGMP,
   335  		Name:  "IPPROTO_IGMP",
   336  	},
   337  	&Value{
   338  		Value: unix.IPPROTO_IPIP,
   339  		Name:  "IPPROTO_IPIP",
   340  	},
   341  	&Value{
   342  		Value: unix.IPPROTO_TCP,
   343  		Name:  "IPPROTO_TCP",
   344  	},
   345  	&Value{
   346  		Value: unix.IPPROTO_EGP,
   347  		Name:  "IPPROTO_EGP",
   348  	},
   349  	&Value{
   350  		Value: unix.IPPROTO_PUP,
   351  		Name:  "IPPROTO_PUP",
   352  	},
   353  	&Value{
   354  		Value: unix.IPPROTO_UDP,
   355  		Name:  "IPPROTO_UDP",
   356  	},
   357  	&Value{
   358  		Value: unix.IPPROTO_IDP,
   359  		Name:  "IPPROTO_IDP",
   360  	},
   361  	&Value{
   362  		Value: unix.IPPROTO_TP,
   363  		Name:  "IPPROTO_TP",
   364  	},
   365  	&Value{
   366  		Value: unix.IPPROTO_DCCP,
   367  		Name:  "IPPROTO_DCCP",
   368  	},
   369  	&Value{
   370  		Value: unix.IPPROTO_IPV6,
   371  		Name:  "IPPROTO_IPV6",
   372  	},
   373  	&Value{
   374  		Value: unix.IPPROTO_RSVP,
   375  		Name:  "IPPROTO_RSVP",
   376  	},
   377  	&Value{
   378  		Value: unix.IPPROTO_GRE,
   379  		Name:  "IPPROTO_GRE",
   380  	},
   381  	&Value{
   382  		Value: unix.IPPROTO_ESP,
   383  		Name:  "IPPROTO_ESP",
   384  	},
   385  	&Value{
   386  		Value: unix.IPPROTO_AH,
   387  		Name:  "IPPROTO_AH",
   388  	},
   389  	&Value{
   390  		Value: unix.IPPROTO_MTP,
   391  		Name:  "IPPROTO_MTP",
   392  	},
   393  	&Value{
   394  		Value: unix.IPPROTO_BEETPH,
   395  		Name:  "IPPROTO_BEETPH",
   396  	},
   397  	&Value{
   398  		Value: unix.IPPROTO_ENCAP,
   399  		Name:  "IPPROTO_ENCAP",
   400  	},
   401  	&Value{
   402  		Value: unix.IPPROTO_PIM,
   403  		Name:  "IPPROTO_PIM",
   404  	},
   405  	&Value{
   406  		Value: unix.IPPROTO_COMP,
   407  		Name:  "IPPROTO_COMP",
   408  	},
   409  	&Value{
   410  		Value: unix.IPPROTO_SCTP,
   411  		Name:  "IPPROTO_SCTP",
   412  	},
   413  	&Value{
   414  		Value: unix.IPPROTO_UDPLITE,
   415  		Name:  "IPPROTO_UDPLITE",
   416  	},
   417  	&Value{
   418  		Value: unix.IPPROTO_MPLS,
   419  		Name:  "IPPROTO_MPLS",
   420  	},
   421  	&Value{
   422  		Value: unix.IPPROTO_RAW,
   423  		Name:  "IPPROTO_RAW",
   424  	},
   425  }
   426  
   427  // SocketProtocol are the possible socket(2) protocols for each protocol family.
   428  var SocketProtocol = map[int32]FlagSet{
   429  	unix.AF_INET:  ipProtocol,
   430  	unix.AF_INET6: ipProtocol,
   431  	unix.AF_NETLINK: {
   432  		&Value{
   433  			Value: unix.NETLINK_ROUTE,
   434  			Name:  "NETLINK_ROUTE",
   435  		},
   436  		&Value{
   437  			Value: unix.NETLINK_UNUSED,
   438  			Name:  "NETLINK_UNUSED",
   439  		},
   440  		&Value{
   441  			Value: unix.NETLINK_USERSOCK,
   442  			Name:  "NETLINK_USERSOCK",
   443  		},
   444  		&Value{
   445  			Value: unix.NETLINK_FIREWALL,
   446  			Name:  "NETLINK_FIREWALL",
   447  		},
   448  		&Value{
   449  			Value: unix.NETLINK_SOCK_DIAG,
   450  			Name:  "NETLINK_SOCK_DIAG",
   451  		},
   452  		&Value{
   453  			Value: unix.NETLINK_NFLOG,
   454  			Name:  "NETLINK_NFLOG",
   455  		},
   456  		&Value{
   457  			Value: unix.NETLINK_XFRM,
   458  			Name:  "NETLINK_XFRM",
   459  		},
   460  		&Value{
   461  			Value: unix.NETLINK_SELINUX,
   462  			Name:  "NETLINK_SELINUX",
   463  		},
   464  		&Value{
   465  			Value: unix.NETLINK_ISCSI,
   466  			Name:  "NETLINK_ISCSI",
   467  		},
   468  		&Value{
   469  			Value: unix.NETLINK_AUDIT,
   470  			Name:  "NETLINK_AUDIT",
   471  		},
   472  		&Value{
   473  			Value: unix.NETLINK_FIB_LOOKUP,
   474  			Name:  "NETLINK_FIB_LOOKUP",
   475  		},
   476  		&Value{
   477  			Value: unix.NETLINK_CONNECTOR,
   478  			Name:  "NETLINK_CONNECTOR",
   479  		},
   480  		&Value{
   481  			Value: unix.NETLINK_NETFILTER,
   482  			Name:  "NETLINK_NETFILTER",
   483  		},
   484  		&Value{
   485  			Value: unix.NETLINK_IP6_FW,
   486  			Name:  "NETLINK_IP6_FW",
   487  		},
   488  		&Value{
   489  			Value: unix.NETLINK_DNRTMSG,
   490  			Name:  "NETLINK_DNRTMSG",
   491  		},
   492  		&Value{
   493  			Value: unix.NETLINK_KOBJECT_UEVENT,
   494  			Name:  "NETLINK_KOBJECT_UEVENT",
   495  		},
   496  		&Value{
   497  			Value: unix.NETLINK_GENERIC,
   498  			Name:  "NETLINK_GENERIC",
   499  		},
   500  		&Value{
   501  			Value: unix.NETLINK_SCSITRANSPORT,
   502  			Name:  "NETLINK_SCSITRANSPORT",
   503  		},
   504  		&Value{
   505  			Value: unix.NETLINK_ECRYPTFS,
   506  			Name:  "NETLINK_ECRYPTFS",
   507  		},
   508  		&Value{
   509  			Value: unix.NETLINK_RDMA,
   510  			Name:  "NETLINK_RDMA",
   511  		},
   512  		&Value{
   513  			Value: unix.NETLINK_CRYPTO,
   514  			Name:  "NETLINK_CRYPTO",
   515  		},
   516  	},
   517  }
   518  
   519  var ControlMessageType = map[int32]string{
   520  	unix.SCM_RIGHTS:      "SCM_RIGHTS",
   521  	unix.SCM_CREDENTIALS: "SCM_CREDENTIALS",
   522  	unix.SO_TIMESTAMP:    "SO_TIMESTAMP",
   523  }
   524  
   525  func SockType(stype int32) string {
   526  	s := SocketType.Parse(uint64(stype & SOCK_TYPE_MASK))
   527  	if flags := SocketFlagSet.Parse(uint64(stype &^ SOCK_TYPE_MASK)); flags != "" {
   528  		s += "|" + flags
   529  	}
   530  	return s
   531  }
   532  
   533  func SockProtocol(family, protocol int32) string {
   534  	protocols, ok := SocketProtocol[family]
   535  	if !ok {
   536  		return fmt.Sprintf("%#x", protocol)
   537  	}
   538  	return protocols.Parse(uint64(protocol))
   539  }
   540  
   541  func SockFlags(flags int32) string {
   542  	if flags == 0 {
   543  		return "0"
   544  	}
   545  	return SocketFlagSet.Parse(uint64(flags))
   546  }
   547  
   548  // from gvisor sys_socket.go. They defined these as linux-specific but
   549  // for the most part they are common to many Unices.
   550  // minListenBacklog is the minimum reasonable backlog for listening sockets.
   551  const minListenBacklog = 8
   552  
   553  // maxListenBacklog is the maximum allowed backlog for listening sockets.
   554  const maxListenBacklog = 1024
   555  
   556  // maxAddrLen is the maximum socket address length we're willing to accept.
   557  const maxAddrLen = 200
   558  
   559  // maxOptLen is the maximum sockopt parameter length we're willing to accept.
   560  const maxOptLen = 1024
   561  
   562  // maxControlLen is the maximum length of the msghdr.msg_control buffer we're
   563  // willing to accept. Note that this limit is smaller than Linux, which allows
   564  // buffers upto INT_MAX.
   565  const maxControlLen = 10 * 1024 * 1024
   566  
   567  // nameLenOffset is the offset from the start of the MessageHeader64 struct to
   568  // the NameLen field.
   569  const nameLenOffset = 8
   570  
   571  // controlLenOffset is the offset form the start of the MessageHeader64 struct
   572  // to the ControlLen field.
   573  const controlLenOffset = 40
   574  
   575  // messageHeader64Len is the length of a MessageHeader64 struct.
   576  var messageHeader64Len = uint64(binary.Size(MessageHeader64{}))
   577  
   578  // multipleMessageHeader64Len is the length of a multipeMessageHeader64 struct.
   579  var multipleMessageHeader64Len = uint64(binary.Size(multipleMessageHeader64{}))
   580  
   581  // MessageHeader64 is the 64-bit representation of the msghdr struct used in
   582  // the recvmsg and sendmsg syscalls.
   583  type MessageHeader64 struct {
   584  	// Name is the optional pointer to a network address buffer.
   585  	Name uint64
   586  
   587  	// NameLen is the length of the buffer pointed to by Name.
   588  	NameLen uint32
   589  	_       uint32
   590  
   591  	// Iov is a pointer to an array of io vectors that describe the memory
   592  	// locations involved in the io operation.
   593  	Iov uint64
   594  
   595  	// IovLen is the length of the array pointed to by Iov.
   596  	IovLen uint64
   597  
   598  	// Control is the optional pointer to ancillary control data.
   599  	Control uint64
   600  
   601  	// ControlLen is the length of the data pointed to by Control.
   602  	ControlLen uint64
   603  
   604  	// Flags on the sent/received message.
   605  	Flags int32
   606  	_     int32
   607  }
   608  
   609  // multipleMessageHeader64 is the 64-bit representation of the mmsghdr struct used in
   610  // the recvmmsg and sendmmsg syscalls.
   611  type multipleMessageHeader64 struct {
   612  	msgHdr MessageHeader64
   613  	msgLen uint32
   614  	_      int32
   615  }