aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Wills <swills@FreeBSD.org>2016-05-24 16:59:54 +0000
committerSteve Wills <swills@FreeBSD.org>2016-05-24 16:59:54 +0000
commit7eb431536b6358b31a447709e091926cecf9bda2 (patch)
treefbbb55826a98dbf120a5ce5bd85108331dbcb0cb
parentd244062f9147a4aced0f76efce3482900e2cb8fc (diff)
downloadports-7eb431536b6358b31a447709e091926cecf9bda2.tar.gz
ports-7eb431536b6358b31a447709e091926cecf9bda2.zip
Notes
-rw-r--r--net/Makefile1
-rw-r--r--net/sock/Makefile16
-rw-r--r--net/sock/distinfo2
-rw-r--r--net/sock/files/patch-src__cliopen.c264
-rw-r--r--net/sock/files/patch-src__loopudp.c261
-rw-r--r--net/sock/files/patch-src__main.c60
-rw-r--r--net/sock/files/patch-src__multicast.c111
-rw-r--r--net/sock/files/patch-src__servopen.c282
-rw-r--r--net/sock/files/patch-src__sock.h30
-rw-r--r--net/sock/files/patch-src__sockopts.c122
-rw-r--r--net/sock/files/patch-src__sourceroute.c16
-rw-r--r--net/sock/files/patch-src__sourceudp.c62
-rw-r--r--net/sock/pkg-descr17
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