00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifdef _SAMBA_BUILD_
00043
00044 #define SOCKET_WRAPPER_NOT_REPLACE
00045 #include "includes.h"
00046 #include "system/network.h"
00047 #include "system/filesys.h"
00048
00049 #ifdef malloc
00050 #undef malloc
00051 #endif
00052 #ifdef calloc
00053 #undef calloc
00054 #endif
00055 #ifdef strdup
00056 #undef strdup
00057 #endif
00058
00059 #else
00060
00061 #include <sys/types.h>
00062 #include <sys/stat.h>
00063 #include <sys/socket.h>
00064 #include <sys/ioctl.h>
00065 #include <errno.h>
00066 #include <sys/un.h>
00067 #include <netinet/in.h>
00068 #include <netinet/tcp.h>
00069 #include <fcntl.h>
00070 #include <stdlib.h>
00071 #include <unistd.h>
00072 #include <string.h>
00073 #include <stdio.h>
00074
00075 #define _PUBLIC_
00076
00077 #endif
00078
00079 #define SWRAP_DLIST_ADD(list,item) do { \
00080 if (!(list)) { \
00081 (item)->prev = NULL; \
00082 (item)->next = NULL; \
00083 (list) = (item); \
00084 } else { \
00085 (item)->prev = NULL; \
00086 (item)->next = (list); \
00087 (list)->prev = (item); \
00088 (list) = (item); \
00089 } \
00090 } while (0)
00091
00092 #define SWRAP_DLIST_REMOVE(list,item) do { \
00093 if ((list) == (item)) { \
00094 (list) = (item)->next; \
00095 if (list) { \
00096 (list)->prev = NULL; \
00097 } \
00098 } else { \
00099 if ((item)->prev) { \
00100 (item)->prev->next = (item)->next; \
00101 } \
00102 if ((item)->next) { \
00103 (item)->next->prev = (item)->prev; \
00104 } \
00105 } \
00106 (item)->prev = NULL; \
00107 (item)->next = NULL; \
00108 } while (0)
00109
00110
00111
00112 #define REWRITE_CALLS
00113
00114 #ifdef REWRITE_CALLS
00115 #define real_accept accept
00116 #define real_connect connect
00117 #define real_bind bind
00118 #define real_listen listen
00119 #define real_getpeername getpeername
00120 #define real_getsockname getsockname
00121 #define real_getsockopt getsockopt
00122 #define real_setsockopt setsockopt
00123 #define real_recvfrom recvfrom
00124 #define real_sendto sendto
00125 #define real_ioctl ioctl
00126 #define real_recv recv
00127 #define real_send send
00128 #define real_socket socket
00129 #define real_close close
00130 #endif
00131
00132 #ifdef HAVE_GETTIMEOFDAY_TZ
00133 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
00134 #else
00135 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
00136 #endif
00137
00138
00139
00140
00141
00142
00143
00144 #define SOCKET_FORMAT "%c%02X%04X"
00145 #define SOCKET_TYPE_CHAR_TCP 'T'
00146 #define SOCKET_TYPE_CHAR_UDP 'U'
00147
00148 #define MAX_WRAPPED_INTERFACES 16
00149
00150 static struct sockaddr *sockaddr_dup(const void *data, socklen_t len)
00151 {
00152 struct sockaddr *ret = (struct sockaddr *)malloc(len);
00153 memcpy(ret, data, len);
00154 return ret;
00155 }
00156
00157 struct socket_info
00158 {
00159 int fd;
00160
00161 int family;
00162 int type;
00163 int protocol;
00164 int bound;
00165 int bcast;
00166 int is_server;
00167
00168 char *path;
00169 char *tmp_path;
00170
00171 struct sockaddr *myname;
00172 socklen_t myname_len;
00173
00174 struct sockaddr *peername;
00175 socklen_t peername_len;
00176
00177 struct {
00178 unsigned long pck_snd;
00179 unsigned long pck_rcv;
00180 } io;
00181
00182 struct socket_info *prev, *next;
00183 };
00184
00185 static struct socket_info *sockets;
00186
00187
00188 static const char *socket_wrapper_dir(void)
00189 {
00190 const char *s = getenv("SOCKET_WRAPPER_DIR");
00191 if (s == NULL) {
00192 return NULL;
00193 }
00194 if (strncmp(s, "./", 2) == 0) {
00195 s += 2;
00196 }
00197 return s;
00198 }
00199
00200 static unsigned int socket_wrapper_default_iface(void)
00201 {
00202 const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
00203 if (s) {
00204 unsigned int iface;
00205 if (sscanf(s, "%u", &iface) == 1) {
00206 if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) {
00207 return iface;
00208 }
00209 }
00210 }
00211
00212 return 1;
00213 }
00214
00215 static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, socklen_t *len)
00216 {
00217 unsigned int iface;
00218 unsigned int prt;
00219 const char *p;
00220 char type;
00221
00222 if ((*len) < sizeof(struct sockaddr_in)) {
00223 return 0;
00224 }
00225
00226 p = strrchr(un->sun_path, '/');
00227 if (p) p++; else p = un->sun_path;
00228
00229 if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) {
00230 errno = EINVAL;
00231 return -1;
00232 }
00233
00234 if (type != SOCKET_TYPE_CHAR_TCP && type != SOCKET_TYPE_CHAR_UDP) {
00235 errno = EINVAL;
00236 return -1;
00237 }
00238
00239 if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
00240 errno = EINVAL;
00241 return -1;
00242 }
00243
00244 if (prt > 0xFFFF) {
00245 errno = EINVAL;
00246 return -1;
00247 }
00248
00249 in->sin_family = AF_INET;
00250 in->sin_addr.s_addr = htonl((127<<24) | iface);
00251 in->sin_port = htons(prt);
00252
00253 *len = sizeof(struct sockaddr_in);
00254 return 0;
00255 }
00256
00257 static int convert_in_un_remote(struct socket_info *si, const struct sockaddr_in *in, struct sockaddr_un *un,
00258 int *bcast)
00259 {
00260 char u_type = '\0';
00261 char b_type = '\0';
00262 char a_type = '\0';
00263 char type = '\0';
00264 unsigned int addr= ntohl(in->sin_addr.s_addr);
00265 unsigned int prt = ntohs(in->sin_port);
00266 unsigned int iface;
00267 int is_bcast = 0;
00268
00269 if (bcast) *bcast = 0;
00270
00271 if (prt == 0) {
00272 errno = EINVAL;
00273 return -1;
00274 }
00275
00276 switch (si->type) {
00277 case SOCK_STREAM:
00278 u_type = SOCKET_TYPE_CHAR_TCP;
00279 break;
00280 case SOCK_DGRAM:
00281 u_type = SOCKET_TYPE_CHAR_UDP;
00282 a_type = SOCKET_TYPE_CHAR_UDP;
00283 b_type = SOCKET_TYPE_CHAR_UDP;
00284 break;
00285 }
00286
00287 if (a_type && addr == 0xFFFFFFFF) {
00288
00289 is_bcast = 2;
00290 type = a_type;
00291 iface = socket_wrapper_default_iface();
00292 } else if (b_type && addr == 0x7FFFFFFF) {
00293
00294 is_bcast = 1;
00295 type = b_type;
00296 iface = socket_wrapper_default_iface();
00297 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
00298
00299 is_bcast = 0;
00300 type = u_type;
00301 iface = (addr & 0x000000FF);
00302 } else {
00303 errno = ENETUNREACH;
00304 return -1;
00305 }
00306
00307 if (bcast) *bcast = is_bcast;
00308
00309 if (is_bcast) {
00310 snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL",
00311 socket_wrapper_dir());
00312
00313 return 0;
00314 }
00315
00316 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
00317 socket_wrapper_dir(), type, iface, prt);
00318
00319 return 0;
00320 }
00321
00322 static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr_in *in, struct sockaddr_un *un,
00323 int *bcast)
00324 {
00325 char u_type = '\0';
00326 char d_type = '\0';
00327 char b_type = '\0';
00328 char a_type = '\0';
00329 char type = '\0';
00330 unsigned int addr= ntohl(in->sin_addr.s_addr);
00331 unsigned int prt = ntohs(in->sin_port);
00332 unsigned int iface;
00333 struct stat st;
00334 int is_bcast = 0;
00335
00336 if (bcast) *bcast = 0;
00337
00338 switch (si->type) {
00339 case SOCK_STREAM:
00340 u_type = SOCKET_TYPE_CHAR_TCP;
00341 d_type = SOCKET_TYPE_CHAR_TCP;
00342 break;
00343 case SOCK_DGRAM:
00344 u_type = SOCKET_TYPE_CHAR_UDP;
00345 d_type = SOCKET_TYPE_CHAR_UDP;
00346 a_type = SOCKET_TYPE_CHAR_UDP;
00347 b_type = SOCKET_TYPE_CHAR_UDP;
00348 break;
00349 }
00350
00351 if (addr == 0) {
00352
00353 is_bcast = 0;
00354 type = d_type;
00355 iface = socket_wrapper_default_iface();
00356 } else if (a_type && addr == 0xFFFFFFFF) {
00357
00358 is_bcast = 2;
00359 type = a_type;
00360 iface = socket_wrapper_default_iface();
00361 } else if (b_type && addr == 0x7FFFFFFF) {
00362
00363 is_bcast = 1;
00364 type = b_type;
00365 iface = socket_wrapper_default_iface();
00366 } else if ((addr & 0xFFFFFF00) == 0x7F000000) {
00367
00368 is_bcast = 0;
00369 type = u_type;
00370 iface = (addr & 0x000000FF);
00371 } else {
00372 errno = EADDRNOTAVAIL;
00373 return -1;
00374 }
00375
00376 if (bcast) *bcast = is_bcast;
00377
00378 if (prt == 0) {
00379
00380 for (prt = 5001; prt < 10000; prt++) {
00381 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
00382 socket_wrapper_dir(), type, iface, prt);
00383 if (stat(un->sun_path, &st) == 0) continue;
00384
00385 ((struct sockaddr_in *)si->myname)->sin_port = htons(prt);
00386 return 0;
00387 }
00388 errno = ENFILE;
00389 return -1;
00390 }
00391
00392 snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
00393 socket_wrapper_dir(), type, iface, prt);
00394 return 0;
00395 }
00396
00397 static struct socket_info *find_socket_info(int fd)
00398 {
00399 struct socket_info *i;
00400 for (i = sockets; i; i = i->next) {
00401 if (i->fd == fd)
00402 return i;
00403 }
00404
00405 return NULL;
00406 }
00407
00408 static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len,
00409 struct sockaddr_un *out_addr, int alloc_sock, int *bcast)
00410 {
00411 if (!out_addr)
00412 return 0;
00413
00414 out_addr->sun_family = AF_UNIX;
00415
00416 switch (in_addr->sa_family) {
00417 case AF_INET:
00418 switch (si->type) {
00419 case SOCK_STREAM:
00420 case SOCK_DGRAM:
00421 break;
00422 default:
00423 errno = ESOCKTNOSUPPORT;
00424 return -1;
00425 }
00426 if (alloc_sock) {
00427 return convert_in_un_alloc(si, (const struct sockaddr_in *)in_addr, out_addr, bcast);
00428 } else {
00429 return convert_in_un_remote(si, (const struct sockaddr_in *)in_addr, out_addr, bcast);
00430 }
00431 default:
00432 break;
00433 }
00434
00435 errno = EAFNOSUPPORT;
00436 return -1;
00437 }
00438
00439 static int sockaddr_convert_from_un(const struct socket_info *si,
00440 const struct sockaddr_un *in_addr,
00441 socklen_t un_addrlen,
00442 int family,
00443 struct sockaddr *out_addr,
00444 socklen_t *_out_addrlen)
00445 {
00446 socklen_t out_addrlen;
00447
00448 if (out_addr == NULL || _out_addrlen == NULL)
00449 return 0;
00450
00451 if (un_addrlen == 0) {
00452 *_out_addrlen = 0;
00453 return 0;
00454 }
00455
00456 out_addrlen = *_out_addrlen;
00457 if (out_addrlen > un_addrlen) {
00458 out_addrlen = un_addrlen;
00459 }
00460
00461 switch (family) {
00462 case AF_INET:
00463 switch (si->type) {
00464 case SOCK_STREAM:
00465 case SOCK_DGRAM:
00466 break;
00467 default:
00468 errno = ESOCKTNOSUPPORT;
00469 return -1;
00470 }
00471 return convert_un_in(in_addr, (struct sockaddr_in *)out_addr, _out_addrlen);
00472 default:
00473 break;
00474 }
00475
00476 errno = EAFNOSUPPORT;
00477 return -1;
00478 }
00479
00480 enum swrap_packet_type {
00481 SWRAP_CONNECT_SEND,
00482 SWRAP_CONNECT_UNREACH,
00483 SWRAP_CONNECT_RECV,
00484 SWRAP_CONNECT_ACK,
00485 SWRAP_ACCEPT_SEND,
00486 SWRAP_ACCEPT_RECV,
00487 SWRAP_ACCEPT_ACK,
00488 SWRAP_RECVFROM,
00489 SWRAP_SENDTO,
00490 SWRAP_SENDTO_UNREACH,
00491 SWRAP_PENDING_RST,
00492 SWRAP_RECV,
00493 SWRAP_RECV_RST,
00494 SWRAP_SEND,
00495 SWRAP_SEND_RST,
00496 SWRAP_CLOSE_SEND,
00497 SWRAP_CLOSE_RECV,
00498 SWRAP_CLOSE_ACK
00499 };
00500
00501 struct swrap_file_hdr {
00502 unsigned long magic;
00503 unsigned short version_major;
00504 unsigned short version_minor;
00505 long timezone;
00506 unsigned long sigfigs;
00507 unsigned long frame_max_len;
00508 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
00509 unsigned long link_type;
00510 };
00511 #define SWRAP_FILE_HDR_SIZE 24
00512
00513 struct swrap_packet {
00514 struct {
00515 unsigned long seconds;
00516 unsigned long micro_seconds;
00517 unsigned long recorded_length;
00518 unsigned long full_length;
00519 } frame;
00520 #define SWRAP_PACKET__FRAME_SIZE 16
00521
00522 struct {
00523 struct {
00524 unsigned char ver_hdrlen;
00525 unsigned char tos;
00526 unsigned short packet_length;
00527 unsigned short identification;
00528 unsigned char flags;
00529 unsigned char fragment;
00530 unsigned char ttl;
00531 unsigned char protocol;
00532 unsigned short hdr_checksum;
00533 unsigned long src_addr;
00534 unsigned long dest_addr;
00535 } hdr;
00536 #define SWRAP_PACKET__IP_HDR_SIZE 20
00537
00538 union {
00539 struct {
00540 unsigned short source_port;
00541 unsigned short dest_port;
00542 unsigned long seq_num;
00543 unsigned long ack_num;
00544 unsigned char hdr_length;
00545 unsigned char control;
00546 unsigned short window;
00547 unsigned short checksum;
00548 unsigned short urg;
00549 } tcp;
00550 #define SWRAP_PACKET__IP_P_TCP_SIZE 20
00551 struct {
00552 unsigned short source_port;
00553 unsigned short dest_port;
00554 unsigned short length;
00555 unsigned short checksum;
00556 } udp;
00557 #define SWRAP_PACKET__IP_P_UDP_SIZE 8
00558 struct {
00559 unsigned char type;
00560 unsigned char code;
00561 unsigned short checksum;
00562 unsigned long unused;
00563 } icmp;
00564 #define SWRAP_PACKET__IP_P_ICMP_SIZE 8
00565 } p;
00566 } ip;
00567 };
00568 #define SWRAP_PACKET_SIZE 56
00569
00570 static const char *socket_wrapper_pcap_file(void)
00571 {
00572 static int initialized = 0;
00573 static const char *s = NULL;
00574 static const struct swrap_file_hdr h;
00575 static const struct swrap_packet p;
00576
00577 if (initialized == 1) {
00578 return s;
00579 }
00580 initialized = 1;
00581
00582
00583
00584
00585
00586
00587
00588
00589 if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
00590 return NULL;
00591 }
00592 if (sizeof(p) != SWRAP_PACKET_SIZE) {
00593 return NULL;
00594 }
00595 if (sizeof(p.frame) != SWRAP_PACKET__FRAME_SIZE) {
00596 return NULL;
00597 }
00598 if (sizeof(p.ip.hdr) != SWRAP_PACKET__IP_HDR_SIZE) {
00599 return NULL;
00600 }
00601 if (sizeof(p.ip.p.tcp) != SWRAP_PACKET__IP_P_TCP_SIZE) {
00602 return NULL;
00603 }
00604 if (sizeof(p.ip.p.udp) != SWRAP_PACKET__IP_P_UDP_SIZE) {
00605 return NULL;
00606 }
00607 if (sizeof(p.ip.p.icmp) != SWRAP_PACKET__IP_P_ICMP_SIZE) {
00608 return NULL;
00609 }
00610
00611 s = getenv("SOCKET_WRAPPER_PCAP_FILE");
00612 if (s == NULL) {
00613 return NULL;
00614 }
00615 if (strncmp(s, "./", 2) == 0) {
00616 s += 2;
00617 }
00618 return s;
00619 }
00620
00621 static struct swrap_packet *swrap_packet_init(struct timeval *tval,
00622 const struct sockaddr_in *src_addr,
00623 const struct sockaddr_in *dest_addr,
00624 int socket_type,
00625 const unsigned char *payload,
00626 size_t payload_len,
00627 unsigned long tcp_seq,
00628 unsigned long tcp_ack,
00629 unsigned char tcp_ctl,
00630 int unreachable,
00631 size_t *_packet_len)
00632 {
00633 struct swrap_packet *ret;
00634 struct swrap_packet *packet;
00635 size_t packet_len;
00636 size_t alloc_len;
00637 size_t nonwire_len = sizeof(packet->frame);
00638 size_t wire_hdr_len = 0;
00639 size_t wire_len = 0;
00640 size_t icmp_hdr_len = 0;
00641 size_t icmp_truncate_len = 0;
00642 unsigned char protocol = 0, icmp_protocol = 0;
00643 unsigned short src_port = src_addr->sin_port;
00644 unsigned short dest_port = dest_addr->sin_port;
00645
00646 switch (socket_type) {
00647 case SOCK_STREAM:
00648 protocol = 0x06;
00649 wire_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.tcp);
00650 wire_len = wire_hdr_len + payload_len;
00651 break;
00652
00653 case SOCK_DGRAM:
00654 protocol = 0x11;
00655 wire_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.udp);
00656 wire_len = wire_hdr_len + payload_len;
00657 break;
00658 }
00659
00660 if (unreachable) {
00661 icmp_protocol = protocol;
00662 protocol = 0x01;
00663 if (wire_len > 64 ) {
00664 icmp_truncate_len = wire_len - 64;
00665 }
00666 icmp_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.icmp);
00667 wire_hdr_len += icmp_hdr_len;
00668 wire_len += icmp_hdr_len;
00669 }
00670
00671 packet_len = nonwire_len + wire_len;
00672 alloc_len = packet_len;
00673 if (alloc_len < sizeof(struct swrap_packet)) {
00674 alloc_len = sizeof(struct swrap_packet);
00675 }
00676 ret = (struct swrap_packet *)malloc(alloc_len);
00677 if (!ret) return NULL;
00678
00679 packet = ret;
00680
00681 packet->frame.seconds = tval->tv_sec;
00682 packet->frame.micro_seconds = tval->tv_usec;
00683 packet->frame.recorded_length = wire_len - icmp_truncate_len;
00684 packet->frame.full_length = wire_len - icmp_truncate_len;
00685
00686 packet->ip.hdr.ver_hdrlen = 0x45;
00687 packet->ip.hdr.tos = 0x00;
00688 packet->ip.hdr.packet_length = htons(wire_len - icmp_truncate_len);
00689 packet->ip.hdr.identification = htons(0xFFFF);
00690 packet->ip.hdr.flags = 0x40;
00691 packet->ip.hdr.fragment = htons(0x0000);
00692 packet->ip.hdr.ttl = 0xFF;
00693 packet->ip.hdr.protocol = protocol;
00694 packet->ip.hdr.hdr_checksum = htons(0x0000);
00695 packet->ip.hdr.src_addr = src_addr->sin_addr.s_addr;
00696 packet->ip.hdr.dest_addr = dest_addr->sin_addr.s_addr;
00697
00698 if (unreachable) {
00699 packet->ip.p.icmp.type = 0x03;
00700 packet->ip.p.icmp.code = 0x01;
00701 packet->ip.p.icmp.checksum = htons(0x0000);
00702 packet->ip.p.icmp.unused = htonl(0x00000000);
00703
00704
00705 packet = (struct swrap_packet *)(((unsigned char *)ret) + icmp_hdr_len);
00706 packet->ip.hdr.ver_hdrlen = 0x45;
00707 packet->ip.hdr.tos = 0x00;
00708 packet->ip.hdr.packet_length = htons(wire_len - icmp_hdr_len);
00709 packet->ip.hdr.identification = htons(0xFFFF);
00710 packet->ip.hdr.flags = 0x40;
00711 packet->ip.hdr.fragment = htons(0x0000);
00712 packet->ip.hdr.ttl = 0xFF;
00713 packet->ip.hdr.protocol = icmp_protocol;
00714 packet->ip.hdr.hdr_checksum = htons(0x0000);
00715 packet->ip.hdr.src_addr = dest_addr->sin_addr.s_addr;
00716 packet->ip.hdr.dest_addr = src_addr->sin_addr.s_addr;
00717
00718 src_port = dest_addr->sin_port;
00719 dest_port = src_addr->sin_port;
00720 }
00721
00722 switch (socket_type) {
00723 case SOCK_STREAM:
00724 packet->ip.p.tcp.source_port = src_port;
00725 packet->ip.p.tcp.dest_port = dest_port;
00726 packet->ip.p.tcp.seq_num = htonl(tcp_seq);
00727 packet->ip.p.tcp.ack_num = htonl(tcp_ack);
00728 packet->ip.p.tcp.hdr_length = 0x50;
00729 packet->ip.p.tcp.control = tcp_ctl;
00730 packet->ip.p.tcp.window = htons(0x7FFF);
00731 packet->ip.p.tcp.checksum = htons(0x0000);
00732 packet->ip.p.tcp.urg = htons(0x0000);
00733
00734 break;
00735
00736 case SOCK_DGRAM:
00737 packet->ip.p.udp.source_port = src_addr->sin_port;
00738 packet->ip.p.udp.dest_port = dest_addr->sin_port;
00739 packet->ip.p.udp.length = htons(8 + payload_len);
00740 packet->ip.p.udp.checksum = htons(0x0000);
00741
00742 break;
00743 }
00744
00745 if (payload && payload_len > 0) {
00746 unsigned char *p = (unsigned char *)ret;
00747 p += nonwire_len;
00748 p += wire_hdr_len;
00749 memcpy(p, payload, payload_len);
00750 }
00751
00752 *_packet_len = packet_len - icmp_truncate_len;
00753 return ret;
00754 }
00755
00756 static int swrap_get_pcap_fd(const char *fname)
00757 {
00758 static int fd = -1;
00759
00760 if (fd != -1) return fd;
00761
00762 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
00763 if (fd != -1) {
00764 struct swrap_file_hdr file_hdr;
00765 file_hdr.magic = 0xA1B2C3D4;
00766 file_hdr.version_major = 0x0002;
00767 file_hdr.version_minor = 0x0004;
00768 file_hdr.timezone = 0x00000000;
00769 file_hdr.sigfigs = 0x00000000;
00770 file_hdr.frame_max_len = SWRAP_FRAME_LENGTH_MAX;
00771 file_hdr.link_type = 0x0065;
00772
00773 write(fd, &file_hdr, sizeof(file_hdr));
00774 return fd;
00775 }
00776
00777 fd = open(fname, O_WRONLY|O_APPEND, 0644);
00778
00779 return fd;
00780 }
00781
00782 static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *addr,
00783 enum swrap_packet_type type,
00784 const void *buf, size_t len)
00785 {
00786 const struct sockaddr_in *src_addr;
00787 const struct sockaddr_in *dest_addr;
00788 const char *file_name;
00789 unsigned long tcp_seq = 0;
00790 unsigned long tcp_ack = 0;
00791 unsigned char tcp_ctl = 0;
00792 int unreachable = 0;
00793 struct timeval tv;
00794 struct swrap_packet *packet;
00795 size_t packet_len = 0;
00796 int fd;
00797
00798 file_name = socket_wrapper_pcap_file();
00799 if (!file_name) {
00800 return;
00801 }
00802
00803 if (si->family != AF_INET) {
00804 return;
00805 }
00806
00807 switch (type) {
00808 case SWRAP_CONNECT_SEND:
00809 if (si->type != SOCK_STREAM) return;
00810
00811 src_addr = (const struct sockaddr_in *)si->myname;
00812 dest_addr = (const struct sockaddr_in *)addr;
00813
00814 tcp_seq = si->io.pck_snd;
00815 tcp_ack = si->io.pck_rcv;
00816 tcp_ctl = 0x02;
00817
00818 si->io.pck_snd += 1;
00819
00820 break;
00821
00822 case SWRAP_CONNECT_RECV:
00823 if (si->type != SOCK_STREAM) return;
00824
00825 dest_addr = (const struct sockaddr_in *)si->myname;
00826 src_addr = (const struct sockaddr_in *)addr;
00827
00828 tcp_seq = si->io.pck_rcv;
00829 tcp_ack = si->io.pck_snd;
00830 tcp_ctl = 0x12;
00831
00832 si->io.pck_rcv += 1;
00833
00834 break;
00835
00836 case SWRAP_CONNECT_UNREACH:
00837 if (si->type != SOCK_STREAM) return;
00838
00839 dest_addr = (const struct sockaddr_in *)si->myname;
00840 src_addr = (const struct sockaddr_in *)addr;
00841
00842
00843 tcp_seq = si->io.pck_snd - 1;
00844 tcp_ack = si->io.pck_rcv;
00845 tcp_ctl = 0x02;
00846 unreachable = 1;
00847
00848 break;
00849
00850 case SWRAP_CONNECT_ACK:
00851 if (si->type != SOCK_STREAM) return;
00852
00853 src_addr = (const struct sockaddr_in *)si->myname;
00854 dest_addr = (const struct sockaddr_in *)addr;
00855
00856 tcp_seq = si->io.pck_snd;
00857 tcp_ack = si->io.pck_rcv;
00858 tcp_ctl = 0x10;
00859
00860 break;
00861
00862 case SWRAP_ACCEPT_SEND:
00863 if (si->type != SOCK_STREAM) return;
00864
00865 dest_addr = (const struct sockaddr_in *)si->myname;
00866 src_addr = (const struct sockaddr_in *)addr;
00867
00868 tcp_seq = si->io.pck_rcv;
00869 tcp_ack = si->io.pck_snd;
00870 tcp_ctl = 0x02;
00871
00872 si->io.pck_rcv += 1;
00873
00874 break;
00875
00876 case SWRAP_ACCEPT_RECV:
00877 if (si->type != SOCK_STREAM) return;
00878
00879 src_addr = (const struct sockaddr_in *)si->myname;
00880 dest_addr = (const struct sockaddr_in *)addr;
00881
00882 tcp_seq = si->io.pck_snd;
00883 tcp_ack = si->io.pck_rcv;
00884 tcp_ctl = 0x12;
00885
00886 si->io.pck_snd += 1;
00887
00888 break;
00889
00890 case SWRAP_ACCEPT_ACK:
00891 if (si->type != SOCK_STREAM) return;
00892
00893 dest_addr = (const struct sockaddr_in *)si->myname;
00894 src_addr = (const struct sockaddr_in *)addr;
00895
00896 tcp_seq = si->io.pck_rcv;
00897 tcp_ack = si->io.pck_snd;
00898 tcp_ctl = 0x10;
00899
00900 break;
00901
00902 case SWRAP_SEND:
00903 src_addr = (const struct sockaddr_in *)si->myname;
00904 dest_addr = (const struct sockaddr_in *)si->peername;
00905
00906 tcp_seq = si->io.pck_snd;
00907 tcp_ack = si->io.pck_rcv;
00908 tcp_ctl = 0x18;
00909
00910 si->io.pck_snd += len;
00911
00912 break;
00913
00914 case SWRAP_SEND_RST:
00915 dest_addr = (const struct sockaddr_in *)si->myname;
00916 src_addr = (const struct sockaddr_in *)si->peername;
00917
00918 if (si->type == SOCK_DGRAM) {
00919 swrap_dump_packet(si, si->peername,
00920 SWRAP_SENDTO_UNREACH,
00921 buf, len);
00922 return;
00923 }
00924
00925 tcp_seq = si->io.pck_rcv;
00926 tcp_ack = si->io.pck_snd;
00927 tcp_ctl = 0x14;
00928
00929 break;
00930
00931 case SWRAP_PENDING_RST:
00932 dest_addr = (const struct sockaddr_in *)si->myname;
00933 src_addr = (const struct sockaddr_in *)si->peername;
00934
00935 if (si->type == SOCK_DGRAM) {
00936 return;
00937 }
00938
00939 tcp_seq = si->io.pck_rcv;
00940 tcp_ack = si->io.pck_snd;
00941 tcp_ctl = 0x14;
00942
00943 break;
00944
00945 case SWRAP_RECV:
00946 dest_addr = (const struct sockaddr_in *)si->myname;
00947 src_addr = (const struct sockaddr_in *)si->peername;
00948
00949 tcp_seq = si->io.pck_rcv;
00950 tcp_ack = si->io.pck_snd;
00951 tcp_ctl = 0x18;
00952
00953 si->io.pck_rcv += len;
00954
00955 break;
00956
00957 case SWRAP_RECV_RST:
00958 dest_addr = (const struct sockaddr_in *)si->myname;
00959 src_addr = (const struct sockaddr_in *)si->peername;
00960
00961 if (si->type == SOCK_DGRAM) {
00962 return;
00963 }
00964
00965 tcp_seq = si->io.pck_rcv;
00966 tcp_ack = si->io.pck_snd;
00967 tcp_ctl = 0x14;
00968
00969 break;
00970
00971 case SWRAP_SENDTO:
00972 src_addr = (const struct sockaddr_in *)si->myname;
00973 dest_addr = (const struct sockaddr_in *)addr;
00974
00975 si->io.pck_snd += len;
00976
00977 break;
00978
00979 case SWRAP_SENDTO_UNREACH:
00980 dest_addr = (const struct sockaddr_in *)si->myname;
00981 src_addr = (const struct sockaddr_in *)addr;
00982
00983 unreachable = 1;
00984
00985 break;
00986
00987 case SWRAP_RECVFROM:
00988 dest_addr = (const struct sockaddr_in *)si->myname;
00989 src_addr = (const struct sockaddr_in *)addr;
00990
00991 si->io.pck_rcv += len;
00992
00993 break;
00994
00995 case SWRAP_CLOSE_SEND:
00996 if (si->type != SOCK_STREAM) return;
00997
00998 src_addr = (const struct sockaddr_in *)si->myname;
00999 dest_addr = (const struct sockaddr_in *)si->peername;
01000
01001 tcp_seq = si->io.pck_snd;
01002 tcp_ack = si->io.pck_rcv;
01003 tcp_ctl = 0x11;
01004
01005 si->io.pck_snd += 1;
01006
01007 break;
01008
01009 case SWRAP_CLOSE_RECV:
01010 if (si->type != SOCK_STREAM) return;
01011
01012 dest_addr = (const struct sockaddr_in *)si->myname;
01013 src_addr = (const struct sockaddr_in *)si->peername;
01014
01015 tcp_seq = si->io.pck_rcv;
01016 tcp_ack = si->io.pck_snd;
01017 tcp_ctl = 0x11;
01018
01019 si->io.pck_rcv += 1;
01020
01021 break;
01022
01023 case SWRAP_CLOSE_ACK:
01024 if (si->type != SOCK_STREAM) return;
01025
01026 src_addr = (const struct sockaddr_in *)si->myname;
01027 dest_addr = (const struct sockaddr_in *)si->peername;
01028
01029 tcp_seq = si->io.pck_snd;
01030 tcp_ack = si->io.pck_rcv;
01031 tcp_ctl = 0x10;
01032
01033 break;
01034 default:
01035 return;
01036 }
01037
01038 swrapGetTimeOfDay(&tv);
01039
01040 packet = swrap_packet_init(&tv, src_addr, dest_addr, si->type,
01041 (const unsigned char *)buf, len,
01042 tcp_seq, tcp_ack, tcp_ctl, unreachable,
01043 &packet_len);
01044 if (!packet) {
01045 return;
01046 }
01047
01048 fd = swrap_get_pcap_fd(file_name);
01049 if (fd != -1) {
01050 write(fd, packet, packet_len);
01051 }
01052
01053 free(packet);
01054 }
01055
01056 _PUBLIC_ int swrap_socket(int family, int type, int protocol)
01057 {
01058 struct socket_info *si;
01059 int fd;
01060
01061 if (!socket_wrapper_dir()) {
01062 return real_socket(family, type, protocol);
01063 }
01064
01065 switch (family) {
01066 case AF_INET:
01067 break;
01068 case AF_UNIX:
01069 return real_socket(family, type, protocol);
01070 default:
01071 errno = EAFNOSUPPORT;
01072 return -1;
01073 }
01074
01075 switch (type) {
01076 case SOCK_STREAM:
01077 break;
01078 case SOCK_DGRAM:
01079 break;
01080 default:
01081 errno = EPROTONOSUPPORT;
01082 return -1;
01083 }
01084
01085 switch (protocol) {
01086 case 0:
01087 break;
01088 default:
01089 errno = EPROTONOSUPPORT;
01090 return -1;
01091 }
01092
01093 fd = real_socket(AF_UNIX, type, 0);
01094
01095 if (fd == -1) return -1;
01096
01097 si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
01098
01099 si->family = family;
01100 si->type = type;
01101 si->protocol = protocol;
01102 si->fd = fd;
01103
01104 SWRAP_DLIST_ADD(sockets, si);
01105
01106 return si->fd;
01107 }
01108
01109 _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
01110 {
01111 struct socket_info *parent_si, *child_si;
01112 int fd;
01113 struct sockaddr_un un_addr;
01114 socklen_t un_addrlen = sizeof(un_addr);
01115 struct sockaddr_un un_my_addr;
01116 socklen_t un_my_addrlen = sizeof(un_my_addr);
01117 struct sockaddr my_addr;
01118 socklen_t my_addrlen = sizeof(my_addr);
01119 int ret;
01120
01121 parent_si = find_socket_info(s);
01122 if (!parent_si) {
01123 return real_accept(s, addr, addrlen);
01124 }
01125
01126 memset(&un_addr, 0, sizeof(un_addr));
01127 memset(&un_my_addr, 0, sizeof(un_my_addr));
01128 memset(&my_addr, 0, sizeof(my_addr));
01129
01130 ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen);
01131 if (ret == -1) return ret;
01132
01133 fd = ret;
01134
01135 ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen,
01136 parent_si->family, addr, addrlen);
01137 if (ret == -1) {
01138 close(fd);
01139 return ret;
01140 }
01141
01142 child_si = (struct socket_info *)malloc(sizeof(struct socket_info));
01143 memset(child_si, 0, sizeof(*child_si));
01144
01145 child_si->fd = fd;
01146 child_si->family = parent_si->family;
01147 child_si->type = parent_si->type;
01148 child_si->protocol = parent_si->protocol;
01149 child_si->bound = 1;
01150 child_si->is_server = 1;
01151
01152 ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen);
01153 if (ret == -1) {
01154 free(child_si);
01155 close(fd);
01156 return ret;
01157 }
01158
01159 ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen,
01160 child_si->family, &my_addr, &my_addrlen);
01161 if (ret == -1) {
01162 free(child_si);
01163 close(fd);
01164 return ret;
01165 }
01166
01167 child_si->myname_len = my_addrlen;
01168 child_si->myname = sockaddr_dup(&my_addr, my_addrlen);
01169
01170 child_si->peername_len = *addrlen;
01171 child_si->peername = sockaddr_dup(addr, *addrlen);
01172
01173 SWRAP_DLIST_ADD(sockets, child_si);
01174
01175 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
01176 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
01177 swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
01178
01179 return fd;
01180 }
01181
01182 static int autobind_start_init;
01183 static int autobind_start;
01184
01185
01186
01187
01188
01189 static int swrap_auto_bind(struct socket_info *si)
01190 {
01191 struct sockaddr_un un_addr;
01192 struct sockaddr_in in;
01193 int i;
01194 char type;
01195 int ret;
01196 int port;
01197 struct stat st;
01198
01199 if (autobind_start_init != 1) {
01200 autobind_start_init = 1;
01201 autobind_start = getpid();
01202 autobind_start %= 50000;
01203 autobind_start += 10000;
01204 }
01205
01206 un_addr.sun_family = AF_UNIX;
01207
01208 switch (si->type) {
01209 case SOCK_STREAM:
01210 type = SOCKET_TYPE_CHAR_TCP;
01211 break;
01212 case SOCK_DGRAM:
01213 type = SOCKET_TYPE_CHAR_UDP;
01214 break;
01215 default:
01216 errno = ESOCKTNOSUPPORT;
01217 return -1;
01218 }
01219
01220 if (autobind_start > 60000) {
01221 autobind_start = 10000;
01222 }
01223
01224 for (i=0;i<1000;i++) {
01225 port = autobind_start + i;
01226 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path),
01227 "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
01228 type, socket_wrapper_default_iface(), port);
01229 if (stat(un_addr.sun_path, &st) == 0) continue;
01230
01231 ret = real_bind(si->fd, (struct sockaddr *)&un_addr, sizeof(un_addr));
01232 if (ret == -1) return ret;
01233
01234 si->tmp_path = strdup(un_addr.sun_path);
01235 si->bound = 1;
01236 autobind_start = port + 1;
01237 break;
01238 }
01239 if (i == 1000) {
01240 errno = ENFILE;
01241 return -1;
01242 }
01243
01244 memset(&in, 0, sizeof(in));
01245 in.sin_family = AF_INET;
01246 in.sin_port = htons(port);
01247 in.sin_addr.s_addr = htonl(127<<24 | socket_wrapper_default_iface());
01248
01249 si->myname_len = sizeof(in);
01250 si->myname = sockaddr_dup(&in, si->myname_len);
01251 return 0;
01252 }
01253
01254
01255 _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
01256 {
01257 int ret;
01258 struct sockaddr_un un_addr;
01259 struct socket_info *si = find_socket_info(s);
01260
01261 if (!si) {
01262 return real_connect(s, serv_addr, addrlen);
01263 }
01264
01265 if (si->bound == 0) {
01266 ret = swrap_auto_bind(si);
01267 if (ret == -1) return -1;
01268 }
01269
01270 ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL);
01271 if (ret == -1) return -1;
01272
01273 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
01274
01275 ret = real_connect(s, (struct sockaddr *)&un_addr,
01276 sizeof(struct sockaddr_un));
01277
01278
01279 if (ret == -1 && errno == ENOENT) {
01280 errno = EHOSTUNREACH;
01281 }
01282
01283 if (ret == 0) {
01284 si->peername_len = addrlen;
01285 si->peername = sockaddr_dup(serv_addr, addrlen);
01286
01287 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
01288 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
01289 } else {
01290 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
01291 }
01292
01293 return ret;
01294 }
01295
01296 _PUBLIC_ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
01297 {
01298 int ret;
01299 struct sockaddr_un un_addr;
01300 struct socket_info *si = find_socket_info(s);
01301
01302 if (!si) {
01303 return real_bind(s, myaddr, addrlen);
01304 }
01305
01306 si->myname_len = addrlen;
01307 si->myname = sockaddr_dup(myaddr, addrlen);
01308
01309 ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr, 1, &si->bcast);
01310 if (ret == -1) return -1;
01311
01312 unlink(un_addr.sun_path);
01313
01314 ret = real_bind(s, (struct sockaddr *)&un_addr,
01315 sizeof(struct sockaddr_un));
01316
01317 if (ret == 0) {
01318 si->bound = 1;
01319 }
01320
01321 return ret;
01322 }
01323
01324 _PUBLIC_ int swrap_listen(int s, int backlog)
01325 {
01326 int ret;
01327 struct socket_info *si = find_socket_info(s);
01328
01329 if (!si) {
01330 return real_listen(s, backlog);
01331 }
01332
01333 ret = real_listen(s, backlog);
01334
01335 return ret;
01336 }
01337
01338 _PUBLIC_ int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
01339 {
01340 struct socket_info *si = find_socket_info(s);
01341
01342 if (!si) {
01343 return real_getpeername(s, name, addrlen);
01344 }
01345
01346 if (!si->peername)
01347 {
01348 errno = ENOTCONN;
01349 return -1;
01350 }
01351
01352 memcpy(name, si->peername, si->peername_len);
01353 *addrlen = si->peername_len;
01354
01355 return 0;
01356 }
01357
01358 _PUBLIC_ int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
01359 {
01360 struct socket_info *si = find_socket_info(s);
01361
01362 if (!si) {
01363 return real_getsockname(s, name, addrlen);
01364 }
01365
01366 memcpy(name, si->myname, si->myname_len);
01367 *addrlen = si->myname_len;
01368
01369 return 0;
01370 }
01371
01372 _PUBLIC_ int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
01373 {
01374 struct socket_info *si = find_socket_info(s);
01375
01376 if (!si) {
01377 return real_getsockopt(s, level, optname, optval, optlen);
01378 }
01379
01380 if (level == SOL_SOCKET) {
01381 return real_getsockopt(s, level, optname, optval, optlen);
01382 }
01383
01384 errno = ENOPROTOOPT;
01385 return -1;
01386 }
01387
01388 _PUBLIC_ int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
01389 {
01390 struct socket_info *si = find_socket_info(s);
01391
01392 if (!si) {
01393 return real_setsockopt(s, level, optname, optval, optlen);
01394 }
01395
01396 if (level == SOL_SOCKET) {
01397 return real_setsockopt(s, level, optname, optval, optlen);
01398 }
01399
01400 switch (si->family) {
01401 case AF_INET:
01402 return 0;
01403 default:
01404 errno = ENOPROTOOPT;
01405 return -1;
01406 }
01407 }
01408
01409 _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
01410 {
01411 struct sockaddr_un un_addr;
01412 socklen_t un_addrlen = sizeof(un_addr);
01413 int ret;
01414 struct socket_info *si = find_socket_info(s);
01415
01416 if (!si) {
01417 return real_recvfrom(s, buf, len, flags, from, fromlen);
01418 }
01419
01420
01421 memset(&un_addr, 0, sizeof(un_addr));
01422 ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, &un_addrlen);
01423 if (ret == -1)
01424 return ret;
01425
01426 if (sockaddr_convert_from_un(si, &un_addr, un_addrlen,
01427 si->family, from, fromlen) == -1) {
01428 return -1;
01429 }
01430
01431 swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret);
01432
01433 return ret;
01434 }
01435
01436
01437 _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
01438 {
01439 struct sockaddr_un un_addr;
01440 int ret;
01441 struct socket_info *si = find_socket_info(s);
01442 int bcast = 0;
01443
01444 if (!si) {
01445 return real_sendto(s, buf, len, flags, to, tolen);
01446 }
01447
01448 if (si->bound == 0) {
01449 ret = swrap_auto_bind(si);
01450 if (ret == -1) return -1;
01451 }
01452
01453 ret = sockaddr_convert_to_un(si, to, tolen, &un_addr, 0, &bcast);
01454 if (ret == -1) return -1;
01455
01456 if (bcast) {
01457 struct stat st;
01458 unsigned int iface;
01459 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
01460 char type;
01461
01462 type = SOCKET_TYPE_CHAR_UDP;
01463
01464 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
01465 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
01466 socket_wrapper_dir(), type, iface, prt);
01467 if (stat(un_addr.sun_path, &st) != 0) continue;
01468
01469
01470 real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr));
01471 }
01472
01473 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
01474
01475 return len;
01476 }
01477
01478 ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr));
01479
01480
01481 if (ret == -1 && errno == ENOENT) {
01482 errno = EHOSTUNREACH;
01483 }
01484
01485 if (ret == -1) {
01486 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
01487 swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
01488 } else {
01489 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, ret);
01490 }
01491
01492 return ret;
01493 }
01494
01495 _PUBLIC_ int swrap_ioctl(int s, int r, void *p)
01496 {
01497 int ret;
01498 struct socket_info *si = find_socket_info(s);
01499 int value;
01500
01501 if (!si) {
01502 return real_ioctl(s, r, p);
01503 }
01504
01505 ret = real_ioctl(s, r, p);
01506
01507 switch (r) {
01508 case FIONREAD:
01509 value = *((int *)p);
01510 if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
01511 swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
01512 } else if (value == 0) {
01513 swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
01514 }
01515 break;
01516 }
01517
01518 return ret;
01519 }
01520
01521 _PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
01522 {
01523 int ret;
01524 struct socket_info *si = find_socket_info(s);
01525
01526 if (!si) {
01527 return real_recv(s, buf, len, flags);
01528 }
01529
01530 ret = real_recv(s, buf, len, flags);
01531 if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
01532 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
01533 } else if (ret == 0) {
01534 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
01535 } else {
01536 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
01537 }
01538
01539 return ret;
01540 }
01541
01542
01543 _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
01544 {
01545 int ret;
01546 struct socket_info *si = find_socket_info(s);
01547
01548 if (!si) {
01549 return real_send(s, buf, len, flags);
01550 }
01551
01552 ret = real_send(s, buf, len, flags);
01553
01554 if (ret == -1) {
01555 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
01556 swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
01557 } else {
01558 swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
01559 }
01560
01561 return ret;
01562 }
01563
01564 _PUBLIC_ int swrap_close(int fd)
01565 {
01566 struct socket_info *si = find_socket_info(fd);
01567 int ret;
01568
01569 if (!si) {
01570 return real_close(fd);
01571 }
01572
01573 SWRAP_DLIST_REMOVE(sockets, si);
01574
01575 if (si->myname && si->peername) {
01576 swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
01577 }
01578
01579 ret = real_close(fd);
01580
01581 if (si->myname && si->peername) {
01582 swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
01583 swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
01584 }
01585
01586 if (si->path) free(si->path);
01587 if (si->myname) free(si->myname);
01588 if (si->peername) free(si->peername);
01589 if (si->tmp_path) {
01590 unlink(si->tmp_path);
01591 free(si->tmp_path);
01592 }
01593 free(si);
01594
01595 return ret;
01596 }