#define real_sendmsg sendmsg
#define real_ioctl ioctl
#define real_recv recv
+#define real_read read
#define real_send send
#define real_readv readv
#define real_writev writev
if (bcast) *bcast = 0;
- switch (si->family) {
+ switch (inaddr->sa_family) {
case AF_INET: {
const struct sockaddr_in *in =
(const struct sockaddr_in *)inaddr;
SWRAP_SEND_RST,
SWRAP_CLOSE_SEND,
SWRAP_CLOSE_RECV,
- SWRAP_CLOSE_ACK
+ SWRAP_CLOSE_ACK,
};
struct swrap_file_hdr {
{
struct socket_info *si;
int fd;
+ int real_type = type;
+#ifdef SOCK_CLOEXEC
+ real_type &= ~SOCK_CLOEXEC;
+#endif
+#ifdef SOCK_NONBLOCK
+ real_type &= ~SOCK_NONBLOCK;
+#endif
if (!socket_wrapper_dir()) {
return real_socket(family, type, protocol);
return -1;
}
- switch (type) {
+ switch (real_type) {
case SOCK_STREAM:
break;
case SOCK_DGRAM:
case 0:
break;
case 6:
- if (type == SOCK_STREAM) {
+ if (real_type == SOCK_STREAM) {
break;
}
/*fall through*/
case 17:
- if (type == SOCK_DGRAM) {
+ if (real_type == SOCK_DGRAM) {
break;
}
/*fall through*/
return -1;
}
+ /* We must call real_socket with type, from the caller, not the version we removed
+ SOCK_CLOEXEC and SOCK_NONBLOCK from */
fd = real_socket(AF_UNIX, type, 0);
if (fd == -1) return -1;
si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
si->family = family;
- si->type = type;
+
+ /* however, the rest of the socket_wrapper code expects just
+ * the type, not the flags */
+ si->type = real_type;
si->protocol = protocol;
si->fd = fd;
switch (si->family) {
case AF_INET:
return 0;
+#ifdef HAVE_IPV6
+ case AF_INET6:
+ return 0;
+#endif
default:
errno = ENOPROTOOPT;
return -1;
fromlen = &ss_len;
}
- len = MIN(len, 1500);
+ if (si->type == SOCK_STREAM) {
+ /* cut down to 1500 byte packets for stream sockets,
+ * which makes it easier to format PCAP capture files
+ * (as the caller will simply continue from here) */
+ len = MIN(len, 1500);
+ }
/* irix 6.4 forgets to null terminate the sun_path string :-( */
memset(&un_addr, 0, sizeof(un_addr));
tolen = si->peername_len;
}
- len = MIN(len, 1500);
-
switch (si->type) {
case SOCK_STREAM:
+ /* cut down to 1500 byte packets for stream sockets,
+ * which makes it easier to format PCAP capture files
+ * (as the caller will simply continue from here) */
+ len = MIN(len, 1500);
+
ret = real_send(s, buf, len, flags);
break;
case SOCK_DGRAM:
return real_recv(s, buf, len, flags);
}
- len = MIN(len, 1500);
+ if (si->type == SOCK_STREAM) {
+ /* cut down to 1500 byte packets for stream sockets,
+ * which makes it easier to format PCAP capture files
+ * (as the caller will simply continue from here) */
+ len = MIN(len, 1500);
+ }
ret = real_recv(s, buf, len, flags);
if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
return ret;
}
+_PUBLIC_ ssize_t swrap_read(int s, void *buf, size_t len)
+{
+ int ret;
+ struct socket_info *si = find_socket_info(s);
+
+ if (!si) {
+ return real_read(s, buf, len);
+ }
+
+ if (si->type == SOCK_STREAM) {
+ /* cut down to 1500 byte packets for stream sockets,
+ * which makes it easier to format PCAP capture files
+ * (as the caller will simply continue from here) */
+ len = MIN(len, 1500);
+ }
+
+ ret = real_read(s, buf, len);
+ if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
+ swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
+ } else if (ret == 0) { /* END OF FILE */
+ swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
+ } else if (ret > 0) {
+ swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
+ }
+
+ return ret;
+}
+
_PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
{
return real_send(s, buf, len, flags);
}
- len = MIN(len, 1500);
+ if (si->type == SOCK_STREAM) {
+ /* cut down to 1500 byte packets for stream sockets,
+ * which makes it easier to format PCAP capture files
+ * (as the caller will simply continue from here) */
+ len = MIN(len, 1500);
+ }
if (si->defer_connect) {
struct sockaddr_un un_addr;
return real_readv(s, vector, count);
}
- /* we read 1500 bytes as maximum */
- if (count > 0) {
+ if (si->type == SOCK_STREAM && count > 0) {
+ /* cut down to 1500 byte packets for stream sockets,
+ * which makes it easier to format PCAP capture files
+ * (as the caller will simply continue from here) */
size_t i, len = 0;
-
+
for (i=0; i < count; i++) {
size_t nlen;
nlen = len + vector[i].iov_len;
return real_writev(s, vector, count);
}
- /* we write 1500 bytes as maximum */
- if (count > 0) {
+ if (si->type == SOCK_STREAM && count > 0) {
+ /* cut down to 1500 byte packets for stream sockets,
+ * which makes it easier to format PCAP capture files
+ * (as the caller will simply continue from here) */
size_t i, len = 0;
for (i=0; i < count; i++) {