update to sysutils/socket: NetBSD IPv6 patches imported

I have created a patch that can be applied to provide IPv6
	support for sysutils/socket utility. The patch imported
	from NetBSD and cleaned up to be cleanly work on FreeBSD.

PR:		ports/36202
Submitted by:	Janos Mohacsi <janos.mohacsi@dante.org.uk>
Approved by:	maintainer timeout
This commit is contained in:
Edwin Groothuis 2003-09-29 12:57:22 +00:00
parent 7c2eba3e25
commit d66b1112ff
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=89802
5 changed files with 756 additions and 14 deletions

View file

@ -7,12 +7,14 @@
PORTNAME= socket
PORTVERSION= 1.1
CATEGORIES= sysutils net
PORTREVISION= 1
CATEGORIES= sysutils net ipv6
MASTER_SITES= http://www.de.freebsd.org/~wosch/src/
MAINTAINER= wosch@FreeBSD.org
COMMENT= Create tcp socket and connect to stdin/out
MAKE_ENV+= SWITCHES="-DUSE_INET6 -DHAVE_SYS_PARAM_H -Wall"
MAN1= socket.1
post-install:

View file

@ -1,13 +1,37 @@
--- Makefile.orig Thu Sep 10 16:59:31 1992
+++ Makefile Mon Apr 22 15:23:31 2002
@@ -8,7 +8,7 @@
### socket.1 in /usr/local/man/man1/socket.1
### Make sure the target directories exist before doing a "make install".
-INSTALLBASE = /usr/local
+INSTALLBASE = ${DESTDIR}/usr/local
INSTALLBINPATH = $(INSTALLBASE)/bin
INSTALLBINMODE = 755
INSTALLMANPATH = $(INSTALLBASE)/man
*** Makefile.orig Fri Mar 22 11:42:23 2002
--- Makefile Fri Mar 22 11:56:04 2002
***************
*** 8,14 ****
### socket.1 in /usr/local/man/man1/socket.1
### Make sure the target directories exist before doing a "make install".
! INSTALLBASE = /usr/local
INSTALLBINPATH = $(INSTALLBASE)/bin
INSTALLBINMODE = 755
INSTALLMANPATH = $(INSTALLBASE)/man
--- 8,14 ----
### socket.1 in /usr/local/man/man1/socket.1
### Make sure the target directories exist before doing a "make install".
! INSTALLBASE = ${PREFIX}
INSTALLBINPATH = $(INSTALLBASE)/bin
INSTALLBINMODE = 755
INSTALLMANPATH = $(INSTALLBASE)/man
***************
*** 43,50 ****
### CDC 4680 EP/IX: (I know it *has* setsid(2), but not with bsd43)
# SWITCHES = -systype bsd43 -DNOSETSID
! # FreeBSD 2.x (4.4BSD)
! SWITCHES=-DHAVE_SYS_PARAM_H -Wall
### It should not be necessary to change anything below this line.
##################################################################
--- 43,49 ----
### CDC 4680 EP/IX: (I know it *has* setsid(2), but not with bsd43)
# SWITCHES = -systype bsd43 -DNOSETSID
!
### It should not be necessary to change anything below this line.
##################################################################

View file

@ -0,0 +1,31 @@
*** globals.h.orig Fri Mar 22 11:42:23 2002
--- globals.h Fri Mar 22 12:05:22 2002
***************
*** 13,19 ****
# include <sys/param.h>
#endif
-
/* globals for socket */
#define IN 0 /* standard input */
--- 13,18 ----
***************
*** 27,35 ****
--- 26,41 ----
#define A(args) ()
#endif
+ #ifndef USE_INET6
int create_server_socket A((int port, int queue_length)) ;
int create_client_socket A((char **hostname, int port)) ;
int resolve_service A((char *name_or_number, char *protocol, char **name)) ;
+ #else /* USE_INET6 */
+ int *create_server_sockets A((char **port, int queue_length)) ;
+ int create_client_socket A((char **hostname, char **port)) ;
+ int socket_local_name A((int socket, char **name, char **ipname, char **port));
+ int socket_remote_name A((int socket, char **name, char **ipname, char **port));
+ #endif /* USE_INET6 */
void catchsig A((int sig)) ;
void usage A((void)) ;
int do_read_write A((int from, int to)) ;

