github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/strace/epsocket.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 strace 16 17 import ( 18 "bytes" 19 "encoding/binary" 20 "strings" 21 22 "github.com/mvdan/u-root-coreutils/pkg/ubinary" 23 "golang.org/x/sys/unix" 24 ) 25 26 // Address is a byte slice cast as a string that represents the address of a 27 // network node. Or, in the case of unix endpoints, it may represent a path. 28 type Address string 29 30 // FullAddress is the network address and port 31 type FullAddress struct { 32 // Addr is the network address. 33 Addr Address 34 35 // Port is the transport port. 36 // 37 // This may not be used by all endpoint types. 38 Port uint16 39 } 40 41 // GetAddress reads an sockaddr struct from the given address and converts it 42 // to the FullAddress format. It supports AF_UNIX, AF_INET and AF_INET6 43 // addresses. 44 func GetAddress(t Task, addr []byte) (FullAddress, error) { 45 r := bytes.NewBuffer(addr[:2]) 46 var fam uint16 47 if err := binary.Read(r, ubinary.NativeEndian, &fam); err != nil { 48 return FullAddress{}, unix.EFAULT 49 } 50 51 // Get the rest of the fields based on the address family. 52 switch fam { 53 case unix.AF_UNIX: 54 path := addr[2:] 55 if len(path) > unix.PathMax { 56 return FullAddress{}, unix.EINVAL 57 } 58 // Drop the terminating NUL (if one exists) and everything after 59 // it for filesystem (non-abstract) addresses. 60 if len(path) > 0 && path[0] != 0 { 61 if n := bytes.IndexByte(path[1:], 0); n >= 0 { 62 path = path[:n+1] 63 } 64 } 65 return FullAddress{ 66 Addr: Address(path), 67 }, nil 68 69 case unix.AF_INET: 70 var a unix.RawSockaddrInet4 71 r = bytes.NewBuffer(addr) 72 if err := binary.Read(r, binary.BigEndian, &a); err != nil { 73 return FullAddress{}, unix.EFAULT 74 } 75 out := FullAddress{ 76 Addr: Address(a.Addr[:]), 77 Port: uint16(a.Port), 78 } 79 if out.Addr == "\x00\x00\x00\x00" { 80 out.Addr = "" 81 } 82 return out, nil 83 84 case unix.AF_INET6: 85 var a unix.RawSockaddrInet6 86 r = bytes.NewBuffer(addr) 87 if err := binary.Read(r, binary.BigEndian, &a); err != nil { 88 return FullAddress{}, unix.EFAULT 89 } 90 91 out := FullAddress{ 92 Addr: Address(a.Addr[:]), 93 Port: uint16(a.Port), 94 } 95 96 //if isLinkLocal(out.Addr) { 97 // out.NIC = NICID(a.Scope_id) 98 //} 99 100 if out.Addr == Address(strings.Repeat("\x00", 16)) { 101 out.Addr = "" 102 } 103 return out, nil 104 105 default: 106 return FullAddress{}, unix.ENOTSUP 107 } 108 }