_PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) { struct sockaddr_un un_addr; int ret; struct socket_info *si = find_socket_info(s); int bcast = 0; if (!si) { return real_sendto(s, buf, len, flags, to, tolen); } if (si->bound == 0) { ret = swrap_auto_bind(si); if (ret == -1) return -1; } ret = sockaddr_convert_to_un(si, to, tolen, &un_addr, 0, &bcast); if (ret == -1) return -1; if (bcast) { struct stat st; unsigned int iface; unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port); char type; type = SOCKET_TYPE_CHAR_UDP; for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) { snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, socket_wrapper_dir(), type, iface, prt); if (stat(un_addr.sun_path, &st) != 0) continue; /* ignore the any errors in broadcast sends */ real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); } swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len); return len; } ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); /* to give better errors */ if (ret == -1 && errno == ENOENT) { errno = EHOSTUNREACH; } if (ret == -1) { swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len); swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len); } else { swrap_dump_packet(si, to, SWRAP_SENDTO, buf, ret); } return ret; }
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) { static ssize_t (*real_sendto)(int, const void*, size_t, int, const struct sockaddr*, socklen_t) = NULL; static int i = -1; static int drop_every = 0; if (real_sendto == NULL) { real_sendto = dlsym(RTLD_NEXT, "sendto"); } if (drop_every == 0) { return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen); } i = (i + 1) % drop_every; if (i == 0) { fprintf(stderr, "tester: drop packet\n"); return len; } else { return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen); } }
ssize_t sendto(int socket, const void *buffer, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len) { static struct sockaddr_in *dest_addr_in; dest_addr_in = (struct sockaddr_in *)dest_addr; if (dest_addr_in->sin_port == old_port) { static struct sockaddr_storage new_dest_addr; memcpy(&new_dest_addr, dest_addr, dest_len); static struct sockaddr_in *new_dest_addr_in; new_dest_addr_in = (struct sockaddr_in *)&new_dest_addr; new_dest_addr_in->sin_port = new_port; return real_sendto(socket, buffer, length, flags, (struct sockaddr *)&new_dest_addr, dest_len); } return real_sendto(socket, buffer, length, flags, dest_addr, dest_len); }
static ssize_t default_sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) { init_write(); if (real_sendto == default_sendto) { debug("Failed to resolve 'sendto', returning EINVAL\n"); errno = EINVAL; return -1; } return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen); }
ssize_t sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) { ssize_t retval; print_trace ("%*ssendto(%d, %p, %d, %d, %p, %d)=...\n", indent, "", s, buf, len, flags, to, tolen); indent+=2; /* call the real sendto function */ retval = real_sendto (s, buf, len, flags, to, tolen); indent-=2; print_trace ("%*ssendto(%d, %p, %d, %d, %p, %d)=%d\n", indent, "", s, buf, len, flags, to, tolen, retval); return retval; }
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr * dest_addr, socklen_t addrlen) { ssize_t rc = real_sendto(sockfd, buf, len, flags, dest_addr, addrlen); if (buf && len) { /** * We violate the prototype here as buf is a const void * We should not change the content of buf but ... * most of the time it is harmless and it allows to * guaranty that the data is indeed zeroized as it is * not needed anymore * This might prevent some application to work if they do expect * their data to be still available after the write. */ memset((void *)buf, 0, len); } return rc; }