From owner-svn-ports-head@freebsd.org Tue May 24 17:18:07 2016 Return-Path: Delivered-To: svn-ports-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7F285B47018; Tue, 24 May 2016 17:18:07 +0000 (UTC) (envelope-from cschuber@gmail.com) Received: from mail-pf0-x243.google.com (mail-pf0-x243.google.com [IPv6:2607:f8b0:400e:c00::243]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4B333143A; Tue, 24 May 2016 17:18:07 +0000 (UTC) (envelope-from cschuber@gmail.com) Received: by mail-pf0-x243.google.com with SMTP id g132so2760853pfb.3; Tue, 24 May 2016 10:18:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:mime-version:from:subject:date:to:cc; bh=yPKLOl0RbeymRtYOdDiIKTORUCXs3jV8zKmRxXeGYsE=; b=dOFVCino1kinSMy+Ie65bZ2eFLaqFSelYblDIjpRaI+F9bEf1lWFBJPXiPMZWUActg FtRTEEeVtGDwWZF1voCxgmGKx2h4GhfijT3shjevL59ElTuKda4CEsf9mxt1I7MnOcvY 70tq9/NBSXegxg1ayKkTztpAf16NldmlHTue6dWnCp6JjjQ2fXnQxDyYBrlccC0f6KUC Xuvnny3fUvsY2Iy+aTP+vXV27pBhXQa4SX0zK6vz40MZB8ZmKyRhvufHEvPj8f6YEqWZ pbieg+VEvoNHs5W+/EOJK+ioX9WJoN398ISgoC3xAwPazqThoRV3aX74gXmB36aEDgoh 9Lzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:message-id:mime-version:from:subject:date:to:cc; bh=yPKLOl0RbeymRtYOdDiIKTORUCXs3jV8zKmRxXeGYsE=; b=PYGy+FRbLmMb21Ft2rxLl7zGrpF9X46gz1FY6WW4ScD0Tfr8qi3fe+yuQRdDMsMw2e JuLWQte3rYr5Q4TTcSAfe3bSs4rSL2oBDsUttdiKfi2y8Yd7W3yynrvRRAU7/T1otHXS Rdyp1ArhTGmWPjnONAPECcmdnOB084HrgKJ196WHDbCSYBAgg8VNc1Ub6gun6FwsgoH2 0PJlHgq6/zUvC4+It1CCzmAWptGEfVgnDAlDEFt1jTsGBI9jNJnpxkuIICOAgF5z1fd2 hvo+25MPxz1cClt+KkqKj3qLPfAAGg7Ipq3XvngjcHtc17uj1dxUFvd/XpW+5ELvfbaZ ZCkQ== X-Gm-Message-State: ALyK8tL/I0hmeG0ZfMlqhx6G79FsZ+ERsD6ASbV1dDAHUm5Z9hJVQmFmiVUFc02xp1x0RQ== X-Received: by 10.98.93.131 with SMTP id n3mr8671983pfj.141.1464110286705; Tue, 24 May 2016 10:18:06 -0700 (PDT) Received: from [25.88.35.112] (S0106d4ca6d8943b0.gv.shawcable.net. [24.68.134.59]) by smtp.gmail.com with ESMTPSA id c82sm15477935pfd.42.2016.05.24.10.18.03 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 24 May 2016 10:18:04 -0700 (PDT) Message-ID: <57448ccc.5508620a.320db.341e@mx.google.com> MIME-Version: 1.0 From: Cy Schubert Subject: RE: svn commit: r415801 - in head/net: . sock sock/files Date: Tue, 24 May 2016 10:18:08 -0700 To: Steve Wills , "ports-committers@freebsd.org" , "svn-ports-all@freebsd.org" , "svn-ports-head@freebsd.org" CC: "cy@freebsd.org" Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.22 X-BeenThere: svn-ports-head@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the ports tree for head List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 May 2016 17:18:07 -0000 Cool. I'll have to check this out... Good book. Sent from my cellphone, ~Cy -----Original Message----- From: Steve Wills Sent: 24/05/2016 10:00 To: ports-committers@freebsd.org; svn-ports-all@freebsd.org; svn-ports-head= @freebsd.org Subject: svn commit: r415801 - in head/net: . sock sock/files Author: swills Date: Tue May 24 16:59:54 2016 New Revision: 415801 URL: https://svnweb.freebsd.org/changeset/ports/415801 Log: net/sock: create port =20 This is a standalone version of W. Richard Stevens' "sock" program, based on the code available for the UNIX Network Programming book. =20 Adapted and reworked code for W. Richard Stevens' "sock" utility by Christian Kreibich. =20 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. =20 The program can be used to generate TCP or UDP packets for testing various network features. It runs as either client or server. =20 WWW: http://www.icir.org/christian/sock.html =20 PR: 206345 Submitted by: Steve Jacobson (with slight modificatio= n) Added: head/net/sock/ head/net/sock/Makefile (contents, props changed) head/net/sock/distinfo (contents, props changed) head/net/sock/files/ head/net/sock/files/patch-src__cliopen.c (contents, props changed) head/net/sock/files/patch-src__loopudp.c (contents, props changed) head/net/sock/files/patch-src__main.c (contents, props changed) head/net/sock/files/patch-src__multicast.c (contents, props changed) head/net/sock/files/patch-src__servopen.c (contents, props changed) head/net/sock/files/patch-src__sock.h (contents, props changed) head/net/sock/files/patch-src__sockopts.c (contents, props changed) head/net/sock/files/patch-src__sourceroute.c (contents, props changed) head/net/sock/files/patch-src__sourceudp.c (contents, props changed) head/net/sock/pkg-descr (contents, props changed) Modified: head/net/Makefile Modified: head/net/Makefile =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- head/net/Makefile Tue May 24 16:15:40 2016 (r415800) +++ head/net/Makefile Tue May 24 16:59:54 2016 (r415801) @@ -1226,6 +1226,7 @@ SUBDIR +=3D sntop SUBDIR +=3D sobby SUBDIR +=3D socat + SUBDIR +=3D sock SUBDIR +=3D socketbind SUBDIR +=3D socketpipe SUBDIR +=3D socketw Added: head/net/sock/Makefile =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/net/sock/Makefile Tue May 24 16:59:54 2016 (r415801) @@ -0,0 +1,16 @@ +# Created by: Steve Jacobson +# $FreeBSD$ + +PORTNAME=3D sock +PORTVERSION=3D 0.3.2 +CATEGORIES=3D net +MASTER_SITES=3D http://www.icir.org/christian/downloads/ + +MAINTAINER=3D sjac@cs.stanford.edu +COMMENT=3D W. Richard Stevens' sock program + +HAS_CONFIGURE=3D yes + +PLIST_FILES=3D bin/sock + +.include Added: head/net/sock/distinfo =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/net/sock/distinfo Tue May 24 16:59:54 2016 (r415801) @@ -0,0 +1,2 @@ +SHA256 (sock-0.3.2.tar.gz) =3D 4ddc33767900e7cd0a4cc0f4d808638d7cfcb746c23= e12274c8eba0622eee2eb +SIZE (sock-0.3.2.tar.gz) =3D 113640 Added: head/net/sock/files/patch-src__cliopen.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/net/sock/files/patch-src__cliopen.c Tue May 24 16:59:54 2016 (r415= 801) @@ -0,0 +1,264 @@ +--- src/cliopen.c.orig 2010-05-28 00:03:25 UTC ++++ src/cliopen.c +@@ -10,42 +10,107 @@ +=20 + #include "sock.h" +=20 ++/* ++ * 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 =3D=3D af_46) { ++ if (inet_pton(AF_INET, host, &inaddr) =3D=3D 1) { ++ /* IPv4 dotted-decimal */ ++ servaddr4.sin_addr =3D inaddr; ++ ++ return (1); ++ } ++ } else { ++ if (inet_pton(AF_INET6, host, inaddr_buf) =3D=3D 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 =3D=3D af_46) { ++ if ( (hp =3D gethostbyname2(host, AF_INET)) !=3D 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 =3D gethostbyname2(host, AF_INET6)) !=3D 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; +=20 + protocol =3D udp ? "udp" : "tcp"; + =20 + /* initialize socket address structure */ +- bzero(&servaddr, sizeof(servaddr)); +- servaddr.sin_family =3D AF_INET; ++ bzero(&servaddr4, sizeof(servaddr4)); ++ servaddr4.sin_family =3D AF_INET; ++ ++ bzero(&servaddr6, sizeof(servaddr6)); ++ servaddr6.sin6_family =3D AF_INET6; + =20 + /* see if "port" is a service name or number */ + if ( (i =3D atoi(port)) =3D=3D 0) { + if ( (sp =3D getservbyname(port, protocol)) =3D=3D NULL) +- err_quit("getservbyname() error for: %s/%s", port, protocol); +- =20 +- servaddr.sin_port =3D sp->s_port; +- } else +- servaddr.sin_port =3D htons(i); ++ err_quit("getservbyname() error for: %s/%s", ++ port, protocol); ++ servaddr4.sin_port =3D sp->s_port; ++ servaddr6.sin6_port =3D sp->s_port; ++ } else { ++ servaddr4.sin_port =3D htons(i); ++ servaddr6.sin6_port =3D htons(i); ++ } + =20 + /* +- * 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. + */ +- =20 +- if (inet_aton(host, &inaddr) =3D=3D 1) +- servaddr.sin_addr =3D inaddr; /* it's dotted-decimal */ +- else if ( (hp =3D gethostbyname(host)) !=3D NULL) +- bcopy(hp->h_addr, &servaddr.sin_addr, hp->h_length); +- else +- err_quit("invalid hostname: %s", host); ++ if (convert_host_address(host) !=3D 1) { ++ if (convert_host_name(host) !=3D 1) { ++ err_quit("invalid hostname: %s", host); ++ } ++ } +=20 +- if ( (fd =3D socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) ++ if ( (fd =3D socket(af_46, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) + err_sys("socket() error"); +=20 + 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. + */ +-=09 + if (bindport !=3D 0 || localip[0] !=3D 0 || udp) { +- bzero(&cliaddr, sizeof(cliaddr)); +- cliaddr.sin_family =3D AF_INET; +- cliaddr.sin_port =3D htons(bindport); /* can be 0 */ +- if (localip[0] !=3D 0) { +- if (inet_aton(localip, &cliaddr.sin_addr) =3D=3D 0) +- err_quit("invalid IP address: %s", localip); +- } else +- cliaddr.sin_addr.s_addr =3D htonl(INADDR_ANY); /* wildcard */ +- =09 +- if (bind(fd, (struct sockaddr *) &cliaddr, sizeof(cliaddr)) < 0) +- err_sys("bind() error"); ++ if (af_46 =3D=3D AF_INET) { ++ bzero(&cliaddr4, sizeof(cliaddr4)); ++ cliaddr4.sin_family =3D AF_INET; ++ /* can be 0 */ ++ cliaddr4.sin_port =3D htons(bindport); ++ if (localip[0] !=3D 0) { ++ if (inet_aton(localip, &cliaddr4.sin_addr) =3D=3D 0) ++ err_quit("invalid IP address: %s", ++ localip); ++ } else { ++ /* wildcard */ ++ cliaddr4.sin_addr.s_addr =3D htonl(INADDR_ANY); ++ } ++ if (bind(fd, (struct sockaddr *) &cliaddr4, ++ sizeof(cliaddr4)) < 0) { ++ err_sys("bind() error"); ++ } ++ } else { ++ bzero(&cliaddr6, sizeof(cliaddr6)); ++ cliaddr6.sin6_len =3D sizeof(struct sockaddr_in6); ++ cliaddr6.sin6_family =3D AF_INET6; ++ /* can be 0 */ ++ cliaddr6.sin6_port =3D htons(bindport); ++ ++ /* Fixme: localip not implemented for IPv6 */ ++ cliaddr6.sin6_addr =3D in6addr_any; ++ ++ /* Fixme: Want to set IPV6_BINDANY? */ ++ ++ if (bind(fd, (struct sockaddr *) &cliaddr6, ++ sizeof(cliaddr6)) < 0) { ++ err_sys("bind() error"); ++ } ++ } + } +-=09 ++ ++ /* 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. + */ +-=09 + if (udp =3D=3D 0 || connectudp) { + for ( ; ; ) { +- if (connect(fd, (struct sockaddr *) &servaddr, sizeof(servaddr)) +- =3D=3D 0) ++ if (AF_INET =3D=3D af_46) { ++ if (connect(fd, (struct sockaddr *) &servaddr4, ++ sizeof(servaddr4)) =3D=3D 0) + break; /* all OK */ +- if (errno =3D=3D EINTR) /* can happen with SIGIO */ ++ } else { ++ servaddr6.sin6_len =3D ++ sizeof(struct sockaddr_in6); ++ servaddr6.sin6_family =3D AF_INET6; ++ if (connect(fd, (struct sockaddr *) &servaddr6, ++ sizeof(servaddr6)) =3D=3D 0) ++ break; /* all OK */ ++ } ++ if (errno =3D=3D EINTR) /* can happen with SIGIO */ + continue; + if (errno =3D=3D 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 =3D sizeof(cliaddr); +- if (getsockname(fd, (struct sockaddr *) &cliaddr, &i) < 0) +- err_sys("getsockname() error"); +- =09 +- /* 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 =3D=3D af_46) { ++ socklen =3D 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 =3D 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)); ++ } + } + =09 + sockopts(fd, 1); /* some options get set after connect() */ Added: head/net/sock/files/patch-src__loopudp.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/net/sock/files/patch-src__loopudp.c Tue May 24 16:59:54 2016 (r415= 801) @@ -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]; + =09 +- struct iovec iov[1]; +- struct msghdr msg; ++ struct iovec iov[1]; ++ struct msghdr msg; + #ifdef HAVE_MSGHDR_MSG_CONTROL =09 + #ifdef IP_RECVDSTADDR /* 4.3BSD Reno and later */ + static struct cmsghdr *cmptr =3D 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 */ + =09 +@@ -68,8 +79,10 @@ loop_udp(int sockfd) + err_sys("shutdown() error"); + =09 + FD_CLR(STDIN_FILENO, &rset); +- stdineof =3D 1; /* don't read stdin anymore */ +- continue; /* back to select() */ ++ /* don't read stdin anymore */ ++ stdineof =3D 1; ++ /* back to select() */ ++ continue; + } + break; /* default: stdin EOF -> done */ + } +@@ -77,23 +90,43 @@ loop_udp(int sockfd) + if (crlf) { + ntowrite =3D crlf_add(wbuf, writelen, rbuf, nread); + if (connectudp) { +- if (write(sockfd, wbuf, ntowrite) !=3D ntowrite) ++ if (write(sockfd, wbuf, ntowrite) !=3D ++ ntowrite) { + err_sys("write error"); ++ } + } else { +- if (sendto(sockfd, wbuf, ntowrite, 0, +- (struct sockaddr *) &servaddr, sizeof(servaddr)) +- !=3D ntowrite) +- err_sys("sendto error"); ++ if (af_46 =3D=3D AF_INET) { ++ if (sendto(sockfd, wbuf, ntowrite, 0, ++ (struct sockaddr *)&servaddr4, ++ sizeof(servaddr4)) !=3D ntowrite) { ++ err_sys("sendto error"); ++ } ++ } else { ++ if (sendto(sockfd, wbuf, ntowrite, 0, ++ (struct sockaddr *)&servaddr6, ++ sizeof(servaddr6)) !=3D ntowrite) { ++ err_sys("sendto error"); ++ } ++ } + } + } else { + if (connectudp) { + if (write(sockfd, rbuf, nread) !=3D nread) + err_sys("write error"); + } else { +- if (sendto(sockfd, rbuf, nread, 0, +- (struct sockaddr *) &servaddr, sizeof(servaddr)) +- !=3D nread) +- err_sys("sendto error"); ++ if (af_46 =3D=3D AF_INET) { ++ if (sendto(sockfd, rbuf, nread, 0, ++ (struct sockaddr *)&servaddr4, ++ sizeof(servaddr4)) !=3D nread) { ++ err_sys("sendto error"); ++ } ++ } else { ++ if (sendto(sockfd, rbuf, nread, 0, ++ (struct sockaddr *)&servaddr6, ++ sizeof(servaddr6)) !=3D 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 =3D sizeof(cliaddr); +-#ifndef MSG_TRUNC /* vanilla BSD sockets */ ++ if (af_46 =3D=3D AF_INET) { ++ clilen =3D sizeof(cliaddr4); ++ } else { ++ clilen =3D sizeof(cliaddr6); ++ } ++ ++#ifndef MSG_TRUNC /* vanilla BSD sockets */ ++ ++ /* Fixme: Not ported for IPv6 */ ++ /* Not compiled in for FreeBSD 8.4 */ + nread =3D recvfrom(sockfd, rbuf, readlen, 0, +- (struct sockaddr *) &cliaddr, &clilen); +- =20 ++ (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) *= / +- =09 ++ /* Also lets us get at control information (destination address) */ ++ ++ /* FreeBSD 8.4 */ + iov[0].iov_base =3D rbuf; + iov[0].iov_len =3D readlen; +- msg.msg_iov =3D iov; +- msg.msg_iovlen =3D 1; +- msg.msg_name =3D (caddr_t) &cliaddr; +- msg.msg_namelen =3D clilen; +- =09 ++ msg.msg_iov =3D iov; ++ msg.msg_iovlen =3D 1; ++ if (af_46 =3D=3D AF_INET) { ++ msg.msg_name =3D (caddr_t) &cliaddr4; ++ } else { ++ msg.msg_name =3D (caddr_t) &cliaddr6; ++ } ++ msg.msg_namelen =3D clilen; ++ + #ifdef HAVE_MSGHDR_MSG_CONTROL + #ifdef IP_RECVDSTADDR ++ /* FreeBSD 8.4 */ + if (cmptr =3D=3D NULL && (cmptr =3D malloc(CONTROLLEN)) =3D=3D NULL) + err_sys("malloc error for control buffer"); +=20 +- msg.msg_control =3D (caddr_t) cmptr; /* for dest address */ ++ /* for dest address */ ++ msg.msg_control =3D (caddr_t) cmptr; + msg.msg_controllen =3D CONTROLLEN; + #else +- msg.msg_control =3D (caddr_t) 0; /* no ancillary data */ ++ /* Not used for FreeBSD 8.4 */ ++ /* no ancillary data */ ++ msg.msg_control =3D (caddr_t) 0; + msg.msg_controllen =3D 0; + #endif /* IP_RECVDSTADDR */ + #endif + #ifdef HAVE_MSGHDR_MSG_FLAGS +- msg.msg_flags =3D 0; /* flags returned here */ ++ /* FreeBSD 8.4 */ ++ /* flags returned here */ ++ msg.msg_flags =3D 0; + #endif =09 + nread =3D recvmsg(sockfd, &msg, 0); + #endif /* MSG_TRUNC */ +@@ -137,22 +189,39 @@ loop_udp(int sockfd) + err_sys("datagram receive error"); + =09 + if (verbose) { +- printf("from %s", INET_NTOA(cliaddr.sin_addr)); ++ if (af_46 =3D=3D 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 !=3D CONTROLLEN) + err_quit("control length (%d) !=3D %d", +- cmptr->cmsg_len, CONTROLLEN); ++ cmptr->cmsg_len, CONTROLLEN); + if (cmptr->cmsg_level !=3D IPPROTO_IP) + err_quit("control level !=3D IPPROTO_IP"); + if (cmptr->cmsg_type !=3D IP_RECVDSTADDR) + err_quit("control type !=3D IP_RECVDSTADDR"); + bcopy(CMSG_DATA(cmptr), &dstinaddr, +- sizeof(struct in_addr)); ++ sizeof(struct in_addr)); + bzero(cmptr, CONTROLLEN); + =09 +- 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) + } + =20 + } else { +- /* Must use recvfrom() for unconnected UDP client */ +- servlen =3D sizeof(servaddr); +- nread =3D 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 =3D=3D AF_INET) { ++ servlen =3D sizeof(servaddr4); ++ nread =3D recvfrom(sockfd, rbuf, readlen, ++ 0, (struct sockaddr *)&servaddr4, ++ &servlen); ++ } else { ++ servlen =3D sizeof(servaddr6); ++ nread =3D recvfrom(sockfd, rbuf, readlen, ++ 0, (struct sockaddr *)&servaddr6, ++ &servlen) [The entire original message is not included.]=