this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sockets sockaddr padding & family fixups

+144 -6
+133 -6
src/libSystem/kernel-bsd/sockets.cpp
··· 1 1 #include "config.h" 2 2 #include <sys/socket.h> 3 3 #include "sockets.h" 4 + #include "libc/darwin_errno_codes.h" 4 5 #include "libc/errno.h" 5 6 #include "common/path.h" 6 7 #include "common/auto.h" 7 8 #include <sys/types.h> 8 9 #include <cstring> 9 10 #include <cstdlib> 11 + #include <cstring> 10 12 #include <poll.h> 11 13 14 + static short familyDarwinToLinux(short f) 15 + { 16 + switch (f) 17 + { 18 + case DARWIN_AF_UNSPEC: 19 + return AF_UNSPEC; 20 + case DARWIN_AF_UNIX: 21 + return AF_UNIX; 22 + case DARWIN_AF_INET: 23 + return AF_INET; 24 + //case DARWIN_AF_APPLETALK: 25 + // return AF_APPLETALK; 26 + case DARWIN_AF_IPX: 27 + return AF_IPX; 28 + case DARWIN_AF_INET6: 29 + return AF_INET6; 30 + default: 31 + return -1; 32 + } 33 + } 34 + 35 + static short familyLinuxToDarwin(short f) 36 + { 37 + switch (f) 38 + { 39 + case AF_UNSPEC: 40 + return DARWIN_AF_UNSPEC; 41 + case AF_UNIX: 42 + return DARWIN_AF_UNIX; 43 + case AF_INET: 44 + return DARWIN_AF_INET; 45 + //case AF_APPLETALK: 46 + // return DARWIN_AF_APPLETALK; 47 + case AF_IPX: 48 + return DARWIN_AF_IPX; 49 + case AF_INET6: 50 + return DARWIN_AF_INET6; 51 + default: 52 + return -1; 53 + } 54 + } 55 + 56 + static bool sockaddrFixupIn(struct sockaddr* addr, socklen_t len) 57 + { 58 + if (offsetof(struct sockaddr,sa_family) == 0) 59 + { 60 + // BSD/Darwin has offset of 1 61 + memmove(addr, reinterpret_cast<char*>(addr)+1, len-1); 62 + } 63 + addr->sa_family = familyDarwinToLinux(addr->sa_family); 64 + return addr->sa_family != -1; 65 + } 66 + 67 + static bool sockaddrFixupOut(struct sockaddr* addr, socklen_t len) 68 + { 69 + bool ok; 70 + addr->sa_family = familyLinuxToDarwin(addr->sa_family); 71 + ok = addr->sa_family != -1; 72 + 73 + if (offsetof(struct sockaddr,sa_family) == 0) 74 + { 75 + // BSD/Darwin has offset of 1 76 + memmove(reinterpret_cast<char*>(addr)+1, addr, len-1); 77 + } 78 + return ok; 79 + } 80 + 12 81 int __darwin_select(int fd, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout) 13 82 { 14 83 struct timeval backup; ··· 23 92 } 24 93 25 94 MAP_FUNCTION3(int,poll,struct pollfd*,nfds_t,int); 26 - MAP_FUNCTION3(int,accept,int,struct sockaddr*,socklen_t*); 95 + 96 + int __darwin_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) 97 + { 98 + int rv = ::accept(sockfd, addr, addrlen); 99 + if (rv == -1) 100 + errnoOut(); 101 + else 102 + sockaddrFixupOut(addr, *addrlen); 103 + return rv; 104 + } 105 + 27 106 MAP_FUNCTION4(ssize_t,send,int,const void*,size_t,int); 28 107 MAP_FUNCTION3(ssize_t,sendmsg,int,struct msghdr*,int); 29 108 30 109 ssize_t __darwin_sendto(int socket, const void *buffer, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len) 31 110 { 32 - return AutoErrno<ssize_t>(sendto,socket,buffer,length,flags,dest_addr,dest_len); 111 + struct sockaddr* buf = reinterpret_cast<struct sockaddr*>(alloca(dest_len)); 112 + memcpy(buf, dest_addr, dest_len); 113 + 114 + if (!sockaddrFixupIn(buf, dest_len)) 115 + { 116 + errno = DARWIN_EAFNOSUPPORT; 117 + return -1; 118 + } 119 + 120 + return AutoErrno<ssize_t>(sendto,socket,buffer,length,flags,buf,dest_len); 33 121 } 34 122 35 123 MAP_FUNCTION4(ssize_t,recv,int,void*,size_t,int); 36 - MAP_FUNCTION3(ssize_t,recvmsg,int,struct msghdr*,int); 124 + MAP_FUNCTION3(ssize_t,recvmsg,int,struct msghdr*,int); // TODO: check msghdr 37 125 38 126 ssize_t __darwin_recvfrom(int socket, void * buffer, size_t length, int flags, struct sockaddr * address, socklen_t * address_len) 39 127 { 40 - return AutoErrno<ssize_t>(recvfrom,socket,buffer,length,flags,address,address_len); 128 + ssize_t s = AutoErrno<ssize_t>(recvfrom,socket,buffer,length,flags,address,address_len); 129 + if (s != -1) 130 + sockaddrFixupOut(address, *address_len); 131 + return s; 41 132 } 42 133 43 134 // for SOL_SOCKET ··· 127 218 return AutoErrno<int>(setsockopt,socket,level,option_name,option_value,option_len); 128 219 } 129 220 130 - MAP_FUNCTION3(int,connect,int,const struct sockaddr*,socklen_t); 131 - MAP_FUNCTION3(int,socket,int,int,int); 221 + int __darwin_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) 222 + { 223 + struct sockaddr* ma = reinterpret_cast<struct sockaddr*>(alloca(sizeof(addrlen))); 224 + 225 + memcpy(ma, addr, addrlen); 226 + ma->sa_family = familyDarwinToLinux(addr->sa_family); 227 + 228 + if (ma->sa_family == -1) 229 + { 230 + errno = DARWIN_EAFNOSUPPORT; 231 + return -1; 232 + } 233 + else 234 + { 235 + int rv = ::connect(sockfd, ma, addrlen); 236 + if (rv == -1) 237 + errnoOut(); 238 + return rv; 239 + } 240 + } 241 + 242 + int __darwin_socket(int domain, int type, int protocol) 243 + { 244 + domain = familyDarwinToLinux(domain); 245 + if (domain == -1) 246 + { 247 + errno = DARWIN_EAFNOSUPPORT; 248 + return -1; 249 + } 250 + else 251 + { 252 + int rv = ::socket(domain, type, protocol); 253 + if (rv == -1) 254 + errnoOut(); 255 + return rv; 256 + } 257 + } 258 + 132 259
+11
src/libSystem/kernel-bsd/sockets.h
··· 21 21 #define DARWIN_SO_ERROR 0x1007 22 22 #define DARWIN_SO_TYPE 0x1008 23 23 24 + #define DARWIN_AF_UNSPEC 0 25 + #define DARWIN_AF_UNIX 1 26 + #define DARWIN_AF_INET 2 27 + #define DARWIN_AF_APPLETALK 16 28 + #define DARWIN_AF_IPX 23 29 + #define DARWIN_AF_INET6 30 30 + 24 31 extern "C" 25 32 { 26 33 ··· 31 38 int __darwin_getsockopt(int socket, int level, int option_name, void * option_value, socklen_t * option_len); 32 39 33 40 int __darwin_setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len); 41 + 42 + int __darwin_socket(int domain, int type, int protocol); 43 + int __darwin_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 44 + int __darwin_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 34 45 35 46 } 36 47