Date: Tue, 24 May 2016 10:18:08 -0700 From: Cy Schubert <cschuber@gmail.com> To: Steve Wills <swills@FreeBSD.org>, "ports-committers@freebsd.org" <ports-committers@freebsd.org>, "svn-ports-all@freebsd.org" <svn-ports-all@freebsd.org>, "svn-ports-head@freebsd.org" <svn-ports-head@freebsd.org> Cc: "cy@freebsd.org" <cy@freebsd.org> Subject: RE: svn commit: r415801 - in head/net: . sock sock/files Message-ID: <57448ccc.5508620a.320db.341e@mx.google.com>
next in thread | raw e-mail | index | archive | help
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 <sjac998@yahoo.com> (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 <sjac@cs.stanford.edu> +# $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 <bsd.port.mk> 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.]=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?57448ccc.5508620a.320db.341e>