1/* 2 * Copyright (C) Jelmer Vernooij 2005 <jelmer@samba.org> 3 * Copyright (C) Stefan Metzmacher 2006 <metze@samba.org> 4 * 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * 3. Neither the name of the author nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 */ 35 36/* 37 Socket wrapper library. Passes all socket communication over 38 unix domain sockets if the environment variable SOCKET_WRAPPER_DIR 39 is set. 40*/ 41 42#ifdef _SAMBA_BUILD_ 43 44#define SOCKET_WRAPPER_NOT_REPLACE 45#include "includes.h" 46#include "system/network.h" 47#include "system/filesys.h" 48 49#ifdef malloc 50#undef malloc 51#endif 52#ifdef calloc 53#undef calloc 54#endif 55#ifdef strdup 56#undef strdup 57#endif 58 59#else /* _SAMBA_BUILD_ */ 60 61#include <sys/types.h> 62#include <sys/stat.h> 63#include <sys/socket.h> 64#include <sys/ioctl.h> 65#include <errno.h> 66#include <sys/un.h> 67#include <netinet/in.h> 68#include <netinet/tcp.h> 69#include <fcntl.h> 70#include <stdlib.h> 71#include <unistd.h> 72#include <string.h> 73#include <stdio.h> 74 75#define _PUBLIC_ 76 77#endif 78 79#define SWRAP_DLIST_ADD(list,item) do { \ 80 if (!(list)) { \ 81 (item)->prev = NULL; \ 82 (item)->next = NULL; \ 83 (list) = (item); \ 84 } else { \ 85 (item)->prev = NULL; \ 86 (item)->next = (list); \ 87 (list)->prev = (item); \ 88 (list) = (item); \ 89 } \ 90} while (0) 91 92#define SWRAP_DLIST_REMOVE(list,item) do { \ 93 if ((list) == (item)) { \ 94 (list) = (item)->next; \ 95 if (list) { \ 96 (list)->prev = NULL; \ 97 } \ 98 } else { \ 99 if ((item)->prev) { \ 100 (item)->prev->next = (item)->next; \ 101 } \ 102 if ((item)->next) { \ 103 (item)->next->prev = (item)->prev; \ 104 } \ 105 } \ 106 (item)->prev = NULL; \ 107 (item)->next = NULL; \ 108} while (0) 109 110/* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support 111 * for now */ 112#define REWRITE_CALLS 113 114#ifdef REWRITE_CALLS 115#define real_accept accept 116#define real_connect connect 117#define real_bind bind 118#define real_listen listen 119#define real_getpeername getpeername 120#define real_getsockname getsockname 121#define real_getsockopt getsockopt 122#define real_setsockopt setsockopt 123#define real_recvfrom recvfrom 124#define real_sendto sendto 125#define real_ioctl ioctl 126#define real_recv recv 127#define real_send send 128#define real_socket socket 129#define real_close close 130#endif 131 132#ifdef HAVE_GETTIMEOFDAY_TZ 133#define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL) 134#else 135#define swrapGetTimeOfDay(tval) gettimeofday(tval) 136#endif 137 138/* we need to use a very terse format here as IRIX 6.4 silently 139 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 142 with this format we have 8 chars left for the directory name 143*/ 144#define SOCKET_FORMAT "%c%02X%04X" 145#define SOCKET_TYPE_CHAR_TCP 'T' 146#define SOCKET_TYPE_CHAR_UDP 'U' 147 148#define MAX_WRAPPED_INTERFACES 16 149 150static struct sockaddr *sockaddr_dup(const void *data, socklen_t len) 151{ 152 struct sockaddr *ret = (struct sockaddr *)malloc(len); 153 memcpy(ret, data, len); 154 return ret; 155} 156 157struct socket_info 158{ 159 int fd; 160 161 int family; 162 int type; 163 int protocol; 164 int bound; 165 int bcast; 166 int is_server; 167 168 char *path; 169 char *tmp_path; 170 171 struct sockaddr *myname; 172 socklen_t myname_len; 173 174 struct sockaddr *peername; 175 socklen_t peername_len; 176 177 struct { 178 unsigned long pck_snd; 179 unsigned long pck_rcv; 180 } io; 181 182 struct socket_info *prev, *next; 183}; 184 185static struct socket_info *sockets; 186 187 188static const char *socket_wrapper_dir(void) 189{ 190 const char *s = getenv("SOCKET_WRAPPER_DIR"); 191 if (s == NULL) { 192 return NULL; 193 } 194 if (strncmp(s, "./", 2) == 0) { 195 s += 2; 196 } 197 return s; 198} 199 200static unsigned int socket_wrapper_default_iface(void) 201{ 202 const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE"); 203 if (s) { 204 unsigned int iface; 205 if (sscanf(s, "%u", &iface) == 1) { 206 if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) { 207 return iface; 208 } 209 } 210 } 211 212 return 1;/* 127.0.0.1 */ 213} 214 215static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, socklen_t *len) 216{ 217 unsigned int iface; 218 unsigned int prt; 219 const char *p; 220 char type; 221 222 if ((*len) < sizeof(struct sockaddr_in)) { 223 return 0; 224 } 225 226 p = strrchr(un->sun_path, '/'); 227 if (p) p++; else p = un->sun_path; 228 229 if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) { 230 errno = EINVAL; 231 return -1; 232 } 233 234 if (type != SOCKET_TYPE_CHAR_TCP && type != SOCKET_TYPE_CHAR_UDP) { 235 errno = EINVAL; 236 return -1; 237 } 238 239 if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) { 240 errno = EINVAL; 241 return -1; 242 } 243 244 if (prt > 0xFFFF) { 245 errno = EINVAL; 246 return -1; 247 } 248 249 in->sin_family = AF_INET; 250 in->sin_addr.s_addr = htonl((127<<24) | iface); 251 in->sin_port = htons(prt); 252 253 *len = sizeof(struct sockaddr_in); 254 return 0; 255} 256 257static int convert_in_un_remote(struct socket_info *si, const struct sockaddr_in *in, struct sockaddr_un *un, 258 int *bcast) 259{ 260 char u_type = '\0'; 261 char b_type = '\0'; 262 char a_type = '\0'; 263 char type = '\0'; 264 unsigned int addr= ntohl(in->sin_addr.s_addr); 265 unsigned int prt = ntohs(in->sin_port); 266 unsigned int iface; 267 int is_bcast = 0; 268 269 if (bcast) *bcast = 0; 270 271 if (prt == 0) { 272 errno = EINVAL; 273 return -1; 274 } 275 276 switch (si->type) { 277 case SOCK_STREAM: 278 u_type = SOCKET_TYPE_CHAR_TCP; 279 break; 280 case SOCK_DGRAM: 281 u_type = SOCKET_TYPE_CHAR_UDP; 282 a_type = SOCKET_TYPE_CHAR_UDP; 283 b_type = SOCKET_TYPE_CHAR_UDP; 284 break; 285 } 286 287 if (a_type && addr == 0xFFFFFFFF) { 288 /* 255.255.255.255 only udp */ 289 is_bcast = 2; 290 type = a_type; 291 iface = socket_wrapper_default_iface(); 292 } else if (b_type && addr == 0x7FFFFFFF) { 293 /* 127.255.255.255 only udp */ 294 is_bcast = 1; 295 type = b_type; 296 iface = socket_wrapper_default_iface(); 297 } else if ((addr & 0xFFFFFF00) == 0x7F000000) { 298 /* 127.0.0.X */ 299 is_bcast = 0; 300 type = u_type; 301 iface = (addr & 0x000000FF); 302 } else { 303 errno = ENETUNREACH; 304 return -1; 305 } 306 307 if (bcast) *bcast = is_bcast; 308 309 if (is_bcast) { 310 snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL", 311 socket_wrapper_dir()); 312 /* the caller need to do more processing */ 313 return 0; 314 } 315 316 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 317 socket_wrapper_dir(), type, iface, prt); 318 319 return 0; 320} 321 322static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr_in *in, struct sockaddr_un *un, 323 int *bcast) 324{ 325 char u_type = '\0'; 326 char d_type = '\0'; 327 char b_type = '\0'; 328 char a_type = '\0'; 329 char type = '\0'; 330 unsigned int addr= ntohl(in->sin_addr.s_addr); 331 unsigned int prt = ntohs(in->sin_port); 332 unsigned int iface; 333 struct stat st; 334 int is_bcast = 0; 335 336 if (bcast) *bcast = 0; 337 338 switch (si->type) { 339 case SOCK_STREAM: 340 u_type = SOCKET_TYPE_CHAR_TCP; 341 d_type = SOCKET_TYPE_CHAR_TCP; 342 break; 343 case SOCK_DGRAM: 344 u_type = SOCKET_TYPE_CHAR_UDP; 345 d_type = SOCKET_TYPE_CHAR_UDP; 346 a_type = SOCKET_TYPE_CHAR_UDP; 347 b_type = SOCKET_TYPE_CHAR_UDP; 348 break; 349 } 350 351 if (addr == 0) { 352 /* 0.0.0.0 */ 353 is_bcast = 0; 354 type = d_type; 355 iface = socket_wrapper_default_iface(); 356 } else if (a_type && addr == 0xFFFFFFFF) { 357 /* 255.255.255.255 only udp */ 358 is_bcast = 2; 359 type = a_type; 360 iface = socket_wrapper_default_iface(); 361 } else if (b_type && addr == 0x7FFFFFFF) { 362 /* 127.255.255.255 only udp */ 363 is_bcast = 1; 364 type = b_type; 365 iface = socket_wrapper_default_iface(); 366 } else if ((addr & 0xFFFFFF00) == 0x7F000000) { 367 /* 127.0.0.X */ 368 is_bcast = 0; 369 type = u_type; 370 iface = (addr & 0x000000FF); 371 } else { 372 errno = EADDRNOTAVAIL; 373 return -1; 374 } 375 376 if (bcast) *bcast = is_bcast; 377 378 if (prt == 0) { 379 /* handle auto-allocation of ephemeral ports */ 380 for (prt = 5001; prt < 10000; prt++) { 381 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 382 socket_wrapper_dir(), type, iface, prt); 383 if (stat(un->sun_path, &st) == 0) continue; 384 385 ((struct sockaddr_in *)si->myname)->sin_port = htons(prt); 386 return 0; 387 } 388 errno = ENFILE; 389 return -1; 390 } 391 392 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 393 socket_wrapper_dir(), type, iface, prt); 394 return 0; 395} 396 397static struct socket_info *find_socket_info(int fd) 398{ 399 struct socket_info *i; 400 for (i = sockets; i; i = i->next) { 401 if (i->fd == fd) 402 return i; 403 } 404 405 return NULL; 406} 407 408static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len, 409 struct sockaddr_un *out_addr, int alloc_sock, int *bcast) 410{ 411 if (!out_addr) 412 return 0; 413 414 out_addr->sun_family = AF_UNIX; 415 416 switch (in_addr->sa_family) { 417 case AF_INET: 418 switch (si->type) { 419 case SOCK_STREAM: 420 case SOCK_DGRAM: 421 break; 422 default: 423 errno = ESOCKTNOSUPPORT; 424 return -1; 425 } 426 if (alloc_sock) { 427 return convert_in_un_alloc(si, (const struct sockaddr_in *)in_addr, out_addr, bcast); 428 } else { 429 return convert_in_un_remote(si, (const struct sockaddr_in *)in_addr, out_addr, bcast); 430 } 431 default: 432 break; 433 } 434 435 errno = EAFNOSUPPORT; 436 return -1; 437} 438 439static int sockaddr_convert_from_un(const struct socket_info *si, 440 const struct sockaddr_un *in_addr, 441 socklen_t un_addrlen, 442 int family, 443 struct sockaddr *out_addr, 444 socklen_t *_out_addrlen) 445{ 446 socklen_t out_addrlen; 447 448 if (out_addr == NULL || _out_addrlen == NULL) 449 return 0; 450 451 if (un_addrlen == 0) { 452 *_out_addrlen = 0; 453 return 0; 454 } 455 456 out_addrlen = *_out_addrlen; 457 if (out_addrlen > un_addrlen) { 458 out_addrlen = un_addrlen; 459 } 460 461 switch (family) { 462 case AF_INET: 463 switch (si->type) { 464 case SOCK_STREAM: 465 case SOCK_DGRAM: 466 break; 467 default: 468 errno = ESOCKTNOSUPPORT; 469 return -1; 470 } 471 return convert_un_in(in_addr, (struct sockaddr_in *)out_addr, _out_addrlen); 472 default: 473 break; 474 } 475 476 errno = EAFNOSUPPORT; 477 return -1; 478} 479 480enum swrap_packet_type { 481 SWRAP_CONNECT_SEND, 482 SWRAP_CONNECT_UNREACH, 483 SWRAP_CONNECT_RECV, 484 SWRAP_CONNECT_ACK, 485 SWRAP_ACCEPT_SEND, 486 SWRAP_ACCEPT_RECV, 487 SWRAP_ACCEPT_ACK, 488 SWRAP_RECVFROM, 489 SWRAP_SENDTO, 490 SWRAP_SENDTO_UNREACH, 491 SWRAP_PENDING_RST, 492 SWRAP_RECV, 493 SWRAP_RECV_RST, 494 SWRAP_SEND, 495 SWRAP_SEND_RST, 496 SWRAP_CLOSE_SEND, 497 SWRAP_CLOSE_RECV, 498 SWRAP_CLOSE_ACK 499}; 500 501struct swrap_file_hdr { 502 unsigned long magic; 503 unsigned short version_major; 504 unsigned short version_minor; 505 long timezone; 506 unsigned long sigfigs; 507 unsigned long frame_max_len; 508#define SWRAP_FRAME_LENGTH_MAX 0xFFFF 509 unsigned long link_type; 510}; 511#define SWRAP_FILE_HDR_SIZE 24 512 513struct swrap_packet { 514 struct { 515 unsigned long seconds; 516 unsigned long micro_seconds; 517 unsigned long recorded_length; 518 unsigned long full_length; 519 } frame; 520#define SWRAP_PACKET__FRAME_SIZE 16 521 522 struct { 523 struct { 524 unsigned char ver_hdrlen; 525 unsigned char tos; 526 unsigned short packet_length; 527 unsigned short identification; 528 unsigned char flags; 529 unsigned char fragment; 530 unsigned char ttl; 531 unsigned char protocol; 532 unsigned short hdr_checksum; 533 unsigned long src_addr; 534 unsigned long dest_addr; 535 } hdr; 536#define SWRAP_PACKET__IP_HDR_SIZE 20 537 538 union { 539 struct { 540 unsigned short source_port; 541 unsigned short dest_port; 542 unsigned long seq_num; 543 unsigned long ack_num; 544 unsigned char hdr_length; 545 unsigned char control; 546 unsigned short window; 547 unsigned short checksum; 548 unsigned short urg; 549 } tcp; 550#define SWRAP_PACKET__IP_P_TCP_SIZE 20 551 struct { 552 unsigned short source_port; 553 unsigned short dest_port; 554 unsigned short length; 555 unsigned short checksum; 556 } udp; 557#define SWRAP_PACKET__IP_P_UDP_SIZE 8 558 struct { 559 unsigned char type; 560 unsigned char code; 561 unsigned short checksum; 562 unsigned long unused; 563 } icmp; 564#define SWRAP_PACKET__IP_P_ICMP_SIZE 8 565 } p; 566 } ip; 567}; 568#define SWRAP_PACKET_SIZE 56 569 570static const char *socket_wrapper_pcap_file(void) 571{ 572 static int initialized = 0; 573 static const char *s = NULL; 574 static const struct swrap_file_hdr h; 575 static const struct swrap_packet p; 576 577 if (initialized == 1) { 578 return s; 579 } 580 initialized = 1; 581 582 /* 583 * TODO: don't use the structs use plain buffer offsets 584 * and PUSH_U8(), PUSH_U16() and PUSH_U32() 585 * 586 * for now make sure we disable PCAP support 587 * if the struct has alignment! 588 */ 589 if (sizeof(h) != SWRAP_FILE_HDR_SIZE) { 590 return NULL; 591 } 592 if (sizeof(p) != SWRAP_PACKET_SIZE) { 593 return NULL; 594 } 595 if (sizeof(p.frame) != SWRAP_PACKET__FRAME_SIZE) { 596 return NULL; 597 } 598 if (sizeof(p.ip.hdr) != SWRAP_PACKET__IP_HDR_SIZE) { 599 return NULL; 600 } 601 if (sizeof(p.ip.p.tcp) != SWRAP_PACKET__IP_P_TCP_SIZE) { 602 return NULL; 603 } 604 if (sizeof(p.ip.p.udp) != SWRAP_PACKET__IP_P_UDP_SIZE) { 605 return NULL; 606 } 607 if (sizeof(p.ip.p.icmp) != SWRAP_PACKET__IP_P_ICMP_SIZE) { 608 return NULL; 609 } 610 611 s = getenv("SOCKET_WRAPPER_PCAP_FILE"); 612 if (s == NULL) { 613 return NULL; 614 } 615 if (strncmp(s, "./", 2) == 0) { 616 s += 2; 617 } 618 return s; 619} 620 621static struct swrap_packet *swrap_packet_init(struct timeval *tval, 622 const struct sockaddr_in *src_addr, 623 const struct sockaddr_in *dest_addr, 624 int socket_type, 625 const unsigned char *payload, 626 size_t payload_len, 627 unsigned long tcp_seq, 628 unsigned long tcp_ack, 629 unsigned char tcp_ctl, 630 int unreachable, 631 size_t *_packet_len) 632{ 633 struct swrap_packet *ret; 634 struct swrap_packet *packet; 635 size_t packet_len; 636 size_t alloc_len; 637 size_t nonwire_len = sizeof(packet->frame); 638 size_t wire_hdr_len = 0; 639 size_t wire_len = 0; 640 size_t icmp_hdr_len = 0; 641 size_t icmp_truncate_len = 0; 642 unsigned char protocol = 0, icmp_protocol = 0; 643 unsigned short src_port = src_addr->sin_port; 644 unsigned short dest_port = dest_addr->sin_port; 645 646 switch (socket_type) { 647 case SOCK_STREAM: 648 protocol = 0x06; /* TCP */ 649 wire_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.tcp); 650 wire_len = wire_hdr_len + payload_len; 651 break; 652 653 case SOCK_DGRAM: 654 protocol = 0x11; /* UDP */ 655 wire_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.udp); 656 wire_len = wire_hdr_len + payload_len; 657 break; 658 } 659 660 if (unreachable) { 661 icmp_protocol = protocol; 662 protocol = 0x01; /* ICMP */ 663 if (wire_len > 64 ) { 664 icmp_truncate_len = wire_len - 64; 665 } 666 icmp_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.icmp); 667 wire_hdr_len += icmp_hdr_len; 668 wire_len += icmp_hdr_len; 669 } 670 671 packet_len = nonwire_len + wire_len; 672 alloc_len = packet_len; 673 if (alloc_len < sizeof(struct swrap_packet)) { 674 alloc_len = sizeof(struct swrap_packet); 675 } 676 ret = (struct swrap_packet *)malloc(alloc_len); 677 if (!ret) return NULL; 678 679 packet = ret; 680 681 packet->frame.seconds = tval->tv_sec; 682 packet->frame.micro_seconds = tval->tv_usec; 683 packet->frame.recorded_length = wire_len - icmp_truncate_len; 684 packet->frame.full_length = wire_len - icmp_truncate_len; 685 686 packet->ip.hdr.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */ 687 packet->ip.hdr.tos = 0x00; 688 packet->ip.hdr.packet_length = htons(wire_len - icmp_truncate_len); 689 packet->ip.hdr.identification = htons(0xFFFF); 690 packet->ip.hdr.flags = 0x40; /* BIT 1 set - means don't fraqment */ 691 packet->ip.hdr.fragment = htons(0x0000); 692 packet->ip.hdr.ttl = 0xFF; 693 packet->ip.hdr.protocol = protocol; 694 packet->ip.hdr.hdr_checksum = htons(0x0000); 695 packet->ip.hdr.src_addr = src_addr->sin_addr.s_addr; 696 packet->ip.hdr.dest_addr = dest_addr->sin_addr.s_addr; 697 698 if (unreachable) { 699 packet->ip.p.icmp.type = 0x03; /* destination unreachable */ 700 packet->ip.p.icmp.code = 0x01; /* host unreachable */ 701 packet->ip.p.icmp.checksum = htons(0x0000); 702 packet->ip.p.icmp.unused = htonl(0x00000000); 703 704 /* set the ip header in the ICMP payload */ 705 packet = (struct swrap_packet *)(((unsigned char *)ret) + icmp_hdr_len); 706 packet->ip.hdr.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */ 707 packet->ip.hdr.tos = 0x00; 708 packet->ip.hdr.packet_length = htons(wire_len - icmp_hdr_len); 709 packet->ip.hdr.identification = htons(0xFFFF); 710 packet->ip.hdr.flags = 0x40; /* BIT 1 set - means don't fraqment */ 711 packet->ip.hdr.fragment = htons(0x0000); 712 packet->ip.hdr.ttl = 0xFF; 713 packet->ip.hdr.protocol = icmp_protocol; 714 packet->ip.hdr.hdr_checksum = htons(0x0000); 715 packet->ip.hdr.src_addr = dest_addr->sin_addr.s_addr; 716 packet->ip.hdr.dest_addr = src_addr->sin_addr.s_addr; 717 718 src_port = dest_addr->sin_port; 719 dest_port = src_addr->sin_port; 720 } 721 722 switch (socket_type) { 723 case SOCK_STREAM: 724 packet->ip.p.tcp.source_port = src_port; 725 packet->ip.p.tcp.dest_port = dest_port; 726 packet->ip.p.tcp.seq_num = htonl(tcp_seq); 727 packet->ip.p.tcp.ack_num = htonl(tcp_ack); 728 packet->ip.p.tcp.hdr_length = 0x50; /* 5 * 32 bit words */ 729 packet->ip.p.tcp.control = tcp_ctl; 730 packet->ip.p.tcp.window = htons(0x7FFF); 731 packet->ip.p.tcp.checksum = htons(0x0000); 732 packet->ip.p.tcp.urg = htons(0x0000); 733 734 break; 735 736 case SOCK_DGRAM: 737 packet->ip.p.udp.source_port = src_addr->sin_port; 738 packet->ip.p.udp.dest_port = dest_addr->sin_port; 739 packet->ip.p.udp.length = htons(8 + payload_len); 740 packet->ip.p.udp.checksum = htons(0x0000); 741 742 break; 743 } 744 745 if (payload && payload_len > 0) { 746 unsigned char *p = (unsigned char *)ret; 747 p += nonwire_len; 748 p += wire_hdr_len; 749 memcpy(p, payload, payload_len); 750 } 751 752 *_packet_len = packet_len - icmp_truncate_len; 753 return ret; 754} 755 756static int swrap_get_pcap_fd(const char *fname) 757{ 758 static int fd = -1; 759 760 if (fd != -1) return fd; 761 762 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644); 763 if (fd != -1) { 764 struct swrap_file_hdr file_hdr; 765 file_hdr.magic = 0xA1B2C3D4; 766 file_hdr.version_major = 0x0002; 767 file_hdr.version_minor = 0x0004; 768 file_hdr.timezone = 0x00000000; 769 file_hdr.sigfigs = 0x00000000; 770 file_hdr.frame_max_len = SWRAP_FRAME_LENGTH_MAX; 771 file_hdr.link_type = 0x0065; /* 101 RAW IP */ 772 773 write(fd, &file_hdr, sizeof(file_hdr)); 774 return fd; 775 } 776 777 fd = open(fname, O_WRONLY|O_APPEND, 0644); 778 779 return fd; 780} 781 782static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *addr, 783 enum swrap_packet_type type, 784 const void *buf, size_t len) 785{ 786 const struct sockaddr_in *src_addr; 787 const struct sockaddr_in *dest_addr; 788 const char *file_name; 789 unsigned long tcp_seq = 0; 790 unsigned long tcp_ack = 0; 791 unsigned char tcp_ctl = 0; 792 int unreachable = 0; 793 struct timeval tv; 794 struct swrap_packet *packet; 795 size_t packet_len = 0; 796 int fd; 797 798 file_name = socket_wrapper_pcap_file(); 799 if (!file_name) { 800 return; 801 } 802 803 if (si->family != AF_INET) { 804 return; 805 } 806 807 switch (type) { 808 case SWRAP_CONNECT_SEND: 809 if (si->type != SOCK_STREAM) return; 810 811 src_addr = (const struct sockaddr_in *)si->myname; 812 dest_addr = (const struct sockaddr_in *)addr; 813 814 tcp_seq = si->io.pck_snd; 815 tcp_ack = si->io.pck_rcv; 816 tcp_ctl = 0x02; /* SYN */ 817 818 si->io.pck_snd += 1; 819 820 break; 821 822 case SWRAP_CONNECT_RECV: 823 if (si->type != SOCK_STREAM) return; 824 825 dest_addr = (const struct sockaddr_in *)si->myname; 826 src_addr = (const struct sockaddr_in *)addr; 827 828 tcp_seq = si->io.pck_rcv; 829 tcp_ack = si->io.pck_snd; 830 tcp_ctl = 0x12; /** SYN,ACK */ 831 832 si->io.pck_rcv += 1; 833 834 break; 835 836 case SWRAP_CONNECT_UNREACH: 837 if (si->type != SOCK_STREAM) return; 838 839 dest_addr = (const struct sockaddr_in *)si->myname; 840 src_addr = (const struct sockaddr_in *)addr; 841 842 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */ 843 tcp_seq = si->io.pck_snd - 1; 844 tcp_ack = si->io.pck_rcv; 845 tcp_ctl = 0x02; /* SYN */ 846 unreachable = 1; 847 848 break; 849 850 case SWRAP_CONNECT_ACK: 851 if (si->type != SOCK_STREAM) return; 852 853 src_addr = (const struct sockaddr_in *)si->myname; 854 dest_addr = (const struct sockaddr_in *)addr; 855 856 tcp_seq = si->io.pck_snd; 857 tcp_ack = si->io.pck_rcv; 858 tcp_ctl = 0x10; /* ACK */ 859 860 break; 861 862 case SWRAP_ACCEPT_SEND: 863 if (si->type != SOCK_STREAM) return; 864 865 dest_addr = (const struct sockaddr_in *)si->myname; 866 src_addr = (const struct sockaddr_in *)addr; 867 868 tcp_seq = si->io.pck_rcv; 869 tcp_ack = si->io.pck_snd; 870 tcp_ctl = 0x02; /* SYN */ 871 872 si->io.pck_rcv += 1; 873 874 break; 875 876 case SWRAP_ACCEPT_RECV: 877 if (si->type != SOCK_STREAM) return; 878 879 src_addr = (const struct sockaddr_in *)si->myname; 880 dest_addr = (const struct sockaddr_in *)addr; 881 882 tcp_seq = si->io.pck_snd; 883 tcp_ack = si->io.pck_rcv; 884 tcp_ctl = 0x12; /* SYN,ACK */ 885 886 si->io.pck_snd += 1; 887 888 break; 889 890 case SWRAP_ACCEPT_ACK: 891 if (si->type != SOCK_STREAM) return; 892 893 dest_addr = (const struct sockaddr_in *)si->myname; 894 src_addr = (const struct sockaddr_in *)addr; 895 896 tcp_seq = si->io.pck_rcv; 897 tcp_ack = si->io.pck_snd; 898 tcp_ctl = 0x10; /* ACK */ 899 900 break; 901 902 case SWRAP_SEND: 903 src_addr = (const struct sockaddr_in *)si->myname; 904 dest_addr = (const struct sockaddr_in *)si->peername; 905 906 tcp_seq = si->io.pck_snd; 907 tcp_ack = si->io.pck_rcv; 908 tcp_ctl = 0x18; /* PSH,ACK */ 909 910 si->io.pck_snd += len; 911 912 break; 913 914 case SWRAP_SEND_RST: 915 dest_addr = (const struct sockaddr_in *)si->myname; 916 src_addr = (const struct sockaddr_in *)si->peername; 917 918 if (si->type == SOCK_DGRAM) { 919 swrap_dump_packet(si, si->peername, 920 SWRAP_SENDTO_UNREACH, 921 buf, len); 922 return; 923 } 924 925 tcp_seq = si->io.pck_rcv; 926 tcp_ack = si->io.pck_snd; 927 tcp_ctl = 0x14; /** RST,ACK */ 928 929 break; 930 931 case SWRAP_PENDING_RST: 932 dest_addr = (const struct sockaddr_in *)si->myname; 933 src_addr = (const struct sockaddr_in *)si->peername; 934 935 if (si->type == SOCK_DGRAM) { 936 return; 937 } 938 939 tcp_seq = si->io.pck_rcv; 940 tcp_ack = si->io.pck_snd; 941 tcp_ctl = 0x14; /* RST,ACK */ 942 943 break; 944 945 case SWRAP_RECV: 946 dest_addr = (const struct sockaddr_in *)si->myname; 947 src_addr = (const struct sockaddr_in *)si->peername; 948 949 tcp_seq = si->io.pck_rcv; 950 tcp_ack = si->io.pck_snd; 951 tcp_ctl = 0x18; /* PSH,ACK */ 952 953 si->io.pck_rcv += len; 954 955 break; 956 957 case SWRAP_RECV_RST: 958 dest_addr = (const struct sockaddr_in *)si->myname; 959 src_addr = (const struct sockaddr_in *)si->peername; 960 961 if (si->type == SOCK_DGRAM) { 962 return; 963 } 964 965 tcp_seq = si->io.pck_rcv; 966 tcp_ack = si->io.pck_snd; 967 tcp_ctl = 0x14; /* RST,ACK */ 968 969 break; 970 971 case SWRAP_SENDTO: 972 src_addr = (const struct sockaddr_in *)si->myname; 973 dest_addr = (const struct sockaddr_in *)addr; 974 975 si->io.pck_snd += len; 976 977 break; 978 979 case SWRAP_SENDTO_UNREACH: 980 dest_addr = (const struct sockaddr_in *)si->myname; 981 src_addr = (const struct sockaddr_in *)addr; 982 983 unreachable = 1; 984 985 break; 986 987 case SWRAP_RECVFROM: 988 dest_addr = (const struct sockaddr_in *)si->myname; 989 src_addr = (const struct sockaddr_in *)addr; 990 991 si->io.pck_rcv += len; 992 993 break; 994 995 case SWRAP_CLOSE_SEND: 996 if (si->type != SOCK_STREAM) return; 997 998 src_addr = (const struct sockaddr_in *)si->myname; 999 dest_addr = (const struct sockaddr_in *)si->peername; 1000 1001 tcp_seq = si->io.pck_snd; 1002 tcp_ack = si->io.pck_rcv; 1003 tcp_ctl = 0x11; /* FIN, ACK */ 1004 1005 si->io.pck_snd += 1; 1006 1007 break; 1008 1009 case SWRAP_CLOSE_RECV: 1010 if (si->type != SOCK_STREAM) return; 1011 1012 dest_addr = (const struct sockaddr_in *)si->myname; 1013 src_addr = (const struct sockaddr_in *)si->peername; 1014 1015 tcp_seq = si->io.pck_rcv; 1016 tcp_ack = si->io.pck_snd; 1017 tcp_ctl = 0x11; /* FIN,ACK */ 1018 1019 si->io.pck_rcv += 1; 1020 1021 break; 1022 1023 case SWRAP_CLOSE_ACK: 1024 if (si->type != SOCK_STREAM) return; 1025 1026 src_addr = (const struct sockaddr_in *)si->myname; 1027 dest_addr = (const struct sockaddr_in *)si->peername; 1028 1029 tcp_seq = si->io.pck_snd; 1030 tcp_ack = si->io.pck_rcv; 1031 tcp_ctl = 0x10; /* ACK */ 1032 1033 break; 1034 default: 1035 return; 1036 } 1037 1038 swrapGetTimeOfDay(&tv); 1039 1040 packet = swrap_packet_init(&tv, src_addr, dest_addr, si->type, 1041 (const unsigned char *)buf, len, 1042 tcp_seq, tcp_ack, tcp_ctl, unreachable, 1043 &packet_len); 1044 if (!packet) { 1045 return; 1046 } 1047 1048 fd = swrap_get_pcap_fd(file_name); 1049 if (fd != -1) { 1050 write(fd, packet, packet_len); 1051 } 1052 1053 free(packet); 1054} 1055 1056_PUBLIC_ int swrap_socket(int family, int type, int protocol) 1057{ 1058 struct socket_info *si; 1059 int fd; 1060 1061 if (!socket_wrapper_dir()) { 1062 return real_socket(family, type, protocol); 1063 } 1064 1065 switch (family) { 1066 case AF_INET: 1067 break; 1068 case AF_UNIX: 1069 return real_socket(family, type, protocol); 1070 default: 1071 errno = EAFNOSUPPORT; 1072 return -1; 1073 } 1074 1075 switch (type) { 1076 case SOCK_STREAM: 1077 break; 1078 case SOCK_DGRAM: 1079 break; 1080 default: 1081 errno = EPROTONOSUPPORT; 1082 return -1; 1083 } 1084 1085 switch (protocol) { 1086 case 0: 1087 break; 1088 default: 1089 errno = EPROTONOSUPPORT; 1090 return -1; 1091 } 1092 1093 fd = real_socket(AF_UNIX, type, 0); 1094 1095 if (fd == -1) return -1; 1096 1097 si = (struct socket_info *)calloc(1, sizeof(struct socket_info)); 1098 1099 si->family = family; 1100 si->type = type; 1101 si->protocol = protocol; 1102 si->fd = fd; 1103 1104 SWRAP_DLIST_ADD(sockets, si); 1105 1106 return si->fd; 1107} 1108 1109_PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) 1110{ 1111 struct socket_info *parent_si, *child_si; 1112 int fd; 1113 struct sockaddr_un un_addr; 1114 socklen_t un_addrlen = sizeof(un_addr); 1115 struct sockaddr_un un_my_addr; 1116 socklen_t un_my_addrlen = sizeof(un_my_addr); 1117 struct sockaddr my_addr; 1118 socklen_t my_addrlen = sizeof(my_addr); 1119 int ret; 1120 1121 parent_si = find_socket_info(s); 1122 if (!parent_si) { 1123 return real_accept(s, addr, addrlen); 1124 } 1125 1126 memset(&un_addr, 0, sizeof(un_addr)); 1127 memset(&un_my_addr, 0, sizeof(un_my_addr)); 1128 memset(&my_addr, 0, sizeof(my_addr)); 1129 1130 ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen); 1131 if (ret == -1) return ret; 1132 1133 fd = ret; 1134 1135 ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen, 1136 parent_si->family, addr, addrlen); 1137 if (ret == -1) { 1138 close(fd); 1139 return ret; 1140 } 1141 1142 child_si = (struct socket_info *)malloc(sizeof(struct socket_info)); 1143 memset(child_si, 0, sizeof(*child_si)); 1144 1145 child_si->fd = fd; 1146 child_si->family = parent_si->family; 1147 child_si->type = parent_si->type; 1148 child_si->protocol = parent_si->protocol; 1149 child_si->bound = 1; 1150 child_si->is_server = 1; 1151 1152 ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen); 1153 if (ret == -1) { 1154 free(child_si); 1155 close(fd); 1156 return ret; 1157 } 1158 1159 ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen, 1160 child_si->family, &my_addr, &my_addrlen); 1161 if (ret == -1) { 1162 free(child_si); 1163 close(fd); 1164 return ret; 1165 } 1166 1167 child_si->myname_len = my_addrlen; 1168 child_si->myname = sockaddr_dup(&my_addr, my_addrlen); 1169 1170 child_si->peername_len = *addrlen; 1171 child_si->peername = sockaddr_dup(addr, *addrlen); 1172 1173 SWRAP_DLIST_ADD(sockets, child_si); 1174 1175 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0); 1176 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0); 1177 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0); 1178 1179 return fd; 1180} 1181 1182static int autobind_start_init; 1183static int autobind_start; 1184 1185/* using sendto() or connect() on an unbound socket would give the 1186 recipient no way to reply, as unlike UDP and TCP, a unix domain 1187 socket can't auto-assign emphemeral port numbers, so we need to 1188 assign it here */ 1189static int swrap_auto_bind(struct socket_info *si) 1190{ 1191 struct sockaddr_un un_addr; 1192 struct sockaddr_in in; 1193 int i; 1194 char type; 1195 int ret; 1196 int port; 1197 struct stat st; 1198 1199 if (autobind_start_init != 1) { 1200 autobind_start_init = 1; 1201 autobind_start = getpid(); 1202 autobind_start %= 50000; 1203 autobind_start += 10000; 1204 } 1205 1206 un_addr.sun_family = AF_UNIX; 1207 1208 switch (si->type) { 1209 case SOCK_STREAM: 1210 type = SOCKET_TYPE_CHAR_TCP; 1211 break; 1212 case SOCK_DGRAM: 1213 type = SOCKET_TYPE_CHAR_UDP; 1214 break; 1215 default: 1216 errno = ESOCKTNOSUPPORT; 1217 return -1; 1218 } 1219 1220 if (autobind_start > 60000) { 1221 autobind_start = 10000; 1222 } 1223 1224 for (i=0;i<1000;i++) { 1225 port = autobind_start + i; 1226 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), 1227 "%s/"SOCKET_FORMAT, socket_wrapper_dir(), 1228 type, socket_wrapper_default_iface(), port); 1229 if (stat(un_addr.sun_path, &st) == 0) continue; 1230 1231 ret = real_bind(si->fd, (struct sockaddr *)&un_addr, sizeof(un_addr)); 1232 if (ret == -1) return ret; 1233 1234 si->tmp_path = strdup(un_addr.sun_path); 1235 si->bound = 1; 1236 autobind_start = port + 1; 1237 break; 1238 } 1239 if (i == 1000) { 1240 errno = ENFILE; 1241 return -1; 1242 } 1243 1244 memset(&in, 0, sizeof(in)); 1245 in.sin_family = AF_INET; 1246 in.sin_port = htons(port); 1247 in.sin_addr.s_addr = htonl(127<<24 | socket_wrapper_default_iface()); 1248 1249 si->myname_len = sizeof(in); 1250 si->myname = sockaddr_dup(&in, si->myname_len); 1251 return 0; 1252} 1253 1254 1255_PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) 1256{ 1257 int ret; 1258 struct sockaddr_un un_addr; 1259 struct socket_info *si = find_socket_info(s); 1260 1261 if (!si) { 1262 return real_connect(s, serv_addr, addrlen); 1263 } 1264 1265 if (si->bound == 0) { 1266 ret = swrap_auto_bind(si); 1267 if (ret == -1) return -1; 1268 } 1269 1270 ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL); 1271 if (ret == -1) return -1; 1272 1273 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0); 1274 1275 ret = real_connect(s, (struct sockaddr *)&un_addr, 1276 sizeof(struct sockaddr_un)); 1277 1278 /* to give better errors */ 1279 if (ret == -1 && errno == ENOENT) { 1280 errno = EHOSTUNREACH; 1281 } 1282 1283 if (ret == 0) { 1284 si->peername_len = addrlen; 1285 si->peername = sockaddr_dup(serv_addr, addrlen); 1286 1287 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0); 1288 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0); 1289 } else { 1290 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0); 1291 } 1292 1293 return ret; 1294} 1295 1296_PUBLIC_ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) 1297{ 1298 int ret; 1299 struct sockaddr_un un_addr; 1300 struct socket_info *si = find_socket_info(s); 1301 1302 if (!si) { 1303 return real_bind(s, myaddr, addrlen); 1304 } 1305 1306 si->myname_len = addrlen; 1307 si->myname = sockaddr_dup(myaddr, addrlen); 1308 1309 ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr, 1, &si->bcast); 1310 if (ret == -1) return -1; 1311 1312 unlink(un_addr.sun_path); 1313 1314 ret = real_bind(s, (struct sockaddr *)&un_addr, 1315 sizeof(struct sockaddr_un)); 1316 1317 if (ret == 0) { 1318 si->bound = 1; 1319 } 1320 1321 return ret; 1322} 1323 1324_PUBLIC_ int swrap_listen(int s, int backlog) 1325{ 1326 int ret; 1327 struct socket_info *si = find_socket_info(s); 1328 1329 if (!si) { 1330 return real_listen(s, backlog); 1331 } 1332 1333 ret = real_listen(s, backlog); 1334 1335 return ret; 1336} 1337 1338_PUBLIC_ int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen) 1339{ 1340 struct socket_info *si = find_socket_info(s); 1341 1342 if (!si) { 1343 return real_getpeername(s, name, addrlen); 1344 } 1345 1346 if (!si->peername) 1347 { 1348 errno = ENOTCONN; 1349 return -1; 1350 } 1351 1352 memcpy(name, si->peername, si->peername_len); 1353 *addrlen = si->peername_len; 1354 1355 return 0; 1356} 1357 1358_PUBLIC_ int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen) 1359{ 1360 struct socket_info *si = find_socket_info(s); 1361 1362 if (!si) { 1363 return real_getsockname(s, name, addrlen); 1364 } 1365 1366 memcpy(name, si->myname, si->myname_len); 1367 *addrlen = si->myname_len; 1368 1369 return 0; 1370} 1371 1372_PUBLIC_ int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) 1373{ 1374 struct socket_info *si = find_socket_info(s); 1375 1376 if (!si) { 1377 return real_getsockopt(s, level, optname, optval, optlen); 1378 } 1379 1380 if (level == SOL_SOCKET) { 1381 return real_getsockopt(s, level, optname, optval, optlen); 1382 } 1383 1384 errno = ENOPROTOOPT; 1385 return -1; 1386} 1387 1388_PUBLIC_ int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) 1389{ 1390 struct socket_info *si = find_socket_info(s); 1391 1392 if (!si) { 1393 return real_setsockopt(s, level, optname, optval, optlen); 1394 } 1395 1396 if (level == SOL_SOCKET) { 1397 return real_setsockopt(s, level, optname, optval, optlen); 1398 } 1399 1400 switch (si->family) { 1401 case AF_INET: 1402 return 0; 1403 default: 1404 errno = ENOPROTOOPT; 1405 return -1; 1406 } 1407} 1408 1409_PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) 1410{ 1411 struct sockaddr_un un_addr; 1412 socklen_t un_addrlen = sizeof(un_addr); 1413 int ret; 1414 struct socket_info *si = find_socket_info(s); 1415 1416 if (!si) { 1417 return real_recvfrom(s, buf, len, flags, from, fromlen); 1418 } 1419 1420 /* irix 6.4 forgets to null terminate the sun_path string :-( */ 1421 memset(&un_addr, 0, sizeof(un_addr)); 1422 ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, &un_addrlen); 1423 if (ret == -1) 1424 return ret; 1425 1426 if (sockaddr_convert_from_un(si, &un_addr, un_addrlen, 1427 si->family, from, fromlen) == -1) { 1428 return -1; 1429 } 1430 1431 swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret); 1432 1433 return ret; 1434} 1435 1436 1437_PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) 1438{ 1439 struct sockaddr_un un_addr; 1440 int ret; 1441 struct socket_info *si = find_socket_info(s); 1442 int bcast = 0; 1443 1444 if (!si) { 1445 return real_sendto(s, buf, len, flags, to, tolen); 1446 } 1447 1448 if (si->bound == 0) { 1449 ret = swrap_auto_bind(si); 1450 if (ret == -1) return -1; 1451 } 1452 1453 ret = sockaddr_convert_to_un(si, to, tolen, &un_addr, 0, &bcast); 1454 if (ret == -1) return -1; 1455 1456 if (bcast) { 1457 struct stat st; 1458 unsigned int iface; 1459 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port); 1460 char type; 1461 1462 type = SOCKET_TYPE_CHAR_UDP; 1463 1464 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) { 1465 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, 1466 socket_wrapper_dir(), type, iface, prt); 1467 if (stat(un_addr.sun_path, &st) != 0) continue; 1468 1469 /* ignore the any errors in broadcast sends */ 1470 real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); 1471 } 1472 1473 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len); 1474 1475 return len; 1476 } 1477 1478 ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); 1479 1480 /* to give better errors */ 1481 if (ret == -1 && errno == ENOENT) { 1482 errno = EHOSTUNREACH; 1483 } 1484 1485 if (ret == -1) { 1486 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len); 1487 swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len); 1488 } else { 1489 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, ret); 1490 } 1491 1492 return ret; 1493} 1494 1495_PUBLIC_ int swrap_ioctl(int s, int r, void *p) 1496{ 1497 int ret; 1498 struct socket_info *si = find_socket_info(s); 1499 int value; 1500 1501 if (!si) { 1502 return real_ioctl(s, r, p); 1503 } 1504 1505 ret = real_ioctl(s, r, p); 1506 1507 switch (r) { 1508 case FIONREAD: 1509 value = *((int *)p); 1510 if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) { 1511 swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0); 1512 } else if (value == 0) { /* END OF FILE */ 1513 swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0); 1514 } 1515 break; 1516 } 1517 1518 return ret; 1519} 1520 1521_PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags) 1522{ 1523 int ret; 1524 struct socket_info *si = find_socket_info(s); 1525 1526 if (!si) { 1527 return real_recv(s, buf, len, flags); 1528 } 1529 1530 ret = real_recv(s, buf, len, flags); 1531 if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) { 1532 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); 1533 } else if (ret == 0) { /* END OF FILE */ 1534 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); 1535 } else { 1536 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret); 1537 } 1538 1539 return ret; 1540} 1541 1542 1543_PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags) 1544{ 1545 int ret; 1546 struct socket_info *si = find_socket_info(s); 1547 1548 if (!si) { 1549 return real_send(s, buf, len, flags); 1550 } 1551 1552 ret = real_send(s, buf, len, flags); 1553 1554 if (ret == -1) { 1555 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len); 1556 swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0); 1557 } else { 1558 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret); 1559 } 1560 1561 return ret; 1562} 1563 1564_PUBLIC_ int swrap_close(int fd) 1565{ 1566 struct socket_info *si = find_socket_info(fd); 1567 int ret; 1568 1569 if (!si) { 1570 return real_close(fd); 1571 } 1572 1573 SWRAP_DLIST_REMOVE(sockets, si); 1574 1575 if (si->myname && si->peername) { 1576 swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0); 1577 } 1578 1579 ret = real_close(fd); 1580 1581 if (si->myname && si->peername) { 1582 swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0); 1583 swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0); 1584 } 1585 1586 if (si->path) free(si->path); 1587 if (si->myname) free(si->myname); 1588 if (si->peername) free(si->peername); 1589 if (si->tmp_path) { 1590 unlink(si->tmp_path); 1591 free(si->tmp_path); 1592 } 1593 free(si); 1594 1595 return ret; 1596} 1597