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 }