Changeset 988 for vendor/current/lib/socket_wrapper
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/lib/socket_wrapper
- Files:
-
- 4 deleted
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/lib/socket_wrapper/socket_wrapper.c
r740 r988 1 1 /* 2 * Copyright (C) Jelmer Vernooij 2005,2008 <jelmer@samba.org> 3 * Copyright (C) Stefan Metzmacher 2006-2009 <metze@samba.org> 2 * Copyright (c) 2005-2008 Jelmer Vernooij <jelmer@samba.org> 3 * Copyright (C) 2006-2014 Stefan Metzmacher <metze@samba.org> 4 * Copyright (C) 2013-2014 Andreas Schneider <asn@samba.org> 4 5 * 5 6 * All rights reserved. 6 * 7 * 7 8 * Redistribution and use in source and binary forms, with or without 8 9 * modification, are permitted provided that the following conditions 9 10 * are met: 10 * 11 * 11 12 * 1. Redistributions of source code must retain the above copyright 12 13 * notice, this list of conditions and the following disclaimer. 13 * 14 * 14 15 * 2. Redistributions in binary form must reproduce the above copyright 15 16 * notice, this list of conditions and the following disclaimer in the 16 17 * documentation and/or other materials provided with the distribution. 17 * 18 * 18 19 * 3. Neither the name of the author nor the names of its contributors 19 20 * may be used to endorse or promote products derived from this software 20 21 * without specific prior written permission. 21 * 22 * 22 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE … … 40 41 */ 41 42 42 #ifdef _SAMBA_BUILD_ 43 44 #define SOCKET_WRAPPER_NOT_REPLACE 45 #include "../replace/replace.h" 46 #include "system/network.h" 47 #include "system/filesys.h" 48 #include "system/time.h" 49 50 #else /* _SAMBA_BUILD_ */ 43 #include "config.h" 51 44 52 45 #include <sys/types.h> … … 55 48 #include <sys/socket.h> 56 49 #include <sys/ioctl.h> 50 #ifdef HAVE_SYS_FILIO_H 57 51 #include <sys/filio.h> 52 #endif 53 #ifdef HAVE_SYS_SIGNALFD_H 54 #include <sys/signalfd.h> 55 #endif 56 #ifdef HAVE_SYS_EVENTFD_H 57 #include <sys/eventfd.h> 58 #endif 59 #ifdef HAVE_SYS_TIMERFD_H 60 #include <sys/timerfd.h> 61 #endif 62 #include <sys/uio.h> 58 63 #include <errno.h> 59 64 #include <sys/un.h> 60 65 #include <netinet/in.h> 61 66 #include <netinet/tcp.h> 67 #include <arpa/inet.h> 62 68 #include <fcntl.h> 63 69 #include <stdlib.h> 64 #include <unistd.h>65 70 #include <string.h> 66 71 #include <stdio.h> 67 72 #include <stdint.h> 68 69 #endif 70 71 #ifndef _PUBLIC_ 72 #define _PUBLIC_ 73 #endif 73 #include <stdarg.h> 74 #include <stdbool.h> 75 #include <unistd.h> 76 #ifdef HAVE_GNU_LIB_NAMES_H 77 #include <gnu/lib-names.h> 78 #endif 79 #ifdef HAVE_RPC_RPC_H 80 #include <rpc/rpc.h> 81 #endif 82 83 enum swrap_dbglvl_e { 84 SWRAP_LOG_ERROR = 0, 85 SWRAP_LOG_WARN, 86 SWRAP_LOG_DEBUG, 87 SWRAP_LOG_TRACE 88 }; 89 90 /* GCC have printf type attribute check. */ 91 #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT 92 #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b))) 93 #else 94 #define PRINTF_ATTRIBUTE(a,b) 95 #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */ 96 97 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE 98 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor)) 99 #else 100 #define DESTRUCTOR_ATTRIBUTE 101 #endif 102 103 #ifdef HAVE_ADDRESS_SANITIZER_ATTRIBUTE 104 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE __attribute__((no_sanitize_address)) 105 #else 106 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE 107 #endif 108 109 #ifdef HAVE_GCC_THREAD_LOCAL_STORAGE 110 # define SWRAP_THREAD __thread 111 #else 112 # define SWRAP_THREAD 113 #endif 114 115 #ifndef MIN 116 #define MIN(a,b) ((a)<(b)?(a):(b)) 117 #endif 118 119 #ifndef ZERO_STRUCT 120 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) 121 #endif 122 123 #ifndef ZERO_STRUCTP 124 #define ZERO_STRUCTP(x) do { \ 125 if ((x) != NULL) \ 126 memset((char *)(x), 0, sizeof(*(x))); \ 127 } while(0) 128 #endif 129 130 #ifndef discard_const 131 #define discard_const(ptr) ((void *)((uintptr_t)(ptr))) 132 #endif 133 134 #ifndef discard_const_p 135 #define discard_const_p(type, ptr) ((type *)discard_const(ptr)) 136 #endif 137 138 #ifdef IPV6_PKTINFO 139 # ifndef IPV6_RECVPKTINFO 140 # define IPV6_RECVPKTINFO IPV6_PKTINFO 141 # endif /* IPV6_RECVPKTINFO */ 142 #endif /* IPV6_PKTINFO */ 143 144 /* 145 * On BSD IP_PKTINFO has a different name because during 146 * the time when they implemented it, there was no RFC. 147 * The name for IPv6 is the same as on Linux. 148 */ 149 #ifndef IP_PKTINFO 150 # ifdef IP_RECVDSTADDR 151 # define IP_PKTINFO IP_RECVDSTADDR 152 # endif 153 #endif 154 74 155 75 156 #define SWRAP_DLIST_ADD(list,item) do { \ … … 104 185 } while (0) 105 186 106 /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support 107 * for now */ 108 #define REWRITE_CALLS 109 110 #ifdef REWRITE_CALLS 111 #define real_accept accept 112 #define real_connect connect 113 #define real_bind bind 114 #define real_listen listen 115 #define real_getpeername getpeername 116 #define real_getsockname getsockname 117 #define real_getsockopt getsockopt 118 #define real_setsockopt setsockopt 119 #define real_recvfrom recvfrom 120 #define real_sendto sendto 121 #define real_sendmsg sendmsg 122 #define real_ioctl ioctl 123 #define real_recv recv 124 #define real_read read 125 #define real_send send 126 #define real_readv readv 127 #define real_writev writev 128 #define real_socket socket 129 #define real_close close 130 #endif 131 132 #ifdef HAVE_GETTIMEOFDAY_TZ 187 #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID) 133 188 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL) 134 189 #else … … 138 193 /* we need to use a very terse format here as IRIX 6.4 silently 139 194 truncates names to 16 chars, so if we use a longer name then we 140 can't tell which port a packet came from with recvfrom() 141 195 can't tell which port a packet came from with recvfrom() 196 142 197 with this format we have 8 chars left for the directory name 143 198 */ … … 148 203 #define SOCKET_TYPE_CHAR_UDP_V6 'Y' 149 204 150 #define MAX_WRAPPED_INTERFACES 16 151 205 /* 206 * Set the packet MTU to 1500 bytes for stream sockets to make it it easier to 207 * format PCAP capture files (as the caller will simply continue from here). 208 */ 209 #define SOCKET_WRAPPER_MTU_DEFAULT 1500 210 #define SOCKET_WRAPPER_MTU_MIN 512 211 #define SOCKET_WRAPPER_MTU_MAX 32768 212 213 #define SOCKET_MAX_SOCKETS 1024 214 215 /* This limit is to avoid broadcast sendto() needing to stat too many 216 * files. It may be raised (with a performance cost) to up to 254 217 * without changing the format above */ 218 #define MAX_WRAPPED_INTERFACES 40 219 220 struct swrap_address { 221 socklen_t sa_socklen; 222 union { 223 struct sockaddr s; 224 struct sockaddr_in in; 152 225 #ifdef HAVE_IPV6 153 /* 154 * FD00::5357:5FXX 155 */ 156 static const struct in6_addr *swrap_ipv6(void) 157 { 158 static struct in6_addr v; 159 static int initialized; 160 int ret; 161 162 if (initialized) { 163 return &v; 164 } 165 initialized = 1; 166 167 ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v); 168 if (ret <= 0) { 169 abort(); 170 } 171 172 return &v; 173 } 174 #endif 175 176 static struct sockaddr *sockaddr_dup(const void *data, socklen_t len) 177 { 178 struct sockaddr *ret = (struct sockaddr *)malloc(len); 179 memcpy(ret, data, len); 180 return ret; 181 } 182 183 static void set_port(int family, int prt, struct sockaddr *addr) 184 { 185 switch (family) { 186 case AF_INET: 187 ((struct sockaddr_in *)addr)->sin_port = htons(prt); 188 break; 189 #ifdef HAVE_IPV6 190 case AF_INET6: 191 ((struct sockaddr_in6 *)addr)->sin6_port = htons(prt); 192 break; 193 #endif 194 } 195 } 196 197 static size_t socket_length(int family) 198 { 199 switch (family) { 200 case AF_INET: 201 return sizeof(struct sockaddr_in); 202 #ifdef HAVE_IPV6 203 case AF_INET6: 204 return sizeof(struct sockaddr_in6); 205 #endif 206 } 207 return 0; 208 } 209 210 226 struct sockaddr_in6 in6; 227 #endif 228 struct sockaddr_un un; 229 struct sockaddr_storage ss; 230 } sa; 231 }; 232 233 struct socket_info_fd { 234 struct socket_info_fd *prev, *next; 235 int fd; 236 }; 211 237 212 238 struct socket_info 213 239 { 214 int fd;240 struct socket_info_fd *fds; 215 241 216 242 int family; … … 222 248 int connected; 223 249 int defer_connect; 224 225 char *path; 226 char *tmp_path; 227 228 struct sockaddr *myname; 229 socklen_t myname_len; 230 231 struct sockaddr *peername; 232 socklen_t peername_len; 250 int pktinfo; 251 252 /* The unix path so we can unlink it on close() */ 253 struct sockaddr_un un_addr; 254 255 struct swrap_address bindname; 256 struct swrap_address myname; 257 struct swrap_address peername; 233 258 234 259 struct { … … 240 265 }; 241 266 242 static struct socket_info *sockets; 243 244 const char *socket_wrapper_dir(void) 267 /* 268 * File descriptors are shared between threads so we should share socket 269 * information too. 270 */ 271 struct socket_info *sockets; 272 273 /* Function prototypes */ 274 275 bool socket_wrapper_enabled(void); 276 void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE; 277 278 #ifdef NDEBUG 279 # define SWRAP_LOG(...) 280 #else 281 282 static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *func, const char *format, ...) PRINTF_ATTRIBUTE(3, 4); 283 # define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__) 284 285 static void swrap_log(enum swrap_dbglvl_e dbglvl, 286 const char *func, 287 const char *format, ...) 288 { 289 char buffer[1024]; 290 va_list va; 291 const char *d; 292 unsigned int lvl = 0; 293 294 d = getenv("SOCKET_WRAPPER_DEBUGLEVEL"); 295 if (d != NULL) { 296 lvl = atoi(d); 297 } 298 299 va_start(va, format); 300 vsnprintf(buffer, sizeof(buffer), format, va); 301 va_end(va); 302 303 if (lvl >= dbglvl) { 304 switch (dbglvl) { 305 case SWRAP_LOG_ERROR: 306 fprintf(stderr, 307 "SWRAP_ERROR(%d) - %s: %s\n", 308 (int)getpid(), func, buffer); 309 break; 310 case SWRAP_LOG_WARN: 311 fprintf(stderr, 312 "SWRAP_WARN(%d) - %s: %s\n", 313 (int)getpid(), func, buffer); 314 break; 315 case SWRAP_LOG_DEBUG: 316 fprintf(stderr, 317 "SWRAP_DEBUG(%d) - %s: %s\n", 318 (int)getpid(), func, buffer); 319 break; 320 case SWRAP_LOG_TRACE: 321 fprintf(stderr, 322 "SWRAP_TRACE(%d) - %s: %s\n", 323 (int)getpid(), func, buffer); 324 break; 325 } 326 } 327 } 328 #endif 329 330 /********************************************************* 331 * SWRAP LOADING LIBC FUNCTIONS 332 *********************************************************/ 333 334 #include <dlfcn.h> 335 336 struct swrap_libc_fns { 337 int (*libc_accept)(int sockfd, 338 struct sockaddr *addr, 339 socklen_t *addrlen); 340 int (*libc_bind)(int sockfd, 341 const struct sockaddr *addr, 342 socklen_t addrlen); 343 int (*libc_close)(int fd); 344 int (*libc_connect)(int sockfd, 345 const struct sockaddr *addr, 346 socklen_t addrlen); 347 int (*libc_dup)(int fd); 348 int (*libc_dup2)(int oldfd, int newfd); 349 int (*libc_fcntl)(int fd, int cmd, ...); 350 FILE *(*libc_fopen)(const char *name, const char *mode); 351 #ifdef HAVE_EVENTFD 352 int (*libc_eventfd)(int count, int flags); 353 #endif 354 int (*libc_getpeername)(int sockfd, 355 struct sockaddr *addr, 356 socklen_t *addrlen); 357 int (*libc_getsockname)(int sockfd, 358 struct sockaddr *addr, 359 socklen_t *addrlen); 360 int (*libc_getsockopt)(int sockfd, 361 int level, 362 int optname, 363 void *optval, 364 socklen_t *optlen); 365 int (*libc_ioctl)(int d, unsigned long int request, ...); 366 int (*libc_listen)(int sockfd, int backlog); 367 int (*libc_open)(const char *pathname, int flags, mode_t mode); 368 int (*libc_pipe)(int pipefd[2]); 369 int (*libc_read)(int fd, void *buf, size_t count); 370 ssize_t (*libc_readv)(int fd, const struct iovec *iov, int iovcnt); 371 int (*libc_recv)(int sockfd, void *buf, size_t len, int flags); 372 int (*libc_recvfrom)(int sockfd, 373 void *buf, 374 size_t len, 375 int flags, 376 struct sockaddr *src_addr, 377 socklen_t *addrlen); 378 int (*libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags); 379 int (*libc_send)(int sockfd, const void *buf, size_t len, int flags); 380 int (*libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags); 381 int (*libc_sendto)(int sockfd, 382 const void *buf, 383 size_t len, 384 int flags, 385 const struct sockaddr *dst_addr, 386 socklen_t addrlen); 387 int (*libc_setsockopt)(int sockfd, 388 int level, 389 int optname, 390 const void *optval, 391 socklen_t optlen); 392 #ifdef HAVE_SIGNALFD 393 int (*libc_signalfd)(int fd, const sigset_t *mask, int flags); 394 #endif 395 int (*libc_socket)(int domain, int type, int protocol); 396 int (*libc_socketpair)(int domain, int type, int protocol, int sv[2]); 397 #ifdef HAVE_TIMERFD_CREATE 398 int (*libc_timerfd_create)(int clockid, int flags); 399 #endif 400 ssize_t (*libc_writev)(int fd, const struct iovec *iov, int iovcnt); 401 }; 402 403 struct swrap { 404 void *libc_handle; 405 void *libsocket_handle; 406 407 bool initialised; 408 bool enabled; 409 410 char *socket_dir; 411 412 struct swrap_libc_fns fns; 413 }; 414 415 static struct swrap swrap; 416 417 /* prototypes */ 418 static const char *socket_wrapper_dir(void); 419 420 #define LIBC_NAME "libc.so" 421 422 enum swrap_lib { 423 SWRAP_LIBC, 424 SWRAP_LIBNSL, 425 SWRAP_LIBSOCKET, 426 }; 427 428 #ifndef NDEBUG 429 static const char *swrap_str_lib(enum swrap_lib lib) 430 { 431 switch (lib) { 432 case SWRAP_LIBC: 433 return "libc"; 434 case SWRAP_LIBNSL: 435 return "libnsl"; 436 case SWRAP_LIBSOCKET: 437 return "libsocket"; 438 } 439 440 /* Compiler would warn us about unhandled enum value if we get here */ 441 return "unknown"; 442 } 443 #endif 444 445 static void *swrap_load_lib_handle(enum swrap_lib lib) 446 { 447 int flags = RTLD_LAZY; 448 void *handle = NULL; 449 int i; 450 451 #ifdef RTLD_DEEPBIND 452 flags |= RTLD_DEEPBIND; 453 #endif 454 455 switch (lib) { 456 case SWRAP_LIBNSL: 457 /* FALL TROUGH */ 458 case SWRAP_LIBSOCKET: 459 #ifdef HAVE_LIBSOCKET 460 handle = swrap.libsocket_handle; 461 if (handle == NULL) { 462 for (i = 10; i >= 0; i--) { 463 char soname[256] = {0}; 464 465 snprintf(soname, sizeof(soname), "libsocket.so.%d", i); 466 handle = dlopen(soname, flags); 467 if (handle != NULL) { 468 break; 469 } 470 } 471 472 swrap.libsocket_handle = handle; 473 } 474 break; 475 #endif 476 /* FALL TROUGH */ 477 case SWRAP_LIBC: 478 handle = swrap.libc_handle; 479 #ifdef LIBC_SO 480 if (handle == NULL) { 481 handle = dlopen(LIBC_SO, flags); 482 483 swrap.libc_handle = handle; 484 } 485 #endif 486 if (handle == NULL) { 487 for (i = 10; i >= 0; i--) { 488 char soname[256] = {0}; 489 490 snprintf(soname, sizeof(soname), "libc.so.%d", i); 491 handle = dlopen(soname, flags); 492 if (handle != NULL) { 493 break; 494 } 495 } 496 497 swrap.libc_handle = handle; 498 } 499 break; 500 } 501 502 if (handle == NULL) { 503 #ifdef RTLD_NEXT 504 handle = swrap.libc_handle = swrap.libsocket_handle = RTLD_NEXT; 505 #else 506 SWRAP_LOG(SWRAP_LOG_ERROR, 507 "Failed to dlopen library: %s\n", 508 dlerror()); 509 exit(-1); 510 #endif 511 } 512 513 return handle; 514 } 515 516 static void *_swrap_load_lib_function(enum swrap_lib lib, const char *fn_name) 517 { 518 void *handle; 519 void *func; 520 521 handle = swrap_load_lib_handle(lib); 522 523 func = dlsym(handle, fn_name); 524 if (func == NULL) { 525 SWRAP_LOG(SWRAP_LOG_ERROR, 526 "Failed to find %s: %s\n", 527 fn_name, dlerror()); 528 exit(-1); 529 } 530 531 SWRAP_LOG(SWRAP_LOG_TRACE, 532 "Loaded %s from %s", 533 fn_name, swrap_str_lib(lib)); 534 return func; 535 } 536 537 #define swrap_load_lib_function(lib, fn_name) \ 538 if (swrap.fns.libc_##fn_name == NULL) { \ 539 void *swrap_cast_ptr = _swrap_load_lib_function(lib, #fn_name); \ 540 *(void **) (&swrap.fns.libc_##fn_name) = \ 541 swrap_cast_ptr; \ 542 } 543 544 545 /* 546 * IMPORTANT 547 * 548 * Functions especially from libc need to be loaded individually, you can't load 549 * all at once or gdb will segfault at startup. The same applies to valgrind and 550 * has probably something todo with with the linker. 551 * So we need load each function at the point it is called the first time. 552 */ 553 static int libc_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) 554 { 555 swrap_load_lib_function(SWRAP_LIBSOCKET, accept); 556 557 return swrap.fns.libc_accept(sockfd, addr, addrlen); 558 } 559 560 static int libc_bind(int sockfd, 561 const struct sockaddr *addr, 562 socklen_t addrlen) 563 { 564 swrap_load_lib_function(SWRAP_LIBSOCKET, bind); 565 566 return swrap.fns.libc_bind(sockfd, addr, addrlen); 567 } 568 569 static int libc_close(int fd) 570 { 571 swrap_load_lib_function(SWRAP_LIBC, close); 572 573 return swrap.fns.libc_close(fd); 574 } 575 576 static int libc_connect(int sockfd, 577 const struct sockaddr *addr, 578 socklen_t addrlen) 579 { 580 swrap_load_lib_function(SWRAP_LIBSOCKET, connect); 581 582 return swrap.fns.libc_connect(sockfd, addr, addrlen); 583 } 584 585 static int libc_dup(int fd) 586 { 587 swrap_load_lib_function(SWRAP_LIBC, dup); 588 589 return swrap.fns.libc_dup(fd); 590 } 591 592 static int libc_dup2(int oldfd, int newfd) 593 { 594 swrap_load_lib_function(SWRAP_LIBC, dup2); 595 596 return swrap.fns.libc_dup2(oldfd, newfd); 597 } 598 599 #ifdef HAVE_EVENTFD 600 static int libc_eventfd(int count, int flags) 601 { 602 swrap_load_lib_function(SWRAP_LIBC, eventfd); 603 604 return swrap.fns.libc_eventfd(count, flags); 605 } 606 #endif 607 608 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE 609 static int libc_vfcntl(int fd, int cmd, va_list ap) 610 { 611 long int args[4]; 612 int rc; 613 int i; 614 615 swrap_load_lib_function(SWRAP_LIBC, fcntl); 616 617 for (i = 0; i < 4; i++) { 618 args[i] = va_arg(ap, long int); 619 } 620 621 rc = swrap.fns.libc_fcntl(fd, 622 cmd, 623 args[0], 624 args[1], 625 args[2], 626 args[3]); 627 628 return rc; 629 } 630 631 static int libc_getpeername(int sockfd, 632 struct sockaddr *addr, 633 socklen_t *addrlen) 634 { 635 swrap_load_lib_function(SWRAP_LIBSOCKET, getpeername); 636 637 return swrap.fns.libc_getpeername(sockfd, addr, addrlen); 638 } 639 640 static int libc_getsockname(int sockfd, 641 struct sockaddr *addr, 642 socklen_t *addrlen) 643 { 644 swrap_load_lib_function(SWRAP_LIBSOCKET, getsockname); 645 646 return swrap.fns.libc_getsockname(sockfd, addr, addrlen); 647 } 648 649 static int libc_getsockopt(int sockfd, 650 int level, 651 int optname, 652 void *optval, 653 socklen_t *optlen) 654 { 655 swrap_load_lib_function(SWRAP_LIBSOCKET, getsockopt); 656 657 return swrap.fns.libc_getsockopt(sockfd, level, optname, optval, optlen); 658 } 659 660 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE 661 static int libc_vioctl(int d, unsigned long int request, va_list ap) 662 { 663 long int args[4]; 664 int rc; 665 int i; 666 667 swrap_load_lib_function(SWRAP_LIBC, ioctl); 668 669 for (i = 0; i < 4; i++) { 670 args[i] = va_arg(ap, long int); 671 } 672 673 rc = swrap.fns.libc_ioctl(d, 674 request, 675 args[0], 676 args[1], 677 args[2], 678 args[3]); 679 680 return rc; 681 } 682 683 static int libc_listen(int sockfd, int backlog) 684 { 685 swrap_load_lib_function(SWRAP_LIBSOCKET, listen); 686 687 return swrap.fns.libc_listen(sockfd, backlog); 688 } 689 690 static FILE *libc_fopen(const char *name, const char *mode) 691 { 692 swrap_load_lib_function(SWRAP_LIBC, fopen); 693 694 return swrap.fns.libc_fopen(name, mode); 695 } 696 697 static int libc_vopen(const char *pathname, int flags, va_list ap) 698 { 699 long int mode = 0; 700 int fd; 701 702 swrap_load_lib_function(SWRAP_LIBC, open); 703 704 mode = va_arg(ap, long int); 705 706 fd = swrap.fns.libc_open(pathname, flags, (mode_t)mode); 707 708 return fd; 709 } 710 711 static int libc_open(const char *pathname, int flags, ...) 712 { 713 va_list ap; 714 int fd; 715 716 va_start(ap, flags); 717 fd = libc_vopen(pathname, flags, ap); 718 va_end(ap); 719 720 return fd; 721 } 722 723 static int libc_pipe(int pipefd[2]) 724 { 725 swrap_load_lib_function(SWRAP_LIBSOCKET, pipe); 726 727 return swrap.fns.libc_pipe(pipefd); 728 } 729 730 static int libc_read(int fd, void *buf, size_t count) 731 { 732 swrap_load_lib_function(SWRAP_LIBC, read); 733 734 return swrap.fns.libc_read(fd, buf, count); 735 } 736 737 static ssize_t libc_readv(int fd, const struct iovec *iov, int iovcnt) 738 { 739 swrap_load_lib_function(SWRAP_LIBSOCKET, readv); 740 741 return swrap.fns.libc_readv(fd, iov, iovcnt); 742 } 743 744 static int libc_recv(int sockfd, void *buf, size_t len, int flags) 745 { 746 swrap_load_lib_function(SWRAP_LIBSOCKET, recv); 747 748 return swrap.fns.libc_recv(sockfd, buf, len, flags); 749 } 750 751 static int libc_recvfrom(int sockfd, 752 void *buf, 753 size_t len, 754 int flags, 755 struct sockaddr *src_addr, 756 socklen_t *addrlen) 757 { 758 swrap_load_lib_function(SWRAP_LIBSOCKET, recvfrom); 759 760 return swrap.fns.libc_recvfrom(sockfd, buf, len, flags, src_addr, addrlen); 761 } 762 763 static int libc_recvmsg(int sockfd, struct msghdr *msg, int flags) 764 { 765 swrap_load_lib_function(SWRAP_LIBSOCKET, recvmsg); 766 767 return swrap.fns.libc_recvmsg(sockfd, msg, flags); 768 } 769 770 static int libc_send(int sockfd, const void *buf, size_t len, int flags) 771 { 772 swrap_load_lib_function(SWRAP_LIBSOCKET, send); 773 774 return swrap.fns.libc_send(sockfd, buf, len, flags); 775 } 776 777 static int libc_sendmsg(int sockfd, const struct msghdr *msg, int flags) 778 { 779 swrap_load_lib_function(SWRAP_LIBSOCKET, sendmsg); 780 781 return swrap.fns.libc_sendmsg(sockfd, msg, flags); 782 } 783 784 static int libc_sendto(int sockfd, 785 const void *buf, 786 size_t len, 787 int flags, 788 const struct sockaddr *dst_addr, 789 socklen_t addrlen) 790 { 791 swrap_load_lib_function(SWRAP_LIBSOCKET, sendto); 792 793 return swrap.fns.libc_sendto(sockfd, buf, len, flags, dst_addr, addrlen); 794 } 795 796 static int libc_setsockopt(int sockfd, 797 int level, 798 int optname, 799 const void *optval, 800 socklen_t optlen) 801 { 802 swrap_load_lib_function(SWRAP_LIBSOCKET, setsockopt); 803 804 return swrap.fns.libc_setsockopt(sockfd, level, optname, optval, optlen); 805 } 806 807 #ifdef HAVE_SIGNALFD 808 static int libc_signalfd(int fd, const sigset_t *mask, int flags) 809 { 810 swrap_load_lib_function(SWRAP_LIBSOCKET, signalfd); 811 812 return swrap.fns.libc_signalfd(fd, mask, flags); 813 } 814 #endif 815 816 static int libc_socket(int domain, int type, int protocol) 817 { 818 swrap_load_lib_function(SWRAP_LIBSOCKET, socket); 819 820 return swrap.fns.libc_socket(domain, type, protocol); 821 } 822 823 static int libc_socketpair(int domain, int type, int protocol, int sv[2]) 824 { 825 swrap_load_lib_function(SWRAP_LIBSOCKET, socketpair); 826 827 return swrap.fns.libc_socketpair(domain, type, protocol, sv); 828 } 829 830 #ifdef HAVE_TIMERFD_CREATE 831 static int libc_timerfd_create(int clockid, int flags) 832 { 833 swrap_load_lib_function(SWRAP_LIBC, timerfd_create); 834 835 return swrap.fns.libc_timerfd_create(clockid, flags); 836 } 837 #endif 838 839 static ssize_t libc_writev(int fd, const struct iovec *iov, int iovcnt) 840 { 841 swrap_load_lib_function(SWRAP_LIBSOCKET, writev); 842 843 return swrap.fns.libc_writev(fd, iov, iovcnt); 844 } 845 846 /********************************************************* 847 * SWRAP HELPER FUNCTIONS 848 *********************************************************/ 849 850 #ifdef HAVE_IPV6 851 /* 852 * FD00::5357:5FXX 853 */ 854 static const struct in6_addr *swrap_ipv6(void) 855 { 856 static struct in6_addr v; 857 static int initialized; 858 int ret; 859 860 if (initialized) { 861 return &v; 862 } 863 initialized = 1; 864 865 ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v); 866 if (ret <= 0) { 867 abort(); 868 } 869 870 return &v; 871 } 872 #endif 873 874 static void set_port(int family, int prt, struct swrap_address *addr) 875 { 876 switch (family) { 877 case AF_INET: 878 addr->sa.in.sin_port = htons(prt); 879 break; 880 #ifdef HAVE_IPV6 881 case AF_INET6: 882 addr->sa.in6.sin6_port = htons(prt); 883 break; 884 #endif 885 } 886 } 887 888 static size_t socket_length(int family) 889 { 890 switch (family) { 891 case AF_INET: 892 return sizeof(struct sockaddr_in); 893 #ifdef HAVE_IPV6 894 case AF_INET6: 895 return sizeof(struct sockaddr_in6); 896 #endif 897 } 898 return 0; 899 } 900 901 static const char *socket_wrapper_dir(void) 245 902 { 246 903 const char *s = getenv("SOCKET_WRAPPER_DIR"); … … 248 905 return NULL; 249 906 } 907 /* TODO use realpath(3) here, when we add support for threads */ 250 908 if (strncmp(s, "./", 2) == 0) { 251 909 s += 2; 252 910 } 911 912 SWRAP_LOG(SWRAP_LOG_TRACE, "socket_wrapper_dir: %s", s); 253 913 return s; 254 914 } 255 915 256 unsigned int socket_wrapper_default_iface(void) 916 static unsigned int socket_wrapper_mtu(void) 917 { 918 static unsigned int max_mtu = 0; 919 unsigned int tmp; 920 const char *s; 921 char *endp; 922 923 if (max_mtu != 0) { 924 return max_mtu; 925 } 926 927 max_mtu = SOCKET_WRAPPER_MTU_DEFAULT; 928 929 s = getenv("SOCKET_WRAPPER_MTU"); 930 if (s == NULL) { 931 goto done; 932 } 933 934 tmp = strtol(s, &endp, 10); 935 if (s == endp) { 936 goto done; 937 } 938 939 if (tmp < SOCKET_WRAPPER_MTU_MIN || tmp > SOCKET_WRAPPER_MTU_MAX) { 940 goto done; 941 } 942 max_mtu = tmp; 943 944 done: 945 return max_mtu; 946 } 947 948 bool socket_wrapper_enabled(void) 949 { 950 const char *s = socket_wrapper_dir(); 951 952 return s != NULL ? true : false; 953 } 954 955 static unsigned int socket_wrapper_default_iface(void) 257 956 { 258 957 const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE"); … … 284 983 } 285 984 985 SWRAP_LOG(SWRAP_LOG_TRACE, "type %c iface %u port %u", 986 type, iface, prt); 987 286 988 if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) { 287 989 errno = EINVAL; … … 352 1054 switch (inaddr->sa_family) { 353 1055 case AF_INET: { 354 const struct sockaddr_in *in = 1056 const struct sockaddr_in *in = 355 1057 (const struct sockaddr_in *)(const void *)inaddr; 356 1058 unsigned int addr = ntohl(in->sin_addr.s_addr); … … 368 1070 b_type = SOCKET_TYPE_CHAR_UDP; 369 1071 break; 1072 default: 1073 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n"); 1074 errno = ESOCKTNOSUPPORT; 1075 return -1; 370 1076 } 371 1077 … … 395 1101 #ifdef HAVE_IPV6 396 1102 case AF_INET6: { 397 const struct sockaddr_in6 *in = 1103 const struct sockaddr_in6 *in = 398 1104 (const struct sockaddr_in6 *)(const void *)inaddr; 399 1105 struct in6_addr cmp1, cmp2; … … 406 1112 type = SOCKET_TYPE_CHAR_UDP_V6; 407 1113 break; 1114 default: 1115 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n"); 1116 errno = ESOCKTNOSUPPORT; 1117 return -1; 408 1118 } 409 1119 … … 426 1136 #endif 427 1137 default: 1138 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family!\n"); 428 1139 errno = ENETUNREACH; 429 1140 return -1; … … 431 1142 432 1143 if (prt == 0) { 1144 SWRAP_LOG(SWRAP_LOG_WARN, "Port not set\n"); 433 1145 errno = EINVAL; 434 1146 return -1; … … 436 1148 437 1149 if (is_bcast) { 438 snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL", 1150 snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL", 439 1151 socket_wrapper_dir()); 1152 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path); 440 1153 /* the caller need to do more processing */ 441 1154 return 0; 442 1155 } 443 1156 444 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 1157 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 445 1158 socket_wrapper_dir(), type, iface, prt); 1159 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path); 446 1160 447 1161 return 0; … … 461 1175 switch (si->family) { 462 1176 case AF_INET: { 463 const struct sockaddr_in *in = 1177 const struct sockaddr_in *in = 464 1178 (const struct sockaddr_in *)(const void *)inaddr; 465 1179 unsigned int addr = ntohl(in->sin_addr.s_addr); … … 482 1196 b_type = SOCKET_TYPE_CHAR_UDP; 483 1197 break; 1198 default: 1199 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n"); 1200 errno = ESOCKTNOSUPPORT; 1201 return -1; 484 1202 } 485 1203 … … 508 1226 return -1; 509 1227 } 1228 1229 /* Store the bind address for connect() */ 1230 if (si->bindname.sa_socklen == 0) { 1231 struct sockaddr_in bind_in; 1232 socklen_t blen = sizeof(struct sockaddr_in); 1233 1234 ZERO_STRUCT(bind_in); 1235 bind_in.sin_family = in->sin_family; 1236 bind_in.sin_port = in->sin_port; 1237 bind_in.sin_addr.s_addr = htonl(0x7F000000 | iface); 1238 1239 si->bindname.sa_socklen = blen; 1240 memcpy(&si->bindname.sa.in, &bind_in, blen); 1241 } 1242 510 1243 break; 511 1244 } 512 1245 #ifdef HAVE_IPV6 513 1246 case AF_INET6: { 514 const struct sockaddr_in6 *in = 1247 const struct sockaddr_in6 *in = 515 1248 (const struct sockaddr_in6 *)(const void *)inaddr; 516 1249 struct in6_addr cmp1, cmp2; … … 523 1256 type = SOCKET_TYPE_CHAR_UDP_V6; 524 1257 break; 1258 default: 1259 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n"); 1260 errno = ESOCKTNOSUPPORT; 1261 return -1; 525 1262 } 526 1263 … … 541 1278 } 542 1279 1280 /* Store the bind address for connect() */ 1281 if (si->bindname.sa_socklen == 0) { 1282 struct sockaddr_in6 bind_in; 1283 socklen_t blen = sizeof(struct sockaddr_in6); 1284 1285 ZERO_STRUCT(bind_in); 1286 bind_in.sin6_family = in->sin6_family; 1287 bind_in.sin6_port = in->sin6_port; 1288 1289 bind_in.sin6_addr = *swrap_ipv6(); 1290 bind_in.sin6_addr.s6_addr[15] = iface; 1291 1292 memcpy(&si->bindname.sa.in6, &bind_in, blen); 1293 si->bindname.sa_socklen = blen; 1294 } 1295 543 1296 break; 544 1297 } 545 1298 #endif 546 1299 default: 1300 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n"); 547 1301 errno = EADDRNOTAVAIL; 548 1302 return -1; … … 551 1305 552 1306 if (bcast) *bcast = is_bcast; 1307 1308 if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) { 1309 errno = EINVAL; 1310 return -1; 1311 } 553 1312 554 1313 if (prt == 0) { 555 1314 /* handle auto-allocation of ephemeral ports */ 556 1315 for (prt = 5001; prt < 10000; prt++) { 557 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 1316 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 558 1317 socket_wrapper_dir(), type, iface, prt); 559 1318 if (stat(un->sun_path, &st) == 0) continue; 560 1319 561 set_port(si->family, prt, si->myname); 1320 set_port(si->family, prt, &si->myname); 1321 set_port(si->family, prt, &si->bindname); 1322 562 1323 break; 563 1324 } … … 568 1329 } 569 1330 570 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 1331 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 571 1332 socket_wrapper_dir(), type, iface, prt); 1333 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path); 572 1334 return 0; 573 1335 } … … 576 1338 { 577 1339 struct socket_info *i; 1340 578 1341 for (i = sockets; i; i = i->next) { 579 if (i->fd == fd) 580 return i; 1342 struct socket_info_fd *f; 1343 for (f = i->fds; f; f = f->next) { 1344 if (f->fd == fd) { 1345 return i; 1346 } 1347 } 581 1348 } 582 1349 … … 584 1351 } 585 1352 586 static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len, 587 struct sockaddr_un *out_addr, int alloc_sock, int *bcast) 1353 #if 0 /* FIXME */ 1354 static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len) 1355 { 1356 struct socket_info *s; 1357 1358 /* first catch invalid input */ 1359 switch (sa->sa_family) { 1360 case AF_INET: 1361 if (len < sizeof(struct sockaddr_in)) { 1362 return false; 1363 } 1364 break; 1365 #if HAVE_IPV6 1366 case AF_INET6: 1367 if (len < sizeof(struct sockaddr_in6)) { 1368 return false; 1369 } 1370 break; 1371 #endif 1372 default: 1373 return false; 1374 break; 1375 } 1376 1377 for (s = sockets; s != NULL; s = s->next) { 1378 if (s->myname == NULL) { 1379 continue; 1380 } 1381 if (s->myname->sa_family != sa->sa_family) { 1382 continue; 1383 } 1384 switch (s->myname->sa_family) { 1385 case AF_INET: { 1386 struct sockaddr_in *sin1, *sin2; 1387 1388 sin1 = (struct sockaddr_in *)s->myname; 1389 sin2 = (struct sockaddr_in *)sa; 1390 1391 if (sin1->sin_addr.s_addr == htonl(INADDR_ANY)) { 1392 continue; 1393 } 1394 if (sin1->sin_port != sin2->sin_port) { 1395 continue; 1396 } 1397 if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) { 1398 continue; 1399 } 1400 1401 /* found */ 1402 return true; 1403 break; 1404 } 1405 #if HAVE_IPV6 1406 case AF_INET6: { 1407 struct sockaddr_in6 *sin1, *sin2; 1408 1409 sin1 = (struct sockaddr_in6 *)s->myname; 1410 sin2 = (struct sockaddr_in6 *)sa; 1411 1412 if (sin1->sin6_port != sin2->sin6_port) { 1413 continue; 1414 } 1415 if (!IN6_ARE_ADDR_EQUAL(&sin1->sin6_addr, 1416 &sin2->sin6_addr)) 1417 { 1418 continue; 1419 } 1420 1421 /* found */ 1422 return true; 1423 break; 1424 } 1425 #endif 1426 default: 1427 continue; 1428 break; 1429 1430 } 1431 } 1432 1433 return false; 1434 } 1435 #endif 1436 1437 static void swrap_remove_stale(int fd) 1438 { 1439 struct socket_info *si = find_socket_info(fd); 1440 struct socket_info_fd *fi; 1441 1442 if (si != NULL) { 1443 for (fi = si->fds; fi; fi = fi->next) { 1444 if (fi->fd == fd) { 1445 SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd); 1446 SWRAP_DLIST_REMOVE(si->fds, fi); 1447 free(fi); 1448 break; 1449 } 1450 } 1451 1452 if (si->fds == NULL) { 1453 SWRAP_DLIST_REMOVE(sockets, si); 1454 if (si->un_addr.sun_path[0] != '\0') { 1455 unlink(si->un_addr.sun_path); 1456 } 1457 free(si); 1458 } 1459 } 1460 } 1461 1462 static int sockaddr_convert_to_un(struct socket_info *si, 1463 const struct sockaddr *in_addr, 1464 socklen_t in_len, 1465 struct sockaddr_un *out_addr, 1466 int alloc_sock, 1467 int *bcast) 588 1468 { 589 1469 struct sockaddr *out = (struct sockaddr *)(void *)out_addr; 590 if (!out_addr) 1470 1471 (void) in_len; /* unused */ 1472 1473 if (out_addr == NULL) { 591 1474 return 0; 1475 } 592 1476 593 1477 out->sa_family = AF_UNIX; … … 597 1481 598 1482 switch (in_addr->sa_family) { 1483 case AF_UNSPEC: { 1484 const struct sockaddr_in *sin; 1485 if (si->family != AF_INET) { 1486 break; 1487 } 1488 if (in_len < sizeof(struct sockaddr_in)) { 1489 break; 1490 } 1491 sin = (const struct sockaddr_in *)(const void *)in_addr; 1492 if(sin->sin_addr.s_addr != htonl(INADDR_ANY)) { 1493 break; 1494 } 1495 1496 /* 1497 * Note: in the special case of AF_UNSPEC and INADDR_ANY, 1498 * AF_UNSPEC is mapped to AF_INET and must be treated here. 1499 */ 1500 1501 /* FALL THROUGH */ 1502 } 599 1503 case AF_INET: 600 1504 #ifdef HAVE_IPV6 … … 606 1510 break; 607 1511 default: 1512 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n"); 608 1513 errno = ESOCKTNOSUPPORT; 609 1514 return -1; … … 619 1524 620 1525 errno = EAFNOSUPPORT; 1526 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n"); 621 1527 return -1; 622 1528 } 623 1529 624 static int sockaddr_convert_from_un(const struct socket_info *si, 625 const struct sockaddr_un *in_addr, 1530 static int sockaddr_convert_from_un(const struct socket_info *si, 1531 const struct sockaddr_un *in_addr, 626 1532 socklen_t un_addrlen, 627 1533 int family, … … 631 1537 int ret; 632 1538 633 if (out_addr == NULL || out_addrlen == NULL) 1539 if (out_addr == NULL || out_addrlen == NULL) 634 1540 return 0; 635 1541 … … 649 1555 break; 650 1556 default: 1557 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n"); 651 1558 errno = ESOCKTNOSUPPORT; 652 1559 return -1; … … 661 1568 } 662 1569 1570 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n"); 663 1571 errno = EAFNOSUPPORT; 664 1572 return -1; … … 777 1685 SWRAP_PACKET_PAYLOAD_SIZE) 778 1686 779 static const char *s ocket_wrapper_pcap_file(void)1687 static const char *swrap_pcap_init_file(void) 780 1688 { 781 1689 static int initialized = 0; … … 794 1702 * TODO: don't use the structs use plain buffer offsets 795 1703 * and PUSH_U8(), PUSH_U16() and PUSH_U32() 796 * 1704 * 797 1705 * for now make sure we disable PCAP support 798 1706 * if the struct has alignment! … … 839 1747 } 840 1748 841 static uint8_t *swrap_p acket_init(struct timeval *tval,842 const struct sockaddr *src,843 const struct sockaddr *dest,844 int socket_type,845 const uint8_t *payload,846 size_t payload_len,847 unsigned long tcp_seqno,848 unsigned long tcp_ack,849 unsigned char tcp_ctl,850 int unreachable,851 size_t *_packet_len)1749 static uint8_t *swrap_pcap_packet_init(struct timeval *tval, 1750 const struct sockaddr *src, 1751 const struct sockaddr *dest, 1752 int socket_type, 1753 const uint8_t *payload, 1754 size_t payload_len, 1755 unsigned long tcp_seqno, 1756 unsigned long tcp_ack, 1757 unsigned char tcp_ctl, 1758 int unreachable, 1759 size_t *_packet_len) 852 1760 { 853 1761 uint8_t *base; … … 876 1784 switch (src->sa_family) { 877 1785 case AF_INET: 878 src_in = (const struct sockaddr_in *) src;879 dest_in = (const struct sockaddr_in *) dest;1786 src_in = (const struct sockaddr_in *)(const void *)src; 1787 dest_in = (const struct sockaddr_in *)(const void *)dest; 880 1788 src_port = src_in->sin_port; 881 1789 dest_port = dest_in->sin_port; … … 884 1792 #ifdef HAVE_IPV6 885 1793 case AF_INET6: 886 src_in6 = (const struct sockaddr_in6 *) src;887 dest_in6 = (const struct sockaddr_in6 *) dest;1794 src_in6 = (const struct sockaddr_in6 *)(const void *)src; 1795 dest_in6 = (const struct sockaddr_in6 *)(const void *)dest; 888 1796 src_port = src_in6->sin6_port; 889 1797 dest_port = dest_in6->sin6_port; … … 940 1848 941 1849 base = (uint8_t *)malloc(alloc_len); 942 if (!base) return NULL; 1850 if (base == NULL) { 1851 return NULL; 1852 } 1853 memset(base, 0x0, alloc_len); 943 1854 944 1855 buf = base; 945 1856 946 frame = (struct swrap_packet_frame *) buf;1857 frame = (struct swrap_packet_frame *)(void *)buf; 947 1858 frame->seconds = tval->tv_sec; 948 1859 frame->micro_seconds = tval->tv_usec; … … 951 1862 buf += SWRAP_PACKET_FRAME_SIZE; 952 1863 953 ip = (union swrap_packet_ip *) buf;1864 ip = (union swrap_packet_ip *)(void *)buf; 954 1865 switch (src->sa_family) { 955 1866 case AF_INET: … … 958 1869 ip->v4.packet_length = htons(wire_len - icmp_truncate_len); 959 1870 ip->v4.identification = htons(0xFFFF); 960 ip->v4.flags = 0x40; /* BIT 1 set - means don't fra qment */1871 ip->v4.flags = 0x40; /* BIT 1 set - means don't fragment */ 961 1872 ip->v4.fragment = htons(0x0000); 962 1873 ip->v4.ttl = 0xFF; … … 982 1893 983 1894 if (unreachable) { 984 pay = (union swrap_packet_payload *) buf;1895 pay = (union swrap_packet_payload *)(void *)buf; 985 1896 switch (src->sa_family) { 986 1897 case AF_INET: … … 992 1903 993 1904 /* set the ip header in the ICMP payload */ 994 ip = (union swrap_packet_ip *) buf;1905 ip = (union swrap_packet_ip *)(void *)buf; 995 1906 ip->v4.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */ 996 1907 ip->v4.tos = 0x00; 997 1908 ip->v4.packet_length = htons(wire_len - icmp_hdr_len); 998 1909 ip->v4.identification = htons(0xFFFF); 999 ip->v4.flags = 0x40; /* BIT 1 set - means don't fra qment */1910 ip->v4.flags = 0x40; /* BIT 1 set - means don't fragment */ 1000 1911 ip->v4.fragment = htons(0x0000); 1001 1912 ip->v4.ttl = 0xFF; … … 1018 1929 1019 1930 /* set the ip header in the ICMP payload */ 1020 ip = (union swrap_packet_ip *) buf;1931 ip = (union swrap_packet_ip *)(void *)buf; 1021 1932 ip->v6.ver_prio = 0x60; /* version 4 and 5 * 32 bit words */ 1022 1933 ip->v6.flow_label_high = 0x00; … … 1035 1946 } 1036 1947 1037 pay = (union swrap_packet_payload *) buf;1948 pay = (union swrap_packet_payload *)(void *)buf; 1038 1949 1039 1950 switch (socket_type) { … … 1070 1981 } 1071 1982 1072 static int swrap_ get_pcap_fd(const char *fname)1983 static int swrap_pcap_get_fd(const char *fname) 1073 1984 { 1074 1985 static int fd = -1; … … 1076 1987 if (fd != -1) return fd; 1077 1988 1078 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);1989 fd = libc_open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644); 1079 1990 if (fd != -1) { 1080 1991 struct swrap_file_hdr file_hdr; … … 1094 2005 } 1095 2006 1096 fd = open(fname, O_WRONLY|O_APPEND, 0644);2007 fd = libc_open(fname, O_WRONLY|O_APPEND, 0644); 1097 2008 1098 2009 return fd; 1099 2010 } 1100 2011 1101 static uint8_t *swrap_ marshall_packet(struct socket_info *si,1102 1103 1104 1105 2012 static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si, 2013 const struct sockaddr *addr, 2014 enum swrap_packet_type type, 2015 const void *buf, size_t len, 2016 size_t *packet_len) 1106 2017 { 1107 2018 const struct sockaddr *src_addr; … … 1129 2040 if (si->type != SOCK_STREAM) return NULL; 1130 2041 1131 src_addr = si->myname;2042 src_addr = &si->myname.sa.s; 1132 2043 dest_addr = addr; 1133 2044 … … 1143 2054 if (si->type != SOCK_STREAM) return NULL; 1144 2055 1145 dest_addr = si->myname;2056 dest_addr = &si->myname.sa.s; 1146 2057 src_addr = addr; 1147 2058 … … 1157 2068 if (si->type != SOCK_STREAM) return NULL; 1158 2069 1159 dest_addr = si->myname;1160 src_addr = addr;2070 dest_addr = &si->myname.sa.s; 2071 src_addr = addr; 1161 2072 1162 2073 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */ … … 1171 2082 if (si->type != SOCK_STREAM) return NULL; 1172 2083 1173 src_addr = si->myname;2084 src_addr = &si->myname.sa.s; 1174 2085 dest_addr = addr; 1175 2086 … … 1183 2094 if (si->type != SOCK_STREAM) return NULL; 1184 2095 1185 dest_addr = si->myname;2096 dest_addr = &si->myname.sa.s; 1186 2097 src_addr = addr; 1187 2098 … … 1197 2108 if (si->type != SOCK_STREAM) return NULL; 1198 2109 1199 src_addr = si->myname;2110 src_addr = &si->myname.sa.s; 1200 2111 dest_addr = addr; 1201 2112 … … 1211 2122 if (si->type != SOCK_STREAM) return NULL; 1212 2123 1213 dest_addr = si->myname;2124 dest_addr = &si->myname.sa.s; 1214 2125 src_addr = addr; 1215 2126 … … 1221 2132 1222 2133 case SWRAP_SEND: 1223 src_addr = si->myname;1224 dest_addr = si->peername;2134 src_addr = &si->myname.sa.s; 2135 dest_addr = &si->peername.sa.s; 1225 2136 1226 2137 tcp_seqno = si->io.pck_snd; … … 1233 2144 1234 2145 case SWRAP_SEND_RST: 1235 dest_addr = si->myname;1236 src_addr = si->peername;2146 dest_addr = &si->myname.sa.s; 2147 src_addr = &si->peername.sa.s; 1237 2148 1238 2149 if (si->type == SOCK_DGRAM) { 1239 return swrap_marshall_packet(si, si->peername, 1240 SWRAP_SENDTO_UNREACH, 1241 buf, len, packet_len); 2150 return swrap_pcap_marshall_packet(si, 2151 &si->peername.sa.s, 2152 SWRAP_SENDTO_UNREACH, 2153 buf, 2154 len, 2155 packet_len); 1242 2156 } 1243 2157 … … 1249 2163 1250 2164 case SWRAP_PENDING_RST: 1251 dest_addr = si->myname;1252 src_addr = si->peername;2165 dest_addr = &si->myname.sa.s; 2166 src_addr = &si->peername.sa.s; 1253 2167 1254 2168 if (si->type == SOCK_DGRAM) { … … 1263 2177 1264 2178 case SWRAP_RECV: 1265 dest_addr = si->myname;1266 src_addr = si->peername;2179 dest_addr = &si->myname.sa.s; 2180 src_addr = &si->peername.sa.s; 1267 2181 1268 2182 tcp_seqno = si->io.pck_rcv; … … 1275 2189 1276 2190 case SWRAP_RECV_RST: 1277 dest_addr = si->myname;1278 src_addr = si->peername;2191 dest_addr = &si->myname.sa.s; 2192 src_addr = &si->peername.sa.s; 1279 2193 1280 2194 if (si->type == SOCK_DGRAM) { … … 1289 2203 1290 2204 case SWRAP_SENDTO: 1291 src_addr = si->myname;2205 src_addr = &si->myname.sa.s; 1292 2206 dest_addr = addr; 1293 2207 … … 1297 2211 1298 2212 case SWRAP_SENDTO_UNREACH: 1299 dest_addr = si->myname;2213 dest_addr = &si->myname.sa.s; 1300 2214 src_addr = addr; 1301 2215 … … 1305 2219 1306 2220 case SWRAP_RECVFROM: 1307 dest_addr = si->myname;2221 dest_addr = &si->myname.sa.s; 1308 2222 src_addr = addr; 1309 2223 … … 1315 2229 if (si->type != SOCK_STREAM) return NULL; 1316 2230 1317 src_addr = si->myname;1318 dest_addr = si->peername;2231 src_addr = &si->myname.sa.s; 2232 dest_addr = &si->peername.sa.s; 1319 2233 1320 2234 tcp_seqno = si->io.pck_snd; … … 1329 2243 if (si->type != SOCK_STREAM) return NULL; 1330 2244 1331 dest_addr = si->myname;1332 src_addr = si->peername;2245 dest_addr = &si->myname.sa.s; 2246 src_addr = &si->peername.sa.s; 1333 2247 1334 2248 tcp_seqno = si->io.pck_rcv; … … 1343 2257 if (si->type != SOCK_STREAM) return NULL; 1344 2258 1345 src_addr = si->myname;1346 dest_addr = si->peername;2259 src_addr = &si->myname.sa.s; 2260 dest_addr = &si->peername.sa.s; 1347 2261 1348 2262 tcp_seqno = si->io.pck_snd; … … 1357 2271 swrapGetTimeOfDay(&tv); 1358 2272 1359 return swrap_packet_init(&tv, src_addr, dest_addr, si->type, 1360 (const uint8_t *)buf, len, 1361 tcp_seqno, tcp_ack, tcp_ctl, unreachable, 1362 packet_len); 1363 } 1364 1365 static void swrap_dump_packet(struct socket_info *si, 1366 const struct sockaddr *addr, 1367 enum swrap_packet_type type, 1368 const void *buf, size_t len) 2273 return swrap_pcap_packet_init(&tv, 2274 src_addr, 2275 dest_addr, 2276 si->type, 2277 (const uint8_t *)buf, 2278 len, 2279 tcp_seqno, 2280 tcp_ack, 2281 tcp_ctl, 2282 unreachable, 2283 packet_len); 2284 } 2285 2286 static void swrap_pcap_dump_packet(struct socket_info *si, 2287 const struct sockaddr *addr, 2288 enum swrap_packet_type type, 2289 const void *buf, size_t len) 1369 2290 { 1370 2291 const char *file_name; … … 1373 2294 int fd; 1374 2295 1375 file_name = s ocket_wrapper_pcap_file();2296 file_name = swrap_pcap_init_file(); 1376 2297 if (!file_name) { 1377 2298 return; 1378 2299 } 1379 2300 1380 packet = swrap_marshall_packet(si, addr, type, buf, len, &packet_len); 1381 if (!packet) { 2301 packet = swrap_pcap_marshall_packet(si, 2302 addr, 2303 type, 2304 buf, 2305 len, 2306 &packet_len); 2307 if (packet == NULL) { 1382 2308 return; 1383 2309 } 1384 2310 1385 fd = swrap_ get_pcap_fd(file_name);2311 fd = swrap_pcap_get_fd(file_name); 1386 2312 if (fd != -1) { 1387 if (write(fd, packet, packet_len) != packet_len) {2313 if (write(fd, packet, packet_len) != (ssize_t)packet_len) { 1388 2314 free(packet); 1389 2315 return; … … 1394 2320 } 1395 2321 1396 _PUBLIC_ int swrap_socket(int family, int type, int protocol) 2322 /**************************************************************************** 2323 * SIGNALFD 2324 ***************************************************************************/ 2325 2326 #ifdef HAVE_SIGNALFD 2327 static int swrap_signalfd(int fd, const sigset_t *mask, int flags) 2328 { 2329 int rc; 2330 2331 rc = libc_signalfd(fd, mask, flags); 2332 if (rc != -1) { 2333 swrap_remove_stale(fd); 2334 } 2335 2336 return rc; 2337 } 2338 2339 int signalfd(int fd, const sigset_t *mask, int flags) 2340 { 2341 return swrap_signalfd(fd, mask, flags); 2342 } 2343 #endif 2344 2345 /**************************************************************************** 2346 * SOCKET 2347 ***************************************************************************/ 2348 2349 static int swrap_socket(int family, int type, int protocol) 1397 2350 { 1398 2351 struct socket_info *si; 2352 struct socket_info_fd *fi; 1399 2353 int fd; 1400 2354 int real_type = type; 2355 2356 /* 2357 * Remove possible addition flags passed to socket() so 2358 * do not fail checking the type. 2359 * See https://lwn.net/Articles/281965/ 2360 */ 1401 2361 #ifdef SOCK_CLOEXEC 1402 2362 real_type &= ~SOCK_CLOEXEC; … … 1406 2366 #endif 1407 2367 1408 if (!socket_wrapper_ dir()) {1409 return real_socket(family, type, protocol);2368 if (!socket_wrapper_enabled()) { 2369 return libc_socket(family, type, protocol); 1410 2370 } 1411 2371 … … 1417 2377 break; 1418 2378 case AF_UNIX: 1419 return real_socket(family, type, protocol);2379 return libc_socket(family, type, protocol); 1420 2380 default: 1421 2381 errno = EAFNOSUPPORT; … … 1451 2411 } 1452 2412 1453 /* We must call real_socket with type, from the caller, not the version we removed 1454 SOCK_CLOEXEC and SOCK_NONBLOCK from */ 1455 fd = real_socket(AF_UNIX, type, 0); 1456 1457 if (fd == -1) return -1; 1458 1459 si = (struct socket_info *)calloc(1, sizeof(struct socket_info)); 2413 /* 2414 * We must call libc_socket with type, from the caller, not the version 2415 * we removed SOCK_CLOEXEC and SOCK_NONBLOCK from 2416 */ 2417 fd = libc_socket(AF_UNIX, type, 0); 2418 2419 if (fd == -1) { 2420 return -1; 2421 } 2422 2423 /* Check if we have a stale fd and remove it */ 2424 si = find_socket_info(fd); 2425 if (si != NULL) { 2426 swrap_remove_stale(fd); 2427 } 2428 2429 si = (struct socket_info *)malloc(sizeof(struct socket_info)); 2430 memset(si, 0, sizeof(struct socket_info)); 2431 if (si == NULL) { 2432 errno = ENOMEM; 2433 return -1; 2434 } 1460 2435 1461 2436 si->family = family; … … 1465 2440 si->type = real_type; 1466 2441 si->protocol = protocol; 1467 si->fd = fd; 1468 2442 2443 /* 2444 * Setup myname so getsockname() can succeed to find out the socket 2445 * type. 2446 */ 2447 switch(si->family) { 2448 case AF_INET: { 2449 struct sockaddr_in sin = { 2450 .sin_family = AF_INET, 2451 }; 2452 2453 si->myname.sa_socklen = sizeof(struct sockaddr_in); 2454 memcpy(&si->myname.sa.in, &sin, si->myname.sa_socklen); 2455 break; 2456 } 2457 case AF_INET6: { 2458 struct sockaddr_in6 sin6 = { 2459 .sin6_family = AF_INET6, 2460 }; 2461 2462 si->myname.sa_socklen = sizeof(struct sockaddr_in6); 2463 memcpy(&si->myname.sa.in6, &sin6, si->myname.sa_socklen); 2464 break; 2465 } 2466 default: 2467 free(si); 2468 errno = EINVAL; 2469 return -1; 2470 } 2471 2472 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd)); 2473 if (fi == NULL) { 2474 free(si); 2475 errno = ENOMEM; 2476 return -1; 2477 } 2478 2479 fi->fd = fd; 2480 2481 SWRAP_DLIST_ADD(si->fds, fi); 1469 2482 SWRAP_DLIST_ADD(sockets, si); 1470 2483 1471 return si->fd; 1472 } 1473 1474 _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) 2484 SWRAP_LOG(SWRAP_LOG_TRACE, 2485 "Created %s socket for protocol %s", 2486 si->family == AF_INET ? "IPv4" : "IPv6", 2487 si->type == SOCK_DGRAM ? "UDP" : "TCP"); 2488 2489 return fd; 2490 } 2491 2492 int socket(int family, int type, int protocol) 2493 { 2494 return swrap_socket(family, type, protocol); 2495 } 2496 2497 /**************************************************************************** 2498 * SOCKETPAIR 2499 ***************************************************************************/ 2500 2501 static int swrap_socketpair(int family, int type, int protocol, int sv[2]) 2502 { 2503 int rc; 2504 2505 rc = libc_socketpair(family, type, protocol, sv); 2506 if (rc != -1) { 2507 swrap_remove_stale(sv[0]); 2508 swrap_remove_stale(sv[1]); 2509 } 2510 2511 return rc; 2512 } 2513 2514 int socketpair(int family, int type, int protocol, int sv[2]) 2515 { 2516 return swrap_socketpair(family, type, protocol, sv); 2517 } 2518 2519 /**************************************************************************** 2520 * SOCKETPAIR 2521 ***************************************************************************/ 2522 2523 #ifdef HAVE_TIMERFD_CREATE 2524 static int swrap_timerfd_create(int clockid, int flags) 2525 { 2526 int fd; 2527 2528 fd = libc_timerfd_create(clockid, flags); 2529 if (fd != -1) { 2530 swrap_remove_stale(fd); 2531 } 2532 2533 return fd; 2534 } 2535 2536 int timerfd_create(int clockid, int flags) 2537 { 2538 return swrap_timerfd_create(clockid, flags); 2539 } 2540 #endif 2541 2542 /**************************************************************************** 2543 * PIPE 2544 ***************************************************************************/ 2545 2546 static int swrap_pipe(int pipefd[2]) 2547 { 2548 int rc; 2549 2550 rc = libc_pipe(pipefd); 2551 if (rc != -1) { 2552 swrap_remove_stale(pipefd[0]); 2553 swrap_remove_stale(pipefd[1]); 2554 } 2555 2556 return rc; 2557 } 2558 2559 int pipe(int pipefd[2]) 2560 { 2561 return swrap_pipe(pipefd); 2562 } 2563 2564 /**************************************************************************** 2565 * ACCEPT 2566 ***************************************************************************/ 2567 2568 static int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) 1475 2569 { 1476 2570 struct socket_info *parent_si, *child_si; 2571 struct socket_info_fd *child_fi; 1477 2572 int fd; 1478 struct sockaddr_un un_addr; 1479 socklen_t un_addrlen = sizeof(un_addr); 1480 struct sockaddr_un un_my_addr; 1481 socklen_t un_my_addrlen = sizeof(un_my_addr); 1482 struct sockaddr *my_addr; 1483 socklen_t my_addrlen, len; 2573 struct swrap_address un_addr = { 2574 .sa_socklen = sizeof(struct sockaddr_un), 2575 }; 2576 struct swrap_address un_my_addr = { 2577 .sa_socklen = sizeof(struct sockaddr_un), 2578 }; 2579 struct swrap_address in_addr = { 2580 .sa_socklen = sizeof(struct sockaddr_storage), 2581 }; 2582 struct swrap_address in_my_addr = { 2583 .sa_socklen = sizeof(struct sockaddr_storage), 2584 }; 1484 2585 int ret; 1485 2586 1486 2587 parent_si = find_socket_info(s); 1487 2588 if (!parent_si) { 1488 return real_accept(s, addr, addrlen);1489 } 1490 1491 /* 2589 return libc_accept(s, addr, addrlen); 2590 } 2591 2592 /* 1492 2593 * assume out sockaddr have the same size as the in parent 1493 2594 * socket family 1494 2595 */ 1495 my_addrlen = socket_length(parent_si->family);1496 if ( my_addrlen <= 0) {2596 in_addr.sa_socklen = socket_length(parent_si->family); 2597 if (in_addr.sa_socklen <= 0) { 1497 2598 errno = EINVAL; 1498 2599 return -1; 1499 2600 } 1500 2601 1501 my_addr = (struct sockaddr *)malloc(my_addrlen); 1502 if (my_addr == NULL) { 1503 return -1; 1504 } 1505 1506 memset(&un_addr, 0, sizeof(un_addr)); 1507 memset(&un_my_addr, 0, sizeof(un_my_addr)); 1508 1509 ret = real_accept(s, (struct sockaddr *)(void *)&un_addr, &un_addrlen); 2602 ret = libc_accept(s, &un_addr.sa.s, &un_addr.sa_socklen); 1510 2603 if (ret == -1) { 1511 free(my_addr); 2604 if (errno == ENOTSOCK) { 2605 /* Remove stale fds */ 2606 swrap_remove_stale(s); 2607 } 1512 2608 return ret; 1513 2609 } … … 1515 2611 fd = ret; 1516 2612 1517 len = my_addrlen; 1518 ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen, 1519 parent_si->family, my_addr, &len); 2613 ret = sockaddr_convert_from_un(parent_si, 2614 &un_addr.sa.un, 2615 un_addr.sa_socklen, 2616 parent_si->family, 2617 &in_addr.sa.s, 2618 &in_addr.sa_socklen); 1520 2619 if (ret == -1) { 1521 free(my_addr);1522 2620 close(fd); 1523 2621 return ret; … … 1525 2623 1526 2624 child_si = (struct socket_info *)malloc(sizeof(struct socket_info)); 1527 memset(child_si, 0, sizeof(*child_si)); 1528 1529 child_si->fd = fd; 2625 memset(child_si, 0, sizeof(struct socket_info)); 2626 2627 child_fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd)); 2628 if (child_fi == NULL) { 2629 free(child_si); 2630 close(fd); 2631 errno = ENOMEM; 2632 return -1; 2633 } 2634 2635 child_fi->fd = fd; 2636 2637 SWRAP_DLIST_ADD(child_si->fds, child_fi); 2638 1530 2639 child_si->family = parent_si->family; 1531 2640 child_si->type = parent_si->type; … … 1535 2644 child_si->connected = 1; 1536 2645 1537 child_si->peername_len = len; 1538 child_si->peername = sockaddr_dup(my_addr, len); 2646 child_si->peername = (struct swrap_address) { 2647 .sa_socklen = in_addr.sa_socklen, 2648 }; 2649 memcpy(&child_si->peername.sa.ss, &in_addr.sa.ss, in_addr.sa_socklen); 1539 2650 1540 2651 if (addr != NULL && addrlen != NULL) { 1541 size_t copy_len = MIN(*addrlen, len);2652 size_t copy_len = MIN(*addrlen, in_addr.sa_socklen); 1542 2653 if (copy_len > 0) { 1543 memcpy(addr, my_addr, copy_len); 1544 } 1545 *addrlen = len; 1546 } 1547 1548 ret = real_getsockname(fd, (struct sockaddr *)(void *)&un_my_addr, 1549 &un_my_addrlen); 2654 memcpy(addr, &in_addr.sa.ss, copy_len); 2655 } 2656 *addrlen = in_addr.sa_socklen; 2657 } 2658 2659 ret = libc_getsockname(fd, 2660 &un_my_addr.sa.s, 2661 &un_my_addr.sa_socklen); 1550 2662 if (ret == -1) { 2663 free(child_fi); 1551 2664 free(child_si); 1552 2665 close(fd); … … 1554 2667 } 1555 2668 1556 len = my_addrlen; 1557 ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen, 1558 child_si->family, my_addr, &len); 2669 ret = sockaddr_convert_from_un(child_si, 2670 &un_my_addr.sa.un, 2671 un_my_addr.sa_socklen, 2672 child_si->family, 2673 &in_my_addr.sa.s, 2674 &in_my_addr.sa_socklen); 1559 2675 if (ret == -1) { 2676 free(child_fi); 1560 2677 free(child_si); 1561 free(my_addr);1562 2678 close(fd); 1563 2679 return ret; 1564 2680 } 1565 2681 1566 child_si->myname_len = len; 1567 child_si->myname = sockaddr_dup(my_addr, len); 1568 free(my_addr); 2682 SWRAP_LOG(SWRAP_LOG_TRACE, 2683 "accept() path=%s, fd=%d", 2684 un_my_addr.sa.un.sun_path, s); 2685 2686 child_si->myname = (struct swrap_address) { 2687 .sa_socklen = in_my_addr.sa_socklen, 2688 }; 2689 memcpy(&child_si->myname.sa.ss, &in_my_addr.sa.ss, in_my_addr.sa_socklen); 1569 2690 1570 2691 SWRAP_DLIST_ADD(sockets, child_si); 1571 2692 1572 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0); 1573 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0); 1574 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0); 2693 if (addr != NULL) { 2694 swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0); 2695 swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0); 2696 swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0); 2697 } 1575 2698 1576 2699 return fd; 2700 } 2701 2702 #ifdef HAVE_ACCEPT_PSOCKLEN_T 2703 int accept(int s, struct sockaddr *addr, Psocklen_t addrlen) 2704 #else 2705 int accept(int s, struct sockaddr *addr, socklen_t *addrlen) 2706 #endif 2707 { 2708 return swrap_accept(s, addr, (socklen_t *)addrlen); 1577 2709 } 1578 2710 … … 1582 2714 /* using sendto() or connect() on an unbound socket would give the 1583 2715 recipient no way to reply, as unlike UDP and TCP, a unix domain 1584 socket can't auto-assign e mphemeral port numbers, so we need to2716 socket can't auto-assign ephemeral port numbers, so we need to 1585 2717 assign it here. 1586 2718 Note: this might change the family from ipv6 to ipv4 1587 2719 */ 1588 static int swrap_auto_bind(struct socket_info *si, int family) 1589 { 1590 struct sockaddr_un un_addr; 2720 static int swrap_auto_bind(int fd, struct socket_info *si, int family) 2721 { 2722 struct swrap_address un_addr = { 2723 .sa_socklen = sizeof(struct sockaddr_un), 2724 }; 1591 2725 int i; 1592 2726 char type; … … 1602 2736 } 1603 2737 1604 un_addr.s un_family = AF_UNIX;2738 un_addr.sa.un.sun_family = AF_UNIX; 1605 2739 1606 2740 switch (family) { … … 1613 2747 break; 1614 2748 case SOCK_DGRAM: 1615 2749 type = SOCKET_TYPE_CHAR_UDP; 1616 2750 break; 1617 2751 default: … … 1622 2756 memset(&in, 0, sizeof(in)); 1623 2757 in.sin_family = AF_INET; 1624 in.sin_addr.s_addr = htonl(127<<24 | 2758 in.sin_addr.s_addr = htonl(127<<24 | 1625 2759 socket_wrapper_default_iface()); 1626 2760 1627 si->myname_len = sizeof(in); 1628 si->myname = sockaddr_dup(&in, si->myname_len); 2761 si->myname = (struct swrap_address) { 2762 .sa_socklen = sizeof(in), 2763 }; 2764 memcpy(&si->myname.sa.in, &in, si->myname.sa_socklen); 1629 2765 break; 1630 2766 } … … 1643 2779 break; 1644 2780 case SOCK_DGRAM: 1645 2781 type = SOCKET_TYPE_CHAR_UDP_V6; 1646 2782 break; 1647 2783 default: … … 1654 2790 in6.sin6_addr = *swrap_ipv6(); 1655 2791 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface(); 1656 si->myname_len = sizeof(in6); 1657 si->myname = sockaddr_dup(&in6, si->myname_len); 2792 2793 si->myname = (struct swrap_address) { 2794 .sa_socklen = sizeof(in6), 2795 }; 2796 memcpy(&si->myname.sa.in6, &in6, si->myname.sa_socklen); 1658 2797 break; 1659 2798 } … … 1668 2807 } 1669 2808 1670 for (i =0;i<1000;i++) {2809 for (i = 0; i < SOCKET_MAX_SOCKETS; i++) { 1671 2810 port = autobind_start + i; 1672 snprintf(un_addr.s un_path, sizeof(un_addr.sun_path),2811 snprintf(un_addr.sa.un.sun_path, sizeof(un_addr.sa.un.sun_path), 1673 2812 "%s/"SOCKET_FORMAT, socket_wrapper_dir(), 1674 2813 type, socket_wrapper_default_iface(), port); 1675 if (stat(un_addr.sun_path, &st) == 0) continue; 1676 1677 ret = real_bind(si->fd, (struct sockaddr *)(void *)&un_addr, 1678 sizeof(un_addr)); 2814 if (stat(un_addr.sa.un.sun_path, &st) == 0) continue; 2815 2816 ret = libc_bind(fd, &un_addr.sa.s, un_addr.sa_socklen); 1679 2817 if (ret == -1) return ret; 1680 2818 1681 si->tmp_path = strdup(un_addr.sun_path); 2819 si->un_addr = un_addr.sa.un; 2820 1682 2821 si->bound = 1; 1683 2822 autobind_start = port + 1; 1684 2823 break; 1685 2824 } 1686 if (i == 1000) { 2825 if (i == SOCKET_MAX_SOCKETS) { 2826 SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for " 2827 "interface "SOCKET_FORMAT, 2828 SOCKET_MAX_SOCKETS, 2829 type, 2830 socket_wrapper_default_iface(), 2831 0); 1687 2832 errno = ENFILE; 1688 2833 return -1; … … 1690 2835 1691 2836 si->family = family; 1692 set_port(si->family, port, si->myname);2837 set_port(si->family, port, &si->myname); 1693 2838 1694 2839 return 0; 1695 2840 } 1696 2841 1697 1698 _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) 2842 /**************************************************************************** 2843 * CONNECT 2844 ***************************************************************************/ 2845 2846 static int swrap_connect(int s, const struct sockaddr *serv_addr, 2847 socklen_t addrlen) 1699 2848 { 1700 2849 int ret; 1701 struct sockaddr_un un_addr; 2850 struct swrap_address un_addr = { 2851 .sa_socklen = sizeof(struct sockaddr_un), 2852 }; 1702 2853 struct socket_info *si = find_socket_info(s); 1703 2854 int bcast = 0; 1704 2855 1705 2856 if (!si) { 1706 return real_connect(s, serv_addr, addrlen);2857 return libc_connect(s, serv_addr, addrlen); 1707 2858 } 1708 2859 1709 2860 if (si->bound == 0) { 1710 ret = swrap_auto_bind(s i, serv_addr->sa_family);2861 ret = swrap_auto_bind(s, si, serv_addr->sa_family); 1711 2862 if (ret == -1) return -1; 1712 2863 } … … 1718 2869 1719 2870 ret = sockaddr_convert_to_un(si, serv_addr, 1720 addrlen, &un_addr , 0, &bcast);2871 addrlen, &un_addr.sa.un, 0, &bcast); 1721 2872 if (ret == -1) return -1; 1722 2873 … … 1730 2881 ret = 0; 1731 2882 } else { 1732 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0); 1733 1734 ret = real_connect(s, (struct sockaddr *)(void *)&un_addr, 1735 sizeof(struct sockaddr_un)); 1736 } 2883 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0); 2884 2885 ret = libc_connect(s, 2886 &un_addr.sa.s, 2887 un_addr.sa_socklen); 2888 } 2889 2890 SWRAP_LOG(SWRAP_LOG_TRACE, 2891 "connect() path=%s, fd=%d", 2892 un_addr.sa.un.sun_path, s); 2893 1737 2894 1738 2895 /* to give better errors */ … … 1742 2899 1743 2900 if (ret == 0) { 1744 si->peername_len = addrlen; 1745 si->peername = sockaddr_dup(serv_addr, addrlen); 2901 si->peername = (struct swrap_address) { 2902 .sa_socklen = addrlen, 2903 }; 2904 2905 memcpy(&si->peername.sa.ss, serv_addr, addrlen); 1746 2906 si->connected = 1; 1747 2907 1748 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0); 1749 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0); 2908 /* 2909 * When we connect() on a socket than we have to bind the 2910 * outgoing connection on the interface we use for the 2911 * transport. We already bound it on the right interface 2912 * but here we have to update the name so getsockname() 2913 * returns correct information. 2914 */ 2915 if (si->bindname.sa_socklen > 0) { 2916 si->myname = (struct swrap_address) { 2917 .sa_socklen = si->bindname.sa_socklen, 2918 }; 2919 2920 memcpy(&si->myname.sa.ss, 2921 &si->bindname.sa.ss, 2922 si->bindname.sa_socklen); 2923 2924 /* Cleanup bindname */ 2925 si->bindname = (struct swrap_address) { 2926 .sa_socklen = 0, 2927 }; 2928 } 2929 2930 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0); 2931 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0); 1750 2932 } else { 1751 swrap_ dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);2933 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0); 1752 2934 } 1753 2935 … … 1755 2937 } 1756 2938 1757 _PUBLIC_ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) 2939 int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) 2940 { 2941 return swrap_connect(s, serv_addr, addrlen); 2942 } 2943 2944 /**************************************************************************** 2945 * BIND 2946 ***************************************************************************/ 2947 2948 static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) 1758 2949 { 1759 2950 int ret; 1760 struct sockaddr_un un_addr; 2951 struct swrap_address un_addr = { 2952 .sa_socklen = sizeof(struct sockaddr_un), 2953 }; 1761 2954 struct socket_info *si = find_socket_info(s); 2955 int bind_error = 0; 2956 #if 0 /* FIXME */ 2957 bool in_use; 2958 #endif 1762 2959 1763 2960 if (!si) { 1764 return real_bind(s, myaddr, addrlen); 1765 } 1766 1767 si->myname_len = addrlen; 1768 si->myname = sockaddr_dup(myaddr, addrlen); 1769 1770 ret = sockaddr_convert_to_un(si, myaddr, addrlen, &un_addr, 1, &si->bcast); 2961 return libc_bind(s, myaddr, addrlen); 2962 } 2963 2964 switch (si->family) { 2965 case AF_INET: { 2966 const struct sockaddr_in *sin; 2967 if (addrlen < sizeof(struct sockaddr_in)) { 2968 bind_error = EINVAL; 2969 break; 2970 } 2971 2972 sin = (const struct sockaddr_in *)(const void *)myaddr; 2973 2974 if (sin->sin_family != AF_INET) { 2975 bind_error = EAFNOSUPPORT; 2976 } 2977 2978 /* special case for AF_UNSPEC */ 2979 if (sin->sin_family == AF_UNSPEC && 2980 (sin->sin_addr.s_addr == htonl(INADDR_ANY))) 2981 { 2982 bind_error = 0; 2983 } 2984 2985 break; 2986 } 2987 #ifdef HAVE_IPV6 2988 case AF_INET6: { 2989 const struct sockaddr_in6 *sin6; 2990 if (addrlen < sizeof(struct sockaddr_in6)) { 2991 bind_error = EINVAL; 2992 break; 2993 } 2994 2995 sin6 = (const struct sockaddr_in6 *)(const void *)myaddr; 2996 2997 if (sin6->sin6_family != AF_INET6) { 2998 bind_error = EAFNOSUPPORT; 2999 } 3000 3001 break; 3002 } 3003 #endif 3004 default: 3005 bind_error = EINVAL; 3006 break; 3007 } 3008 3009 if (bind_error != 0) { 3010 errno = bind_error; 3011 return -1; 3012 } 3013 3014 #if 0 /* FIXME */ 3015 in_use = check_addr_port_in_use(myaddr, addrlen); 3016 if (in_use) { 3017 errno = EADDRINUSE; 3018 return -1; 3019 } 3020 #endif 3021 3022 si->myname.sa_socklen = addrlen; 3023 memcpy(&si->myname.sa.ss, myaddr, addrlen); 3024 3025 ret = sockaddr_convert_to_un(si, 3026 myaddr, 3027 addrlen, 3028 &un_addr.sa.un, 3029 1, 3030 &si->bcast); 1771 3031 if (ret == -1) return -1; 1772 3032 1773 unlink(un_addr.sun_path); 1774 1775 ret = real_bind(s, (struct sockaddr *)(void *)&un_addr, 1776 sizeof(struct sockaddr_un)); 3033 unlink(un_addr.sa.un.sun_path); 3034 3035 ret = libc_bind(s, &un_addr.sa.s, un_addr.sa_socklen); 3036 3037 SWRAP_LOG(SWRAP_LOG_TRACE, 3038 "bind() path=%s, fd=%d", 3039 un_addr.sa.un.sun_path, s); 1777 3040 1778 3041 if (ret == 0) { … … 1783 3046 } 1784 3047 1785 _PUBLIC_ int swrap_listen(int s, int backlog) 3048 int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) 3049 { 3050 return swrap_bind(s, myaddr, addrlen); 3051 } 3052 3053 /**************************************************************************** 3054 * BINDRESVPORT 3055 ***************************************************************************/ 3056 3057 #ifdef HAVE_BINDRESVPORT 3058 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen); 3059 3060 static int swrap_bindresvport_sa(int sd, struct sockaddr *sa) 3061 { 3062 struct swrap_address myaddr = { 3063 .sa_socklen = sizeof(struct sockaddr_storage), 3064 }; 3065 socklen_t salen; 3066 static uint16_t port; 3067 uint16_t i; 3068 int rc = -1; 3069 int af; 3070 3071 #define SWRAP_STARTPORT 600 3072 #define SWRAP_ENDPORT (IPPORT_RESERVED - 1) 3073 #define SWRAP_NPORTS (SWRAP_ENDPORT - SWRAP_STARTPORT + 1) 3074 3075 if (port == 0) { 3076 port = (getpid() % SWRAP_NPORTS) + SWRAP_STARTPORT; 3077 } 3078 3079 if (sa == NULL) { 3080 salen = myaddr.sa_socklen; 3081 sa = &myaddr.sa.s; 3082 3083 rc = swrap_getsockname(sd, &myaddr.sa.s, &salen); 3084 if (rc < 0) { 3085 return -1; 3086 } 3087 3088 af = sa->sa_family; 3089 memset(&myaddr.sa.ss, 0, salen); 3090 } else { 3091 af = sa->sa_family; 3092 } 3093 3094 for (i = 0; i < SWRAP_NPORTS; i++, port++) { 3095 switch(af) { 3096 case AF_INET: { 3097 struct sockaddr_in *sinp = (struct sockaddr_in *)(void *)sa; 3098 3099 salen = sizeof(struct sockaddr_in); 3100 sinp->sin_port = htons(port); 3101 break; 3102 } 3103 case AF_INET6: { 3104 struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *)(void *)sa; 3105 3106 salen = sizeof(struct sockaddr_in6); 3107 sin6p->sin6_port = htons(port); 3108 break; 3109 } 3110 default: 3111 errno = EAFNOSUPPORT; 3112 return -1; 3113 } 3114 sa->sa_family = af; 3115 3116 if (port > SWRAP_ENDPORT) { 3117 port = SWRAP_STARTPORT; 3118 } 3119 3120 rc = swrap_bind(sd, (struct sockaddr *)sa, salen); 3121 if (rc == 0 || errno != EADDRINUSE) { 3122 break; 3123 } 3124 } 3125 3126 return rc; 3127 } 3128 3129 int bindresvport(int sockfd, struct sockaddr_in *sinp) 3130 { 3131 return swrap_bindresvport_sa(sockfd, (struct sockaddr *)sinp); 3132 } 3133 #endif 3134 3135 /**************************************************************************** 3136 * LISTEN 3137 ***************************************************************************/ 3138 3139 static int swrap_listen(int s, int backlog) 1786 3140 { 1787 3141 int ret; … … 1789 3143 1790 3144 if (!si) { 1791 return real_listen(s, backlog);1792 } 1793 1794 ret = real_listen(s, backlog);3145 return libc_listen(s, backlog); 3146 } 3147 3148 ret = libc_listen(s, backlog); 1795 3149 1796 3150 return ret; 1797 3151 } 1798 3152 1799 _PUBLIC_ int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen) 3153 int listen(int s, int backlog) 3154 { 3155 return swrap_listen(s, backlog); 3156 } 3157 3158 /**************************************************************************** 3159 * FOPEN 3160 ***************************************************************************/ 3161 3162 static FILE *swrap_fopen(const char *name, const char *mode) 3163 { 3164 FILE *fp; 3165 3166 fp = libc_fopen(name, mode); 3167 if (fp != NULL) { 3168 int fd = fileno(fp); 3169 3170 swrap_remove_stale(fd); 3171 } 3172 3173 return fp; 3174 } 3175 3176 FILE *fopen(const char *name, const char *mode) 3177 { 3178 return swrap_fopen(name, mode); 3179 } 3180 3181 /**************************************************************************** 3182 * OPEN 3183 ***************************************************************************/ 3184 3185 static int swrap_vopen(const char *pathname, int flags, va_list ap) 3186 { 3187 int ret; 3188 3189 ret = libc_vopen(pathname, flags, ap); 3190 if (ret != -1) { 3191 /* 3192 * There are methods for closing descriptors (libc-internal code 3193 * paths, direct syscalls) which close descriptors in ways that 3194 * we can't intercept, so try to recover when we notice that 3195 * that's happened 3196 */ 3197 swrap_remove_stale(ret); 3198 } 3199 return ret; 3200 } 3201 3202 int open(const char *pathname, int flags, ...) 3203 { 3204 va_list ap; 3205 int fd; 3206 3207 va_start(ap, flags); 3208 fd = swrap_vopen(pathname, flags, ap); 3209 va_end(ap); 3210 3211 return fd; 3212 } 3213 3214 /**************************************************************************** 3215 * GETPEERNAME 3216 ***************************************************************************/ 3217 3218 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen) 1800 3219 { 1801 3220 struct socket_info *si = find_socket_info(s); 3221 socklen_t len; 1802 3222 1803 3223 if (!si) { 1804 return real_getpeername(s, name, addrlen);1805 } 1806 1807 if ( !si->peername)3224 return libc_getpeername(s, name, addrlen); 3225 } 3226 3227 if (si->peername.sa_socklen == 0) 1808 3228 { 1809 3229 errno = ENOTCONN; … … 1811 3231 } 1812 3232 1813 memcpy(name, si->peername, si->peername_len); 1814 *addrlen = si->peername_len; 3233 len = MIN(*addrlen, si->peername.sa_socklen); 3234 if (len == 0) { 3235 return 0; 3236 } 3237 3238 memcpy(name, &si->peername.sa.ss, len); 3239 *addrlen = si->peername.sa_socklen; 1815 3240 1816 3241 return 0; 1817 3242 } 1818 3243 1819 _PUBLIC_ int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen) 3244 #ifdef HAVE_ACCEPT_PSOCKLEN_T 3245 int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen) 3246 #else 3247 int getpeername(int s, struct sockaddr *name, socklen_t *addrlen) 3248 #endif 3249 { 3250 return swrap_getpeername(s, name, (socklen_t *)addrlen); 3251 } 3252 3253 /**************************************************************************** 3254 * GETSOCKNAME 3255 ***************************************************************************/ 3256 3257 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen) 1820 3258 { 1821 3259 struct socket_info *si = find_socket_info(s); 3260 socklen_t len; 1822 3261 1823 3262 if (!si) { 1824 return real_getsockname(s, name, addrlen); 1825 } 1826 1827 memcpy(name, si->myname, si->myname_len); 1828 *addrlen = si->myname_len; 3263 return libc_getsockname(s, name, addrlen); 3264 } 3265 3266 len = MIN(*addrlen, si->myname.sa_socklen); 3267 if (len == 0) { 3268 return 0; 3269 } 3270 3271 memcpy(name, &si->myname.sa.ss, len); 3272 *addrlen = si->myname.sa_socklen; 1829 3273 1830 3274 return 0; 1831 3275 } 1832 3276 1833 _PUBLIC_ int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) 3277 #ifdef HAVE_ACCEPT_PSOCKLEN_T 3278 int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen) 3279 #else 3280 int getsockname(int s, struct sockaddr *name, socklen_t *addrlen) 3281 #endif 3282 { 3283 return swrap_getsockname(s, name, (socklen_t *)addrlen); 3284 } 3285 3286 /**************************************************************************** 3287 * GETSOCKOPT 3288 ***************************************************************************/ 3289 3290 #ifndef SO_PROTOCOL 3291 # ifdef SO_PROTOTYPE /* The Solaris name */ 3292 # define SO_PROTOCOL SO_PROTOTYPE 3293 # endif /* SO_PROTOTYPE */ 3294 #endif /* SO_PROTOCOL */ 3295 3296 static int swrap_getsockopt(int s, int level, int optname, 3297 void *optval, socklen_t *optlen) 1834 3298 { 1835 3299 struct socket_info *si = find_socket_info(s); 1836 3300 1837 3301 if (!si) { 1838 return real_getsockopt(s, level, optname, optval, optlen); 3302 return libc_getsockopt(s, 3303 level, 3304 optname, 3305 optval, 3306 optlen); 1839 3307 } 1840 3308 1841 3309 if (level == SOL_SOCKET) { 1842 return real_getsockopt(s, level, optname, optval, optlen); 1843 } 3310 switch (optname) { 3311 #ifdef SO_DOMAIN 3312 case SO_DOMAIN: 3313 if (optval == NULL || optlen == NULL || 3314 *optlen < (socklen_t)sizeof(int)) { 3315 errno = EINVAL; 3316 return -1; 3317 } 3318 3319 *optlen = sizeof(int); 3320 *(int *)optval = si->family; 3321 return 0; 3322 #endif /* SO_DOMAIN */ 3323 3324 #ifdef SO_PROTOCOL 3325 case SO_PROTOCOL: 3326 if (optval == NULL || optlen == NULL || 3327 *optlen < (socklen_t)sizeof(int)) { 3328 errno = EINVAL; 3329 return -1; 3330 } 3331 3332 *optlen = sizeof(int); 3333 *(int *)optval = si->protocol; 3334 return 0; 3335 #endif /* SO_PROTOCOL */ 3336 case SO_TYPE: 3337 if (optval == NULL || optlen == NULL || 3338 *optlen < (socklen_t)sizeof(int)) { 3339 errno = EINVAL; 3340 return -1; 3341 } 3342 3343 *optlen = sizeof(int); 3344 *(int *)optval = si->type; 3345 return 0; 3346 default: 3347 return libc_getsockopt(s, 3348 level, 3349 optname, 3350 optval, 3351 optlen); 3352 } 3353 } 1844 3354 1845 3355 errno = ENOPROTOOPT; … … 1847 3357 } 1848 3358 1849 _PUBLIC_ int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) 3359 #ifdef HAVE_ACCEPT_PSOCKLEN_T 3360 int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen) 3361 #else 3362 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) 3363 #endif 3364 { 3365 return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen); 3366 } 3367 3368 /**************************************************************************** 3369 * SETSOCKOPT 3370 ***************************************************************************/ 3371 3372 static int swrap_setsockopt(int s, int level, int optname, 3373 const void *optval, socklen_t optlen) 1850 3374 { 1851 3375 struct socket_info *si = find_socket_info(s); 1852 3376 1853 3377 if (!si) { 1854 return real_setsockopt(s, level, optname, optval, optlen); 3378 return libc_setsockopt(s, 3379 level, 3380 optname, 3381 optval, 3382 optlen); 1855 3383 } 1856 3384 1857 3385 if (level == SOL_SOCKET) { 1858 return real_setsockopt(s, level, optname, optval, optlen); 3386 return libc_setsockopt(s, 3387 level, 3388 optname, 3389 optval, 3390 optlen); 1859 3391 } 1860 3392 1861 3393 switch (si->family) { 1862 3394 case AF_INET: 3395 if (level == IPPROTO_IP) { 3396 #ifdef IP_PKTINFO 3397 if (optname == IP_PKTINFO) { 3398 si->pktinfo = AF_INET; 3399 } 3400 #endif /* IP_PKTINFO */ 3401 } 1863 3402 return 0; 1864 3403 #ifdef HAVE_IPV6 1865 3404 case AF_INET6: 3405 if (level == IPPROTO_IPV6) { 3406 #ifdef IPV6_RECVPKTINFO 3407 if (optname == IPV6_RECVPKTINFO) { 3408 si->pktinfo = AF_INET6; 3409 } 3410 #endif /* IPV6_PKTINFO */ 3411 } 1866 3412 return 0; 1867 3413 #endif … … 1872 3418 } 1873 3419 1874 _PUBLIC_ int swrap_ioctl(int s, int r, void *p) 1875 { 1876 int ret; 3420 int setsockopt(int s, int level, int optname, 3421 const void *optval, socklen_t optlen) 3422 { 3423 return swrap_setsockopt(s, level, optname, optval, optlen); 3424 } 3425 3426 /**************************************************************************** 3427 * IOCTL 3428 ***************************************************************************/ 3429 3430 static int swrap_vioctl(int s, unsigned long int r, va_list va) 3431 { 1877 3432 struct socket_info *si = find_socket_info(s); 3433 va_list ap; 1878 3434 int value; 3435 int rc; 1879 3436 1880 3437 if (!si) { 1881 return real_ioctl(s, r, p); 1882 } 1883 1884 ret = real_ioctl(s, r, p); 3438 return libc_vioctl(s, r, va); 3439 } 3440 3441 va_copy(ap, va); 3442 3443 rc = libc_vioctl(s, r, va); 1885 3444 1886 3445 switch (r) { 1887 3446 case FIONREAD: 1888 value = *((int *)p); 1889 if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) { 1890 swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0); 3447 value = *((int *)va_arg(ap, int *)); 3448 3449 if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) { 3450 swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0); 1891 3451 } else if (value == 0) { /* END OF FILE */ 1892 swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0); 1893 } 1894 break; 1895 } 1896 1897 return ret; 1898 } 1899 1900 static ssize_t swrap_sendmsg_before(struct socket_info *si, 3452 swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0); 3453 } 3454 break; 3455 } 3456 3457 va_end(ap); 3458 3459 return rc; 3460 } 3461 3462 #ifdef HAVE_IOCTL_INT 3463 int ioctl(int s, int r, ...) 3464 #else 3465 int ioctl(int s, unsigned long int r, ...) 3466 #endif 3467 { 3468 va_list va; 3469 int rc; 3470 3471 va_start(va, r); 3472 3473 rc = swrap_vioctl(s, (unsigned long int) r, va); 3474 3475 va_end(va); 3476 3477 return rc; 3478 } 3479 3480 /***************** 3481 * CMSG 3482 *****************/ 3483 3484 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 3485 3486 #ifndef CMSG_ALIGN 3487 # ifdef _ALIGN /* BSD */ 3488 #define CMSG_ALIGN _ALIGN 3489 # else 3490 #define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1)) 3491 # endif /* _ALIGN */ 3492 #endif /* CMSG_ALIGN */ 3493 3494 /** 3495 * @brief Add a cmsghdr to a msghdr. 3496 * 3497 * This is an function to add any type of cmsghdr. It will operate on the 3498 * msg->msg_control and msg->msg_controllen you pass in by adapting them to 3499 * the buffer position after the added cmsg element. Hence, this function is 3500 * intended to be used with an intermediate msghdr and not on the original 3501 * one handed in by the client. 3502 * 3503 * @param[in] msg The msghdr to which to add the cmsg. 3504 * 3505 * @param[in] level The cmsg level to set. 3506 * 3507 * @param[in] type The cmsg type to set. 3508 * 3509 * @param[in] data The cmsg data to set. 3510 * 3511 * @param[in] len the length of the data to set. 3512 */ 3513 static void swrap_msghdr_add_cmsghdr(struct msghdr *msg, 3514 int level, 3515 int type, 3516 const void *data, 3517 size_t len) 3518 { 3519 size_t cmlen = CMSG_LEN(len); 3520 size_t cmspace = CMSG_SPACE(len); 3521 uint8_t cmbuf[cmspace]; 3522 void *cast_ptr = (void *)cmbuf; 3523 struct cmsghdr *cm = (struct cmsghdr *)cast_ptr; 3524 uint8_t *p; 3525 3526 memset(cmbuf, 0, cmspace); 3527 3528 if (msg->msg_controllen < cmlen) { 3529 cmlen = msg->msg_controllen; 3530 msg->msg_flags |= MSG_CTRUNC; 3531 } 3532 3533 if (msg->msg_controllen < cmspace) { 3534 cmspace = msg->msg_controllen; 3535 } 3536 3537 /* 3538 * We copy the full input data into an intermediate cmsghdr first 3539 * in order to more easily cope with truncation. 3540 */ 3541 cm->cmsg_len = cmlen; 3542 cm->cmsg_level = level; 3543 cm->cmsg_type = type; 3544 memcpy(CMSG_DATA(cm), data, len); 3545 3546 /* 3547 * We now copy the possibly truncated buffer. 3548 * We copy cmlen bytes, but consume cmspace bytes, 3549 * leaving the possible padding uninitialiazed. 3550 */ 3551 p = (uint8_t *)msg->msg_control; 3552 memcpy(p, cm, cmlen); 3553 p += cmspace; 3554 msg->msg_control = p; 3555 msg->msg_controllen -= cmspace; 3556 3557 return; 3558 } 3559 3560 static int swrap_msghdr_add_pktinfo(struct socket_info *si, 3561 struct msghdr *msg) 3562 { 3563 /* Add packet info */ 3564 switch (si->pktinfo) { 3565 #if defined(IP_PKTINFO) && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR)) 3566 case AF_INET: { 3567 struct sockaddr_in *sin; 3568 #if defined(HAVE_STRUCT_IN_PKTINFO) 3569 struct in_pktinfo pkt; 3570 #elif defined(IP_RECVDSTADDR) 3571 struct in_addr pkt; 3572 #endif 3573 3574 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in)) { 3575 sin = &si->bindname.sa.in; 3576 } else { 3577 if (si->myname.sa_socklen != sizeof(struct sockaddr_in)) { 3578 return 0; 3579 } 3580 sin = &si->myname.sa.in; 3581 } 3582 3583 ZERO_STRUCT(pkt); 3584 3585 #if defined(HAVE_STRUCT_IN_PKTINFO) 3586 pkt.ipi_ifindex = socket_wrapper_default_iface(); 3587 pkt.ipi_addr.s_addr = sin->sin_addr.s_addr; 3588 #elif defined(IP_RECVDSTADDR) 3589 pkt = sin->sin_addr; 3590 #endif 3591 3592 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IP, IP_PKTINFO, 3593 &pkt, sizeof(pkt)); 3594 3595 break; 3596 } 3597 #endif /* IP_PKTINFO */ 3598 #if defined(HAVE_IPV6) 3599 case AF_INET6: { 3600 #if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO) 3601 struct sockaddr_in6 *sin6; 3602 struct in6_pktinfo pkt6; 3603 3604 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in6)) { 3605 sin6 = &si->bindname.sa.in6; 3606 } else { 3607 if (si->myname.sa_socklen != sizeof(struct sockaddr_in6)) { 3608 return 0; 3609 } 3610 sin6 = &si->myname.sa.in6; 3611 } 3612 3613 ZERO_STRUCT(pkt6); 3614 3615 pkt6.ipi6_ifindex = socket_wrapper_default_iface(); 3616 pkt6.ipi6_addr = sin6->sin6_addr; 3617 3618 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IPV6, IPV6_PKTINFO, 3619 &pkt6, sizeof(pkt6)); 3620 #endif /* HAVE_STRUCT_IN6_PKTINFO */ 3621 3622 break; 3623 } 3624 #endif /* IPV6_PKTINFO */ 3625 default: 3626 return -1; 3627 } 3628 3629 return 0; 3630 } 3631 3632 static int swrap_msghdr_add_socket_info(struct socket_info *si, 3633 struct msghdr *omsg) 3634 { 3635 int rc = 0; 3636 3637 if (si->pktinfo > 0) { 3638 rc = swrap_msghdr_add_pktinfo(si, omsg); 3639 } 3640 3641 return rc; 3642 } 3643 3644 static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg, 3645 uint8_t **cm_data, 3646 size_t *cm_data_space); 3647 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg, 3648 uint8_t **cm_data, 3649 size_t *cm_data_space); 3650 3651 static int swrap_sendmsg_filter_cmsghdr(struct msghdr *msg, 3652 uint8_t **cm_data, 3653 size_t *cm_data_space) { 3654 struct cmsghdr *cmsg; 3655 int rc = -1; 3656 3657 /* Nothing to do */ 3658 if (msg->msg_controllen == 0 || msg->msg_control == NULL) { 3659 return 0; 3660 } 3661 3662 for (cmsg = CMSG_FIRSTHDR(msg); 3663 cmsg != NULL; 3664 cmsg = CMSG_NXTHDR(msg, cmsg)) { 3665 switch (cmsg->cmsg_level) { 3666 case IPPROTO_IP: 3667 rc = swrap_sendmsg_filter_cmsg_socket(cmsg, 3668 cm_data, 3669 cm_data_space); 3670 break; 3671 default: 3672 rc = swrap_sendmsg_copy_cmsg(cmsg, 3673 cm_data, 3674 cm_data_space); 3675 break; 3676 } 3677 } 3678 3679 return rc; 3680 } 3681 3682 static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg, 3683 uint8_t **cm_data, 3684 size_t *cm_data_space) 3685 { 3686 size_t cmspace; 3687 uint8_t *p; 3688 3689 cmspace = 3690 (*cm_data_space) + 3691 CMSG_SPACE(cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr))); 3692 3693 p = realloc((*cm_data), cmspace); 3694 if (p == NULL) { 3695 return -1; 3696 } 3697 (*cm_data) = p; 3698 3699 p = (*cm_data) + (*cm_data_space); 3700 *cm_data_space = cmspace; 3701 3702 memcpy(p, cmsg, cmsg->cmsg_len); 3703 3704 return 0; 3705 } 3706 3707 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg, 3708 uint8_t **cm_data, 3709 size_t *cm_data_space); 3710 3711 3712 static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg, 3713 uint8_t **cm_data, 3714 size_t *cm_data_space) 3715 { 3716 int rc = -1; 3717 3718 switch(cmsg->cmsg_type) { 3719 #ifdef IP_PKTINFO 3720 case IP_PKTINFO: 3721 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg, 3722 cm_data, 3723 cm_data_space); 3724 break; 3725 #endif 3726 #ifdef IPV6_PKTINFO 3727 case IPV6_PKTINFO: 3728 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg, 3729 cm_data, 3730 cm_data_space); 3731 break; 3732 #endif 3733 default: 3734 break; 3735 } 3736 3737 return rc; 3738 } 3739 3740 static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg, 3741 uint8_t **cm_data, 3742 size_t *cm_data_space) 3743 { 3744 (void)cmsg; /* unused */ 3745 (void)cm_data; /* unused */ 3746 (void)cm_data_space; /* unused */ 3747 3748 /* 3749 * Passing a IP pktinfo to a unix socket might be rejected by the 3750 * Kernel, at least on FreeBSD. So skip this cmsg. 3751 */ 3752 return 0; 3753 } 3754 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */ 3755 3756 static ssize_t swrap_sendmsg_before(int fd, 3757 struct socket_info *si, 1901 3758 struct msghdr *msg, 1902 3759 struct iovec *tmp_iov, … … 1920 3777 1921 3778 switch (si->type) { 1922 case SOCK_STREAM: 3779 case SOCK_STREAM: { 3780 unsigned long mtu; 3781 1923 3782 if (!si->connected) { 1924 3783 errno = ENOTCONN; … … 1930 3789 } 1931 3790 1932 /* 1933 * cut down to 1500 byte packets for stream sockets, 1934 * which makes it easier to format PCAP capture files 1935 * (as the caller will simply continue from here) 1936 */ 1937 1938 for (i=0; i < msg->msg_iovlen; i++) { 3791 mtu = socket_wrapper_mtu(); 3792 for (i = 0; i < (size_t)msg->msg_iovlen; i++) { 1939 3793 size_t nlen; 1940 3794 nlen = len + msg->msg_iov[i].iov_len; 1941 if (nlen > 1500) {3795 if (nlen > mtu) { 1942 3796 break; 1943 3797 } … … 1946 3800 if (msg->msg_iovlen == 0) { 1947 3801 *tmp_iov = msg->msg_iov[0]; 1948 tmp_iov->iov_len = MIN(tmp_iov->iov_len, 1500);3802 tmp_iov->iov_len = MIN(tmp_iov->iov_len, (size_t)mtu); 1949 3803 msg->msg_iov = tmp_iov; 1950 3804 msg->msg_iovlen = 1; 1951 3805 } 1952 3806 break; 1953 3807 } 1954 3808 case SOCK_DGRAM: 1955 3809 if (si->connected) { … … 1983 3837 1984 3838 if (si->bound == 0) { 1985 ret = swrap_auto_bind(si, si->family); 1986 if (ret == -1) return -1; 3839 ret = swrap_auto_bind(fd, si, si->family); 3840 if (ret == -1) { 3841 if (errno == ENOTSOCK) { 3842 swrap_remove_stale(fd); 3843 return -ENOTSOCK; 3844 } else { 3845 SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed"); 3846 return -1; 3847 } 3848 } 1987 3849 } 1988 3850 … … 1991 3853 } 1992 3854 1993 ret = sockaddr_convert_to_un(si, si->peername, si->peername_len, 1994 tmp_un, 0, NULL); 3855 ret = sockaddr_convert_to_un(si, 3856 &si->peername.sa.s, 3857 si->peername.sa_socklen, 3858 tmp_un, 3859 0, 3860 NULL); 1995 3861 if (ret == -1) return -1; 1996 3862 1997 ret = real_connect(si->fd, (struct sockaddr *)(void *)tmp_un, 3863 ret = libc_connect(fd, 3864 (struct sockaddr *)(void *)tmp_un, 1998 3865 sizeof(*tmp_un)); 1999 3866 … … 2014 3881 } 2015 3882 3883 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 3884 if (msg->msg_controllen > 0 && msg->msg_control != NULL) { 3885 uint8_t *cmbuf = NULL; 3886 size_t cmlen = 0; 3887 3888 ret = swrap_sendmsg_filter_cmsghdr(msg, &cmbuf, &cmlen); 3889 if (ret < 0) { 3890 free(cmbuf); 3891 return -1; 3892 } 3893 3894 if (cmlen == 0) { 3895 msg->msg_controllen = 0; 3896 msg->msg_control = NULL; 3897 } else if (cmlen < msg->msg_controllen && cmbuf != NULL) { 3898 memcpy(msg->msg_control, cmbuf, cmlen); 3899 msg->msg_controllen = cmlen; 3900 } 3901 free(cmbuf); 3902 } 3903 #endif 3904 2016 3905 return 0; 2017 3906 } 2018 3907 2019 static void swrap_sendmsg_after(struct socket_info *si, 3908 static void swrap_sendmsg_after(int fd, 3909 struct socket_info *si, 2020 3910 struct msghdr *msg, 2021 3911 const struct sockaddr *to, … … 2030 3920 2031 3921 /* to give better errors */ 2032 if (ret == -1 && saved_errno == ENOENT) { 2033 saved_errno = EHOSTUNREACH; 2034 } 2035 2036 for (i=0; i < msg->msg_iovlen; i++) { 3922 if (ret == -1) { 3923 if (saved_errno == ENOENT) { 3924 saved_errno = EHOSTUNREACH; 3925 } else if (saved_errno == ENOTSOCK) { 3926 /* If the fd is not a socket, remove it */ 3927 swrap_remove_stale(fd); 3928 } 3929 } 3930 3931 for (i = 0; i < (size_t)msg->msg_iovlen; i++) { 2037 3932 avail += msg->msg_iov[i].iov_len; 2038 3933 } … … 2052 3947 } 2053 3948 2054 for (i =0; i <msg->msg_iovlen; i++) {2055 size_t this_time = MIN(remain, msg->msg_iov[i].iov_len);3949 for (i = 0; i < (size_t)msg->msg_iovlen; i++) { 3950 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len); 2056 3951 memcpy(buf + ofs, 2057 3952 msg->msg_iov[i].iov_base, … … 2065 3960 case SOCK_STREAM: 2066 3961 if (ret == -1) { 2067 swrap_ dump_packet(si, NULL, SWRAP_SEND, buf, len);2068 swrap_ dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);3962 swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len); 3963 swrap_pcap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0); 2069 3964 } else { 2070 swrap_ dump_packet(si, NULL, SWRAP_SEND, buf, len);3965 swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len); 2071 3966 } 2072 3967 break; … … 2074 3969 case SOCK_DGRAM: 2075 3970 if (si->connected) { 2076 to = si->peername;3971 to = &si->peername.sa.s; 2077 3972 } 2078 3973 if (ret == -1) { 2079 swrap_ dump_packet(si, to, SWRAP_SENDTO, buf, len);2080 swrap_ dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);3974 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len); 3975 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len); 2081 3976 } else { 2082 swrap_ dump_packet(si, to, SWRAP_SENDTO, buf, len);3977 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len); 2083 3978 } 2084 3979 break; … … 2089 3984 } 2090 3985 2091 _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) 2092 { 2093 struct sockaddr_un un_addr; 2094 socklen_t un_addrlen = sizeof(un_addr); 2095 int ret; 3986 static int swrap_recvmsg_before(int fd, 3987 struct socket_info *si, 3988 struct msghdr *msg, 3989 struct iovec *tmp_iov) 3990 { 3991 size_t i, len = 0; 3992 ssize_t ret; 3993 3994 (void)fd; /* unused */ 3995 3996 switch (si->type) { 3997 case SOCK_STREAM: { 3998 unsigned int mtu; 3999 if (!si->connected) { 4000 errno = ENOTCONN; 4001 return -1; 4002 } 4003 4004 if (msg->msg_iovlen == 0) { 4005 break; 4006 } 4007 4008 mtu = socket_wrapper_mtu(); 4009 for (i = 0; i < (size_t)msg->msg_iovlen; i++) { 4010 size_t nlen; 4011 nlen = len + msg->msg_iov[i].iov_len; 4012 if (nlen > mtu) { 4013 break; 4014 } 4015 } 4016 msg->msg_iovlen = i; 4017 if (msg->msg_iovlen == 0) { 4018 *tmp_iov = msg->msg_iov[0]; 4019 tmp_iov->iov_len = MIN(tmp_iov->iov_len, (size_t)mtu); 4020 msg->msg_iov = tmp_iov; 4021 msg->msg_iovlen = 1; 4022 } 4023 break; 4024 } 4025 case SOCK_DGRAM: 4026 if (msg->msg_name == NULL) { 4027 errno = EINVAL; 4028 return -1; 4029 } 4030 4031 if (msg->msg_iovlen == 0) { 4032 break; 4033 } 4034 4035 if (si->bound == 0) { 4036 ret = swrap_auto_bind(fd, si, si->family); 4037 if (ret == -1) { 4038 /* 4039 * When attempting to read or write to a 4040 * descriptor, if an underlying autobind fails 4041 * because it's not a socket, stop intercepting 4042 * uses of that descriptor. 4043 */ 4044 if (errno == ENOTSOCK) { 4045 swrap_remove_stale(fd); 4046 return -ENOTSOCK; 4047 } else { 4048 SWRAP_LOG(SWRAP_LOG_ERROR, 4049 "swrap_recvmsg_before failed"); 4050 return -1; 4051 } 4052 } 4053 } 4054 break; 4055 default: 4056 errno = EHOSTUNREACH; 4057 return -1; 4058 } 4059 4060 return 0; 4061 } 4062 4063 static int swrap_recvmsg_after(int fd, 4064 struct socket_info *si, 4065 struct msghdr *msg, 4066 const struct sockaddr_un *un_addr, 4067 socklen_t un_addrlen, 4068 ssize_t ret) 4069 { 4070 int saved_errno = errno; 4071 size_t i; 4072 uint8_t *buf = NULL; 4073 off_t ofs = 0; 4074 size_t avail = 0; 4075 size_t remain; 4076 int rc; 4077 4078 /* to give better errors */ 4079 if (ret == -1) { 4080 if (saved_errno == ENOENT) { 4081 saved_errno = EHOSTUNREACH; 4082 } else if (saved_errno == ENOTSOCK) { 4083 /* If the fd is not a socket, remove it */ 4084 swrap_remove_stale(fd); 4085 } 4086 } 4087 4088 for (i = 0; i < (size_t)msg->msg_iovlen; i++) { 4089 avail += msg->msg_iov[i].iov_len; 4090 } 4091 4092 /* Convert the socket address before we leave */ 4093 if (si->type == SOCK_DGRAM && un_addr != NULL) { 4094 rc = sockaddr_convert_from_un(si, 4095 un_addr, 4096 un_addrlen, 4097 si->family, 4098 msg->msg_name, 4099 &msg->msg_namelen); 4100 if (rc == -1) { 4101 goto done; 4102 } 4103 } 4104 4105 if (avail == 0) { 4106 rc = 0; 4107 goto done; 4108 } 4109 4110 if (ret == -1) { 4111 remain = MIN(80, avail); 4112 } else { 4113 remain = ret; 4114 } 4115 4116 /* we capture it as one single packet */ 4117 buf = (uint8_t *)malloc(remain); 4118 if (buf == NULL) { 4119 /* we just not capture the packet */ 4120 errno = saved_errno; 4121 return -1; 4122 } 4123 4124 for (i = 0; i < (size_t)msg->msg_iovlen; i++) { 4125 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len); 4126 memcpy(buf + ofs, 4127 msg->msg_iov[i].iov_base, 4128 this_time); 4129 ofs += this_time; 4130 remain -= this_time; 4131 } 4132 4133 switch (si->type) { 4134 case SOCK_STREAM: 4135 if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) { 4136 swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); 4137 } else if (ret == 0) { /* END OF FILE */ 4138 swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); 4139 } else if (ret > 0) { 4140 swrap_pcap_dump_packet(si, NULL, SWRAP_RECV, buf, ret); 4141 } 4142 break; 4143 4144 case SOCK_DGRAM: 4145 if (ret == -1) { 4146 break; 4147 } 4148 4149 if (un_addr != NULL) { 4150 swrap_pcap_dump_packet(si, 4151 msg->msg_name, 4152 SWRAP_RECVFROM, 4153 buf, 4154 ret); 4155 } else { 4156 swrap_pcap_dump_packet(si, 4157 msg->msg_name, 4158 SWRAP_RECV, 4159 buf, 4160 ret); 4161 } 4162 4163 break; 4164 } 4165 4166 rc = 0; 4167 done: 4168 free(buf); 4169 errno = saved_errno; 4170 4171 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 4172 if (rc == 0 && 4173 msg->msg_controllen > 0 && 4174 msg->msg_control != NULL) { 4175 rc = swrap_msghdr_add_socket_info(si, msg); 4176 if (rc < 0) { 4177 return -1; 4178 } 4179 } 4180 #endif 4181 4182 return rc; 4183 } 4184 4185 /**************************************************************************** 4186 * RECVFROM 4187 ***************************************************************************/ 4188 4189 static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, 4190 struct sockaddr *from, socklen_t *fromlen) 4191 { 4192 struct swrap_address from_addr = { 4193 .sa_socklen = sizeof(struct sockaddr_un), 4194 }; 4195 ssize_t ret; 2096 4196 struct socket_info *si = find_socket_info(s); 2097 struct sockaddr_storage ss; 2098 socklen_t ss_len = sizeof(ss); 2099 2100 if (!si) { 2101 return real_recvfrom(s, buf, len, flags, from, fromlen); 2102 } 2103 2104 if (!from) { 2105 from = (struct sockaddr *)(void *)&ss; 2106 fromlen = &ss_len; 2107 } 2108 2109 if (si->type == SOCK_STREAM) { 2110 /* cut down to 1500 byte packets for stream sockets, 2111 * which makes it easier to format PCAP capture files 2112 * (as the caller will simply continue from here) */ 2113 len = MIN(len, 1500); 2114 } 2115 2116 /* irix 6.4 forgets to null terminate the sun_path string :-( */ 2117 memset(&un_addr, 0, sizeof(un_addr)); 2118 ret = real_recvfrom(s, buf, len, flags, 2119 (struct sockaddr *)(void *)&un_addr, &un_addrlen); 2120 if (ret == -1) 2121 return ret; 2122 2123 if (sockaddr_convert_from_un(si, &un_addr, un_addrlen, 2124 si->family, from, fromlen) == -1) { 2125 return -1; 2126 } 2127 2128 swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret); 2129 2130 return ret; 2131 } 2132 2133 2134 _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) 2135 { 4197 struct swrap_address saddr = { 4198 .sa_socklen = sizeof(struct sockaddr_storage), 4199 }; 2136 4200 struct msghdr msg; 2137 4201 struct iovec tmp; 2138 struct sockaddr_un un_addr; 4202 int tret; 4203 4204 if (!si) { 4205 return libc_recvfrom(s, 4206 buf, 4207 len, 4208 flags, 4209 from, 4210 fromlen); 4211 } 4212 4213 tmp.iov_base = buf; 4214 tmp.iov_len = len; 4215 4216 ZERO_STRUCT(msg); 4217 if (from != NULL && fromlen != NULL) { 4218 msg.msg_name = from; /* optional address */ 4219 msg.msg_namelen = *fromlen; /* size of address */ 4220 } else { 4221 msg.msg_name = &saddr.sa.s; /* optional address */ 4222 msg.msg_namelen = saddr.sa_socklen; /* size of address */ 4223 } 4224 msg.msg_iov = &tmp; /* scatter/gather array */ 4225 msg.msg_iovlen = 1; /* # elements in msg_iov */ 4226 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 4227 msg.msg_control = NULL; /* ancillary data, see below */ 4228 msg.msg_controllen = 0; /* ancillary data buffer len */ 4229 msg.msg_flags = 0; /* flags on received message */ 4230 #endif 4231 4232 tret = swrap_recvmsg_before(s, si, &msg, &tmp); 4233 if (tret < 0) { 4234 return -1; 4235 } 4236 4237 buf = msg.msg_iov[0].iov_base; 4238 len = msg.msg_iov[0].iov_len; 4239 4240 ret = libc_recvfrom(s, 4241 buf, 4242 len, 4243 flags, 4244 &from_addr.sa.s, 4245 &from_addr.sa_socklen); 4246 if (ret == -1) { 4247 return ret; 4248 } 4249 4250 tret = swrap_recvmsg_after(s, 4251 si, 4252 &msg, 4253 &from_addr.sa.un, 4254 from_addr.sa_socklen, 4255 ret); 4256 if (tret != 0) { 4257 return tret; 4258 } 4259 4260 if (from != NULL && fromlen != NULL) { 4261 *fromlen = msg.msg_namelen; 4262 } 4263 4264 return ret; 4265 } 4266 4267 #ifdef HAVE_ACCEPT_PSOCKLEN_T 4268 ssize_t recvfrom(int s, void *buf, size_t len, int flags, 4269 struct sockaddr *from, Psocklen_t fromlen) 4270 #else 4271 ssize_t recvfrom(int s, void *buf, size_t len, int flags, 4272 struct sockaddr *from, socklen_t *fromlen) 4273 #endif 4274 { 4275 return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen); 4276 } 4277 4278 /**************************************************************************** 4279 * SENDTO 4280 ***************************************************************************/ 4281 4282 static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, 4283 const struct sockaddr *to, socklen_t tolen) 4284 { 4285 struct msghdr msg; 4286 struct iovec tmp; 4287 struct swrap_address un_addr = { 4288 .sa_socklen = sizeof(struct sockaddr_un), 4289 }; 2139 4290 const struct sockaddr_un *to_un = NULL; 2140 4291 ssize_t ret; 4292 int rc; 2141 4293 struct socket_info *si = find_socket_info(s); 2142 4294 int bcast = 0; 2143 4295 2144 4296 if (!si) { 2145 return real_sendto(s, buf, len, flags, to, tolen);4297 return libc_sendto(s, buf, len, flags, to, tolen); 2146 4298 } 2147 4299 … … 2154 4306 msg.msg_iov = &tmp; /* scatter/gather array */ 2155 4307 msg.msg_iovlen = 1; /* # elements in msg_iov */ 2156 #if 0 /* not available on solaris */4308 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL 2157 4309 msg.msg_control = NULL; /* ancillary data, see below */ 2158 4310 msg.msg_controllen = 0; /* ancillary data buffer len */ … … 2160 4312 #endif 2161 4313 2162 ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, &to_un, &to, &bcast); 2163 if (ret == -1) return -1; 4314 rc = swrap_sendmsg_before(s, 4315 si, 4316 &msg, 4317 &tmp, 4318 &un_addr.sa.un, 4319 &to_un, 4320 &to, 4321 &bcast); 4322 if (rc < 0) { 4323 return -1; 4324 } 2164 4325 2165 4326 buf = msg.msg_iov[0].iov_base; … … 2169 4330 struct stat st; 2170 4331 unsigned int iface; 2171 unsigned int prt = ntohs(((const struct sockaddr_in *) to)->sin_port);4332 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port); 2172 4333 char type; 2173 4334 … … 2175 4336 2176 4337 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) { 2177 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, 4338 snprintf(un_addr.sa.un.sun_path, 4339 sizeof(un_addr.sa.un.sun_path), 4340 "%s/"SOCKET_FORMAT, 2178 4341 socket_wrapper_dir(), type, iface, prt); 2179 if (stat(un_addr.s un_path, &st) != 0) continue;4342 if (stat(un_addr.sa.un.sun_path, &st) != 0) continue; 2180 4343 2181 4344 /* ignore the any errors in broadcast sends */ 2182 real_sendto(s, buf, len, flags, 2183 (struct sockaddr *)(void *)&un_addr, 2184 sizeof(un_addr)); 2185 } 2186 2187 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len); 4345 libc_sendto(s, 4346 buf, 4347 len, 4348 flags, 4349 &un_addr.sa.s, 4350 un_addr.sa_socklen); 4351 } 4352 4353 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len); 2188 4354 2189 4355 return len; 2190 4356 } 2191 4357 2192 ret = real_sendto(s, buf, len, flags, msg.msg_name, msg.msg_namelen); 2193 2194 swrap_sendmsg_after(si, &msg, to, ret); 4358 ret = libc_sendto(s, 4359 buf, 4360 len, 4361 flags, 4362 (struct sockaddr *)msg.msg_name, 4363 msg.msg_namelen); 4364 4365 swrap_sendmsg_after(s, si, &msg, to, ret); 2195 4366 2196 4367 return ret; 2197 4368 } 2198 4369 2199 _PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags) 2200 { 2201 int ret; 2202 struct socket_info *si = find_socket_info(s); 2203 2204 if (!si) { 2205 return real_recv(s, buf, len, flags); 2206 } 2207 2208 if (si->type == SOCK_STREAM) { 2209 /* cut down to 1500 byte packets for stream sockets, 2210 * which makes it easier to format PCAP capture files 2211 * (as the caller will simply continue from here) */ 2212 len = MIN(len, 1500); 2213 } 2214 2215 ret = real_recv(s, buf, len, flags); 2216 if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) { 2217 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); 2218 } else if (ret == 0) { /* END OF FILE */ 2219 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); 2220 } else if (ret > 0) { 2221 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret); 4370 ssize_t sendto(int s, const void *buf, size_t len, int flags, 4371 const struct sockaddr *to, socklen_t tolen) 4372 { 4373 return swrap_sendto(s, buf, len, flags, to, tolen); 4374 } 4375 4376 /**************************************************************************** 4377 * READV 4378 ***************************************************************************/ 4379 4380 static ssize_t swrap_recv(int s, void *buf, size_t len, int flags) 4381 { 4382 struct socket_info *si; 4383 struct msghdr msg; 4384 struct swrap_address saddr = { 4385 .sa_socklen = sizeof(struct sockaddr_storage), 4386 }; 4387 struct iovec tmp; 4388 ssize_t ret; 4389 int tret; 4390 4391 si = find_socket_info(s); 4392 if (si == NULL) { 4393 return libc_recv(s, buf, len, flags); 4394 } 4395 4396 tmp.iov_base = buf; 4397 tmp.iov_len = len; 4398 4399 ZERO_STRUCT(msg); 4400 msg.msg_name = &saddr.sa.s; /* optional address */ 4401 msg.msg_namelen = saddr.sa_socklen; /* size of address */ 4402 msg.msg_iov = &tmp; /* scatter/gather array */ 4403 msg.msg_iovlen = 1; /* # elements in msg_iov */ 4404 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 4405 msg.msg_control = NULL; /* ancillary data, see below */ 4406 msg.msg_controllen = 0; /* ancillary data buffer len */ 4407 msg.msg_flags = 0; /* flags on received message */ 4408 #endif 4409 4410 tret = swrap_recvmsg_before(s, si, &msg, &tmp); 4411 if (tret < 0) { 4412 return -1; 4413 } 4414 4415 buf = msg.msg_iov[0].iov_base; 4416 len = msg.msg_iov[0].iov_len; 4417 4418 ret = libc_recv(s, buf, len, flags); 4419 4420 tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret); 4421 if (tret != 0) { 4422 return tret; 2222 4423 } 2223 4424 … … 2225 4426 } 2226 4427 2227 _PUBLIC_ ssize_t swrap_read(int s, void *buf, size_t len) 2228 { 2229 int ret; 2230 struct socket_info *si = find_socket_info(s); 2231 2232 if (!si) { 2233 return real_read(s, buf, len); 2234 } 2235 2236 if (si->type == SOCK_STREAM) { 2237 /* cut down to 1500 byte packets for stream sockets, 2238 * which makes it easier to format PCAP capture files 2239 * (as the caller will simply continue from here) */ 2240 len = MIN(len, 1500); 2241 } 2242 2243 ret = real_read(s, buf, len); 2244 if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) { 2245 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); 2246 } else if (ret == 0) { /* END OF FILE */ 2247 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); 2248 } else if (ret > 0) { 2249 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret); 4428 ssize_t recv(int s, void *buf, size_t len, int flags) 4429 { 4430 return swrap_recv(s, buf, len, flags); 4431 } 4432 4433 /**************************************************************************** 4434 * READ 4435 ***************************************************************************/ 4436 4437 static ssize_t swrap_read(int s, void *buf, size_t len) 4438 { 4439 struct socket_info *si; 4440 struct msghdr msg; 4441 struct iovec tmp; 4442 struct swrap_address saddr = { 4443 .sa_socklen = sizeof(struct sockaddr_storage), 4444 }; 4445 ssize_t ret; 4446 int tret; 4447 4448 si = find_socket_info(s); 4449 if (si == NULL) { 4450 return libc_read(s, buf, len); 4451 } 4452 4453 tmp.iov_base = buf; 4454 tmp.iov_len = len; 4455 4456 ZERO_STRUCT(msg); 4457 msg.msg_name = &saddr.sa.ss; /* optional address */ 4458 msg.msg_namelen = saddr.sa_socklen; /* size of address */ 4459 msg.msg_iov = &tmp; /* scatter/gather array */ 4460 msg.msg_iovlen = 1; /* # elements in msg_iov */ 4461 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 4462 msg.msg_control = NULL; /* ancillary data, see below */ 4463 msg.msg_controllen = 0; /* ancillary data buffer len */ 4464 msg.msg_flags = 0; /* flags on received message */ 4465 #endif 4466 4467 tret = swrap_recvmsg_before(s, si, &msg, &tmp); 4468 if (tret < 0) { 4469 if (tret == -ENOTSOCK) { 4470 return libc_read(s, buf, len); 4471 } 4472 return -1; 4473 } 4474 4475 buf = msg.msg_iov[0].iov_base; 4476 len = msg.msg_iov[0].iov_len; 4477 4478 ret = libc_read(s, buf, len); 4479 4480 tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret); 4481 if (tret != 0) { 4482 return tret; 2250 4483 } 2251 4484 … … 2253 4486 } 2254 4487 2255 2256 _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags) 4488 ssize_t read(int s, void *buf, size_t len) 4489 { 4490 return swrap_read(s, buf, len); 4491 } 4492 4493 /**************************************************************************** 4494 * SEND 4495 ***************************************************************************/ 4496 4497 static ssize_t swrap_send(int s, const void *buf, size_t len, int flags) 2257 4498 { 2258 4499 struct msghdr msg; … … 2260 4501 struct sockaddr_un un_addr; 2261 4502 ssize_t ret; 4503 int rc; 2262 4504 struct socket_info *si = find_socket_info(s); 2263 4505 2264 4506 if (!si) { 2265 return real_send(s, buf, len, flags);4507 return libc_send(s, buf, len, flags); 2266 4508 } 2267 4509 … … 2274 4516 msg.msg_iov = &tmp; /* scatter/gather array */ 2275 4517 msg.msg_iovlen = 1; /* # elements in msg_iov */ 2276 #if 0 /* not available on solaris */4518 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL 2277 4519 msg.msg_control = NULL; /* ancillary data, see below */ 2278 4520 msg.msg_controllen = 0; /* ancillary data buffer len */ … … 2280 4522 #endif 2281 4523 2282 ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, NULL, NULL, NULL); 2283 if (ret == -1) return -1; 4524 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL); 4525 if (rc < 0) { 4526 return -1; 4527 } 2284 4528 2285 4529 buf = msg.msg_iov[0].iov_base; 2286 4530 len = msg.msg_iov[0].iov_len; 2287 4531 2288 ret = real_send(s, buf, len, flags);2289 2290 swrap_sendmsg_after(s i, &msg, NULL, ret);4532 ret = libc_send(s, buf, len, flags); 4533 4534 swrap_sendmsg_after(s, si, &msg, NULL, ret); 2291 4535 2292 4536 return ret; 2293 4537 } 2294 4538 2295 _PUBLIC_ ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags) 4539 ssize_t send(int s, const void *buf, size_t len, int flags) 4540 { 4541 return swrap_send(s, buf, len, flags); 4542 } 4543 4544 /**************************************************************************** 4545 * RECVMSG 4546 ***************************************************************************/ 4547 4548 static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags) 4549 { 4550 struct swrap_address from_addr = { 4551 .sa_socklen = sizeof(struct sockaddr_un), 4552 }; 4553 struct socket_info *si; 4554 struct msghdr msg; 4555 struct iovec tmp; 4556 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 4557 size_t msg_ctrllen_filled; 4558 size_t msg_ctrllen_left; 4559 #endif 4560 4561 ssize_t ret; 4562 int rc; 4563 4564 si = find_socket_info(s); 4565 if (si == NULL) { 4566 return libc_recvmsg(s, omsg, flags); 4567 } 4568 4569 tmp.iov_base = NULL; 4570 tmp.iov_len = 0; 4571 4572 ZERO_STRUCT(msg); 4573 msg.msg_name = &from_addr.sa; /* optional address */ 4574 msg.msg_namelen = from_addr.sa_socklen; /* size of address */ 4575 msg.msg_iov = omsg->msg_iov; /* scatter/gather array */ 4576 msg.msg_iovlen = omsg->msg_iovlen; /* # elements in msg_iov */ 4577 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 4578 msg_ctrllen_filled = 0; 4579 msg_ctrllen_left = omsg->msg_controllen; 4580 4581 msg.msg_control = omsg->msg_control; /* ancillary data, see below */ 4582 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */ 4583 msg.msg_flags = omsg->msg_flags; /* flags on received message */ 4584 #endif 4585 4586 rc = swrap_recvmsg_before(s, si, &msg, &tmp); 4587 if (rc < 0) { 4588 return -1; 4589 } 4590 4591 ret = libc_recvmsg(s, &msg, flags); 4592 4593 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 4594 msg_ctrllen_filled += msg.msg_controllen; 4595 msg_ctrllen_left -= msg.msg_controllen; 4596 4597 if (omsg->msg_control != NULL) { 4598 uint8_t *p; 4599 4600 p = omsg->msg_control; 4601 p += msg_ctrllen_filled; 4602 4603 msg.msg_control = p; 4604 msg.msg_controllen = msg_ctrllen_left; 4605 } else { 4606 msg.msg_control = NULL; 4607 msg.msg_controllen = 0; 4608 } 4609 #endif 4610 4611 rc = swrap_recvmsg_after(s, 4612 si, 4613 &msg, 4614 &from_addr.sa.un, 4615 from_addr.sa_socklen, 4616 ret); 4617 if (rc != 0) { 4618 return rc; 4619 } 4620 4621 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 4622 if (omsg->msg_control != NULL) { 4623 /* msg.msg_controllen = space left */ 4624 msg_ctrllen_left = msg.msg_controllen; 4625 msg_ctrllen_filled = omsg->msg_controllen - msg_ctrllen_left; 4626 } 4627 4628 /* Update the original message length */ 4629 omsg->msg_controllen = msg_ctrllen_filled; 4630 omsg->msg_flags = msg.msg_flags; 4631 #endif 4632 omsg->msg_iovlen = msg.msg_iovlen; 4633 4634 /* 4635 * From the manpage: 4636 * 4637 * The msg_name field points to a caller-allocated buffer that is 4638 * used to return the source address if the socket is unconnected. The 4639 * caller should set msg_namelen to the size of this buffer before this 4640 * call; upon return from a successful call, msg_name will contain the 4641 * length of the returned address. If the application does not need 4642 * to know the source address, msg_name can be specified as NULL. 4643 */ 4644 if (si->type == SOCK_STREAM) { 4645 omsg->msg_namelen = 0; 4646 } else if (omsg->msg_name != NULL && 4647 omsg->msg_namelen != 0 && 4648 omsg->msg_namelen >= msg.msg_namelen) { 4649 memcpy(omsg->msg_name, msg.msg_name, msg.msg_namelen); 4650 omsg->msg_namelen = msg.msg_namelen; 4651 } 4652 4653 return ret; 4654 } 4655 4656 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags) 4657 { 4658 return swrap_recvmsg(sockfd, msg, flags); 4659 } 4660 4661 /**************************************************************************** 4662 * SENDMSG 4663 ***************************************************************************/ 4664 4665 static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags) 2296 4666 { 2297 4667 struct msghdr msg; … … 2301 4671 const struct sockaddr *to = NULL; 2302 4672 ssize_t ret; 4673 int rc; 2303 4674 struct socket_info *si = find_socket_info(s); 2304 4675 int bcast = 0; 2305 4676 2306 4677 if (!si) { 2307 return real_sendmsg(s, omsg, flags); 2308 } 4678 return libc_sendmsg(s, omsg, flags); 4679 } 4680 4681 ZERO_STRUCT(un_addr); 2309 4682 2310 4683 tmp.iov_base = NULL; 2311 4684 tmp.iov_len = 0; 2312 4685 2313 msg = *omsg; 2314 #if 0 2315 msg.msg_name = omsg->msg_name; /* optional address */ 2316 msg.msg_namelen = omsg->msg_namelen; /* size of address */ 4686 ZERO_STRUCT(msg); 4687 4688 if (si->connected == 0) { 4689 msg.msg_name = omsg->msg_name; /* optional address */ 4690 msg.msg_namelen = omsg->msg_namelen; /* size of address */ 4691 } 2317 4692 msg.msg_iov = omsg->msg_iov; /* scatter/gather array */ 2318 4693 msg.msg_iovlen = omsg->msg_iovlen; /* # elements in msg_iov */ 2319 /* the following is not available on solaris */ 2320 msg.msg_control = omsg->msg_control; /* ancillary data, see below */ 2321 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */ 4694 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 4695 if (msg.msg_controllen > 0 && msg.msg_control != NULL) { 4696 /* omsg is a const so use a local buffer for modifications */ 4697 uint8_t cmbuf[omsg->msg_controllen]; 4698 4699 memcpy(cmbuf, omsg->msg_control, omsg->msg_controllen); 4700 4701 msg.msg_control = cmbuf; /* ancillary data, see below */ 4702 msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */ 4703 } 2322 4704 msg.msg_flags = omsg->msg_flags; /* flags on received message */ 2323 4705 #endif 2324 4706 2325 ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, &to_un, &to, &bcast); 2326 if (ret == -1) return -1; 4707 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast); 4708 if (rc < 0) { 4709 return -1; 4710 } 2327 4711 2328 4712 if (bcast) { 2329 4713 struct stat st; 2330 4714 unsigned int iface; 2331 unsigned int prt = ntohs(((const struct sockaddr_in *) to)->sin_port);4715 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port); 2332 4716 char type; 2333 4717 size_t i, len = 0; … … 2337 4721 size_t remain; 2338 4722 2339 for (i =0; i <msg.msg_iovlen; i++) {4723 for (i = 0; i < (size_t)msg.msg_iovlen; i++) { 2340 4724 avail += msg.msg_iov[i].iov_len; 2341 4725 } … … 2350 4734 } 2351 4735 2352 for (i =0; i <msg.msg_iovlen; i++) {2353 size_t this_time = MIN(remain, msg.msg_iov[i].iov_len);4736 for (i = 0; i < (size_t)msg.msg_iovlen; i++) { 4737 size_t this_time = MIN(remain, (size_t)msg.msg_iov[i].iov_len); 2354 4738 memcpy(buf + ofs, 2355 4739 msg.msg_iov[i].iov_base, … … 2370 4754 2371 4755 /* ignore the any errors in broadcast sends */ 2372 real_sendmsg(s, &msg, flags);2373 } 2374 2375 swrap_ dump_packet(si, to, SWRAP_SENDTO, buf, len);4756 libc_sendmsg(s, &msg, flags); 4757 } 4758 4759 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len); 2376 4760 free(buf); 2377 4761 … … 2379 4763 } 2380 4764 2381 ret = real_sendmsg(s, &msg, flags);2382 2383 swrap_sendmsg_after(s i, &msg, to, ret);4765 ret = libc_sendmsg(s, &msg, flags); 4766 4767 swrap_sendmsg_after(s, si, &msg, to, ret); 2384 4768 2385 4769 return ret; 2386 4770 } 2387 4771 2388 int swrap_readv(int s, const struct iovec *vector, size_t count) 2389 { 2390 int ret; 2391 struct socket_info *si = find_socket_info(s); 2392 struct iovec v; 2393 2394 if (!si) { 2395 return real_readv(s, vector, count); 2396 } 2397 2398 if (!si->connected) { 2399 errno = ENOTCONN; 4772 ssize_t sendmsg(int s, const struct msghdr *omsg, int flags) 4773 { 4774 return swrap_sendmsg(s, omsg, flags); 4775 } 4776 4777 /**************************************************************************** 4778 * READV 4779 ***************************************************************************/ 4780 4781 static ssize_t swrap_readv(int s, const struct iovec *vector, int count) 4782 { 4783 struct socket_info *si; 4784 struct msghdr msg; 4785 struct iovec tmp; 4786 struct swrap_address saddr = { 4787 .sa_socklen = sizeof(struct sockaddr_storage) 4788 }; 4789 ssize_t ret; 4790 int rc; 4791 4792 si = find_socket_info(s); 4793 if (si == NULL) { 4794 return libc_readv(s, vector, count); 4795 } 4796 4797 tmp.iov_base = NULL; 4798 tmp.iov_len = 0; 4799 4800 ZERO_STRUCT(msg); 4801 msg.msg_name = &saddr.sa.s; /* optional address */ 4802 msg.msg_namelen = saddr.sa_socklen; /* size of address */ 4803 msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */ 4804 msg.msg_iovlen = count; /* # elements in msg_iov */ 4805 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 4806 msg.msg_control = NULL; /* ancillary data, see below */ 4807 msg.msg_controllen = 0; /* ancillary data buffer len */ 4808 msg.msg_flags = 0; /* flags on received message */ 4809 #endif 4810 4811 rc = swrap_recvmsg_before(s, si, &msg, &tmp); 4812 if (rc < 0) { 4813 if (rc == -ENOTSOCK) { 4814 return libc_readv(s, vector, count); 4815 } 2400 4816 return -1; 2401 4817 } 2402 4818 2403 if (si->type == SOCK_STREAM && count > 0) { 2404 /* cut down to 1500 byte packets for stream sockets, 2405 * which makes it easier to format PCAP capture files 2406 * (as the caller will simply continue from here) */ 2407 size_t i, len = 0; 2408 2409 for (i=0; i < count; i++) { 2410 size_t nlen; 2411 nlen = len + vector[i].iov_len; 2412 if (nlen > 1500) { 2413 break; 2414 } 2415 } 2416 count = i; 2417 if (count == 0) { 2418 v = vector[0]; 2419 v.iov_len = MIN(v.iov_len, 1500); 2420 vector = &v; 2421 count = 1; 2422 } 2423 } 2424 2425 ret = real_readv(s, vector, count); 2426 if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) { 2427 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); 2428 } else if (ret == 0) { /* END OF FILE */ 2429 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); 2430 } else if (ret > 0) { 2431 uint8_t *buf; 2432 off_t ofs = 0; 2433 size_t i; 2434 size_t remain = ret; 2435 2436 /* we capture it as one single packet */ 2437 buf = (uint8_t *)malloc(ret); 2438 if (!buf) { 2439 /* we just not capture the packet */ 2440 errno = 0; 2441 return ret; 2442 } 2443 2444 for (i=0; i < count; i++) { 2445 size_t this_time = MIN(remain, vector[i].iov_len); 2446 memcpy(buf + ofs, 2447 vector[i].iov_base, 2448 this_time); 2449 ofs += this_time; 2450 remain -= this_time; 2451 } 2452 2453 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret); 2454 free(buf); 4819 ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen); 4820 4821 rc = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret); 4822 if (rc != 0) { 4823 return rc; 2455 4824 } 2456 4825 … … 2458 4827 } 2459 4828 2460 int swrap_writev(int s, const struct iovec *vector, size_t count) 4829 ssize_t readv(int s, const struct iovec *vector, int count) 4830 { 4831 return swrap_readv(s, vector, count); 4832 } 4833 4834 /**************************************************************************** 4835 * WRITEV 4836 ***************************************************************************/ 4837 4838 static ssize_t swrap_writev(int s, const struct iovec *vector, int count) 2461 4839 { 2462 4840 struct msghdr msg; … … 2464 4842 struct sockaddr_un un_addr; 2465 4843 ssize_t ret; 4844 int rc; 2466 4845 struct socket_info *si = find_socket_info(s); 2467 4846 2468 4847 if (!si) { 2469 return real_writev(s, vector, count);4848 return libc_writev(s, vector, count); 2470 4849 } 2471 4850 … … 2478 4857 msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */ 2479 4858 msg.msg_iovlen = count; /* # elements in msg_iov */ 2480 #if 0 /* not available on solaris */4859 #if HAVE_STRUCT_MSGHDR_MSG_CONTROL 2481 4860 msg.msg_control = NULL; /* ancillary data, see below */ 2482 4861 msg.msg_controllen = 0; /* ancillary data buffer len */ … … 2484 4863 #endif 2485 4864 2486 ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, NULL, NULL, NULL); 2487 if (ret == -1) return -1; 2488 2489 ret = real_writev(s, msg.msg_iov, msg.msg_iovlen); 2490 2491 swrap_sendmsg_after(si, &msg, NULL, ret); 4865 rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL); 4866 if (rc < 0) { 4867 if (rc == -ENOTSOCK) { 4868 return libc_readv(s, vector, count); 4869 } 4870 return -1; 4871 } 4872 4873 ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen); 4874 4875 swrap_sendmsg_after(s, si, &msg, NULL, ret); 2492 4876 2493 4877 return ret; 2494 4878 } 2495 4879 2496 _PUBLIC_ int swrap_close(int fd) 4880 ssize_t writev(int s, const struct iovec *vector, int count) 4881 { 4882 return swrap_writev(s, vector, count); 4883 } 4884 4885 /**************************** 4886 * CLOSE 4887 ***************************/ 4888 4889 static int swrap_close(int fd) 2497 4890 { 2498 4891 struct socket_info *si = find_socket_info(fd); 4892 struct socket_info_fd *fi; 2499 4893 int ret; 2500 4894 2501 4895 if (!si) { 2502 return real_close(fd); 4896 return libc_close(fd); 4897 } 4898 4899 for (fi = si->fds; fi; fi = fi->next) { 4900 if (fi->fd == fd) { 4901 SWRAP_DLIST_REMOVE(si->fds, fi); 4902 free(fi); 4903 break; 4904 } 4905 } 4906 4907 if (si->fds) { 4908 /* there are still references left */ 4909 return libc_close(fd); 2503 4910 } 2504 4911 2505 4912 SWRAP_DLIST_REMOVE(sockets, si); 2506 4913 2507 if (si->myname && si->peername) { 2508 swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0); 2509 } 2510 2511 ret = real_close(fd); 2512 2513 if (si->myname && si->peername) { 2514 swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0); 2515 swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0); 2516 } 2517 2518 if (si->path) free(si->path); 2519 if (si->myname) free(si->myname); 2520 if (si->peername) free(si->peername); 2521 if (si->tmp_path) { 2522 unlink(si->tmp_path); 2523 free(si->tmp_path); 4914 if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) { 4915 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0); 4916 } 4917 4918 ret = libc_close(fd); 4919 4920 if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) { 4921 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0); 4922 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0); 4923 } 4924 4925 if (si->un_addr.sun_path[0] != '\0') { 4926 unlink(si->un_addr.sun_path); 2524 4927 } 2525 4928 free(si); … … 2527 4930 return ret; 2528 4931 } 4932 4933 int close(int fd) 4934 { 4935 return swrap_close(fd); 4936 } 4937 4938 /**************************** 4939 * DUP 4940 ***************************/ 4941 4942 static int swrap_dup(int fd) 4943 { 4944 struct socket_info *si; 4945 struct socket_info_fd *fi; 4946 4947 si = find_socket_info(fd); 4948 4949 if (!si) { 4950 return libc_dup(fd); 4951 } 4952 4953 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd)); 4954 if (fi == NULL) { 4955 errno = ENOMEM; 4956 return -1; 4957 } 4958 4959 fi->fd = libc_dup(fd); 4960 if (fi->fd == -1) { 4961 int saved_errno = errno; 4962 free(fi); 4963 errno = saved_errno; 4964 return -1; 4965 } 4966 4967 /* Make sure we don't have an entry for the fd */ 4968 swrap_remove_stale(fi->fd); 4969 4970 SWRAP_DLIST_ADD(si->fds, fi); 4971 return fi->fd; 4972 } 4973 4974 int dup(int fd) 4975 { 4976 return swrap_dup(fd); 4977 } 4978 4979 /**************************** 4980 * DUP2 4981 ***************************/ 4982 4983 static int swrap_dup2(int fd, int newfd) 4984 { 4985 struct socket_info *si; 4986 struct socket_info_fd *fi; 4987 4988 si = find_socket_info(fd); 4989 4990 if (!si) { 4991 return libc_dup2(fd, newfd); 4992 } 4993 4994 if (find_socket_info(newfd)) { 4995 /* dup2() does an implicit close of newfd, which we 4996 * need to emulate */ 4997 swrap_close(newfd); 4998 } 4999 5000 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd)); 5001 if (fi == NULL) { 5002 errno = ENOMEM; 5003 return -1; 5004 } 5005 5006 fi->fd = libc_dup2(fd, newfd); 5007 if (fi->fd == -1) { 5008 int saved_errno = errno; 5009 free(fi); 5010 errno = saved_errno; 5011 return -1; 5012 } 5013 5014 /* Make sure we don't have an entry for the fd */ 5015 swrap_remove_stale(fi->fd); 5016 5017 SWRAP_DLIST_ADD(si->fds, fi); 5018 return fi->fd; 5019 } 5020 5021 int dup2(int fd, int newfd) 5022 { 5023 return swrap_dup2(fd, newfd); 5024 } 5025 5026 /**************************** 5027 * FCNTL 5028 ***************************/ 5029 5030 static int swrap_vfcntl(int fd, int cmd, va_list va) 5031 { 5032 struct socket_info_fd *fi; 5033 struct socket_info *si; 5034 int rc; 5035 5036 si = find_socket_info(fd); 5037 if (si == NULL) { 5038 rc = libc_vfcntl(fd, cmd, va); 5039 5040 return rc; 5041 } 5042 5043 switch (cmd) { 5044 case F_DUPFD: 5045 fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd)); 5046 if (fi == NULL) { 5047 errno = ENOMEM; 5048 return -1; 5049 } 5050 5051 fi->fd = libc_vfcntl(fd, cmd, va); 5052 if (fi->fd == -1) { 5053 int saved_errno = errno; 5054 free(fi); 5055 errno = saved_errno; 5056 return -1; 5057 } 5058 5059 /* Make sure we don't have an entry for the fd */ 5060 swrap_remove_stale(fi->fd); 5061 5062 SWRAP_DLIST_ADD(si->fds, fi); 5063 5064 rc = fi->fd; 5065 break; 5066 default: 5067 rc = libc_vfcntl(fd, cmd, va); 5068 break; 5069 } 5070 5071 return rc; 5072 } 5073 5074 int fcntl(int fd, int cmd, ...) 5075 { 5076 va_list va; 5077 int rc; 5078 5079 va_start(va, cmd); 5080 5081 rc = swrap_vfcntl(fd, cmd, va); 5082 5083 va_end(va); 5084 5085 return rc; 5086 } 5087 5088 /**************************** 5089 * EVENTFD 5090 ***************************/ 5091 5092 #ifdef HAVE_EVENTFD 5093 static int swrap_eventfd(int count, int flags) 5094 { 5095 int fd; 5096 5097 fd = libc_eventfd(count, flags); 5098 if (fd != -1) { 5099 swrap_remove_stale(fd); 5100 } 5101 5102 return fd; 5103 } 5104 5105 #ifdef HAVE_EVENTFD_UNSIGNED_INT 5106 int eventfd(unsigned int count, int flags) 5107 #else 5108 int eventfd(int count, int flags) 5109 #endif 5110 { 5111 return swrap_eventfd(count, flags); 5112 } 5113 #endif 5114 5115 /**************************** 5116 * DESTRUCTOR 5117 ***************************/ 5118 5119 /* 5120 * This function is called when the library is unloaded and makes sure that 5121 * sockets get closed and the unix file for the socket are unlinked. 5122 */ 5123 void swrap_destructor(void) 5124 { 5125 struct socket_info *s = sockets; 5126 5127 while (s != NULL) { 5128 struct socket_info_fd *f = s->fds; 5129 if (f != NULL) { 5130 swrap_close(f->fd); 5131 } 5132 s = sockets; 5133 } 5134 5135 if (swrap.libc_handle != NULL) { 5136 dlclose(swrap.libc_handle); 5137 } 5138 if (swrap.libsocket_handle) { 5139 dlclose(swrap.libsocket_handle); 5140 } 5141 } -
vendor/current/lib/socket_wrapper/wscript
r740 r988 1 1 #!/usr/bin/env python 2 2 3 import Options3 import os 4 4 5 def set_options(opt): 6 gr = opt.option_group('developer options') 7 gr.add_option('--enable-socket-wrapper', 8 help=("Turn on socket wrapper library (default=no)"), 9 action="store_true", dest='enable_socket_wrapper', default=False) 5 VERSION="1.1.4" 10 6 11 7 def configure(conf): 12 if (Options.options.enable_socket_wrapper or Options.options.developer or Options.options.enable_selftest): 13 conf.DEFINE('SOCKET_WRAPPER', 1) 14 conf.ADD_GLOBAL_DEPENDENCY('socket_wrapper') 8 if conf.CHECK_BUNDLED_SYSTEM('socket_wrapper', minversion=VERSION, set_target=False): 9 conf.DEFINE('USING_SYSTEM_SOCKET_WRAPPER', 1) 10 libsocket_wrapper_so_path = 'libsocket_wrapper.so' 11 else: 12 # check HAVE_GCC_THREAD_LOCAL_STORAGE 13 conf.CHECK_CODE(''' 14 __thread int tls; 15 15 16 int main(void) { 17 return 0; 18 } 19 ''', 20 'HAVE_GCC_THREAD_LOCAL_STORAGE', 21 addmain=False, 22 msg='Checking for thread local storage') 23 24 # check HAVE_DESTRUCTOR_ATTRIBUTE 25 conf.CHECK_CODE(''' 26 void test_destructor_attribute(void) __attribute__ ((destructor)); 27 28 void test_destructor_attribute(void) 29 { 30 return; 31 } 32 33 int main(void) { 34 return 0; 35 } 36 ''', 37 'HAVE_DESTRUCTOR_ATTRIBUTE', 38 addmain=False, 39 msg='Checking for library destructor support') 40 41 # check HAVE_FUNCTION_ATTRIBUTE_FORMAT 42 conf.CHECK_CODE(''' 43 void log_fn(const char *format, ...) __attribute__ ((format (printf, 1, 2))); 44 45 int main(void) { 46 return 0; 47 } 48 ''', 49 'HAVE_FUNCTION_ATTRIBUTE_FORMAT', 50 addmain=False, 51 msg='Checking for printf format validation support') 52 53 conf.CHECK_HEADERS('sys/signalfd.h') 54 conf.CHECK_HEADERS('sys/eventfd.h') 55 conf.CHECK_HEADERS('sys/timerfd.h') 56 conf.CHECK_HEADERS('gnu/lib-names.h') 57 conf.CHECK_HEADERS('rpc/rpc.h') 58 59 conf.CHECK_STRUCTURE_MEMBER('struct msghdr', 60 'msg_control', 61 headers='sys/types.h sys/socket.h', 62 define='HAVE_STRUCT_MSGHDR_MSG_CONTROL') 63 64 conf.CHECK_STRUCTURE_MEMBER('struct in_pktinfo', 65 'ipi_addr', 66 headers='sys/types.h sys/socket.h netinet/in.h', 67 define='HAVE_STRUCT_IN_PKTINFO') 68 69 conf.CHECK_STRUCTURE_MEMBER('struct in6_pktinfo', 70 'ipi6_addr', 71 headers='sys/types.h sys/socket.h netinet/in.h', 72 define='HAVE_STRUCT_IN6_PKTINFO') 73 74 conf.CHECK_FUNCS('getaddrinfo') 75 conf.CHECK_FUNCS('signalfd eventfd timerfd_create') 76 conf.CHECK_FUNCS('bindresvport') 77 78 conf.CHECK_FUNCS_IN('bind', 79 'socket', 80 checklibc=True, 81 headers='sys/types.h sys/socket.h') 82 83 conf.CHECK_C_PROTOTYPE('accept', 84 'int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)', 85 define='HAVE_ACCEPT_PSOCKLEN_T', headers='sys/types.h sys/socket.h') 86 87 conf.CHECK_C_PROTOTYPE('ioctl', 88 'int ioctl(int s, int r, ...)', 89 define='HAVE_IOCTL_INT', headers='unistd.h sys/ioctl.h') 90 91 if conf.CONFIG_SET("HAVE_EVENTFD"): 92 conf.CHECK_C_PROTOTYPE('eventfd', 93 'int eventfd(unsigned int count, int flags)', 94 define='HAVE_EVENTFD_UNSIGNED_INT', headers='sys/eventfd.h') 95 96 # Create full path to socket_wrapper 97 srcdir = os.path.realpath(conf.srcdir) 98 libsocket_wrapper_so_path = srcdir + '/bin/default/lib/socket_wrapper/libsocket-wrapper.so' 99 100 conf.DEFINE('LIBSOCKET_WRAPPER_SO_PATH', libsocket_wrapper_so_path) 101 conf.DEFINE('SOCKET_WRAPPER', 1) 102 103 def build(bld): 104 if not bld.CONFIG_SET("USING_SYSTEM_SOCKET_WRAPPER"): 105 # We need to do it this way or the library wont work. 106 # Using private_library=True will add symbol version which 107 # breaks preloading! 108 bld.SAMBA_LIBRARY('socket_wrapper', 109 source='socket_wrapper.c', 110 deps='dl', 111 install=False, 112 realname='libsocket-wrapper.so')
Note:
See TracChangeset
for help on using the changeset viewer.