diff options
author | Steve Wills <swills@FreeBSD.org> | 2016-05-24 16:59:54 +0000 |
---|---|---|
committer | Steve Wills <swills@FreeBSD.org> | 2016-05-24 16:59:54 +0000 |
commit | 7eb431536b6358b31a447709e091926cecf9bda2 (patch) | |
tree | fbbb55826a98dbf120a5ce5bd85108331dbcb0cb | |
parent | d244062f9147a4aced0f76efce3482900e2cb8fc (diff) | |
download | ports-7eb431536b6358b31a447709e091926cecf9bda2.tar.gz ports-7eb431536b6358b31a447709e091926cecf9bda2.zip |
Notes
-rw-r--r-- | net/Makefile | 1 | ||||
-rw-r--r-- | net/sock/Makefile | 16 | ||||
-rw-r--r-- | net/sock/distinfo | 2 | ||||
-rw-r--r-- | net/sock/files/patch-src__cliopen.c | 264 | ||||
-rw-r--r-- | net/sock/files/patch-src__loopudp.c | 261 | ||||
-rw-r--r-- | net/sock/files/patch-src__main.c | 60 | ||||
-rw-r--r-- | net/sock/files/patch-src__multicast.c | 111 | ||||
-rw-r--r-- | net/sock/files/patch-src__servopen.c | 282 | ||||
-rw-r--r-- | net/sock/files/patch-src__sock.h | 30 | ||||
-rw-r--r-- | net/sock/files/patch-src__sockopts.c | 122 | ||||
-rw-r--r-- | net/sock/files/patch-src__sourceroute.c | 16 | ||||
-rw-r--r-- | net/sock/files/patch-src__sourceudp.c | 62 | ||||
-rw-r--r-- | net/sock/pkg-descr | 17 |
13 files changed, 1244 insertions, 0 deletions
diff --git a/net/Makefile b/net/Makefile index 5cb7bd621942..e531e07273c0 100644 --- a/net/Makefile +++ b/net/Makefile @@ -1226,6 +1226,7 @@ SUBDIR += sntop SUBDIR += sobby SUBDIR += socat + SUBDIR += sock SUBDIR += socketbind SUBDIR += socketpipe SUBDIR += socketw diff --git a/net/sock/Makefile b/net/sock/Makefile new file mode 100644 index 000000000000..7c75d549344a --- /dev/null +++ b/net/sock/Makefile @@ -0,0 +1,16 @@ +# Created by: Steve Jacobson <sjac@cs.stanford.edu> +# $FreeBSD$ + +PORTNAME= sock +PORTVERSION= 0.3.2 +CATEGORIES= net +MASTER_SITES= http://www.icir.org/christian/downloads/ + +MAINTAINER= sjac@cs.stanford.edu +COMMENT= W. Richard Stevens' sock program + +HAS_CONFIGURE= yes + +PLIST_FILES= bin/sock + +.include <bsd.port.mk> diff --git a/net/sock/distinfo b/net/sock/distinfo new file mode 100644 index 000000000000..cc8e1184b2f1 --- /dev/null +++ b/net/sock/distinfo @@ -0,0 +1,2 @@ +SHA256 (sock-0.3.2.tar.gz) = 4ddc33767900e7cd0a4cc0f4d808638d7cfcb746c23e12274c8eba0622eee2eb +SIZE (sock-0.3.2.tar.gz) = 113640 diff --git a/net/sock/files/patch-src__cliopen.c b/net/sock/files/patch-src__cliopen.c new file mode 100644 index 000000000000..34ed1a3458fe --- /dev/null +++ b/net/sock/files/patch-src__cliopen.c @@ -0,0 +1,264 @@ +--- src/cliopen.c.orig 2010-05-28 00:03:25 UTC ++++ src/cliopen.c +@@ -10,42 +10,107 @@ + + #include "sock.h" + ++/* ++ * Try to convert the host name as an IPv4 dotted-decimal number ++ * or an IPv6 address. ++ */ ++int convert_host_address(char *host) ++{ ++ struct in_addr inaddr; ++ char inaddr_buf[INET6_ADDRSTRLEN]; ++ ++ if (AF_INET == af_46) { ++ if (inet_pton(AF_INET, host, &inaddr) == 1) { ++ /* IPv4 dotted-decimal */ ++ servaddr4.sin_addr = inaddr; ++ ++ return (1); ++ } ++ } else { ++ if (inet_pton(AF_INET6, host, inaddr_buf) == 1) { ++ /* IPv6 address */ ++ memcpy(&servaddr6.sin6_addr, inaddr_buf, ++ sizeof(struct in6_addr)); ++ ++ return (1); ++ } ++ } ++ ++ return (0); ++} ++ ++/* ++ * Try to convert the host name as a host name string. ++ */ ++int convert_host_name(char *host) ++{ ++ struct hostent *hp; ++ ++ if (AF_INET == af_46) { ++ if ( (hp = gethostbyname2(host, AF_INET)) != NULL) { ++ /* IPv4 address */ ++ memcpy(&servaddr4.sin_addr, hp->h_addr, hp->h_length); ++ ++ return (1); ++ } ++ } else { ++ /* ++ * Fixme: This doesn't work on FreeBSD 8.4. ++ * Only an IPv4 address is returned. ++ * getaddrinfo() doesn't work either. ++ */ ++ if ( (hp = gethostbyname2(host, AF_INET6)) != NULL) { ++ /* IPv6 address */ ++ memcpy(&servaddr6.sin6_addr, hp->h_addr, hp->h_length); ++ ++ return (1); ++ } ++ } ++ ++ return (0); ++} ++ + int cliopen(char *host, char *port) + { + int fd, i, on; + char *protocol; +- struct in_addr inaddr; ++ char inaddr_buf[INET6_ADDRSTRLEN]; + struct servent *sp; +- struct hostent *hp; ++ socklen_t socklen; + + protocol = udp ? "udp" : "tcp"; + + /* initialize socket address structure */ +- bzero(&servaddr, sizeof(servaddr)); +- servaddr.sin_family = AF_INET; ++ bzero(&servaddr4, sizeof(servaddr4)); ++ servaddr4.sin_family = AF_INET; ++ ++ bzero(&servaddr6, sizeof(servaddr6)); ++ servaddr6.sin6_family = AF_INET6; + + /* see if "port" is a service name or number */ + if ( (i = atoi(port)) == 0) { + if ( (sp = getservbyname(port, protocol)) == NULL) +- err_quit("getservbyname() error for: %s/%s", port, protocol); +- +- servaddr.sin_port = sp->s_port; +- } else +- servaddr.sin_port = htons(i); ++ err_quit("getservbyname() error for: %s/%s", ++ port, protocol); ++ servaddr4.sin_port = sp->s_port; ++ servaddr6.sin6_port = sp->s_port; ++ } else { ++ servaddr4.sin_port = htons(i); ++ servaddr6.sin6_port = htons(i); ++ } + + /* +- * First try to convert the host name as a dotted-decimal number. +- * Only if that fails do we call gethostbyname(). ++ * First try to convert the host name as an IPv4 dotted-decimal number ++ * or an IPv6 address. Only if that fails do we try to convert the ++ * host name as a host name string. + */ +- +- if (inet_aton(host, &inaddr) == 1) +- servaddr.sin_addr = inaddr; /* it's dotted-decimal */ +- else if ( (hp = gethostbyname(host)) != NULL) +- bcopy(hp->h_addr, &servaddr.sin_addr, hp->h_length); +- else +- err_quit("invalid hostname: %s", host); ++ if (convert_host_address(host) != 1) { ++ if (convert_host_name(host) != 1) { ++ err_quit("invalid hostname: %s", host); ++ } ++ } + +- if ( (fd = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) ++ if ( (fd = socket(af_46, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) + err_sys("socket() error"); + + if (reuseaddr) { +@@ -71,21 +136,46 @@ int cliopen(char *host, char *port) + * (and port) using -l option. Allow localip[] to be set but bindport + * to be 0. + */ +- + if (bindport != 0 || localip[0] != 0 || udp) { +- bzero(&cliaddr, sizeof(cliaddr)); +- cliaddr.sin_family = AF_INET; +- cliaddr.sin_port = htons(bindport); /* can be 0 */ +- if (localip[0] != 0) { +- if (inet_aton(localip, &cliaddr.sin_addr) == 0) +- err_quit("invalid IP address: %s", localip); +- } else +- cliaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* wildcard */ +- +- if (bind(fd, (struct sockaddr *) &cliaddr, sizeof(cliaddr)) < 0) +- err_sys("bind() error"); ++ if (af_46 == AF_INET) { ++ bzero(&cliaddr4, sizeof(cliaddr4)); ++ cliaddr4.sin_family = AF_INET; ++ /* can be 0 */ ++ cliaddr4.sin_port = htons(bindport); ++ if (localip[0] != 0) { ++ if (inet_aton(localip, &cliaddr4.sin_addr) == 0) ++ err_quit("invalid IP address: %s", ++ localip); ++ } else { ++ /* wildcard */ ++ cliaddr4.sin_addr.s_addr = htonl(INADDR_ANY); ++ } ++ if (bind(fd, (struct sockaddr *) &cliaddr4, ++ sizeof(cliaddr4)) < 0) { ++ err_sys("bind() error"); ++ } ++ } else { ++ bzero(&cliaddr6, sizeof(cliaddr6)); ++ cliaddr6.sin6_len = sizeof(struct sockaddr_in6); ++ cliaddr6.sin6_family = AF_INET6; ++ /* can be 0 */ ++ cliaddr6.sin6_port = htons(bindport); ++ ++ /* Fixme: localip not implemented for IPv6 */ ++ cliaddr6.sin6_addr = in6addr_any; ++ ++ /* Fixme: Want to set IPV6_BINDANY? */ ++ ++ if (bind(fd, (struct sockaddr *) &cliaddr6, ++ sizeof(cliaddr6)) < 0) { ++ err_sys("bind() error"); ++ } ++ } + } +- ++ ++ /* Fixme: Does not work */ ++ //join_mcast_client(fd, &cliaddr4, &cliaddr6, &servaddr4, &servaddr6); ++ + /* Need to allocate buffers before connect(), since they can affect + * TCP options (window scale, etc.). + */ +@@ -96,13 +186,21 @@ int cliopen(char *host, char *port) + /* + * Connect to the server. Required for TCP, optional for UDP. + */ +- + if (udp == 0 || connectudp) { + for ( ; ; ) { +- if (connect(fd, (struct sockaddr *) &servaddr, sizeof(servaddr)) +- == 0) ++ if (AF_INET == af_46) { ++ if (connect(fd, (struct sockaddr *) &servaddr4, ++ sizeof(servaddr4)) == 0) + break; /* all OK */ +- if (errno == EINTR) /* can happen with SIGIO */ ++ } else { ++ servaddr6.sin6_len = ++ sizeof(struct sockaddr_in6); ++ servaddr6.sin6_family = AF_INET6; ++ if (connect(fd, (struct sockaddr *) &servaddr6, ++ sizeof(servaddr6)) == 0) ++ break; /* all OK */ ++ } ++ if (errno == EINTR) /* can happen with SIGIO */ + continue; + if (errno == EISCONN) /* can happen with SIGIO */ + break; +@@ -114,16 +212,38 @@ int cliopen(char *host, char *port) + /* Call getsockname() to find local address bound to socket: + TCP ephemeral port was assigned by connect() or bind(); + UDP ephemeral port was assigned by bind(). */ +- i = sizeof(cliaddr); +- if (getsockname(fd, (struct sockaddr *) &cliaddr, &i) < 0) +- err_sys("getsockname() error"); +- +- /* Can't do one fprintf() since inet_ntoa() stores +- the result in a static location. */ +- fprintf(stderr, "connected on %s.%d ", +- INET_NTOA(cliaddr.sin_addr), ntohs(cliaddr.sin_port)); +- fprintf(stderr, "to %s.%d\n", +- INET_NTOA(servaddr.sin_addr), ntohs(servaddr.sin_port)); ++ if (AF_INET == af_46) { ++ socklen = sizeof(cliaddr4); ++ if (getsockname(fd, ++ (struct sockaddr *) &cliaddr4, &socklen) < 0) { ++ err_sys("getsockname() error"); ++ } ++ /* Can't do one fprintf() since inet_ntoa() stores ++ the result in a static location. */ ++ fprintf(stderr, "connected on %s.%d ", ++ INET_NTOA(cliaddr4.sin_addr), ++ ntohs(cliaddr4.sin_port)); ++ fprintf(stderr, "to %s.%d\n", ++ INET_NTOA(servaddr4.sin_addr), ++ ntohs(servaddr4.sin_port)); ++ } else { ++ socklen = sizeof(cliaddr6); ++ if (getsockname(fd, ++ (struct sockaddr *) &cliaddr6, &socklen) < 0) { ++ err_sys("getsockname() error"); ++ } ++ ++ inet_ntop(AF_INET6, ++ &cliaddr6.sin6_addr.__u6_addr.__u6_addr8, ++ inaddr_buf, sizeof(inaddr_buf)); ++ fprintf(stderr, "connected on %s.%d ", ++ inaddr_buf, ntohs(cliaddr6.sin6_port)); ++ inet_ntop(AF_INET6, ++ &servaddr6.sin6_addr.__u6_addr.__u6_addr8, ++ inaddr_buf, sizeof(inaddr_buf)); ++ fprintf(stderr, "to %s.%d\n", ++ inaddr_buf, ntohs(servaddr6.sin6_port)); ++ } + } + + sockopts(fd, 1); /* some options get set after connect() */ diff --git a/net/sock/files/patch-src__loopudp.c b/net/sock/files/patch-src__loopudp.c new file mode 100644 index 000000000000..01f31f7154de --- /dev/null +++ b/net/sock/files/patch-src__loopudp.c @@ -0,0 +1,261 @@ +--- src/loopudp.c.orig 2010-05-28 00:03:25 UTC ++++ src/loopudp.c +@@ -21,17 +21,28 @@ + void + loop_udp(int sockfd) + { +- int maxfdp1, nread, ntowrite, stdineof, clilen, servlen, flags; ++ int maxfdp1, nread, ntowrite, stdineof, clilen, flags; ++ socklen_t servlen; + fd_set rset; +- struct sockaddr_in cliaddr; /* for UDP server */ +- struct sockaddr_in servaddr; /* for UDP client */ ++ struct sockaddr_in cliaddr4; /* for IPv4 UDP server */ ++ struct sockaddr_in6 cliaddr6; /* for IPv6 UDP server */ ++ /* ++ * The original local variable servaddr, and later servaddr4 and ++ * servaddr6, were not initialized before use. Using the initialized ++ * global sockaddr structs allows the sendto() code, below, to work ++ * correctly. This was a problem with the original IPv4 code, and ++ * later the IPv6 code. ++ */ ++ //struct sockaddr_in servaddr4; /* for IPv4 UDP client */ ++ //struct sockaddr_in6 servaddr6; /* for IPv6 UDP client */ ++ char inaddr_buf[INET6_ADDRSTRLEN]; + +- struct iovec iov[1]; +- struct msghdr msg; ++ struct iovec iov[1]; ++ struct msghdr msg; + #ifdef HAVE_MSGHDR_MSG_CONTROL + #ifdef IP_RECVDSTADDR /* 4.3BSD Reno and later */ + static struct cmsghdr *cmptr = NULL; /* malloc'ed */ +- struct in_addr dstinaddr; /* for UDP server */ ++ struct in_addr dstinaddr; /* for UDP server */ + #define CONTROLLEN (sizeof(struct cmsghdr) + sizeof(struct in_addr)) + #endif /* IP_RECVDSTADDR */ + +@@ -68,8 +79,10 @@ loop_udp(int sockfd) + err_sys("shutdown() error"); + + FD_CLR(STDIN_FILENO, &rset); +- stdineof = 1; /* don't read stdin anymore */ +- continue; /* back to select() */ ++ /* don't read stdin anymore */ ++ stdineof = 1; ++ /* back to select() */ ++ continue; + } + break; /* default: stdin EOF -> done */ + } +@@ -77,23 +90,43 @@ loop_udp(int sockfd) + if (crlf) { + ntowrite = crlf_add(wbuf, writelen, rbuf, nread); + if (connectudp) { +- if (write(sockfd, wbuf, ntowrite) != ntowrite) ++ if (write(sockfd, wbuf, ntowrite) != ++ ntowrite) { + err_sys("write error"); ++ } + } else { +- if (sendto(sockfd, wbuf, ntowrite, 0, +- (struct sockaddr *) &servaddr, sizeof(servaddr)) +- != ntowrite) +- err_sys("sendto error"); ++ if (af_46 == AF_INET) { ++ if (sendto(sockfd, wbuf, ntowrite, 0, ++ (struct sockaddr *)&servaddr4, ++ sizeof(servaddr4)) != ntowrite) { ++ err_sys("sendto error"); ++ } ++ } else { ++ if (sendto(sockfd, wbuf, ntowrite, 0, ++ (struct sockaddr *)&servaddr6, ++ sizeof(servaddr6)) != ntowrite) { ++ err_sys("sendto error"); ++ } ++ } + } + } else { + if (connectudp) { + if (write(sockfd, rbuf, nread) != nread) + err_sys("write error"); + } else { +- if (sendto(sockfd, rbuf, nread, 0, +- (struct sockaddr *) &servaddr, sizeof(servaddr)) +- != nread) +- err_sys("sendto error"); ++ if (af_46 == AF_INET) { ++ if (sendto(sockfd, rbuf, nread, 0, ++ (struct sockaddr *)&servaddr4, ++ sizeof(servaddr4)) != nread) { ++ err_sys("sendto error"); ++ } ++ } else { ++ if (sendto(sockfd, rbuf, nread, 0, ++ (struct sockaddr *)&servaddr6, ++ sizeof(servaddr6)) != nread) { ++ err_sys("sendto error"); ++ } ++ } + } + } + } +@@ -101,35 +134,54 @@ loop_udp(int sockfd) + if (FD_ISSET(sockfd, &rset)) { + /* data to read from socket */ + if (server) { +- clilen = sizeof(cliaddr); +-#ifndef MSG_TRUNC /* vanilla BSD sockets */ ++ if (af_46 == AF_INET) { ++ clilen = sizeof(cliaddr4); ++ } else { ++ clilen = sizeof(cliaddr6); ++ } ++ ++#ifndef MSG_TRUNC /* vanilla BSD sockets */ ++ ++ /* Fixme: Not ported for IPv6 */ ++ /* Not compiled in for FreeBSD 8.4 */ + nread = recvfrom(sockfd, rbuf, readlen, 0, +- (struct sockaddr *) &cliaddr, &clilen); +- ++ (struct sockaddr *) &cliaddr4, &clilen); ++ + #else /* 4.3BSD Reno and later; use recvmsg() to get at MSG_TRUNC flag */ +- /* Also lets us get at control information (destination address) */ +- ++ /* Also lets us get at control information (destination address) */ ++ ++ /* FreeBSD 8.4 */ + iov[0].iov_base = rbuf; + iov[0].iov_len = readlen; +- msg.msg_iov = iov; +- msg.msg_iovlen = 1; +- msg.msg_name = (caddr_t) &cliaddr; +- msg.msg_namelen = clilen; +- ++ msg.msg_iov = iov; ++ msg.msg_iovlen = 1; ++ if (af_46 == AF_INET) { ++ msg.msg_name = (caddr_t) &cliaddr4; ++ } else { ++ msg.msg_name = (caddr_t) &cliaddr6; ++ } ++ msg.msg_namelen = clilen; ++ + #ifdef HAVE_MSGHDR_MSG_CONTROL + #ifdef IP_RECVDSTADDR ++ /* FreeBSD 8.4 */ + if (cmptr == NULL && (cmptr = malloc(CONTROLLEN)) == NULL) + err_sys("malloc error for control buffer"); + +- msg.msg_control = (caddr_t) cmptr; /* for dest address */ ++ /* for dest address */ ++ msg.msg_control = (caddr_t) cmptr; + msg.msg_controllen = CONTROLLEN; + #else +- msg.msg_control = (caddr_t) 0; /* no ancillary data */ ++ /* Not used for FreeBSD 8.4 */ ++ /* no ancillary data */ ++ msg.msg_control = (caddr_t) 0; + msg.msg_controllen = 0; + #endif /* IP_RECVDSTADDR */ + #endif + #ifdef HAVE_MSGHDR_MSG_FLAGS +- msg.msg_flags = 0; /* flags returned here */ ++ /* FreeBSD 8.4 */ ++ /* flags returned here */ ++ msg.msg_flags = 0; + #endif + nread = recvmsg(sockfd, &msg, 0); + #endif /* MSG_TRUNC */ +@@ -137,22 +189,39 @@ loop_udp(int sockfd) + err_sys("datagram receive error"); + + if (verbose) { +- printf("from %s", INET_NTOA(cliaddr.sin_addr)); ++ if (af_46 == AF_INET) { ++ printf("from %s", ++ INET_NTOA(cliaddr4.sin_addr)); ++ } else { ++ inet_ntop(AF_INET6, ++ &cliaddr6.sin6_addr. ++ __u6_addr.__u6_addr8, ++ inaddr_buf, ++ sizeof(inaddr_buf)); ++ printf("from %s", inaddr_buf); ++ } + #ifdef HAVE_MSGHDR_MSG_CONTROL + #ifdef IP_RECVDSTADDR ++ /* ++ * Fixme: not ported for IPv6 ++ * Fixme: recvdstaddr fails (earlier, ++ * in setsockopt()) for IPv6 under ++ * FreeBSD 8.4 ++ */ + if (recvdstaddr) { + if (cmptr->cmsg_len != CONTROLLEN) + err_quit("control length (%d) != %d", +- cmptr->cmsg_len, CONTROLLEN); ++ cmptr->cmsg_len, CONTROLLEN); + if (cmptr->cmsg_level != IPPROTO_IP) + err_quit("control level != IPPROTO_IP"); + if (cmptr->cmsg_type != IP_RECVDSTADDR) + err_quit("control type != IP_RECVDSTADDR"); + bcopy(CMSG_DATA(cmptr), &dstinaddr, +- sizeof(struct in_addr)); ++ sizeof(struct in_addr)); + bzero(cmptr, CONTROLLEN); + +- printf(", to %s", INET_NTOA(dstinaddr)); ++ printf(", to %s", ++ INET_NTOA(dstinaddr)); + } + #endif /* IP_RECVDSTADDR */ + #endif /* HAVE_MSGHDR_MSG_CONTROL */ +@@ -178,15 +247,37 @@ loop_udp(int sockfd) + } + + } else { +- /* Must use recvfrom() for unconnected UDP client */ +- servlen = sizeof(servaddr); +- nread = recvfrom(sockfd, rbuf, readlen, 0, +- (struct sockaddr *) &servaddr, &servlen); +- if (nread < 0) ++ /* ++ * Must use recvfrom() for unconnected ++ * UDP client ++ */ ++ /* Fixme: not tested on FreeBSD 8.4 */ ++ if (af_46 == AF_INET) { ++ servlen = sizeof(servaddr4); ++ nread = recvfrom(sockfd, rbuf, readlen, ++ 0, (struct sockaddr *)&servaddr4, ++ &servlen); ++ } else { ++ servlen = sizeof(servaddr6); ++ nread = recvfrom(sockfd, rbuf, readlen, ++ 0, (struct sockaddr *)&servaddr6, ++ &servlen); ++ } ++ if (nread < 0) { + err_sys("datagram recvfrom() error"); +- ++ } + if (verbose) { +- printf("from %s", INET_NTOA(servaddr.sin_addr)); ++ if (af_46 == AF_INET) { ++ printf("from %s", ++ INET_NTOA(servaddr4.sin_addr)); ++ } else { ++ inet_ntop(AF_INET6, ++ &servaddr6.sin6_addr. ++ __u6_addr.__u6_addr8, ++ inaddr_buf, ++ sizeof(inaddr_buf)); ++ printf("from %s", inaddr_buf); ++ } + printf(": "); + fflush(stdout); + } diff --git a/net/sock/files/patch-src__main.c b/net/sock/files/patch-src__main.c new file mode 100644 index 000000000000..971eb5473cfe --- /dev/null +++ b/net/sock/files/patch-src__main.c @@ -0,0 +1,60 @@ +--- src/main.c.orig 2010-05-28 00:03:25 UTC ++++ src/main.c +@@ -23,9 +23,10 @@ + char *host; /* hostname or dotted-decimal string */ + char *port; + +- /* DefinE global variables */ ++ /* Define global variables */ ++int af_46 = AF_INET; /* AF_INET or AF_INET6 */ + int bindport; /* 0 or TCP or UDP port number to bind */ +- /* set by -b or -l options */ ++ /* set by -b or -l options */ + int broadcast; /* SO_BROADCAST */ + int cbreak; /* set terminal to cbreak mode */ + int chunkwrite; /* write in small chunks; not all-at-once */ +@@ -76,7 +77,8 @@ int urgwrite; /* write urgent byte af + int verbose; /* each -v increments this by 1 */ + int usewritev; /* use writev() instead of write() */ + +-struct sockaddr_in cliaddr, servaddr; ++struct sockaddr_in cliaddr4, servaddr4; ++struct sockaddr_in6 cliaddr6, servaddr6; + + static void usage(const char *); + +@@ -90,13 +92,16 @@ main(int argc, char *argv[]) + usage(""); + + opterr = 0; /* don't want getopt() writing to stderr */ +- while ( (c = getopt(argc, argv, "2b:cf:g:hij:kl:n:op:q:r:st:uvw:x:y:ABCDEFG:H:IJ:KL:NO:P:Q:R:S:TU:VWX:YZ")) != -1) { ++ while ( (c = getopt(argc, argv, "26b:cf:g:hij:kl:n:op:q:r:st:uvw:x:y:ABCDEFG:H:IJ:KL:NO:P:Q:R:S:TU:VWX:YZ")) != -1) { + switch (c) { + #ifdef IP_ONESBCAST + case '2': /* use 255.255.255.255 as broadcast address */ + onesbcast = 1; + break; + #endif ++ case '6': /* use IPv6 */ ++ af_46 = AF_INET6; ++ break; + + case 'b': + bindport = atoi(optarg); +@@ -309,7 +314,7 @@ main(int argc, char *argv[]) + } + } + +- /* check for options that don't make sense */ ++ /* check for options that don't make sense */ + if (udp && halfclose) + usage("can't specify -h and -u"); + if (udp && debug) +@@ -439,6 +444,7 @@ usage(const char *msg) + #ifdef IP_ONESBCAST + " -2 IP_ONESBCAST option (255.255.255.255 for broadcast\n" + #endif ++" -6 use IPv6 instead of IPv4\n" + ); + + if (msg[0] != 0) diff --git a/net/sock/files/patch-src__multicast.c b/net/sock/files/patch-src__multicast.c new file mode 100644 index 000000000000..475bc82fa7f9 --- /dev/null +++ b/net/sock/files/patch-src__multicast.c @@ -0,0 +1,111 @@ +--- src/multicast.c.orig 2010-05-28 00:03:25 UTC ++++ src/multicast.c +@@ -10,24 +10,96 @@ + + #include "sock.h" + ++/* ++ * Works for IPv4 and IPv6. ++ * For IPv4, the server is able to join a multicast group such as 224.0.0.1. ++ * The client is able to connect to the same multicast address and port ++ * assigned to the server. The client can then send data, which the server ++ * receives. ++ * For IPv6, the server is able to join a multicast group of the form ff02::n. ++ * The client is never able to connect to that address/port, however. ++ */ + void +-join_mcast(int fd, struct sockaddr_in *sin) ++join_mcast_server(int fd, struct sockaddr_in *sin, struct sockaddr_in6 *sin6) + { + #ifdef IP_ADD_MEMBERSHIP /* only include if host supports mcasting */ +- u_long inaddr; +- struct ip_mreq mreq; ++ u_long inaddr; ++ struct ip_mreq mreq; ++ struct ipv6_mreq mreq6; + +- inaddr = sin->sin_addr.s_addr; +- if (IN_MULTICAST(inaddr) == 0) +- return; /* not a multicast address */ ++ if (af_46 == AF_INET) { ++ inaddr = sin->sin_addr.s_addr; ++ /* ++ * FreeBSD 8.4: IN_MULTICAST() test fails in the original code ++ * because it was testing inaddr with the wrong endianness. ++ * Fixed in this version of the code, at least for FreeBSD. ++ */ ++ inaddr = ntohl(inaddr); + +- mreq.imr_multiaddr.s_addr = inaddr; +- mreq.imr_interface.s_addr = htonl(INADDR_ANY); /* need way to change */ +- if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, +- sizeof(mreq)) == -1 ) +- err_sys("IP_ADD_MEMBERSHIP error"); ++ if (IN_MULTICAST(inaddr) == 0) { ++ return; /* not a multicast address */ ++ } ++ } else { ++ if (IN6_IS_ADDR_MULTICAST(&(sin6->sin6_addr)) == 0) { ++ return; /* not a multicast address */ ++ } ++ } ++ ++ if (af_46 == AF_INET) { ++ mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr; ++ /* need way to change */ ++ mreq.imr_interface.s_addr = htonl(INADDR_ANY); ++ if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, ++ sizeof(mreq)) == -1 ) { ++ err_sys("IP_ADD_MEMBERSHIP error"); ++ } ++ } else { ++ memset((char *)&mreq6, 0, sizeof(mreq6)); ++ mreq6.ipv6mr_multiaddr = sin6->sin6_addr; ++ mreq6.ipv6mr_interface = sin6->sin6_scope_id; ++ if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6, ++ sizeof(mreq6)) == -1 ) { ++ err_sys("IP_ADD_MEMBERSHIP error"); ++ } ++ } + + if (verbose) +- fprintf(stderr, "multicast group joined\n"); ++ fprintf(stderr, "multicast group joined\n"); ++#endif /* IP_ADD_MEMBERSHIP */ ++} ++ ++/* ++ * Added for IPv6. Fixme: Does not work at present. ++ * The client is currently unable to connect to the multicast address/port ++ * which was joined by the server. A function similar to this may be needed ++ * to permit that connection to be made. ++ */ ++void ++join_mcast_client(int fd, ++ struct sockaddr_in *cli_sin, struct sockaddr_in6 *cli_sin6, ++ struct sockaddr_in *serv_sin, struct sockaddr_in6 *serv_sin6) ++{ ++#ifdef IP_ADD_MEMBERSHIP /* only include if host supports mcasting */ ++ struct ipv6_mreq mreq6; ++ ++ if (af_46 == AF_INET6) { ++ if (IN6_IS_ADDR_MULTICAST(&(serv_sin6->sin6_addr)) == 0) { ++ return; /* not a multicast address */ ++ } ++ } ++ ++ if (af_46 == AF_INET6) { ++ memset((char *)&mreq6, 0, sizeof(mreq6)); ++ mreq6.ipv6mr_multiaddr = serv_sin6->sin6_addr; ++ mreq6.ipv6mr_interface = serv_sin6->sin6_scope_id; ++ if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6, ++ sizeof(mreq6)) == -1 ) { ++ err_sys("IP_ADD_MEMBERSHIP error"); ++ } ++ } ++ ++ if (verbose) { ++ fprintf(stderr, "multicast group joined\n"); ++ } + #endif /* IP_ADD_MEMBERSHIP */ + } diff --git a/net/sock/files/patch-src__servopen.c b/net/sock/files/patch-src__servopen.c new file mode 100644 index 000000000000..321e1c7dbdeb --- /dev/null +++ b/net/sock/files/patch-src__servopen.c @@ -0,0 +1,282 @@ +--- src/servopen.c.orig 2010-05-28 00:03:25 UTC ++++ src/servopen.c +@@ -19,38 +19,67 @@ + int + servopen(char *host, char *port) + { +- int fd, newfd, i, on, pid; +- char *protocol; ++ int fd, newfd, i, on, pid; ++ char *protocol; + struct in_addr inaddr; + struct servent *sp; ++ socklen_t len; ++ char inaddr_buf[INET6_ADDRSTRLEN]; + + protocol = udp ? "udp" : "tcp"; + +- /* Initialize the socket address structure */ +- bzero(&servaddr, sizeof(servaddr)); +- servaddr.sin_family = AF_INET; ++ /* Initialize the socket address structure */ ++ bzero(&servaddr4, sizeof(servaddr4)); ++ servaddr4.sin_family = AF_INET; + +- /* Caller normally wildcards the local Internet address, meaning +- a connection will be accepted on any connected interface. +- We only allow an IP address for the "host", not a name. */ +- if (host == NULL) +- servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* wildcard */ +- else { +- if (inet_aton(host, &inaddr) == 0) +- err_quit("invalid host name for server: %s", host); +- servaddr.sin_addr = inaddr; ++ bzero(&servaddr6, sizeof(servaddr6)); ++ servaddr6.sin6_family = AF_INET6; ++ ++ /* ++ * Caller normally wildcards the local Internet address, meaning ++ * a connection will be accepted on any connected interface. ++ * We only allow an IP address for the "host", not a name. ++ */ ++ if (host == NULL) { ++ if (AF_INET == af_46) { ++ /* wildcard */ ++ servaddr4.sin_addr.s_addr = htonl(INADDR_ANY); ++ } else { ++ /* wildcard */ ++ servaddr6.sin6_addr = in6addr_any; ++ } ++ } else { ++ if (AF_INET == af_46) { ++ if (inet_pton(AF_INET, host, &inaddr) == 0) { ++ err_quit("invalid host name for server: %s", ++ host); ++ } ++ /* IPv4 address */ ++ servaddr4.sin_addr = inaddr; ++ } else { ++ if (inet_pton(AF_INET6, host, inaddr_buf) == 0) { ++ err_quit("invalid host name for server: %s", ++ host); ++ } ++ /* IPv6 address */ ++ memcpy(&servaddr6.sin6_addr, inaddr_buf, ++ sizeof(struct in6_addr)); ++ } + } + +- /* See if "port" is a service name or number */ ++ /* See if "port" is a service name or number */ + if ( (i = atoi(port)) == 0) { + if ( (sp = getservbyname(port, protocol)) == NULL) +- err_ret("getservbyname() error for: %s/%s", port, protocol); +- +- servaddr.sin_port = sp->s_port; +- } else +- servaddr.sin_port = htons(i); ++ err_ret("getservbyname() error for: %s/%s", port, ++ protocol); ++ servaddr4.sin_port = sp->s_port; ++ servaddr6.sin6_port = sp->s_port; ++ } else { ++ servaddr4.sin_port = htons(i); ++ servaddr6.sin6_port = htons(i); ++ } + +- if ( (fd = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) ++ if ( (fd = socket(af_46, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) + err_sys("socket() error"); + + if (reuseaddr) { +@@ -67,28 +96,37 @@ servopen(char *host, char *port) + } + #endif + +- /* Bind our well-known port so the client can connect to us. */ +- if (bind(fd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) +- err_sys("can't bind local address"); ++ /* Bind our well-known port so the client can connect to us. */ ++ if (AF_INET == af_46) { ++ if (bind(fd, (struct sockaddr *) &servaddr4, ++ sizeof(servaddr4)) < 0) { ++ err_sys("can't bind local address"); ++ } ++ } else { ++ if (bind(fd, (struct sockaddr *) &servaddr6, ++ sizeof(servaddr6)) < 0) { ++ err_sys("can't bind local address"); ++ } ++ } + +- join_mcast(fd, &servaddr); ++ join_mcast_server(fd, &servaddr4, &servaddr6); + + if (udp) { + buffers(fd); + +- if (foreignip[0] != 0) { /* connect to foreignip/port# */ +- bzero(&cliaddr, sizeof(cliaddr)); +- if (inet_aton(foreignip, &cliaddr.sin_addr) == 0) ++ /* Fixme: Not ported for IPv6 */ ++ if (foreignip[0] != 0) { /* connect to foreignip/port# */ ++ bzero(&cliaddr4, sizeof(cliaddr4)); ++ if (inet_aton(foreignip, &cliaddr4.sin_addr) == 0) + err_quit("invalid IP address: %s", foreignip); +- cliaddr.sin_family = AF_INET; +- cliaddr.sin_port = htons(foreignport); +- /* connect() for datagram socket doesn't appear to allow +- wildcarding of either IP address or port number */ ++ cliaddr4.sin_family = AF_INET; ++ cliaddr4.sin_port = htons(foreignport); ++ /* connect() for datagram socket doesn't appear to allow ++ wildcarding of either IP address or port number */ + +- if (connect(fd, (struct sockaddr *) &cliaddr, sizeof(cliaddr)) +- < 0) ++ if (connect(fd, (struct sockaddr *) &cliaddr4, ++ sizeof(cliaddr4)) < 0) + err_sys("connect() error"); +- + } + + sockopts(fd, 1); +@@ -96,58 +134,108 @@ servopen(char *host, char *port) + return(fd); /* nothing else to do */ + } + +- buffers(fd); /* may set receive buffer size; must do here to get +- correct window advertised on SYN */ ++ buffers(fd); /* may set receive buffer size; must do here to ++ get correct window advertised on SYN */ + sockopts(fd, 0); /* only set some socket options for fd */ + + listen(fd, listenq); + +- if (pauselisten) +- sleep_us(pauselisten*1000); /* lets connection queue build up */ ++ if (pauselisten) { ++ /* lets connection queue build up */ ++ sleep_us(pauselisten*1000); ++ } + +- if (dofork) +- TELL_WAIT(); /* initialize synchronization primitives */ ++ if (dofork) { ++ /* initialize synchronization primitives */ ++ TELL_WAIT(); ++ } + + for ( ; ; ) { +- i = sizeof(cliaddr); +- if ( (newfd = accept(fd, (struct sockaddr *) &cliaddr, &i)) < 0) +- err_sys("accept() error"); ++ if (AF_INET == af_46) { ++ len = sizeof(cliaddr4); ++ if ( (newfd = accept(fd, (struct sockaddr *) &cliaddr4, ++ &len)) < 0) { ++ err_sys("accept() error"); ++ } ++ } else { ++ len = sizeof(cliaddr6); ++ if ( (newfd = accept(fd, (struct sockaddr *) &cliaddr6, ++ &len)) < 0) { ++ err_sys("accept() error"); ++ } ++ } + + if (dofork) { + if ( (pid = fork()) < 0) + err_sys("fork error"); + + if (pid > 0) { +- close(newfd); /* parent closes connected socket */ +- WAIT_CHILD(); /* wait for child to output to terminal */ +- continue; /* and back to for(;;) for another accept() */ ++ /* parent closes connected socket */ ++ close(newfd); ++ /* wait for child to output to terminal */ ++ WAIT_CHILD(); ++ /* and back to for(;;) for another accept() */ ++ continue; + } else { +- close(fd); /* child closes listening socket */ ++ /* child closes listening socket */ ++ close(fd); + } + } + +- /* child (or iterative server) continues here */ ++ /* child (or iterative server) continues here */ + if (verbose) { +- /* Call getsockname() to find local address bound to socket: +- local internet address is now determined (if multihomed). */ +- i = sizeof(servaddr); +- if (getsockname(newfd, (struct sockaddr *) &servaddr, &i) < 0) +- err_sys("getsockname() error"); ++ /* ++ * Call getsockname() to find local address bound ++ * to socket: local internet address is now ++ * determined (if multihomed). ++ */ ++ if (AF_INET == af_46) { ++ len = sizeof(servaddr4); ++ if (getsockname(newfd, ++ (struct sockaddr *)&servaddr4, &len) < 0) { ++ err_sys("getsockname() error"); ++ } + +- /* Can't do one fprintf() since inet_ntoa() stores +- the result in a static location. */ +- fprintf(stderr, "connection on %s.%d ", +- INET_NTOA(servaddr.sin_addr), ntohs(servaddr.sin_port)); +- fprintf(stderr, "from %s.%d\n", +- INET_NTOA(cliaddr.sin_addr), ntohs(cliaddr.sin_port)); ++ /* ++ * Can't do one fprintf() since inet_ntoa() ++ * stores the result in a static location. ++ */ ++ fprintf(stderr, "connection on %s.%d ", ++ INET_NTOA(servaddr4.sin_addr), ++ ntohs(servaddr4.sin_port)); ++ fprintf(stderr, "from %s.%d\n", ++ INET_NTOA(cliaddr4.sin_addr), ++ ntohs(cliaddr4.sin_port)); ++ } else { ++ len = sizeof(servaddr6); ++ if (getsockname(newfd, ++ (struct sockaddr *)&servaddr6, &len) < 0) { ++ err_sys("getsockname() error"); ++ } ++ inet_ntop(AF_INET6, ++ &servaddr6.sin6_addr.__u6_addr.__u6_addr8, ++ inaddr_buf, sizeof(inaddr_buf)); ++ fprintf(stderr, "connection on %s.%d ", ++ inaddr_buf, ntohs(servaddr6.sin6_port)); ++ inet_ntop(AF_INET6, ++ &cliaddr6.sin6_addr.__u6_addr.__u6_addr8, ++ inaddr_buf, sizeof(inaddr_buf)); ++ fprintf(stderr, "from %s.%d\n", ++ inaddr_buf, ntohs(cliaddr6.sin6_port)); ++ } + } + +- buffers(newfd); /* setsockopt() again, in case it didn't propagate +- from listening socket to connected socket */ +- sockopts(newfd, 1); /* can set all socket options for this socket */ ++ /* setsockopt() again, in case it didn't propagate ++ from listening socket to connected socket */ ++ buffers(newfd); + +- if (dofork) +- TELL_PARENT(getppid()); /* tell parent we're done with terminal */ ++ /* can set all socket options for this socket */ ++ sockopts(newfd, 1); ++ ++ if (dofork) { ++ /* tell parent we're done with terminal */ ++ TELL_PARENT(getppid()); ++ } + + return(newfd); + } diff --git a/net/sock/files/patch-src__sock.h b/net/sock/files/patch-src__sock.h new file mode 100644 index 000000000000..efc6c9b11216 --- /dev/null +++ b/net/sock/files/patch-src__sock.h @@ -0,0 +1,30 @@ +--- src/sock.h.orig 2010-05-28 00:03:25 UTC ++++ src/sock.h +@@ -62,6 +62,7 @@ extern int errno; + #define max(a,b) ((a) > (b) ? (a) : (b)) + + /* declare global variables */ ++extern int af_46; + extern int bindport; + extern int broadcast; + extern int cbreak; +@@ -114,6 +115,8 @@ extern int verbose; + extern int usewritev; + + extern struct sockaddr_in cliaddr, servaddr; ++extern struct sockaddr_in cliaddr4, servaddr4; ++extern struct sockaddr_in6 cliaddr6, servaddr6; + + /* Earlier versions of gcc under SunOS 4.x have problems passing arguments + that are structs (as opposed to pointers to structs). This shows up +@@ -130,7 +133,9 @@ void buffers(int); + int cliopen(char *, char *); + int crlf_add(char *, int, const char *, int); + int crlf_strip(char *, int, const char *, int); +-void join_mcast(int, struct sockaddr_in *); ++void join_mcast_server(int, struct sockaddr_in *, struct sockaddr_in6 *); ++void join_mcast_client(int, struct sockaddr_in *, struct sockaddr_in6 *, ++ struct sockaddr_in *, struct sockaddr_in6 *); + void loop_tcp(int); + void loop_udp(int); + void pattern(char *, int); diff --git a/net/sock/files/patch-src__sockopts.c b/net/sock/files/patch-src__sockopts.c new file mode 100644 index 000000000000..2e8aebddd1e0 --- /dev/null +++ b/net/sock/files/patch-src__sockopts.c @@ -0,0 +1,122 @@ +--- src/sockopts.c.orig 2010-05-28 00:03:25 UTC ++++ src/sockopts.c +@@ -30,6 +30,13 @@ sockopts(int sockfd, int doall) + unsigned optlen; + struct linger ling; + struct timeval timer; ++ int level; ++ ++ if (AF_INET == af_46) { ++ level = IPPROTO_IP; ++ } else { ++ level = IPPROTO_IPV6; ++ } + + /* "doall" is 0 for a server's listening socket (i.e., before + accept() has returned.) Some socket options such as SO_KEEPALIVE +@@ -73,13 +80,13 @@ sockopts(int sockfd, int doall) + + #ifdef IP_TOS + if (iptos != -1 && doall == 0) { +- if (setsockopt(sockfd, IPPROTO_IP, IP_TOS, ++ if (setsockopt(sockfd, level, IP_TOS, + &iptos, sizeof(iptos)) < 0) + err_sys("IP_TOS setsockopt error"); + + option = 0; + optlen = sizeof(option); +- if (getsockopt(sockfd, IPPROTO_IP, IP_TOS, ++ if (getsockopt(sockfd, level, IP_TOS, + &option, &optlen) < 0) + err_sys("IP_TOS getsockopt error"); + if (option != iptos) +@@ -92,13 +99,13 @@ sockopts(int sockfd, int doall) + + #ifdef IP_TTL + if (ipttl != -1 && doall == 0) { +- if (setsockopt(sockfd, IPPROTO_IP, IP_TTL, ++ if (setsockopt(sockfd, level, IP_TTL, + &ipttl, sizeof(ipttl)) < 0) + err_sys("IP_TTL setsockopt error"); + + option = 0; + optlen = sizeof(option); +- if (getsockopt(sockfd, IPPROTO_IP, IP_TTL, ++ if (getsockopt(sockfd, level, IP_TTL, + &option, &optlen) < 0) + err_sys("IP_TTL getsockopt error"); + if (option != ipttl) +@@ -150,13 +157,13 @@ sockopts(int sockfd, int doall) + #ifdef IP_ONESBCAST + if (onesbcast) { + option = 1; +- if (setsockopt(sockfd, IPPROTO_IP, IP_ONESBCAST, ++ if (setsockopt(sockfd, level, IP_ONESBCAST, + &option, sizeof(option)) < 0) + err_sys("IP_ONESBCAST setsockopt error"); + + option = 0; + optlen = sizeof(option); +- if (getsockopt(sockfd, IPPROTO_IP, IP_ONESBCAST, ++ if (getsockopt(sockfd, level, IP_ONESBCAST, + &option, &optlen) < 0) + err_sys("IP_ONESBCAST getsockopt error"); + if (option == 0) +@@ -175,7 +182,7 @@ sockopts(int sockfd, int doall) + if (inet_aton(joinip, &join.imr_multiaddr) == 0) + err_quit("invalid multicast address: %s", joinip); + join.imr_interface.s_addr = htonl(INADDR_ANY); +- if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, ++ if (setsockopt(sockfd, level, IP_ADD_MEMBERSHIP, + &join, sizeof(join)) < 0) + err_sys("IP_ADD_MEMBERSHIP setsockopt error"); + +@@ -188,12 +195,12 @@ sockopts(int sockfd, int doall) + if (mcastttl) { + u_char ttl = mcastttl; + +- if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, ++ if (setsockopt(sockfd, level, IP_MULTICAST_TTL, + &ttl, sizeof(ttl)) < 0) + err_sys("IP_MULTICAST_TTL setsockopt error"); + + optlen = sizeof(ttl); +- if (getsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, ++ if (getsockopt(sockfd, level, IP_MULTICAST_TTL, + &ttl, &optlen) < 0) + err_sys("IP_MULTICAST_TTL getsockopt error"); + if (ttl != mcastttl) +@@ -288,7 +295,7 @@ sockopts(int sockfd, int doall) + + if (verbose) + fprintf(stderr, "SO_RCVTIMEO: %ld.%06ld\n", +- timer.tv_sec, timer.tv_usec); ++ (long)timer.tv_sec, timer.tv_usec); + #else + fprintf(stderr, "warning: SO_RCVTIMEO not supported by host\n"); + #endif +@@ -311,7 +318,7 @@ sockopts(int sockfd, int doall) + + if (verbose) + fprintf(stderr, "SO_SNDTIMEO: %ld.%06ld\n", +- timer.tv_sec, timer.tv_usec); ++ (long)timer.tv_sec, timer.tv_usec); + #else + fprintf(stderr, "warning: SO_SNDTIMEO not supported by host\n"); + #endif +@@ -320,13 +327,13 @@ sockopts(int sockfd, int doall) + if (recvdstaddr && udp) { + #ifdef IP_RECVDSTADDR + option = 1; +- if (setsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, ++ if (setsockopt(sockfd, level, IP_RECVDSTADDR, + &option, sizeof(option)) < 0) + err_sys("IP_RECVDSTADDR setsockopt error"); + + option = 0; + optlen = sizeof(option); +- if (getsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, ++ if (getsockopt(sockfd, level, IP_RECVDSTADDR, + &option, &optlen) < 0) + err_sys("IP_RECVDSTADDR getsockopt error"); + if (option == 0) diff --git a/net/sock/files/patch-src__sourceroute.c b/net/sock/files/patch-src__sourceroute.c new file mode 100644 index 000000000000..89c0f506d469 --- /dev/null +++ b/net/sock/files/patch-src__sourceroute.c @@ -0,0 +1,16 @@ +--- src/sourceroute.c.orig 2010-05-28 00:03:25 UTC ++++ src/sourceroute.c +@@ -88,10 +88,11 @@ sroute_set(int sockfd) + sroute_opt[1] = 3 + (sroute_cnt * 4); /* total length, incl. destination */ + + /* destination must be stored as final entry */ +- bcopy(&servaddr.sin_addr, optr, sizeof(u_long)); ++ bcopy(&servaddr4.sin_addr, optr, sizeof(u_long)); + optr += sizeof(u_long); + if (verbose) { +- fprintf(stderr, "source route to %s\n", inet_ntoa(servaddr.sin_addr)); ++ fprintf(stderr, "source route to %s\n", ++ inet_ntoa(servaddr4.sin_addr)); + fprintf(stderr, "source route size %d bytes\n", sroute_opt[1]); + } + diff --git a/net/sock/files/patch-src__sourceudp.c b/net/sock/files/patch-src__sourceudp.c new file mode 100644 index 000000000000..88ca9a42d145 --- /dev/null +++ b/net/sock/files/patch-src__sourceudp.c @@ -0,0 +1,62 @@ +--- src/sourceudp.c.orig 2010-05-28 00:03:25 UTC ++++ src/sourceudp.c +@@ -29,28 +29,41 @@ source_udp(int sockfd) /* TODO: use send + if (connectudp) { + if ( (n = write(sockfd, wbuf, writelen)) != writelen) { + if (ignorewerr) { +- err_ret("write returned %d, expected %d", n, writelen); +- /* also call getsockopt() to clear so_error */ ++ err_ret("write returned %d, expected %d", ++ n, writelen); ++ /* also call getsockopt() to clear so_error */ + optlen = sizeof(option); +- if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, +- &option, &optlen) < 0) +- err_sys("SO_ERROR getsockopt error"); +- } else +- err_sys("write returned %d, expected %d", n, writelen); ++ if (getsockopt(sockfd, SOL_SOCKET, ++ SO_ERROR, &option, &optlen) < 0) ++ err_sys("SO_ERROR getsockopt error"); ++ } else { ++ err_sys("write returned %d, expected %d", ++ n, writelen); ++ } + } + } else { +- if ( (n = sendto(sockfd, wbuf, writelen, 0, +- (struct sockaddr *) &servaddr, +- sizeof(struct sockaddr))) != writelen) { +- if (ignorewerr) { +- err_ret("sendto returned %d, expected %d", n, writelen); +- /* also call getsockopt() to clear so_error */ ++ if (af_46 == AF_INET) { ++ n = sendto(sockfd, wbuf, writelen, 0, ++ (struct sockaddr *) &servaddr4, ++ sizeof(servaddr4)); ++ } else { ++ n = sendto(sockfd, wbuf, writelen, 0, ++ (struct sockaddr *) &servaddr6, ++ sizeof(servaddr6)); ++ } ++ if (n != writelen) { ++ if (ignorewerr) { ++ err_ret("sendto returned %d, expected %d", ++ n, writelen); ++ /* also call getsockopt() to clear so_error */ + optlen = sizeof(option); +- if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, +- &option, &optlen) < 0) +- err_sys("SO_ERROR getsockopt error"); +- } else +- err_sys("sendto returned %d, expected %d", n, writelen); ++ if (getsockopt(sockfd, SOL_SOCKET, ++ SO_ERROR, &option, &optlen) < 0) ++ err_sys("SO_ERROR getsockopt error"); ++ } else { ++ err_sys("sendto returned %d, expected %d", ++ n, writelen); ++ } + } + } + diff --git a/net/sock/pkg-descr b/net/sock/pkg-descr new file mode 100644 index 000000000000..55e8a143dcae --- /dev/null +++ b/net/sock/pkg-descr @@ -0,0 +1,17 @@ +This is a standalone version of W. Richard Stevens' "sock" program, +based on the code available for the UNIX Network Programming book. + +Adapted and reworked code for W. Richard Stevens' "sock" utility +by Christian Kreibich. + +From the author: In TCP/IP Illustrated Vol. 1, Richard Stevens used +a program called "sock" to demonstrate the many properties of TCP/IP. +Unfortunately, the book only speaks about how to use the program but +does not point to a site for downloading its sources. While sock is +contained in the code package accompanying UNIX Network Programming, +this code is also getting dated. + +The program can be used to generate TCP or UDP packets for testing +various network features. It runs as either client or server. + +WWW: http://www.icir.org/christian/sock.html |