View file

@ -0,0 +1,327 @@
*** socket.c.orig Fri Mar 22 11:42:23 2002
--- socket.c Fri Mar 22 12:06:16 2002
***************
*** 9,14 ****
--- 9,17 ----
#include <sys/types.h>
#include <sys/socket.h>
+ #ifdef USE_INET6
+ #include <sys/time.h>
+ #endif /* USE_INET6 */
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
***************
*** 36,44 ****
char *progname ; /* name of the game */
char *pipe_program = NULL ; /* program to execute in two-way pipe */
void server A((int port, char *service_name)) ;
- void handle_server_connection A((void)) ;
void client A((char *host, int port, char *service_name)) ;
extern void init_signals A((void)) ;
extern void do_io A((void)) ;
--- 39,53 ----
char *progname ; /* name of the game */
char *pipe_program = NULL ; /* program to execute in two-way pipe */
+ #ifndef USE_INET6
void server A((int port, char *service_name)) ;
void client A((char *host, int port, char *service_name)) ;
+ #else /* USE_INET6 */
+ void server A((char *port)) ;
+ void client A((char *host, char *port)) ;
+ #endif /* USE_INET6 */
+
+ void handle_server_connection A((void)) ;
extern void init_signals A((void)) ;
extern void do_io A((void)) ;
***************
*** 51,58 ****
--- 60,69 ----
int error = 0 ; /* usage error occurred */
extern int optind ; /* from getopt() */
/* char *host ; */ /* name of remote host */
+ #ifndef USE_INET6
int port ; /* port number for socket */
char *service_name ; /* name of service for port */
+ #endif /* USE_INET6 */
/* print version ID if requested */
if (argv[1] && !strcmp(argv[1], "-version")) {
***************
*** 62,68 ****
/* set up progname for later use */
progname = argv[0] ;
! if ((cp = strrchr(progname, '/'))) progname = cp + 1 ;
/* parse options */
while ((opt = getopt(argc, argv, "bcflp:qrsvw?")) != -1) {
--- 73,80 ----
/* set up progname for later use */
progname = argv[0] ;
! cp = strrchr(progname, '/');
! if (cp) progname = cp + 1 ;
/* parse options */
while ((opt = getopt(argc, argv, "bcflp:qrsvw?")) != -1) {
***************
*** 130,135 ****
--- 142,148 ----
/* set up signal handling */
init_signals() ;
+ #ifndef USE_INET6
/* get port number */
port = resolve_service(argv[optind + 1 - serverflag],
"tcp", &service_name) ;
***************
*** 138,178 ****
--- 151,231 ----
exit(5) ;
}
+ #endif /* not USE_INET6 */
/* and go */
if (serverflag) {
if (backgflag) {
background() ;
}
+ #ifndef USE_INET6
server(port, service_name) ;
+ #else /* USE_INET6 */
+ server(argv[optind]) ;
+ #endif /* USE_INET6 */
} else {
+ #ifndef USE_INET6
client(argv[optind], port, service_name) ;
+ #else /* USE_INET6 */
+ client(argv[optind], argv[optind + 1]) ;
+ #endif /* USE_INET6 */
}
exit(0) ;
}
+ #ifndef USE_INET6
void server(port, service_name)
int port ;
char *service_name ;
+ #else /* USE_INET6 */
+ void server(port)
+ char *port ;
+ #endif /* USE_INET6 */
{
+ #ifndef USE_INET6
int socket_handle, alen ;
+ #else /* USE_INET6 */
+ int *socket_handle_list ;
+ #endif /* USE_INET6 */
/* allocate server socket */
+ #ifndef USE_INET6
socket_handle = create_server_socket(port, 1) ;
if (socket_handle < 0) {
+ #else /* USE_INET6 */
+ socket_handle_list = create_server_sockets(&port, 1) ;
+ if (!socket_handle_list) {
+ #endif /* USE_INET6 */
perror2("server socket") ;
exit(1) ;
}
+ #ifdef USE_INET6
+
+ #endif /* USE_INET6 */
if (verboseflag) {
+ #ifndef USE_INET6
fprintf(stderr, "listening on port %d", port) ;
if (service_name) {
fprintf(stderr, " (%s)", service_name) ;
}
fprintf(stderr, "\n") ;
+ #else /* USE_INET6 */
+ char *ip, *port;
+ int fd, i;
+
+ fd = socket_handle_list[1];
+ for (i = 1; i <= socket_handle_list[0]; i++) {
+ if (!fd || fd < socket_handle_list[i])
+ fd = socket_handle_list[i];
+ socket_local_name (fd, NULL, &ip, &port);
+ fprintf(stderr, "listening at address %s on port %s\n", ip, port) ;
+ }
+ #endif /* USE_INET6 */
}
/* server loop */
do {
+ #ifndef USE_INET6
struct sockaddr_in sa ;
alen = sizeof(sa) ;
***************
*** 189,204 ****
long norder ;
char dotted[20] ;
! he = gethostbyaddr((char *)&sa.sin_addr.s_addr,
sizeof(sa.sin_addr.s_addr), AF_INET) ;
if (!he) {
norder = htonl(sa.sin_addr.s_addr) ;
sprintf(dotted, "%d.%d.%d.%d",
! (int)((norder >> 24) & 0xff),
! (int)((norder >> 16) & 0xff),
! (int)((norder >> 8) & 0xff),
! (int)(norder & 0xff)) ;
}
fprintf(stderr, "connection from %s\n",
(he ? he->h_name : dotted)) ;
}
--- 242,317 ----
long norder ;
char dotted[20] ;
! he = gethostbyaddr((const char *)&sa.sin_addr.s_addr,
sizeof(sa.sin_addr.s_addr), AF_INET) ;
if (!he) {
norder = htonl(sa.sin_addr.s_addr) ;
sprintf(dotted, "%d.%d.%d.%d",
! (int)((norder >> 24) & 0xff),
! (int)((norder >> 16) & 0xff),
! (int)((norder >> 8) & 0xff),
! (int)(norder & 0xff)) ;
! #else /* USE_INET6 */
! struct timeval tv;
! fd_set readfd;
! int fd, i, nfds, retval;
!
! fd = socket_handle_list[1];
! for (i = 1; i <= socket_handle_list[0]; i++) {
! if (!fd || fd < socket_handle_list[i])
! fd = socket_handle_list[i];
! }
! nfds=fd+1;
!
! FD_ZERO(&readfd);
! for (i = 1; i <= socket_handle_list[0]; i++)
! FD_SET(socket_handle_list[i],&readfd);
!
! tv.tv_sec = 10;
! tv.tv_usec = 0;
!
! retval = select(nfds, &readfd, NULL, NULL, &tv);
!
! if(retval!=-1) {
! for (i = 1; i <= socket_handle_list[0]; i++) {
! fd = socket_handle_list[i];
! if (FD_ISSET(fd, &readfd)) {
!
! /* accept a connection */
! active_socket = accept(fd, (struct sockaddr *) 0, (int *)0);
! if (active_socket == -1) {
! perror2("accept") ;
! } else {
! /* if verbose, get name of peer and give message */
! if (verboseflag) {
! char *host, *ip, *port;
!
! if(!socket_remote_name(active_socket,&host, &ip, &port)) {
! fprintf(stderr, "connection from %s at %s to %s\n", host, ip, port);
! }
! else
! fprintf(stderr, "cannot get name or address of peer") ;
! }
!
! if (forkflag) {
! switch (fork()) {
! case 0:
! handle_server_connection() ;
! exit(0) ;
! case -1:
! perror2("fork") ;
! break ;
! default:
! close(active_socket) ;
! wait_for_children() ;
! }
! } else {
! handle_server_connection() ;
! }
! }
! #endif /* USE_INET6 */
}
+ #ifndef USE_INET6
fprintf(stderr, "connection from %s\n",
(he ? he->h_name : dotted)) ;
}
***************
*** 216,224 ****
--- 329,342 ----
}
} else {
handle_server_connection() ;
+ #endif /* not USE_INET6 */
}
}
} while (loopflag) ;
+ #ifdef USE_INET6
+
+ free (socket_handle_list);
+ #endif /* USE_INET6 */
}
***************
*** 239,251 ****
--- 357,381 ----
}
+ #ifndef USE_INET6
void client(host, port, service_name)
+ #else /* USE_INET6 */
+ void client(host, port)
+ #endif /* USE_INET6 */
char *host ;
+ #ifndef USE_INET6
int port ;
char *service_name ;
+ #else /* USE_INET6 */
+ char *port ;
+ #endif /* USE_INET6 */
{
/* get connection */
+ #ifndef USE_INET6
active_socket = create_client_socket(&host, port) ;
+ #else /* USE_INET6 */
+ active_socket = create_client_socket(&host, &port) ;
+ #endif /* USE_INET6 */
if (active_socket == -1) {
perror2("client socket") ;
exit(errno) ;
***************
*** 254,264 ****
--- 384,401 ----
exit(13) ;
}
if (verboseflag) {
+ #ifndef USE_INET6
fprintf(stderr, "connected to %s port %d", host, port) ;
if (service_name) {
fprintf(stderr, " (%s)", service_name) ;
}
fprintf(stderr, "\n") ;
+ #else /* USE_INET6 */
+ char *host, *ip, *port;
+
+ socket_local_name (active_socket, &host, &ip, &port);
+ fprintf(stderr, "connected to %s with address %s at port %s\n", host, ip, port) ;
+ #endif /* USE_INET6 */
}
/* open pipes to program if requested */

View file

@ -0,0 +1,358 @@
*** socketp.c.orig Fri Mar 22 11:42:23 2002
--- socketp.c Fri Mar 22 12:07:59 2002
***************
*** 21,26 ****
--- 21,27 ----
extern int is_number A((char *));
+ #ifndef USE_INET6
/*
* create a server socket on PORT accepting QUEUE_LENGTH connections
*/
***************
*** 31,39 ****
struct sockaddr_in sa ;
int s;
! if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
return -1 ;
- }
bzero((char *) &sa, sizeof(sa)) ;
sa.sin_family = AF_INET ;
--- 32,40 ----
struct sockaddr_in sa ;
int s;
! s = socket(AF_INET, SOCK_STREAM, 0);
! if (s < 0)
return -1 ;
bzero((char *) &sa, sizeof(sa)) ;
sa.sin_family = AF_INET ;
***************
*** 41,56 ****
sa.sin_port = htons(port) ;
if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
! return -1 ;
}
if (listen(s, 1) < 0) {
! return -1 ;
}
return s ;
}
/* create a client socket connected to PORT on HOSTNAME */
int create_client_socket(hostname, port)
char **hostname ;
--- 42,126 ----
sa.sin_port = htons(port) ;
if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
! return -1 ;
}
if (listen(s, 1) < 0) {
! return -1 ;
}
return s ;
}
+ #else /* USE_INET6 */
+ /*
+ * create a server socket(s) on PORT accepting QUEUE_LENGTH connections
+ *
+ * FWD (ifdef USE_INET6):
+ * there can be more than one socket; one for each supported address
+ * family. This is for portability as not all IPv6 stacks implement
+ * the wildcard bind as a bind to *ll IPv4 *and* IPv6 addresses.
+ * so we'll just open a socket for each address getaddrinfo() gives
+ * back to us. The price of portability...
+ */
+ int *create_server_sockets(port, queue_length)
+ char **port ;
+ int queue_length ;
+ {
+ struct addrinfo hints, *r, *res;
+ int *s, *slist, error, maxs;
+ int reuse_addr = 1;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = 0;
+ error = getaddrinfo(NULL, *port, &hints, &res);
+
+ if (!error) {
+ for (maxs = 0, r = res; r; r = r->ai_next, maxs++);
+ slist = malloc ((maxs+1) * sizeof(int));
+ if (slist) {
+ slist[0] = maxs; /* max. num of sockets */
+
+ s = slist+1;
+ for (r = res; r; r = r->ai_next) {
+ *s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
+ if (*s < 0)
+ continue;
+
+ setsockopt(*s,SOL_SOCKET,SO_REUSEADDR,&reuse_addr,sizeof(reuse_addr));
+
+ if (bind(*s, r->ai_addr, r->ai_addrlen) < 0) {
+ close (*s);
+ continue;
+ }
+
+ if (listen(*s, 1) < 0) {
+ close (*s);
+ continue;
+ }
+ s++;
+ }
+ }
+ }
+ else
+ slist = NULL;
+ if (res)
+ freeaddrinfo(res);
+ if (slist && !slist[0]) {
+ free (slist);
+ slist = NULL;
+ }
+
+ return (slist);
+ }
+ #endif /* USE_INET6 */
+
+
+ /* create a client socket connected to PORT on HOSTNAME */
+ #ifndef USE_INET6
/* create a client socket connected to PORT on HOSTNAME */
int create_client_socket(hostname, port)
char **hostname ;
***************
*** 64,94 ****
bzero(&sa, sizeof(sa)) ;
if ((addr = inet_addr(*hostname)) != -1) {
! /* is Internet addr in octet notation */
! bcopy(&addr, (char *) &sa.sin_addr, sizeof(addr)) ; /* set address */
! sa.sin_family = AF_INET ;
} else {
! /* do we know the host's address? */
! if ((hp = gethostbyname(*hostname)) == NULL) {
! return -2 ;
! }
! *hostname = hp->h_name ;
! bcopy(hp->h_addr, (char *) &sa.sin_addr, hp->h_length) ;
! sa.sin_family = hp->h_addrtype ;
}
sa.sin_port = htons((u_short) port) ;
if ((s = socket(sa.sin_family, SOCK_STREAM, 0)) < 0) { /* get socket */
! return -1 ;
}
if (connect(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) { /* connect */
! close(s) ;
! return -1 ;
}
return s ;
}
/* return the port number for service NAME_OR_NUMBER. If NAME is non-null,
* the name is the service is written there.
*/
--- 134,311 ----
bzero(&sa, sizeof(sa)) ;
if ((addr = inet_addr(*hostname)) != -1) {
! /* is Internet addr in octet notation */
! bcopy(&addr, (char *) &sa.sin_addr, sizeof(addr)) ; /* set address */
! sa.sin_family = AF_INET ;
} else {
! /* do we know the host's address? */
! if ((hp = gethostbyname(*hostname)) == NULL) {
! return -2 ;
! }
! *hostname = hp->h_name ;
! bcopy(hp->h_addr, (char *) &sa.sin_addr, hp->h_length) ;
! sa.sin_family = hp->h_addrtype ;
}
sa.sin_port = htons((u_short) port) ;
if ((s = socket(sa.sin_family, SOCK_STREAM, 0)) < 0) { /* get socket */
! return -1 ;
}
if (connect(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) { /* connect */
! close(s) ;
! return -1 ;
}
return s ;
}
+ #else /* USE_INET6 */
+ int create_client_socket(hostname, port)
+ char **hostname ;
+ char **port ;
+ {
+ int s, connected, err ;
+ struct addrinfo hints, *r, *res;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype= SOCK_STREAM;
+ err = getaddrinfo(*hostname, *port, &hints, &res);
+ if (res) freeaddrinfo(res);
+
+ if (!err) {
+ /* numeric */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = 0;
+ err = getaddrinfo(*hostname, *port, &hints, &res);
+ if (err) s = -2;
+ } else {
+ /* non-numeric */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = 0;
+ err = getaddrinfo(*hostname, *port, &hints, &res);
+ if (err) s = -2;
+ }
+
+
+ if (!err) {
+ err = 0; s = -1;
+ connected = 0;
+ for (r = res; r && !connected; r = r->ai_next) {
+ s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
+ if (s < 0)
+ continue;
+
+ if (connect(s, r->ai_addr, r->ai_addrlen) < 0) {
+ err = errno;
+ close(s);
+ s = -1;
+ continue;
+ }
+ connected++;
+ break;
+ }
+ if (!connected) s = -1;
+ }
+
+ if (res)
+ freeaddrinfo(res);
+
+ return (s);
+ }
+ #endif /* USE_INET6 */
+
+ #ifdef USE_INET6
+ /* Determines hostname, address and port number used for the peer of socket */
+ int socket_remote_name(socket, name, ipname, port)
+ int socket;
+ char **name;
+ char **ipname;
+ char **port;
+ {
+ struct sockaddr_storage server;
+ int length=sizeof(server), retval, error;
+ static char host[NI_MAXHOST],ip[NI_MAXHOST],portstr[NI_MAXSERV];
+
+ error = getpeername(socket,(struct sockaddr*)&server,&length);
+ if(!error) {
+ error = getnameinfo((struct sockaddr*)&server, length, host,
+ NI_MAXHOST, NULL, 0, 0);
+ error = getnameinfo((struct sockaddr*)&server, length, ip,
+ NI_MAXHOST, NULL, NI_MAXSERV,
+ NI_NUMERICHOST);
+ retval = error;
+
+ error = getnameinfo((struct sockaddr*)&server, length, NULL, 0,
+ portstr, NI_MAXSERV, 0);
+
+ if (error)
+ retval = getnameinfo((struct sockaddr*)&server, length, ip,
+ NI_MAXHOST, portstr, NI_MAXSERV,
+ NI_NUMERICSERV);
+ }
+ else
+ retval = error;
+
+ if(name)
+ *name=host;
+ if(ipname)
+ *ipname=ip;
+ if(port)
+ *port=portstr;
+
+ return(retval);
+ }
+
+ /* Determines the hostname, address and port number used for our socket */
+ int socket_local_name(socket, name, ipname, port)
+ int socket;
+ char **name;
+ char **ipname;
+ char **port;
+ {
+ struct sockaddr_storage server;
+ int length=sizeof(server), retval, error;
+ static char host[NI_MAXHOST],ip[NI_MAXHOST],portstr[NI_MAXSERV];
+
+ error = getsockname(socket,(struct sockaddr*)&server,&length);
+ if(!error) {
+ error = getnameinfo((struct sockaddr*)&server, length, host,
+ NI_MAXHOST, NULL, 0, 0);
+ error = getnameinfo((struct sockaddr*)&server, length, ip,
+ NI_MAXHOST, NULL, NI_MAXSERV,
+ NI_NUMERICHOST);
+ retval = error;
+
+ error = getnameinfo((struct sockaddr*)&server, length, NULL, 0,
+ portstr, NI_MAXSERV, 0);
+
+ if (error)
+ retval = getnameinfo((struct sockaddr*)&server, length, ip,
+ NI_MAXHOST, portstr, NI_MAXSERV,
+ NI_NUMERICSERV);
+ }
+ else
+ retval = error;
+
+ if(name)
+ *name=host;
+ if(ipname)
+ *ipname=ip;
+ if(port)
+ *port=portstr;
+
+ return(retval);
+ }
+ #endif /* USE_INET6 */
+
+ #ifndef USE_INET6
/* return the port number for service NAME_OR_NUMBER. If NAME is non-null,
* the name is the service is written there.
*/
***************
*** 122,126 ****
--- 339,344 ----
return ntohs(servent->s_port) ;
}
}
+ #endif /* !USE_INET6 */
/*EOF*/