diff --git a/DISCLAIMER b/DISCLAIMER new file mode 100644 index 0000000..e24e4a8 --- /dev/null +++ b/DISCLAIMER @@ -0,0 +1,11 @@ + LIMITS OF LIABILITY AND DISCLAIMER OF WARRANTY + +The authors and publisher of the book "UNIX Network Programming" have +used their best efforts in preparing this software. These efforts +include the development, research, and testing of the theories and +programs to determine their effectiveness. The authors and publisher +make no warranty of any kind, express or implied, with regard to +these programs or the documentation contained in the book. The authors +and publisher shall not be liable in any event for incidental or +consequential damages in connection with, or arising out of, the +furnishing, performance, or use of these programs. diff --git a/Make.defines.in b/Make.defines.in new file mode 100644 index 0000000..ce542a9 --- /dev/null +++ b/Make.defines.in @@ -0,0 +1,41 @@ +# +# This file is generated by autoconf from "Make.defines.in". +# +# This is the "Make.defines" file that almost every "Makefile" in the +# source directories below this directory include. +# The "../" in the pathnames actually refer to this directory, since +# "make" is executed in all the subdirectories of this directory. +# +# System = @host@ + +CC = @CC@ +CFLAGS = -I../lib @CFLAGS@ +LIBS = @LIBUNP@ @LIBS@ +LIBS_XTI = @LIBUNPXTI@ @LIBUNP@ @LIBS_XTI@ +RANLIB = @RANLIB@ + +# Following is the main library, built from all the object files +# in the lib/ and libfree/ directories. +LIBUNP_NAME = @LIBUNP_NAME@ + +# Following is the XTI library, built from all the object files +# in the libxti/ directory. +LIBUNPXTI_NAME = @LIBUNPXTI_NAME@ + +# Following are all the object files to create in the lib/ directory. +LIB_OBJS = @LIB_OBJS@ + +# Following are all the object files to create in the libfree/ directory. +LIBFREE_OBJS = @LIBFREE_OBJS@ + +# Following are all the object files to create in the libgai/ directory. +LIBGAI_OBJS = @LIBGAI_OBJS@ + +# Following are all the object files to create in the libroute/ directory. +LIBROUTE_OBJS = @LIBROUTE_OBJS@ + +# Following are all the object files to create in the libxti/ directory. +LIBXTI_OBJS = @LIBXTI_OBJS@ + +CLEANFILES = core core.* *.core *.o temp.* *.out typescript* \ + *.lc *.lh *.bsdi *.sparc *.uw diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..452f73e --- /dev/null +++ b/Makefile.in @@ -0,0 +1,11 @@ +include ./Make.defines + +all: + @echo "Nothing to make in this directory" + @echo "Please read the README file" + +clean: + rm -f $(CLEANFILES) + +distclean: + rm -f $(CLEANFILES) config.cache config.log config.status config.h Make.defines Makefile diff --git a/README b/README new file mode 100644 index 0000000..b760854 --- /dev/null +++ b/README @@ -0,0 +1,115 @@ +QUICK AND DIRTY +=============== + +Execute the following from the src/ directory: + + ./configure # try to figure out all implementation differences + + cd lib # build the basic library that all programs need + make # use "gmake" everywhere on BSD/OS systems + + cd ../libfree # continue building the basic library + make + + cd ../libroute # only if your system supports 4.4BSD style routing sockets + make # only if your system supports 4.4BSD style routing sockets + + cd ../libxti # only if your system supports XTI + make # only if your system supports XTI + + cd ../intro # build and test a basic client program + make daytimetcpcli + ./daytimetcpcli 127.0.0.1 + +If all that works, you're all set to start compiling individual programs. + +Notice that all the source code assumes tabs every 4 columns, not 8. + +MORE DETAILS +============ + +5. If you need to make any changes to the "unp.h" header, notice that it + is a hard link in each directory, so you only need to change it once. + +6. Go into the "lib/" directory and type "make". This builds the library + "libunp.a" that is required by almost all of the programs. There may + be compiler warnings (see NOTES below). This step is where you'll find + all of your system's dependencies, and you must just update your cf/ + files from step 1, rerun "config" and do this step again. + +6. Go into the "libfree/" directory and type "make". This adds to the + "libunp.a" library. The files in this directory do not #include + the "unp.h" header, as people may want to use these functions + independent of the book's examples. + +8. Once the library is made from steps 5 and 6, you can then go into any + of the source code directories and make whatever program you are + interested in. Note that the horizontal rules at the beginning and + end of each program listing in the book contain the directory name and + filename. + + BEWARE: Not all programs in each directory will compile on all systems + (e.g., the file src/advio/recvfromflags.c will not compile unless your + system supports the IP_RECVDSTADDR socket option). Also, not all files + in each directory are included in the book. Beware of any files with + "test" in the filename: they are probably a quick test program that I + wrote to check something, and may or may not work. + +NOTES +----- + +- Many systems do not have correct function prototypes for the socket + functions, and this can cause many warnings during compilation. + For example, Solaris 2.5 omits the "const" from the 2nd argument + to connect(). Lots of systems use "int" for the length of socket + address structures, while Posix.1g specifies "size_t". Lots of + systems still have the pointer argument to [sg]etsockopt() as a + "char *" instead of a "void *", and this also causes warnings. + +- SunOS 4.1.x: If you are using Sun's acc compiler, you need to run + the configure program as + + CC=acc CFLAGS=-w CPPFLAGS=-w ./configure + + Failure to do this results in numerous system headers () + not being found during configuration, causing compile errors later. + +- If your system supports IPv6 and you want to run the examples in the + book using hostnames, you must install the latest BIND release. You + can get it from ftp://ftp.vix.com/pub/bind/release. All you need from + this release is a resolver library that you should then add to the + LDLIBS and LDLIBS_THREADS lines. + +- IPv6 support is still in its infancy. There may be differences + between the IPv6 sockets API specifications and what the vendor + provides. This may require hand tweaking, but should get better + over time. + +- If your system supports an older draft of the Posix pthreads standard, + but configure detects the support of pthreads, you will have to disable + this by hand. Digital Unix V3.2C has this problem, for example, as it + supports draft 4, not the final draft. + + To fix this, remove wrappthread.o from LIB_OBJS in "Make.defines" and + don't try to build and run any of the threads programs. + +COMMON DIFFERENCES +------------------ + +These are the common differences that I see in various headers that are +not "yet" at the level of Posix.1g or X/Open XNS Issue 5. + +- getsockopt() and setsockopt(): 5th argument is not correct type. + +- t_bind(): second argument is missing "const". + +- t_connect(): second argument is missing "const". + +- t_open(): first argument is missing "const". + +- t_optmsmg(): second argument is missing "const". + +- If your defines the members of the t_opthdr{} as longs, + instead of t_uscalar_t, some of the printf formats of these value + might generate warnings from your compiler, since you are printing + a long without a corresponding long format specifier. diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..021f875 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +2004/12/12 diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..2a62037 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,213 @@ +dnl ################################################################## +dnl Our macro to check for a function prototype in a given header. +dnl +AC_DEFUN(AC_CHECK_FUNC_PROTO, + [AC_CACHE_CHECK(for $1 function prototype in $2, ac_cv_have_$1_proto, + AC_EGREP_HEADER($1, $2, + ac_cv_have_$1_proto=yes, + ac_cv_have_$1_proto=no)) + if test $ac_cv_have_$1_proto = yes ; then + ac_tr_func=HAVE_`echo $1 | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO + AC_DEFINE_UNQUOTED($ac_tr_func) + fi +]) + +dnl ################################################################## +dnl We cannot use the AC_CHECK_TYPE macros because AC_CHECK_TYPE +dnl #includes only , , and . +dnl Unfortunately, many implementations today hide typedefs in wierd +dnl locations: Solaris 2.5.1 has uint8_t and uint32_t in . +dnl SunOS 4.1.x has int8_t in . +dnl So we define our own macro AC_UNP_CHECK_TYPE that does the same +dnl #includes as "unp.h", and then looks for the typedef. +dnl +dnl This macro should be invoked after all the header checks have been +dnl performed, since we #include "confdefs.h" below, and then use the +dnl HAVE_foo_H values that it can #define. +dnl +AC_DEFUN(AC_UNP_CHECK_TYPE, + [AC_MSG_CHECKING(if $1 defined) + AC_CACHE_VAL(ac_cv_type_$1, + AC_TRY_COMPILE( +[ +#include "confdefs.h" /* the header built by configure so far */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ERRNO_H +# include +#endif +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_SIGNAL_H +# include +#endif +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_UIO_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_WAIT_H +# include +#endif +#ifdef HAVE_SYS_UN_H +# include +#endif +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_FILIO_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif +#ifdef HAVE_PTHREAD_H +# include +#endif], + [ $1 foo ], + ac_cv_type_$1=yes, + ac_cv_type_$1=no)) + AC_MSG_RESULT($ac_cv_type_$1) + if test $ac_cv_type_$1 = no ; then + AC_DEFINE($1, $2, $3) + fi +]) + +dnl ################################################################## +dnl The following checks for any typedefs for XTI programs. +dnl We perform all the #includes that "libxti/unpxti.h" performs. +dnl +AC_DEFUN(AC_UNPXTI_CHECK_TYPE, + [AC_MSG_CHECKING(if $1 defined) + AC_CACHE_VAL(ac_cv_type_$1, + AC_TRY_COMPILE( +[ +#include "confdefs.h" /* the header built by configure so far */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ERRNO_H +# include +#endif +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_SIGNAL_H +# include +#endif +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_UIO_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_WAIT_H +# include +#endif +#ifdef HAVE_SYS_UN_H +# include +#endif +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_FILIO_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif +#ifdef HAVE_PTHREAD_H +# include +#endif +#ifdef HAVE_POLL_H +# include +#endif +#ifdef HAVE_XTI_H +# include +#endif +#ifdef HAVE_NETCONFIG_H +# include +#endif +#ifdef HAVE_NETDIR_H +# include +#endif +#ifdef HAVE_STROPTS_H +# include +#endif], + [ $1 foo ], + ac_cv_type_$1=yes, + ac_cv_type_$1=no)) + AC_MSG_RESULT($ac_cv_type_$1) + if test $ac_cv_type_$1 = no ; then + AC_DEFINE($1, $2, $3) + fi +]) diff --git a/advio/Makefile b/advio/Makefile new file mode 100644 index 0000000..54a9ba6 --- /dev/null +++ b/advio/Makefile @@ -0,0 +1,54 @@ +include ../Make.defines + +PROGS = tcpcli01 tcpcli02 tcpserv02 \ + udpcli01 udpcli02 udpcli03 \ + udpserv01 udpserv03 udpserv04 \ + daytimetcpcli daytimeudpcli3 daytimeudpcli4 + +all: ${PROGS} + +tcpcli01: tcpcli01.o + ${CC} ${CFLAGS} -o $@ tcpcli01.o ${LIBS} + +tcpcli02: tcpcli02.o str_cli_select02.o + ${CC} ${CFLAGS} -o $@ tcpcli02.o str_cli_select02.o ${LIBS} + +tcpcli03: tcpcli03.o str_cli_poll03.o + ${CC} ${CFLAGS} -o $@ tcpcli03.o str_cli_poll03.o ${LIBS} + +tcpcli04: tcpcli04.o str_cli_kqueue04.o + ${CC} ${CFLAGS} -o $@ tcpcli04.o str_cli_kqueue04.o ${LIBS} + +tcpserv02: tcpserv02.o str_echo_stdio02.o sig_chld_waitpid.o + ${CC} ${CFLAGS} -o $@ tcpserv02.o str_echo_stdio02.o \ + sig_chld_waitpid.o ${LIBS} + +udpcli01: udpcli01.o dgclitimeo1.o + ${CC} ${CFLAGS} -o $@ udpcli01.o dgclitimeo1.o ${LIBS} + +udpcli02: udpcli02.o dgclitimeo2.o + ${CC} ${CFLAGS} -o $@ udpcli02.o dgclitimeo2.o ${LIBS} + +udpcli03: udpcli03.o dgclitimeo3.o + ${CC} ${CFLAGS} -o $@ udpcli03.o dgclitimeo3.o ${LIBS} + +udpserv01: udpserv01.o dgechoaddr.o recvfromflags.o + ${CC} ${CFLAGS} -o $@ udpserv01.o dgechoaddr.o recvfromflags.o ${LIBS} + +udpserv03: udpserv03.o + ${CC} ${CFLAGS} -o $@ udpserv03.o ${LIBS} + +udpserv04: udpserv04.o + ${CC} ${CFLAGS} -o $@ udpserv04.o ${LIBS} + +daytimetcpcli: daytimetcpcli.o + ${CC} ${CFLAGS} -o $@ daytimetcpcli.o ${LIBS} + +daytimeudpcli3: daytimeudpcli3.o + ${CC} ${CFLAGS} -o $@ daytimeudpcli3.o ${LIBS} + +daytimeudpcli4: daytimeudpcli4.o + ${CC} ${CFLAGS} -o $@ daytimeudpcli4.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/advio/daytimetcpcli.c b/advio/daytimetcpcli.c new file mode 100644 index 0000000..7b4dcab --- /dev/null +++ b/advio/daytimetcpcli.c @@ -0,0 +1,32 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n, npend; + char recvline[MAXLINE + 1]; + socklen_t len; + struct sockaddr_storage ss; + + if (argc != 3) + err_quit("usage: a.out "); + + sockfd = Tcp_connect(argv[1], argv[2]); + + len = sizeof(ss); + Getpeername(sockfd, (SA *)&ss, &len); + printf("connected to %s\n", Sock_ntop_host((SA *)&ss, len)); + + for ( ; ; ) { + if ( (n = Recv(sockfd, recvline, MAXLINE, MSG_PEEK)) == 0) + break; /* server closed connection */ + + Ioctl(sockfd, FIONREAD, &npend); /* check FIONREAD support */ + printf("%d bytes from PEEK, %d bytes pending\n", n, npend); + + n = Read(sockfd, recvline, MAXLINE); + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } + exit(0); +} diff --git a/advio/daytimeudpcli3.c b/advio/daytimeudpcli3.c new file mode 100644 index 0000000..29da552 --- /dev/null +++ b/advio/daytimeudpcli3.c @@ -0,0 +1,30 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n, nq; + char recvline[MAXLINE + 1]; + socklen_t salen; + struct sockaddr *sa; + + if (argc != 3) + err_quit("usage: a.out "); + + sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen); + + printf("sending to %s\n", Sock_ntop_host(sa, salen)); + + Sendto(sockfd, "", 1, 0, sa, salen); /* send 1-byte datagram */ + + n = Recvfrom(sockfd, recvline, MAXLINE, MSG_PEEK, NULL, NULL); + + Ioctl(sockfd, FIONREAD, &nq); /* check FIONREAD support */ + printf("%d bytes from PEEK, %d bytes pending\n", n, nq); + + n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL); + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + + exit(0); +} diff --git a/advio/daytimeudpcli4.c b/advio/daytimeudpcli4.c new file mode 100644 index 0000000..3e47bd1 --- /dev/null +++ b/advio/daytimeudpcli4.c @@ -0,0 +1,32 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n, nq; + char recvline[MAXLINE + 1]; + socklen_t len; + struct sockaddr_storage ss; + + if (argc != 3) + err_quit("usage: a.out "); + + sockfd = Udp_connect(argv[1], argv[2]); + + len = sizeof(ss); + Getpeername(sockfd, (SA *)&ss, &len); + printf("connected to %s\n", Sock_ntop_host((SA *)&ss, len)); + + Write(sockfd, "", 2); /* send 1-byte datagram */ + + n = Recv(sockfd, recvline, MAXLINE, MSG_PEEK); + + Ioctl(sockfd, FIONREAD, &nq); /* check FIONREAD support */ + printf("%d bytes from PEEK, %d bytes pending\n", n, nq); + + n = Read(sockfd, recvline, MAXLINE); + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + + exit(0); +} diff --git a/advio/dgclitimeo.c b/advio/dgclitimeo.c new file mode 100644 index 0000000..48702ba --- /dev/null +++ b/advio/dgclitimeo.c @@ -0,0 +1,22 @@ +#include "unp.h" + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + if (Readable_timeo(sockfd, 5) == 0) { + fprintf(stderr, "socket timeout\n"); + continue; + } + n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL); + + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } +} diff --git a/advio/dgclitimeo1.c b/advio/dgclitimeo1.c new file mode 100644 index 0000000..9cf1622 --- /dev/null +++ b/advio/dgclitimeo1.c @@ -0,0 +1,21 @@ +#include "unp.h" + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + if (Readable_timeo(sockfd, 5) == 0) { + fprintf(stderr, "socket timeout\n"); + } else { + n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL); + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } + } +} diff --git a/advio/dgclitimeo2.c b/advio/dgclitimeo2.c new file mode 100644 index 0000000..8f258a3 --- /dev/null +++ b/advio/dgclitimeo2.c @@ -0,0 +1,30 @@ +#include "unp.h" + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + struct timeval tv; + + tv.tv_sec = 5; + tv.tv_usec = 0; + Setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL); + if (n < 0) { + if (errno == EWOULDBLOCK) { + fprintf(stderr, "socket timeout\n"); + continue; + } else + err_sys("recvfrom error"); + } + + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } +} diff --git a/advio/dgclitimeo2.lc b/advio/dgclitimeo2.lc new file mode 100644 index 0000000..cd6002e --- /dev/null +++ b/advio/dgclitimeo2.lc @@ -0,0 +1,30 @@ +#include "unp.h"## 1 ##src/advio/dgclitimeo2.c## + +void## 2 ##src/advio/dgclitimeo2.c## +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)## 3 ##src/advio/dgclitimeo2.c## +{## 4 ##src/advio/dgclitimeo2.c## + int n;## 5 ##src/advio/dgclitimeo2.c## + char sendline[MAXLINE], recvline[MAXLINE + 1];## 6 ##src/advio/dgclitimeo2.c## + struct timeval tv;## 7 ##src/advio/dgclitimeo2.c## + + tv.tv_sec = 5;## 8 ##src/advio/dgclitimeo2.c## + tv.tv_usec = 0;## 9 ##src/advio/dgclitimeo2.c## + Setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));## 10 ##src/advio/dgclitimeo2.c## + + while (Fgets(sendline, MAXLINE, fp) != NULL) {## 11 ##src/advio/dgclitimeo2.c## + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);## 12 ##src/advio/dgclitimeo2.c## + + n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);## 13 ##src/advio/dgclitimeo2.c## + if (n < 0) {## 14 ##src/advio/dgclitimeo2.c## + if (errno == EWOULDBLOCK) {## 15 ##src/advio/dgclitimeo2.c## + fprintf(stderr, "socket timeout\n");## 16 ##src/advio/dgclitimeo2.c## + continue;## 17 ##src/advio/dgclitimeo2.c## + } else## 18 ##src/advio/dgclitimeo2.c## + err_sys("recvfrom error");## 19 ##src/advio/dgclitimeo2.c## + }## 20 ##src/advio/dgclitimeo2.c## + + recvline[n] = 0; /* null terminate */## 21 ##src/advio/dgclitimeo2.c## + Fputs(recvline, stdout);## 22 ##src/advio/dgclitimeo2.c## + }## 23 ##src/advio/dgclitimeo2.c## +}## 24 ##src/advio/dgclitimeo2.c## diff --git a/advio/dgclitimeo3.c b/advio/dgclitimeo3.c new file mode 100644 index 0000000..ff32f18 --- /dev/null +++ b/advio/dgclitimeo3.c @@ -0,0 +1,35 @@ +#include "unp.h" + +static void sig_alrm(int); + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + + Signal(SIGALRM, sig_alrm); + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + alarm(5); + if ( (n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL)) < 0) { + if (errno == EINTR) + fprintf(stderr, "socket timeout\n"); + else + err_sys("recvfrom error"); + } else { + alarm(0); + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } + } +} + +static void +sig_alrm(int signo) +{ + return; /* just interrupt the recvfrom() */ +} diff --git a/advio/dgclitimeo3.lc b/advio/dgclitimeo3.lc new file mode 100644 index 0000000..5fd7153 --- /dev/null +++ b/advio/dgclitimeo3.lc @@ -0,0 +1,35 @@ +#include "unp.h"## 1 ##src/advio/dgclitimeo3.c## + +static void sig_alrm(int);## 2 ##src/advio/dgclitimeo3.c## + +void## 3 ##src/advio/dgclitimeo3.c## +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)## 4 ##src/advio/dgclitimeo3.c## +{## 5 ##src/advio/dgclitimeo3.c## + int n;## 6 ##src/advio/dgclitimeo3.c## + char sendline[MAXLINE], recvline[MAXLINE + 1];## 7 ##src/advio/dgclitimeo3.c## + + Signal(SIGALRM, sig_alrm);## 8 ##src/advio/dgclitimeo3.c## + + while (Fgets(sendline, MAXLINE, fp) != NULL) {## 9 ##src/advio/dgclitimeo3.c## + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);## 10 ##src/advio/dgclitimeo3.c## + + alarm(5);## 11 ##src/advio/dgclitimeo3.c## + if ((n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL)) < 0) {## 12 ##src/advio/dgclitimeo3.c## + if (errno == EINTR)## 13 ##src/advio/dgclitimeo3.c## + fprintf(stderr, "socket timeout\n");## 14 ##src/advio/dgclitimeo3.c## + else## 15 ##src/advio/dgclitimeo3.c## + err_sys("recvfrom error");## 16 ##src/advio/dgclitimeo3.c## + } else {## 17 ##src/advio/dgclitimeo3.c## + alarm(0);## 18 ##src/advio/dgclitimeo3.c## + recvline[n] = 0; /* null terminate */## 19 ##src/advio/dgclitimeo3.c## + Fputs(recvline, stdout);## 20 ##src/advio/dgclitimeo3.c## + }## 21 ##src/advio/dgclitimeo3.c## + }## 22 ##src/advio/dgclitimeo3.c## +}## 23 ##src/advio/dgclitimeo3.c## + +static void## 24 ##src/advio/dgclitimeo3.c## +sig_alrm(int signo)## 25 ##src/advio/dgclitimeo3.c## +{## 26 ##src/advio/dgclitimeo3.c## + return; /* just interrupt the recvfrom() */## 27 ##src/advio/dgclitimeo3.c## +}## 28 ##src/advio/dgclitimeo3.c## diff --git a/advio/dgechoaddr.c b/advio/dgechoaddr.c new file mode 100644 index 0000000..b8ab892 --- /dev/null +++ b/advio/dgechoaddr.c @@ -0,0 +1,56 @@ +#include "unpifi.h" + +#undef MAXLINE +#define MAXLINE 20 /* to see datagram truncation */ + +void +dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen) +{ + int flags; + const int on = 1; + socklen_t len; + ssize_t n; + char mesg[MAXLINE], str[INET6_ADDRSTRLEN], + ifname[IFNAMSIZ]; + struct in_addr in_zero; + struct unp_in_pktinfo pktinfo; + +#ifdef IP_RECVDSTADDR + if (setsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)) < 0) + err_ret("setsockopt of IP_RECVDSTADDR"); +#endif +#ifdef IP_RECVIF + if (setsockopt(sockfd, IPPROTO_IP, IP_RECVIF, &on, sizeof(on)) < 0) + err_ret("setsockopt of IP_RECVIF"); +#endif + bzero(&in_zero, sizeof(struct in_addr)); /* all 0 IPv4 address */ + + for ( ; ; ) { + len = clilen; + flags = 0; + n = Recvfrom_flags(sockfd, mesg, MAXLINE, &flags, + pcliaddr, &len, &pktinfo); + printf("%d-byte datagram from %s", n, Sock_ntop(pcliaddr, len)); + if (memcmp(&pktinfo.ipi_addr, &in_zero, sizeof(in_zero)) != 0) + printf(", to %s", Inet_ntop(AF_INET, &pktinfo.ipi_addr, + str, sizeof(str))); + if (pktinfo.ipi_ifindex > 0) + printf(", recv i/f = %s", + If_indextoname(pktinfo.ipi_ifindex, ifname)); +#ifdef MSG_TRUNC + if (flags & MSG_TRUNC) printf(" (datagram truncated)"); +#endif +#ifdef MSG_CTRUNC + if (flags & MSG_CTRUNC) printf(" (control info truncated)"); +#endif +#ifdef MSG_BCAST + if (flags & MSG_BCAST) printf(" (broadcast)"); +#endif +#ifdef MSG_MCAST + if (flags & MSG_MCAST) printf(" (multicast)"); +#endif + printf("\n"); + + Sendto(sockfd, mesg, n, 0, pcliaddr, len); + } +} diff --git a/advio/dgechoaddr.lc b/advio/dgechoaddr.lc new file mode 100644 index 0000000..2e445a3 --- /dev/null +++ b/advio/dgechoaddr.lc @@ -0,0 +1,59 @@ +#include "unpifi.h"## 1 ##src/advio/dgechoaddr.c## + +#undef MAXLINE## 2 ##src/advio/dgechoaddr.c## +#define MAXLINE 20 /* to see datagram truncation */## 3 ##src/advio/dgechoaddr.c## + +void## 4 ##src/advio/dgechoaddr.c## +dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)## 5 ##src/advio/dgechoaddr.c## +{## 6 ##src/advio/dgechoaddr.c## + int flags;## 7 ##src/advio/dgechoaddr.c## + const int on = 1;## 8 ##src/advio/dgechoaddr.c## + socklen_t len;## 9 ##src/advio/dgechoaddr.c## + ssize_t n;## 10 ##src/advio/dgechoaddr.c## + char mesg[MAXLINE], str[INET6_ADDRSTRLEN], ifname[IFNAMSIZ];## 11 ##src/advio/dgechoaddr.c## + struct in_addr in_zero;## 12 ##src/advio/dgechoaddr.c## + struct in_pktinfo pktinfo;## 13 ##src/advio/dgechoaddr.c## + +#ifdef IP_RECVDSTADDR## 14 ##src/advio/dgechoaddr.c## + if (setsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)) < 0)## 15 ##src/advio/dgechoaddr.c## + err_ret("setsockopt of IP_RECVDSTADDR");## 16 ##src/advio/dgechoaddr.c## +#endif## 17 ##src/advio/dgechoaddr.c## +#ifdef IP_RECVIF## 18 ##src/advio/dgechoaddr.c## + if (setsockopt(sockfd, IPPROTO_IP, IP_RECVIF, &on, sizeof(on)) < 0)## 19 ##src/advio/dgechoaddr.c## + err_ret("setsockopt of IP_RECVIF");## 20 ##src/advio/dgechoaddr.c## +#endif## 21 ##src/advio/dgechoaddr.c## + bzero(&in_zero, sizeof(struct in_addr)); /* all 0 IPv4 address */## 22 ##src/advio/dgechoaddr.c## + + for (;;) {## 23 ##src/advio/dgechoaddr.c## + len = clilen;## 24 ##src/advio/dgechoaddr.c## + flags = 0;## 25 ##src/advio/dgechoaddr.c## + n = Recvfrom_flags(sockfd, mesg, MAXLINE, &flags,## 26 ##src/advio/dgechoaddr.c## + pcliaddr, &len, &pktinfo);## 27 ##src/advio/dgechoaddr.c## + printf("%d-byte datagram from %s", n, Sock_ntop(pcliaddr, len));## 28 ##src/advio/dgechoaddr.c## + if (memcmp(&pktinfo.ipi_addr, &in_zero, sizeof(in_zero)) != 0)## 29 ##src/advio/dgechoaddr.c## + printf(", to %s", Inet_ntop(AF_INET, &pktinfo.ipi_addr,## 30 ##src/advio/dgechoaddr.c## + str, sizeof(str)));## 31 ##src/advio/dgechoaddr.c## + if (pktinfo.ipi_ifindex > 0)## 32 ##src/advio/dgechoaddr.c## + printf(", recv i/f = %s",## 33 ##src/advio/dgechoaddr.c## + If_indextoname(pktinfo.ipi_ifindex, ifname));## 34 ##src/advio/dgechoaddr.c## +#ifdef MSG_TRUNC## 35 ##src/advio/dgechoaddr.c## + if (flags & MSG_TRUNC)## 36 ##src/advio/dgechoaddr.c## + printf(" (datagram truncated)");## 37 ##src/advio/dgechoaddr.c## +#endif## 38 ##src/advio/dgechoaddr.c## +#ifdef MSG_CTRUNC## 39 ##src/advio/dgechoaddr.c## + if (flags & MSG_CTRUNC)## 40 ##src/advio/dgechoaddr.c## + printf(" (control info truncated)");## 41 ##src/advio/dgechoaddr.c## +#endif## 42 ##src/advio/dgechoaddr.c## +#ifdef MSG_BCAST## 43 ##src/advio/dgechoaddr.c## + if (flags & MSG_BCAST)## 44 ##src/advio/dgechoaddr.c## + printf(" (broadcast)");## 45 ##src/advio/dgechoaddr.c## +#endif## 46 ##src/advio/dgechoaddr.c## +#ifdef MSG_MCAST## 47 ##src/advio/dgechoaddr.c## + if (flags & MSG_MCAST)## 48 ##src/advio/dgechoaddr.c## + printf(" (multicast)");## 49 ##src/advio/dgechoaddr.c## +#endif## 50 ##src/advio/dgechoaddr.c## + printf("\n");## 51 ##src/advio/dgechoaddr.c## + + Sendto(sockfd, mesg, n, 0, pcliaddr, len);## 52 ##src/advio/dgechoaddr.c## + }## 53 ##src/advio/dgechoaddr.c## +}## 54 ##src/advio/dgechoaddr.c## diff --git a/advio/old/dgechoaddr.c b/advio/old/dgechoaddr.c new file mode 100644 index 0000000..e31c268 --- /dev/null +++ b/advio/old/dgechoaddr.c @@ -0,0 +1,41 @@ +#include "unp.h" + +#undef MAXLINE +#define MAXLINE 20 /* to see datagram truncation */ + +void +dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen) +{ + int flags; + const int on = 1; + socklen_t len; + ssize_t n; + char mesg[MAXLINE], str[INET6_ADDRSTRLEN]; + struct in_addr dstaddr; + +#ifdef IP_RECVDSTADDR + Setsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)); +#endif + + for ( ; ; ) { + len = clilen; + flags = 0; + n = Recvfrom_flags(sockfd, mesg, MAXLINE, &flags, + pcliaddr, &len, &dstaddr); + printf("%d-byte datagram from %s", n, Sock_ntop(pcliaddr, len)); + if ((flags & MSG_CTRUNC) == 0) + printf(", to %s", Inet_ntop(AF_INET, &dstaddr, str, sizeof(str))); +#ifdef MSG_TRUNC + if (flags & MSG_TRUNC) printf(" (datagram truncated)"); +#endif +#ifdef MSG_BCAST + if (flags & MSG_BCAST) printf(" (broadcast)"); +#endif +#ifdef MSG_MCAST + if (flags & MSG_MCAST) printf(" (multicast)"); +#endif + printf("\n"); + + Sendto(sockfd, mesg, n, 0, pcliaddr, clilen); + } +} diff --git a/advio/old/recvfromflags.c b/advio/old/recvfromflags.c new file mode 100644 index 0000000..bb74e0d --- /dev/null +++ b/advio/old/recvfromflags.c @@ -0,0 +1,77 @@ +#include "unp.h" + +ssize_t +recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp, + SA *sa, socklen_t *salenptr, void *dstaddrp) +{ + struct msghdr msg; + struct iovec iov[1]; + ssize_t n; + +#ifdef HAVE_MSGHDR_MSG_CONTROL +#define CONTROL_LEN (sizeof(struct cmsghdr) + sizeof(struct in_addr)) + char control[CONTROL_LEN]; + + msg.msg_control = control; + msg.msg_controllen = sizeof(control); + msg.msg_flags = 0; +#else + bzero(&msg, sizeof(msg)); /* make certain msg_accrightslen = 0 */ +#endif + + msg.msg_name = sa; + msg.msg_namelen = *salenptr; + iov[0].iov_base = ptr; + iov[0].iov_len = nbytes; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + if ( (n = recvmsg(fd, &msg, *flagsp)) < 0) + return(n); + + *salenptr = msg.msg_namelen; /* pass back results */ +#ifdef HAVE_MSGHDR_MSG_CONTROL + *flagsp = msg.msg_flags; /* pass back results */ + + /* + * We need someway to indicate to the caller that nothing was + * returned through dstaddrp (since all 32-bit values are valid + * IP destination addresses). To avoid having to add yet another + * pointer argument, we return MSG_CTRUNC (which unp.h always + * defines, even if the implementation does not). + */ + +#ifdef IP_RECVDSTADDR + if (dstaddrp && msg.msg_controllen > 0 && + (msg.msg_flags & MSG_CTRUNC) == 0) { + struct cmsghdr *cmptr = CMSG_FIRSTHDR(&msg); + + if (cmptr->cmsg_len != CONTROL_LEN) + err_quit("control length = %d", cmptr->cmsg_len); + if (cmptr->cmsg_level != IPPROTO_IP) + err_quit("control level != IPPROTO_IP"); + if (cmptr->cmsg_type != IP_RECVDSTADDR) + err_quit("control type != IP_RECVDSTADDR"); + memcpy(dstaddrp, CMSG_DATA(cmptr), sizeof(struct in_addr)); + } else +#endif + *flagsp |= MSG_CTRUNC; /* dest IP addr not returned */ +#else + *flagsp |= MSG_CTRUNC; /* dest IP addr not returned */ +#endif /* HAVE_MSGHDR_MSG_CONTROL */ + + return(n); +} + +ssize_t +Recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp, + SA *sa, socklen_t *salenptr, void *dstaddrp) +{ + ssize_t n; + + n = recvfrom_flags(fd, ptr, nbytes, flagsp, sa, salenptr, dstaddrp); + if (n < 0) + err_quit("recvfrom_flags error"); + + return(n); +} diff --git a/advio/old/test01.c b/advio/old/test01.c new file mode 100644 index 0000000..b09c318 --- /dev/null +++ b/advio/old/test01.c @@ -0,0 +1,72 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, flag; + ssize_t n; + char buff[MAXLINE]; + const int on = 1; + socklen_t addrlen, len; + struct sockaddr *cliaddr; + + if (argc == 2) + sockfd = Udp_server(NULL, argv[1], &addrlen); + else if (argc == 3) + sockfd = Udp_server(argv[1], argv[2], &addrlen); + else + err_quit("usage: test01 "); + + cliaddr = Malloc(addrlen); + +#ifdef IP_RECVDSTADDR + Setsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)); + + len = sizeof(flag); + Getsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, &flag, &len); + printf("IP_RECVDSTADDR option = %d, size = %d\n", flag, len); +#else + printf("IP_RECVDSTADDR not defined\n"); +#endif + +#ifdef IP_RECVIF + Setsockopt(sockfd, IPPROTO_IP, IP_RECVIF, &on, sizeof(on)); + + len = sizeof(flag); + Getsockopt(sockfd, IPPROTO_IP, IP_RECVIF, &flag, &len); + printf("IP_RECVIF option = %d, size = %d\n", flag, len); +#else + printf("IP_RECVIF not defined\n"); +#endif + + for ( ; ; ) { +#define CONTROL_LEN (sizeof(struct cmsghdr) + sizeof(struct in_addr)) + char control[CONTROL_LEN]; + + msg.msg_control = control; + msg.msg_controllen = sizeof(control); + msg.msg_flags = 0; +#else + bzero(&msg, sizeof(msg)); /* make certain msg_accrightslen = 0 */ +#endif + + msg.msg_name = sa; + msg.msg_namelen = *salenptr; + iov[0].iov_base = ptr; + iov[0].iov_len = nbytes; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + if ( (n = recvmsg(fd, &msg, *flagsp)) < 0) + return(n); + + len = addrlen; + n = Recvfrom(sockfd, buff, MAXLINE, 0, cliaddr, &len); + printf("datagram from %s\n", Sock_ntop(cliaddr, len)); + + ticks = time(NULL); + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); + Sendto(sockfd, buff, strlen(buff), 0, cliaddr, len); + } + exit(0); +} diff --git a/advio/recvfromflags.c b/advio/recvfromflags.c new file mode 100644 index 0000000..a3a316c --- /dev/null +++ b/advio/recvfromflags.c @@ -0,0 +1,96 @@ +/* include recvfrom_flags1 */ +#include "unp.h" +#include /* ALIGN macro for CMSG_NXTHDR() macro */ + +ssize_t +recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp, + SA *sa, socklen_t *salenptr, struct unp_in_pktinfo *pktp) +{ + struct msghdr msg; + struct iovec iov[1]; + ssize_t n; + +#ifdef HAVE_MSGHDR_MSG_CONTROL + struct cmsghdr *cmptr; + union { + struct cmsghdr cm; + char control[CMSG_SPACE(sizeof(struct in_addr)) + + CMSG_SPACE(sizeof(struct unp_in_pktinfo))]; + } control_un; + + msg.msg_control = control_un.control; + msg.msg_controllen = sizeof(control_un.control); + msg.msg_flags = 0; +#else + bzero(&msg, sizeof(msg)); /* make certain msg_accrightslen = 0 */ +#endif + + msg.msg_name = sa; + msg.msg_namelen = *salenptr; + iov[0].iov_base = ptr; + iov[0].iov_len = nbytes; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + if ( (n = recvmsg(fd, &msg, *flagsp)) < 0) + return(n); + + *salenptr = msg.msg_namelen; /* pass back results */ + if (pktp) + bzero(pktp, sizeof(struct unp_in_pktinfo)); /* 0.0.0.0, i/f = 0 */ +/* end recvfrom_flags1 */ + +/* include recvfrom_flags2 */ +#ifndef HAVE_MSGHDR_MSG_CONTROL + *flagsp = 0; /* pass back results */ + return(n); +#else + + *flagsp = msg.msg_flags; /* pass back results */ + if (msg.msg_controllen < sizeof(struct cmsghdr) || + (msg.msg_flags & MSG_CTRUNC) || pktp == NULL) + return(n); + + for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL; + cmptr = CMSG_NXTHDR(&msg, cmptr)) { + +#ifdef IP_RECVDSTADDR + if (cmptr->cmsg_level == IPPROTO_IP && + cmptr->cmsg_type == IP_RECVDSTADDR) { + + memcpy(&pktp->ipi_addr, CMSG_DATA(cmptr), + sizeof(struct in_addr)); + continue; + } +#endif + +#ifdef IP_RECVIF + if (cmptr->cmsg_level == IPPROTO_IP && + cmptr->cmsg_type == IP_RECVIF) { + struct sockaddr_dl *sdl; + + sdl = (struct sockaddr_dl *) CMSG_DATA(cmptr); + pktp->ipi_ifindex = sdl->sdl_index; + continue; + } +#endif + err_quit("unknown ancillary data, len = %d, level = %d, type = %d", + cmptr->cmsg_len, cmptr->cmsg_level, cmptr->cmsg_type); + } + return(n); +#endif /* HAVE_MSGHDR_MSG_CONTROL */ +} +/* end recvfrom_flags2 */ + +ssize_t +Recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp, + SA *sa, socklen_t *salenptr, struct unp_in_pktinfo *pktp) +{ + ssize_t n; + + n = recvfrom_flags(fd, ptr, nbytes, flagsp, sa, salenptr, pktp); + if (n < 0) + err_quit("recvfrom_flags error"); + + return(n); +} diff --git a/advio/recvfromflags.lc b/advio/recvfromflags.lc new file mode 100644 index 0000000..439702e --- /dev/null +++ b/advio/recvfromflags.lc @@ -0,0 +1,99 @@ +/* include recvfrom_flags1 */ +#include "unp.h"## 1 ##src/advio/recvfromflags.c## +#include /* ALIGN macro for CMSG_NXTHDR() macro */## 2 ##src/advio/recvfromflags.c## + +#ifdef HAVE_SOCKADDR_DL_STRUCT## 3 ##src/advio/recvfromflags.c## +# include ## 4 ##src/advio/recvfromflags.c## +#endif## 5 ##src/advio/recvfromflags.c## + +ssize_t## 6 ##src/advio/recvfromflags.c## +recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,## 7 ##src/advio/recvfromflags.c## + SA *sa, socklen_t *salenptr, struct in_pktinfo *pktp)## 8 ##src/advio/recvfromflags.c## +{## 9 ##src/advio/recvfromflags.c## + struct msghdr msg;## 10 ##src/advio/recvfromflags.c## + struct iovec iov[1];## 11 ##src/advio/recvfromflags.c## + ssize_t n;## 12 ##src/advio/recvfromflags.c## + +#ifdef HAVE_MSGHDR_MSG_CONTROL## 13 ##src/advio/recvfromflags.c## + struct cmsghdr *cmptr;## 14 ##src/advio/recvfromflags.c## + union {## 15 ##src/advio/recvfromflags.c## + struct cmsghdr cm;## 16 ##src/advio/recvfromflags.c## + char control[CMSG_SPACE(sizeof(struct in_addr)) +## 17 ##src/advio/recvfromflags.c## + CMSG_SPACE(sizeof(struct in_pktinfo))];## 18 ##src/advio/recvfromflags.c## + } control_un;## 19 ##src/advio/recvfromflags.c## + + msg.msg_control = control_un.control;## 20 ##src/advio/recvfromflags.c## + msg.msg_controllen = sizeof(control_un.control);## 21 ##src/advio/recvfromflags.c## + msg.msg_flags = 0;## 22 ##src/advio/recvfromflags.c## +#else## 23 ##src/advio/recvfromflags.c## + bzero(&msg, sizeof(msg)); /* make certain msg_accrightslen = 0 */## 24 ##src/advio/recvfromflags.c## +#endif## 25 ##src/advio/recvfromflags.c## + + msg.msg_name = sa;## 26 ##src/advio/recvfromflags.c## + msg.msg_namelen = *salenptr;## 27 ##src/advio/recvfromflags.c## + iov[0].iov_base = ptr;## 28 ##src/advio/recvfromflags.c## + iov[0].iov_len = nbytes;## 29 ##src/advio/recvfromflags.c## + msg.msg_iov = iov;## 30 ##src/advio/recvfromflags.c## + msg.msg_iovlen = 1;## 31 ##src/advio/recvfromflags.c## + + if ((n = recvmsg(fd, &msg, *flagsp)) < 0)## 32 ##src/advio/recvfromflags.c## + return (n);## 33 ##src/advio/recvfromflags.c## + + *salenptr = msg.msg_namelen; /* pass back results */## 34 ##src/advio/recvfromflags.c## + if (pktp)## 35 ##src/advio/recvfromflags.c## + bzero(pktp, sizeof(struct in_pktinfo)); /* 0.0.0.0, i/f = 0 */## 36 ##src/advio/recvfromflags.c## +/* end recvfrom_flags1 */ + +/* include recvfrom_flags2 */ +#ifndef HAVE_MSGHDR_MSG_CONTROL## 37 ##src/advio/recvfromflags.c## + *flagsp = 0; /* pass back results */## 38 ##src/advio/recvfromflags.c## + return (n);## 39 ##src/advio/recvfromflags.c## +#else## 40 ##src/advio/recvfromflags.c## + + *flagsp = msg.msg_flags; /* pass back results */## 41 ##src/advio/recvfromflags.c## + if (msg.msg_controllen < sizeof(struct cmsghdr) ||## 42 ##src/advio/recvfromflags.c## + (msg.msg_flags & MSG_CTRUNC) || pktp == NULL)## 43 ##src/advio/recvfromflags.c## + return (n);## 44 ##src/advio/recvfromflags.c## + + for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL;## 45 ##src/advio/recvfromflags.c## + cmptr = CMSG_NXTHDR(&msg, cmptr)) {## 46 ##src/advio/recvfromflags.c## + +#ifdef IP_RECVDSTADDR## 47 ##src/advio/recvfromflags.c## + if (cmptr->cmsg_level == IPPROTO_IP &&## 48 ##src/advio/recvfromflags.c## + cmptr->cmsg_type == IP_RECVDSTADDR) {## 49 ##src/advio/recvfromflags.c## + + memcpy(&pktp->ipi_addr, CMSG_DATA(cmptr),## 50 ##src/advio/recvfromflags.c## + sizeof(struct in_addr));## 51 ##src/advio/recvfromflags.c## + continue;## 52 ##src/advio/recvfromflags.c## + }## 53 ##src/advio/recvfromflags.c## +#endif## 54 ##src/advio/recvfromflags.c## + +#ifdef IP_RECVIF## 55 ##src/advio/recvfromflags.c## + if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF) {## 56 ##src/advio/recvfromflags.c## + struct sockaddr_dl *sdl;## 57 ##src/advio/recvfromflags.c## + + sdl = (struct sockaddr_dl *) CMSG_DATA(cmptr);## 58 ##src/advio/recvfromflags.c## + pktp->ipi_ifindex = sdl->sdl_index;## 59 ##src/advio/recvfromflags.c## + continue;## 60 ##src/advio/recvfromflags.c## + }## 61 ##src/advio/recvfromflags.c## +#endif## 62 ##src/advio/recvfromflags.c## + err_quit("unknown ancillary data, len = %d, level = %d, type = %d",## 63 ##src/advio/recvfromflags.c## + cmptr->cmsg_len, cmptr->cmsg_level, cmptr->cmsg_type);## 64 ##src/advio/recvfromflags.c## + }## 65 ##src/advio/recvfromflags.c## + return (n);## 66 ##src/advio/recvfromflags.c## +#endif /* HAVE_MSGHDR_MSG_CONTROL */## 67 ##src/advio/recvfromflags.c## +}## 68 ##src/advio/recvfromflags.c## +/* end recvfrom_flags2 */ + +ssize_t## 69 ##src/advio/recvfromflags.c## +Recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,## 70 ##src/advio/recvfromflags.c## + SA *sa, socklen_t *salenptr, struct in_pktinfo *pktp)## 71 ##src/advio/recvfromflags.c## +{## 72 ##src/advio/recvfromflags.c## + ssize_t n;## 73 ##src/advio/recvfromflags.c## + + n = recvfrom_flags(fd, ptr, nbytes, flagsp, sa, salenptr, pktp);## 74 ##src/advio/recvfromflags.c## + if (n < 0)## 75 ##src/advio/recvfromflags.c## + err_quit("recvfrom_flags error");## 76 ##src/advio/recvfromflags.c## + + return (n);## 77 ##src/advio/recvfromflags.c## +}## 78 ##src/advio/recvfromflags.c## diff --git a/advio/script.1 b/advio/script.1 new file mode 100644 index 0000000..7df1561 --- /dev/null +++ b/advio/script.1 @@ -0,0 +1,6 @@ +kalae % ./udpserv01 +9-byte datagram from 206.62.226.33.41164, to 206.62.226.35, recv i/f = ef0 +13-byte datagram from 206.62.226.65.1057, to 206.62.226.95, recv i/f = we0 (broadcast) +4-byte datagram from 206.62.226.33.41176, to 224.0.0.1, recv i/f = ef0 (multicast) +20-byte datagram from 127.0.0.1.4632, to 127.0.0.1, recv i/f = lo0 (datagram truncated) +9-byte datagram from 206.62.226.33.41178, to 206.62.226.66, recv i/f = ef0 diff --git a/advio/sig_chld_waitpid.c b/advio/sig_chld_waitpid.c new file mode 100644 index 0000000..5fa9cbf --- /dev/null +++ b/advio/sig_chld_waitpid.c @@ -0,0 +1,13 @@ +#include "unp.h" + +void +sig_chld(int signo) +{ + pid_t pid; + int stat; + + while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) { + printf("child %d terminated\n", pid); + } + return; +} diff --git a/advio/str_cli_kqueue04.c b/advio/str_cli_kqueue04.c new file mode 100644 index 0000000..00550a7 --- /dev/null +++ b/advio/str_cli_kqueue04.c @@ -0,0 +1,52 @@ +#include "unp.h" + +void +str_cli(FILE *fp, int sockfd) +{ + int kq, i, n, nev, stdineof = 0, isfile; + char buf[MAXLINE]; + struct kevent kev[2]; + struct timespec ts; + struct stat st; + + isfile = ((fstat(fileno(fp), &st) == 0) && + (st.st_mode & S_IFMT) == S_IFREG); + + EV_SET(&kev[0], fileno(fp), EVFILT_READ, EV_ADD, 0, 0, NULL); + EV_SET(&kev[1], sockfd, EVFILT_READ, EV_ADD, 0, 0, NULL); + + kq = Kqueue(); + ts.tv_sec = ts.tv_nsec = 0; + Kevent(kq, kev, 2, NULL, 0, &ts); + + for ( ; ; ) { + nev = Kevent(kq, NULL, 0, kev, 2, NULL); + + for (i = 0; i < nev; i++) { + if (kev[i].ident == sockfd) { /* socket is readable */ + if ( (n = Read(sockfd, buf, MAXLINE)) == 0) { + if (stdineof == 1) + return; /* normal termination */ + else + err_quit("str_cli: server terminated prematurely"); + } + + Write(fileno(stdout), buf, n); + } + + if (kev[i].ident == fileno(fp)) { /* input is readable */ + n = Read(fileno(fp), buf, MAXLINE); + if (n > 0) + Writen(sockfd, buf, n); + + if (n == 0 || (isfile && n == kev[i].data)) { + stdineof = 1; + Shutdown(sockfd, SHUT_WR); /* send FIN */ + kev[i].flags = EV_DELETE; + Kevent(kq, &kev[i], 1, NULL, 0, &ts); /* remove kevent */ + continue; + } + } + } + } +} diff --git a/advio/str_cli_poll03.c b/advio/str_cli_poll03.c new file mode 100644 index 0000000..c4748b8 --- /dev/null +++ b/advio/str_cli_poll03.c @@ -0,0 +1,60 @@ +#include "unp.h" +#include + +void +str_cli(FILE *fp, int sockfd) +{ + int stdineof; + char buf[MAXLINE]; + int n; + int wfd; + struct pollfd pollfd[2]; + struct dvpoll dopoll; + int i; + int result; + + wfd = Open("/dev/poll", O_RDWR, 0); + + pollfd[0].fd = fileno(fp); + pollfd[0].events = POLLIN; + pollfd[0].revents = 0; + + pollfd[1].fd = sockfd; + pollfd[1].events = POLLIN; + pollfd[1].revents = 0; + + Write(wfd, pollfd, sizeof(struct pollfd) * 2); + + stdineof = 0; + for ( ; ; ) { + /* block until /dev/poll says something is ready */ + dopoll.dp_timeout = -1; + dopoll.dp_nfds = 2; + dopoll.dp_fds = pollfd; + result = Ioctl(wfd, DP_POLL, &dopoll); + + /* loop through ready file descriptors */ + for (i = 0; i < result; i++) { + if (dopoll.dp_fds[i].fd == sockfd) { + /* socket is readable */ + if ( (n = Read(sockfd, buf, MAXLINE)) == 0) { + if (stdineof == 1) + return; /* normal termination */ + else + err_quit("str_cli: server terminated prematurely"); + } + + Write(fileno(stdout), buf, n); + } else { + /* input is readable */ + if ( (n = Read(fileno(fp), buf, MAXLINE)) == 0) { + stdineof = 1; + Shutdown(sockfd, SHUT_WR); /* send FIN */ + continue; + } + + Writen(sockfd, buf, n); + } + } + } +} diff --git a/advio/str_cli_select02.c b/advio/str_cli_select02.c new file mode 100644 index 0000000..9a01462 --- /dev/null +++ b/advio/str_cli_select02.c @@ -0,0 +1,40 @@ +#include "unp.h" + +void +str_cli(FILE *fp, int sockfd) +{ + int maxfdp1, stdineof = 0; + fd_set rset; + char sendline[MAXLINE], recvline[MAXLINE]; + + FD_ZERO(&rset); + for ( ; ; ) { + if (stdineof == 0) + FD_SET(fileno(fp), &rset); + FD_SET(sockfd, &rset); + maxfdp1 = max(fileno(fp), sockfd) + 1; + Select(maxfdp1, &rset, NULL, NULL, NULL); + + if (FD_ISSET(sockfd, &rset)) { /* socket is readable */ + if (Readline(sockfd, recvline, MAXLINE) == 0) { + if (stdineof == 1) + return; /* normal termination */ + else + err_quit("str_cli: server terminated prematurely"); + } + + Fputs(recvline, stdout); + } + + if (FD_ISSET(fileno(fp), &rset)) { /* input is readable */ + if (Fgets(sendline, MAXLINE, fp) == NULL) { + stdineof = 1; + Shutdown(sockfd, SHUT_WR); /* send FIN */ + FD_CLR(fileno(fp), &rset); + continue; + } + + Writen(sockfd, sendline, strlen(sendline)); + } + } +} diff --git a/advio/str_echo_stdio02.c b/advio/str_echo_stdio02.c new file mode 100644 index 0000000..538137f --- /dev/null +++ b/advio/str_echo_stdio02.c @@ -0,0 +1,14 @@ +#include "unp.h" + +void +str_echo(int sockfd) +{ + char line[MAXLINE]; + FILE *fpin, *fpout; + + fpin = Fdopen(sockfd, "r"); + fpout = Fdopen(sockfd, "w"); + + while (Fgets(line, MAXLINE, fpin) != NULL) + Fputs(line, fpout); +} diff --git a/advio/str_echo_stdio02.lc b/advio/str_echo_stdio02.lc new file mode 100644 index 0000000..32e4819 --- /dev/null +++ b/advio/str_echo_stdio02.lc @@ -0,0 +1,14 @@ +#include "unp.h"## 1 ##src/advio/str_echo_stdio02.c## + +void## 2 ##src/advio/str_echo_stdio02.c## +str_echo(int sockfd)## 3 ##src/advio/str_echo_stdio02.c## +{## 4 ##src/advio/str_echo_stdio02.c## + char line[MAXLINE];## 5 ##src/advio/str_echo_stdio02.c## + FILE *fpin, *fpout;## 6 ##src/advio/str_echo_stdio02.c## + + fpin = Fdopen(sockfd, "r");## 7 ##src/advio/str_echo_stdio02.c## + fpout = Fdopen(sockfd, "w");## 8 ##src/advio/str_echo_stdio02.c## + + while (Fgets(line, MAXLINE, fpin) != NULL)## 9 ##src/advio/str_echo_stdio02.c## + Fputs(line, fpout);## 10 ##src/advio/str_echo_stdio02.c## +}## 11 ##src/advio/str_echo_stdio02.c## diff --git a/advio/tcpcli01.c b/advio/tcpcli01.c new file mode 100644 index 0000000..66ce515 --- /dev/null +++ b/advio/tcpcli01.c @@ -0,0 +1,25 @@ +/* Use standard echo server; baseline measurements for nonblocking version */ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(7); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect_timeo(sockfd, (SA *) &servaddr, sizeof(servaddr), 10); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/advio/tcpcli02.c b/advio/tcpcli02.c new file mode 100644 index 0000000..af1f1bf --- /dev/null +++ b/advio/tcpcli02.c @@ -0,0 +1,24 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/advio/tcpcli03.c b/advio/tcpcli03.c new file mode 100644 index 0000000..af1f1bf --- /dev/null +++ b/advio/tcpcli03.c @@ -0,0 +1,24 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/advio/tcpcli04.c b/advio/tcpcli04.c new file mode 100644 index 0000000..af1f1bf --- /dev/null +++ b/advio/tcpcli04.c @@ -0,0 +1,24 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/advio/tcpserv02.c b/advio/tcpserv02.c new file mode 100644 index 0000000..a964276 --- /dev/null +++ b/advio/tcpserv02.c @@ -0,0 +1,41 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + pid_t childpid; + socklen_t clilen; + struct sockaddr_in cliaddr, servaddr; + void sig_chld(int); + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + Signal(SIGCHLD, sig_chld); + + for ( ; ; ) { + clilen = sizeof(cliaddr); + if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) { + if (errno == EINTR) + continue; /* back to for() */ + else + err_sys("accept error"); + } + + if ( (childpid = Fork()) == 0) { /* child process */ + Close(listenfd); /* close listening socket */ + str_echo(connfd); /* process the request */ + exit(0); + } + Close(connfd); /* parent closes connected socket */ + } +} diff --git a/advio/udpcli01.c b/advio/udpcli01.c new file mode 100644 index 0000000..01beb88 --- /dev/null +++ b/advio/udpcli01.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(7); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/advio/udpcli02.c b/advio/udpcli02.c new file mode 100644 index 0000000..01beb88 --- /dev/null +++ b/advio/udpcli02.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(7); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/advio/udpcli03.c b/advio/udpcli03.c new file mode 100644 index 0000000..01beb88 --- /dev/null +++ b/advio/udpcli03.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(7); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/advio/udpserv01.c b/advio/udpserv01.c new file mode 100644 index 0000000..a21a857 --- /dev/null +++ b/advio/udpserv01.c @@ -0,0 +1,19 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr, cliaddr; + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr)); +} diff --git a/advio/udpserv03.c b/advio/udpserv03.c new file mode 100644 index 0000000..02e5b60 --- /dev/null +++ b/advio/udpserv03.c @@ -0,0 +1,101 @@ +/* include udpserv1 */ +#include "unpifi.h" + +void mydg_echo(int, SA *, socklen_t, SA *); + +int +main(int argc, char **argv) +{ + int sockfd; + const int on = 1; + pid_t pid; + struct ifi_info *ifi, *ifihead; + struct sockaddr_in *sa, cliaddr, wildaddr; + + for (ifihead = ifi = Get_ifi_info(AF_INET, 1); + ifi != NULL; ifi = ifi->ifi_next) { + + /*4bind unicast address */ + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + + sa = (struct sockaddr_in *) ifi->ifi_addr; + sa->sin_family = AF_INET; + sa->sin_port = htons(SERV_PORT); + Bind(sockfd, (SA *) sa, sizeof(*sa)); + printf("bound %s\n", Sock_ntop((SA *) sa, sizeof(*sa))); + + if ( (pid = Fork()) == 0) { /* child */ + mydg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr), (SA *) sa); + exit(0); /* never executed */ + } +/* end udpserv1 */ +/* include udpserv2 */ + if (ifi->ifi_flags & IFF_BROADCAST) { + /* 4try to bind broadcast address */ + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + + sa = (struct sockaddr_in *) ifi->ifi_brdaddr; + sa->sin_family = AF_INET; + sa->sin_port = htons(SERV_PORT); + if (bind(sockfd, (SA *) sa, sizeof(*sa)) < 0) { + if (errno == EADDRINUSE) { + printf("EADDRINUSE: %s\n", + Sock_ntop((SA *) sa, sizeof(*sa))); + Close(sockfd); + continue; + } else + err_sys("bind error for %s", + Sock_ntop((SA *) sa, sizeof(*sa))); + } + printf("bound %s\n", Sock_ntop((SA *) sa, sizeof(*sa))); + + if ( (pid = Fork()) == 0) { /* child */ + mydg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr), + (SA *) sa); + exit(0); /* never executed */ + } + } + } +/* end udpserv2 */ +/* include udpserv3 */ + /* 4bind wildcard address */ + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + + bzero(&wildaddr, sizeof(wildaddr)); + wildaddr.sin_family = AF_INET; + wildaddr.sin_addr.s_addr = htonl(INADDR_ANY); + wildaddr.sin_port = htons(SERV_PORT); + Bind(sockfd, (SA *) &wildaddr, sizeof(wildaddr)); + printf("bound %s\n", Sock_ntop((SA *) &wildaddr, sizeof(wildaddr))); + + if ( (pid = Fork()) == 0) { /* child */ + mydg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr), (SA *) sa); + exit(0); /* never executed */ + } + exit(0); +} +/* end udpserv3 */ + +/* include mydg_echo */ +void +mydg_echo(int sockfd, SA *pcliaddr, socklen_t clilen, SA *myaddr) +{ + int n; + char mesg[MAXLINE]; + socklen_t len; + + for ( ; ; ) { + len = clilen; + n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len); + printf("child %d, datagram from %s", getpid(), + Sock_ntop(pcliaddr, len)); + printf(", to %s\n", Sock_ntop(myaddr, clilen)); + + Sendto(sockfd, mesg, n, 0, pcliaddr, len); + } +} +/* end mydg_echo */ diff --git a/advio/udpserv03.lc b/advio/udpserv03.lc new file mode 100644 index 0000000..f342f38 --- /dev/null +++ b/advio/udpserv03.lc @@ -0,0 +1,101 @@ +/* include udpserv1 */ +#include "unpifi.h"## 1 ##src/advio/udpserv03.c## + +void mydg_echo(int, SA *, socklen_t, SA *);## 2 ##src/advio/udpserv03.c## + +int## 3 ##src/advio/udpserv03.c## +main(int argc, char **argv)## 4 ##src/advio/udpserv03.c## +{## 5 ##src/advio/udpserv03.c## + int sockfd;## 6 ##src/advio/udpserv03.c## + const int on = 1;## 7 ##src/advio/udpserv03.c## + pid_t pid;## 8 ##src/advio/udpserv03.c## + struct ifi_info *ifi, *ifihead;## 9 ##src/advio/udpserv03.c## + struct sockaddr_in *sa, cliaddr, wildaddr;## 10 ##src/advio/udpserv03.c## + + for (ifihead = ifi = Get_ifi_info(AF_INET, 1);## 11 ##src/advio/udpserv03.c## + ifi != NULL; ifi = ifi->ifi_next) {## 12 ##src/advio/udpserv03.c## + + /* 4bind unicast address */## 13 ##src/advio/udpserv03.c## + sockfd = Socket(AF_INET, SOCK_DGRAM, 0);## 14 ##src/advio/udpserv03.c## + + Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 15 ##src/advio/udpserv03.c## + + sa = (struct sockaddr_in *) ifi->ifi_addr;## 16 ##src/advio/udpserv03.c## + sa->sin_family = AF_INET;## 17 ##src/advio/udpserv03.c## + sa->sin_port = htons(SERV_PORT);## 18 ##src/advio/udpserv03.c## + Bind(sockfd, (SA *) sa, sizeof(*sa));## 19 ##src/advio/udpserv03.c## + printf("bound %s\n", Sock_ntop((SA *) sa, sizeof(*sa)));## 20 ##src/advio/udpserv03.c## + + if ((pid = Fork()) == 0) { /* child */## 21 ##src/advio/udpserv03.c## + mydg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr), (SA *) sa);## 22 ##src/advio/udpserv03.c## + exit(0); /* never executed */## 23 ##src/advio/udpserv03.c## + }## 24 ##src/advio/udpserv03.c## +/* end udpserv1 */ +/* include udpserv2 */ + if (ifi->ifi_flags & IFF_BROADCAST) {## 25 ##src/advio/udpserv03.c## + /* 4try to bind broadcast address */## 26 ##src/advio/udpserv03.c## + sockfd = Socket(AF_INET, SOCK_DGRAM, 0);## 27 ##src/advio/udpserv03.c## + Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 28 ##src/advio/udpserv03.c## + + sa = (struct sockaddr_in *) ifi->ifi_brdaddr;## 29 ##src/advio/udpserv03.c## + sa->sin_family = AF_INET;## 30 ##src/advio/udpserv03.c## + sa->sin_port = htons(SERV_PORT);## 31 ##src/advio/udpserv03.c## + if (bind(sockfd, (SA *) sa, sizeof(*sa)) < 0) {## 32 ##src/advio/udpserv03.c## + if (errno == EADDRINUSE) {## 33 ##src/advio/udpserv03.c## + printf("EADDRINUSE: %s\n",## 34 ##src/advio/udpserv03.c## + Sock_ntop((SA *) sa, sizeof(*sa)));## 35 ##src/advio/udpserv03.c## + Close(sockfd);## 36 ##src/advio/udpserv03.c## + continue;## 37 ##src/advio/udpserv03.c## + } else## 38 ##src/advio/udpserv03.c## + err_sys("bind error for %s",## 39 ##src/advio/udpserv03.c## + Sock_ntop((SA *) sa, sizeof(*sa)));## 40 ##src/advio/udpserv03.c## + }## 41 ##src/advio/udpserv03.c## + printf("bound %s\n", Sock_ntop((SA *) sa, sizeof(*sa)));## 42 ##src/advio/udpserv03.c## + + if ((pid = Fork()) == 0) { /* child */## 43 ##src/advio/udpserv03.c## + mydg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr),## 44 ##src/advio/udpserv03.c## + (SA *) sa);## 45 ##src/advio/udpserv03.c## + exit(0); /* never executed */## 46 ##src/advio/udpserv03.c## + }## 47 ##src/advio/udpserv03.c## + }## 48 ##src/advio/udpserv03.c## + }## 49 ##src/advio/udpserv03.c## +/* end udpserv2 */ +/* include udpserv3 */ + /* 4bind wildcard address */## 50 ##src/advio/udpserv03.c## + sockfd = Socket(AF_INET, SOCK_DGRAM, 0);## 51 ##src/advio/udpserv03.c## + Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 52 ##src/advio/udpserv03.c## + + bzero(&wildaddr, sizeof(wildaddr));## 53 ##src/advio/udpserv03.c## + wildaddr.sin_family = AF_INET;## 54 ##src/advio/udpserv03.c## + wildaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 55 ##src/advio/udpserv03.c## + wildaddr.sin_port = htons(SERV_PORT);## 56 ##src/advio/udpserv03.c## + Bind(sockfd, (SA *) &wildaddr, sizeof(wildaddr));## 57 ##src/advio/udpserv03.c## + printf("bound %s\n", Sock_ntop((SA *) &wildaddr, sizeof(wildaddr)));## 58 ##src/advio/udpserv03.c## + + if ((pid = Fork()) == 0) { /* child */## 59 ##src/advio/udpserv03.c## + mydg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr), (SA *) sa);## 60 ##src/advio/udpserv03.c## + exit(0); /* never executed */## 61 ##src/advio/udpserv03.c## + }## 62 ##src/advio/udpserv03.c## + exit(0);## 63 ##src/advio/udpserv03.c## +}## 64 ##src/advio/udpserv03.c## +/* end udpserv3 */ + +/* include mydg_echo */ +void## 65 ##src/advio/udpserv03.c## +mydg_echo(int sockfd, SA *pcliaddr, socklen_t clilen, SA *myaddr)## 66 ##src/advio/udpserv03.c## +{## 67 ##src/advio/udpserv03.c## + int n;## 68 ##src/advio/udpserv03.c## + char mesg[MAXLINE];## 69 ##src/advio/udpserv03.c## + socklen_t len;## 70 ##src/advio/udpserv03.c## + + for (;;) {## 71 ##src/advio/udpserv03.c## + len = clilen;## 72 ##src/advio/udpserv03.c## + n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);## 73 ##src/advio/udpserv03.c## + printf("child %d, datagram from %s", getpid(),## 74 ##src/advio/udpserv03.c## + Sock_ntop(pcliaddr, len));## 75 ##src/advio/udpserv03.c## + printf(", to %s\n", Sock_ntop(myaddr, clilen));## 76 ##src/advio/udpserv03.c## + + Sendto(sockfd, mesg, n, 0, pcliaddr, len);## 77 ##src/advio/udpserv03.c## + }## 78 ##src/advio/udpserv03.c## +}## 79 ##src/advio/udpserv03.c## +/* end mydg_echo */ diff --git a/advio/udpserv04.c b/advio/udpserv04.c new file mode 100644 index 0000000..e4f37ce --- /dev/null +++ b/advio/udpserv04.c @@ -0,0 +1,103 @@ +#include "unpifi.h" + +void mydg_echo(int, SA *, socklen_t); + +int +main(int argc, char **argv) +{ + int sockfd, family, port; + const int on = 1; + pid_t pid; + socklen_t salen; + struct sockaddr *sa, *wild; + struct ifi_info *ifi, *ifihead; + + if (argc == 2) + sockfd = Udp_client(NULL, argv[1], (void **) &sa, &salen); + else if (argc == 3) + sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen); + else + err_quit("usage: udpserv04 [ ] "); + family = sa->sa_family; + port = sock_get_port(sa, salen); + Close(sockfd); /* we just want family, port, salen */ + + for (ifihead = ifi = Get_ifi_info(family, 1); + ifi != NULL; ifi = ifi->ifi_next) { + + /*4bind unicast address */ + sockfd = Socket(family, SOCK_DGRAM, 0); + Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + + sock_set_port(ifi->ifi_addr, salen, port); + Bind(sockfd, ifi->ifi_addr, salen); + printf("bound %s\n", Sock_ntop(ifi->ifi_addr, salen)); + + if ( (pid = Fork()) == 0) { /* child */ + mydg_echo(sockfd, ifi->ifi_addr, salen); + exit(0); /* never executed */ + } + + if (ifi->ifi_flags & IFF_BROADCAST) { + /* 4try to bind broadcast address */ + sockfd = Socket(family, SOCK_DGRAM, 0); + Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + + sock_set_port(ifi->ifi_brdaddr, salen, port); + if (bind(sockfd, ifi->ifi_brdaddr, salen) < 0) { + if (errno == EADDRINUSE) { + printf("EADDRINUSE: %s\n", + Sock_ntop(ifi->ifi_brdaddr, salen)); + Close(sockfd); + continue; + } else + err_sys("bind error for %s", + Sock_ntop(ifi->ifi_brdaddr, salen)); + } + printf("bound %s\n", Sock_ntop(ifi->ifi_brdaddr, salen)); + + if ( (pid = Fork()) == 0) { /* child */ + mydg_echo(sockfd, ifi->ifi_brdaddr, salen); + exit(0); /* never executed */ + } + } + } + + /* 4bind wildcard address */ + sockfd = Socket(family, SOCK_DGRAM, 0); + Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + + wild = Malloc(salen); + memcpy(wild, sa, salen); /* copy family and port */ + sock_set_wild(wild, salen); + + Bind(sockfd, wild, salen); + printf("bound %s\n", Sock_ntop(wild, salen)); + + if ( (pid = Fork()) == 0) { /* child */ + mydg_echo(sockfd, wild, salen); + exit(0); /* never executed */ + } + exit(0); +} + +void +mydg_echo(int sockfd, SA *myaddr, socklen_t salen) +{ + int n; + char mesg[MAXLINE]; + socklen_t len; + struct sockaddr *cli; + + cli = Malloc(salen); + + for ( ; ; ) { + len = salen; + n = Recvfrom(sockfd, mesg, MAXLINE, 0, cli, &len); + printf("child %d, datagram from %s", + getpid(), Sock_ntop(cli, len)); + printf(", to %s\n", Sock_ntop(myaddr, salen)); + + Sendto(sockfd, mesg, n, 0, cli, len); + } +} diff --git a/advio/udpserv04.lc b/advio/udpserv04.lc new file mode 100644 index 0000000..b20a60b --- /dev/null +++ b/advio/udpserv04.lc @@ -0,0 +1,102 @@ +#include "unpifi.h"## 1 ##src/advio/udpserv04.c## + +void mydg_echo(int, SA *, socklen_t);## 2 ##src/advio/udpserv04.c## + +int## 3 ##src/advio/udpserv04.c## +main(int argc, char **argv)## 4 ##src/advio/udpserv04.c## +{## 5 ##src/advio/udpserv04.c## + int sockfd, family, port;## 6 ##src/advio/udpserv04.c## + const int on = 1;## 7 ##src/advio/udpserv04.c## + pid_t pid;## 8 ##src/advio/udpserv04.c## + socklen_t salen;## 9 ##src/advio/udpserv04.c## + struct sockaddr *sa, *wild;## 10 ##src/advio/udpserv04.c## + struct ifi_info *ifi, *ifihead;## 11 ##src/advio/udpserv04.c## + + if (argc == 2)## 12 ##src/advio/udpserv04.c## + sockfd = Udp_client(NULL, argv[1], (void **) &sa, &salen);## 13 ##src/advio/udpserv04.c## + else if (argc == 3)## 14 ##src/advio/udpserv04.c## + sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen);## 15 ##src/advio/udpserv04.c## + else## 16 ##src/advio/udpserv04.c## + err_quit("usage: udpserv04 [ ] ");## 17 ##src/advio/udpserv04.c## + family = sa->sa_family;## 18 ##src/advio/udpserv04.c## + port = sock_get_port(sa, salen);## 19 ##src/advio/udpserv04.c## + Close(sockfd); /* we just want family, port, salen */## 20 ##src/advio/udpserv04.c## + + for (ifihead = ifi = Get_ifi_info(family, 1);## 21 ##src/advio/udpserv04.c## + ifi != NULL; ifi = ifi->ifi_next) {## 22 ##src/advio/udpserv04.c## + + /* 4bind unicast address */## 23 ##src/advio/udpserv04.c## + sockfd = Socket(family, SOCK_DGRAM, 0);## 24 ##src/advio/udpserv04.c## + Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 25 ##src/advio/udpserv04.c## + + sock_set_port(ifi->ifi_addr, salen, port);## 26 ##src/advio/udpserv04.c## + Bind(sockfd, ifi->ifi_addr, salen);## 27 ##src/advio/udpserv04.c## + printf("bound %s\n", Sock_ntop(ifi->ifi_addr, salen));## 28 ##src/advio/udpserv04.c## + + if ((pid = Fork()) == 0) { /* child */## 29 ##src/advio/udpserv04.c## + mydg_echo(sockfd, ifi->ifi_addr, salen);## 30 ##src/advio/udpserv04.c## + exit(0); /* never executed */## 31 ##src/advio/udpserv04.c## + }## 32 ##src/advio/udpserv04.c## + + if (ifi->ifi_flags & IFF_BROADCAST) {## 33 ##src/advio/udpserv04.c## + /* 4try to bind broadcast address */## 34 ##src/advio/udpserv04.c## + sockfd = Socket(family, SOCK_DGRAM, 0);## 35 ##src/advio/udpserv04.c## + Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 36 ##src/advio/udpserv04.c## + + sock_set_port(ifi->ifi_brdaddr, salen, port);## 37 ##src/advio/udpserv04.c## + if (bind(sockfd, ifi->ifi_brdaddr, salen) < 0) {## 38 ##src/advio/udpserv04.c## + if (errno == EADDRINUSE) {## 39 ##src/advio/udpserv04.c## + printf("EADDRINUSE: %s\n",## 40 ##src/advio/udpserv04.c## + Sock_ntop(ifi->ifi_brdaddr, salen));## 41 ##src/advio/udpserv04.c## + Close(sockfd);## 42 ##src/advio/udpserv04.c## + continue;## 43 ##src/advio/udpserv04.c## + } else## 44 ##src/advio/udpserv04.c## + err_sys("bind error for %s",## 45 ##src/advio/udpserv04.c## + Sock_ntop(ifi->ifi_brdaddr, salen));## 46 ##src/advio/udpserv04.c## + }## 47 ##src/advio/udpserv04.c## + printf("bound %s\n", Sock_ntop(ifi->ifi_brdaddr, salen));## 48 ##src/advio/udpserv04.c## + + if ((pid = Fork()) == 0) { /* child */## 49 ##src/advio/udpserv04.c## + mydg_echo(sockfd, ifi->ifi_brdaddr, salen);## 50 ##src/advio/udpserv04.c## + exit(0); /* never executed */## 51 ##src/advio/udpserv04.c## + }## 52 ##src/advio/udpserv04.c## + }## 53 ##src/advio/udpserv04.c## + }## 54 ##src/advio/udpserv04.c## + + /* 4bind wildcard address */## 55 ##src/advio/udpserv04.c## + sockfd = Socket(family, SOCK_DGRAM, 0);## 56 ##src/advio/udpserv04.c## + Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 57 ##src/advio/udpserv04.c## + + wild = Malloc(salen);## 58 ##src/advio/udpserv04.c## + memcpy(wild, sa, salen); /* copy family and port */## 59 ##src/advio/udpserv04.c## + sock_set_wild(wild, salen);## 60 ##src/advio/udpserv04.c## + + Bind(sockfd, wild, salen);## 61 ##src/advio/udpserv04.c## + printf("bound %s\n", Sock_ntop(wild, salen));## 62 ##src/advio/udpserv04.c## + + if ((pid = Fork()) == 0) { /* child */## 63 ##src/advio/udpserv04.c## + mydg_echo(sockfd, wild, salen);## 64 ##src/advio/udpserv04.c## + exit(0); /* never executed */## 65 ##src/advio/udpserv04.c## + }## 66 ##src/advio/udpserv04.c## + exit(0);## 67 ##src/advio/udpserv04.c## +}## 68 ##src/advio/udpserv04.c## + +void## 69 ##src/advio/udpserv04.c## +mydg_echo(int sockfd, SA *myaddr, socklen_t salen)## 70 ##src/advio/udpserv04.c## +{## 71 ##src/advio/udpserv04.c## + int n;## 72 ##src/advio/udpserv04.c## + char mesg[MAXLINE];## 73 ##src/advio/udpserv04.c## + socklen_t len;## 74 ##src/advio/udpserv04.c## + struct sockaddr *cli;## 75 ##src/advio/udpserv04.c## + + cli = Malloc(salen);## 76 ##src/advio/udpserv04.c## + + for (;;) {## 77 ##src/advio/udpserv04.c## + len = salen;## 78 ##src/advio/udpserv04.c## + n = Recvfrom(sockfd, mesg, MAXLINE, 0, cli, &len);## 79 ##src/advio/udpserv04.c## + printf("child %d, datagram from %s", getpid(), Sock_ntop(cli, len));## 80 ##src/advio/udpserv04.c## + printf(", to %s\n", Sock_ntop(myaddr, salen));## 81 ##src/advio/udpserv04.c## + + Sendto(sockfd, mesg, n, 0, cli, len);## 82 ##src/advio/udpserv04.c## + }## 83 ##src/advio/udpserv04.c## +}## 84 ##src/advio/udpserv04.c## diff --git a/bcast/Makefile b/bcast/Makefile new file mode 100644 index 0000000..022ce69 --- /dev/null +++ b/bcast/Makefile @@ -0,0 +1,32 @@ +include ../Make.defines + +PROGS = udpcli01 udpcli02 udpcli03 udpcli04 udpcli05 udpcli06 + +all: ${PROGS} + +# Version in book. +udpcli01: udpcli01.o dgclibcast1.o + ${CC} ${CFLAGS} -o $@ udpcli01.o dgclibcast1.o ${LIBS} + +# Incorrect version with alarm(1) and sleep(1) to tickle race condition. +udpcli02: udpcli02.o dgclibcast2.o + ${CC} ${CFLAGS} -o $@ udpcli02.o dgclibcast2.o ${LIBS} + +# Incorrect version that blocks signals, but still has a race condition. +udpcli03: udpcli03.o dgclibcast3.o + ${CC} ${CFLAGS} -o $@ udpcli03.o dgclibcast3.o ${LIBS} + +# Correct version using pselect(). +udpcli04: udpcli04.o dgclibcast4.o + ${CC} ${CFLAGS} -o $@ udpcli04.o dgclibcast4.o ${LIBS} + +# Correct version using sigsetjmp()/siglongjmp(). +udpcli05: udpcli05.o dgclibcast5.o + ${CC} ${CFLAGS} -o $@ udpcli05.o dgclibcast5.o ${LIBS} + +# Correct version using a pipe from signal handler to select(). +udpcli06: udpcli06.o dgclibcast6.o + ${CC} ${CFLAGS} -o $@ udpcli06.o dgclibcast6.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/bcast/dgclibcast1.c b/bcast/dgclibcast1.c new file mode 100644 index 0000000..2889f0a --- /dev/null +++ b/bcast/dgclibcast1.c @@ -0,0 +1,47 @@ +#include "unp.h" + +static void recvfrom_alarm(int); + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + const int on = 1; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + socklen_t len; + struct sockaddr *preply_addr; + + preply_addr = Malloc(servlen); + + Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); + + Signal(SIGALRM, recvfrom_alarm); + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + alarm(5); + for ( ; ; ) { + len = servlen; + n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len); + if (n < 0) { + if (errno == EINTR) + break; /* waited long enough for replies */ + else + err_sys("recvfrom error"); + } else { + recvline[n] = 0; /* null terminate */ + printf("from %s: %s", + Sock_ntop_host(preply_addr, len), recvline); + } + } + } + free(preply_addr); +} + +static void +recvfrom_alarm(int signo) +{ + return; /* just interrupt the recvfrom() */ +} diff --git a/bcast/dgclibcast1.lc b/bcast/dgclibcast1.lc new file mode 100644 index 0000000..5680acc --- /dev/null +++ b/bcast/dgclibcast1.lc @@ -0,0 +1,46 @@ +#include "unp.h"## 1 ##src/bcast/dgclibcast1.c## + +static void recvfrom_alarm(int);## 2 ##src/bcast/dgclibcast1.c## + +void## 3 ##src/bcast/dgclibcast1.c## +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)## 4 ##src/bcast/dgclibcast1.c## +{## 5 ##src/bcast/dgclibcast1.c## + int n;## 6 ##src/bcast/dgclibcast1.c## + const int on = 1;## 7 ##src/bcast/dgclibcast1.c## + char sendline[MAXLINE], recvline[MAXLINE + 1];## 8 ##src/bcast/dgclibcast1.c## + socklen_t len;## 9 ##src/bcast/dgclibcast1.c## + struct sockaddr *preply_addr;## 10 ##src/bcast/dgclibcast1.c## + + preply_addr = Malloc(servlen);## 11 ##src/bcast/dgclibcast1.c## + + Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));## 12 ##src/bcast/dgclibcast1.c## + + Signal(SIGALRM, recvfrom_alarm);## 13 ##src/bcast/dgclibcast1.c## + + while (Fgets(sendline, MAXLINE, fp) != NULL) {## 14 ##src/bcast/dgclibcast1.c## + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);## 15 ##src/bcast/dgclibcast1.c## + + alarm(5);## 16 ##src/bcast/dgclibcast1.c## + for (;;) {## 17 ##src/bcast/dgclibcast1.c## + len = servlen;## 18 ##src/bcast/dgclibcast1.c## + n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);## 19 ##src/bcast/dgclibcast1.c## + if (n < 0) {## 20 ##src/bcast/dgclibcast1.c## + if (errno == EINTR)## 21 ##src/bcast/dgclibcast1.c## + break; /* waited long enough for replies */## 22 ##src/bcast/dgclibcast1.c## + else## 23 ##src/bcast/dgclibcast1.c## + err_sys("recvfrom error");## 24 ##src/bcast/dgclibcast1.c## + } else {## 25 ##src/bcast/dgclibcast1.c## + recvline[n] = 0; /* null terminate */## 26 ##src/bcast/dgclibcast1.c## + printf("from %s: %s",## 27 ##src/bcast/dgclibcast1.c## + Sock_ntop_host(preply_addr, len), recvline);## 28 ##src/bcast/dgclibcast1.c## + }## 29 ##src/bcast/dgclibcast1.c## + }## 30 ##src/bcast/dgclibcast1.c## + }## 31 ##src/bcast/dgclibcast1.c## +}## 32 ##src/bcast/dgclibcast1.c## + +static void## 33 ##src/bcast/dgclibcast1.c## +recvfrom_alarm(int signo)## 34 ##src/bcast/dgclibcast1.c## +{## 35 ##src/bcast/dgclibcast1.c## + return; /* just interrupt the recvfrom() */## 36 ##src/bcast/dgclibcast1.c## +}## 37 ##src/bcast/dgclibcast1.c## diff --git a/bcast/dgclibcast2.c b/bcast/dgclibcast2.c new file mode 100644 index 0000000..8a75094 --- /dev/null +++ b/bcast/dgclibcast2.c @@ -0,0 +1,48 @@ +#include "unp.h" + +static void recvfrom_alarm(int); + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + const int on = 1; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + socklen_t len; + struct sockaddr *preply_addr; + + preply_addr = Malloc(servlen); + + Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); + + Signal(SIGALRM, recvfrom_alarm); + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + alarm(1); + for ( ; ; ) { + len = servlen; + n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len); + if (n == -1) { + if (errno == EINTR) + break; /* waited long enough for replies */ + else + err_sys("recvfrom error"); + } else { + recvline[n] = 0; /* null terminate */ + sleep(1); + printf("from %s: %s", + Sock_ntop_host(preply_addr, len), recvline); + } + } + } + free(preply_addr); +} + +static void +recvfrom_alarm(int signo) +{ + return; /* just interrupt the recvfrom() */ +} diff --git a/bcast/dgclibcast3.c b/bcast/dgclibcast3.c new file mode 100644 index 0000000..ef1354f --- /dev/null +++ b/bcast/dgclibcast3.c @@ -0,0 +1,53 @@ +#include "unp.h" + +static void recvfrom_alarm(int); + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + const int on = 1; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + sigset_t sigset_alrm; + socklen_t len; + struct sockaddr *preply_addr; + + preply_addr = Malloc(servlen); + + Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); + + Sigemptyset(&sigset_alrm); + Sigaddset(&sigset_alrm, SIGALRM); + + Signal(SIGALRM, recvfrom_alarm); + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + alarm(5); + for ( ; ; ) { + len = servlen; + Sigprocmask(SIG_UNBLOCK, &sigset_alrm, NULL); + n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len); + Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL); + if (n < 0) { + if (errno == EINTR) + break; /* waited long enough for replies */ + else + err_sys("recvfrom error"); + } else { + recvline[n] = 0; /* null terminate */ + printf("from %s: %s", + Sock_ntop_host(preply_addr, len), recvline); + } + } + } + free(preply_addr); +} + +static void +recvfrom_alarm(int signo) +{ + return; /* just interrupt the recvfrom() */ +} diff --git a/bcast/dgclibcast3.lc b/bcast/dgclibcast3.lc new file mode 100644 index 0000000..711841e --- /dev/null +++ b/bcast/dgclibcast3.lc @@ -0,0 +1,52 @@ +#include "unp.h"## 1 ##src/bcast/dgclibcast3.c## + +static void recvfrom_alarm(int);## 2 ##src/bcast/dgclibcast3.c## + +void## 3 ##src/bcast/dgclibcast3.c## +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)## 4 ##src/bcast/dgclibcast3.c## +{## 5 ##src/bcast/dgclibcast3.c## + int n;## 6 ##src/bcast/dgclibcast3.c## + const int on = 1;## 7 ##src/bcast/dgclibcast3.c## + char sendline[MAXLINE], recvline[MAXLINE + 1];## 8 ##src/bcast/dgclibcast3.c## + sigset_t sigset_alrm;## 9 ##src/bcast/dgclibcast3.c## + socklen_t len;## 10 ##src/bcast/dgclibcast3.c## + struct sockaddr *preply_addr;## 11 ##src/bcast/dgclibcast3.c## + + preply_addr = Malloc(servlen);## 12 ##src/bcast/dgclibcast3.c## + + Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));## 13 ##src/bcast/dgclibcast3.c## + + Sigemptyset(&sigset_alrm);## 14 ##src/bcast/dgclibcast3.c## + Sigaddset(&sigset_alrm, SIGALRM);## 15 ##src/bcast/dgclibcast3.c## + + Signal(SIGALRM, recvfrom_alarm);## 16 ##src/bcast/dgclibcast3.c## + + while (Fgets(sendline, MAXLINE, fp) != NULL) {## 17 ##src/bcast/dgclibcast3.c## + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);## 18 ##src/bcast/dgclibcast3.c## + + alarm(5);## 19 ##src/bcast/dgclibcast3.c## + for (;;) {## 20 ##src/bcast/dgclibcast3.c## + len = servlen;## 21 ##src/bcast/dgclibcast3.c## + Sigprocmask(SIG_UNBLOCK, &sigset_alrm, NULL);## 22 ##src/bcast/dgclibcast3.c## + n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);## 23 ##src/bcast/dgclibcast3.c## + Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL);## 24 ##src/bcast/dgclibcast3.c## + if (n < 0) {## 25 ##src/bcast/dgclibcast3.c## + if (errno == EINTR)## 26 ##src/bcast/dgclibcast3.c## + break; /* waited long enough for replies */## 27 ##src/bcast/dgclibcast3.c## + else## 28 ##src/bcast/dgclibcast3.c## + err_sys("recvfrom error");## 29 ##src/bcast/dgclibcast3.c## + } else {## 30 ##src/bcast/dgclibcast3.c## + recvline[n] = 0; /* null terminate */## 31 ##src/bcast/dgclibcast3.c## + printf("from %s: %s",## 32 ##src/bcast/dgclibcast3.c## + Sock_ntop_host(preply_addr, len), recvline);## 33 ##src/bcast/dgclibcast3.c## + }## 34 ##src/bcast/dgclibcast3.c## + }## 35 ##src/bcast/dgclibcast3.c## + }## 36 ##src/bcast/dgclibcast3.c## +}## 37 ##src/bcast/dgclibcast3.c## + +static void## 38 ##src/bcast/dgclibcast3.c## +recvfrom_alarm(int signo)## 39 ##src/bcast/dgclibcast3.c## +{## 40 ##src/bcast/dgclibcast3.c## + return; /* just interrupt the recvfrom() */## 41 ##src/bcast/dgclibcast3.c## +}## 42 ##src/bcast/dgclibcast3.c## diff --git a/bcast/dgclibcast4.c b/bcast/dgclibcast4.c new file mode 100644 index 0000000..85656b9 --- /dev/null +++ b/bcast/dgclibcast4.c @@ -0,0 +1,58 @@ +#include "unp.h" + +static void recvfrom_alarm(int); + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + const int on = 1; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + fd_set rset; + sigset_t sigset_alrm, sigset_empty; + socklen_t len; + struct sockaddr *preply_addr; + + preply_addr = Malloc(servlen); + + Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); + + FD_ZERO(&rset); + + Sigemptyset(&sigset_empty); + Sigemptyset(&sigset_alrm); + Sigaddset(&sigset_alrm, SIGALRM); + + Signal(SIGALRM, recvfrom_alarm); + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL); + alarm(5); + for ( ; ; ) { + FD_SET(sockfd, &rset); + n = pselect(sockfd+1, &rset, NULL, NULL, NULL, &sigset_empty); + if (n < 0) { + if (errno == EINTR) + break; + else + err_sys("pselect error"); + } else if (n != 1) + err_sys("pselect error: returned %d", n); + + len = servlen; + n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len); + recvline[n] = 0; /* null terminate */ + printf("from %s: %s", + Sock_ntop_host(preply_addr, len), recvline); + } + } + free(preply_addr); +} + +static void +recvfrom_alarm(int signo) +{ + return; /* just interrupt the recvfrom() */ +} diff --git a/bcast/dgclibcast4.lc b/bcast/dgclibcast4.lc new file mode 100644 index 0000000..09f1d9f --- /dev/null +++ b/bcast/dgclibcast4.lc @@ -0,0 +1,57 @@ +#include "unp.h"## 1 ##src/bcast/dgclibcast4.c## + +static void recvfrom_alarm(int);## 2 ##src/bcast/dgclibcast4.c## + +void## 3 ##src/bcast/dgclibcast4.c## +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)## 4 ##src/bcast/dgclibcast4.c## +{## 5 ##src/bcast/dgclibcast4.c## + int n;## 6 ##src/bcast/dgclibcast4.c## + const int on = 1;## 7 ##src/bcast/dgclibcast4.c## + char sendline[MAXLINE], recvline[MAXLINE + 1];## 8 ##src/bcast/dgclibcast4.c## + fd_set rset;## 9 ##src/bcast/dgclibcast4.c## + sigset_t sigset_alrm, sigset_empty;## 10 ##src/bcast/dgclibcast4.c## + socklen_t len;## 11 ##src/bcast/dgclibcast4.c## + struct sockaddr *preply_addr;## 12 ##src/bcast/dgclibcast4.c## + + preply_addr = Malloc(servlen);## 13 ##src/bcast/dgclibcast4.c## + + Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));## 14 ##src/bcast/dgclibcast4.c## + + FD_ZERO(&rset);## 15 ##src/bcast/dgclibcast4.c## + + Sigemptyset(&sigset_empty);## 16 ##src/bcast/dgclibcast4.c## + Sigemptyset(&sigset_alrm);## 17 ##src/bcast/dgclibcast4.c## + Sigaddset(&sigset_alrm, SIGALRM);## 18 ##src/bcast/dgclibcast4.c## + + Signal(SIGALRM, recvfrom_alarm);## 19 ##src/bcast/dgclibcast4.c## + + while (Fgets(sendline, MAXLINE, fp) != NULL) {## 20 ##src/bcast/dgclibcast4.c## + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);## 21 ##src/bcast/dgclibcast4.c## + + Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL);## 22 ##src/bcast/dgclibcast4.c## + alarm(5);## 23 ##src/bcast/dgclibcast4.c## + for (;;) {## 24 ##src/bcast/dgclibcast4.c## + FD_SET(sockfd, &rset);## 25 ##src/bcast/dgclibcast4.c## + n = pselect(sockfd + 1, &rset, NULL, NULL, NULL, &sigset_empty);## 26 ##src/bcast/dgclibcast4.c## + if (n < 0) {## 27 ##src/bcast/dgclibcast4.c## + if (errno == EINTR)## 28 ##src/bcast/dgclibcast4.c## + break;## 29 ##src/bcast/dgclibcast4.c## + else## 30 ##src/bcast/dgclibcast4.c## + err_sys("pselect error");## 31 ##src/bcast/dgclibcast4.c## + } else if (n != 1)## 32 ##src/bcast/dgclibcast4.c## + err_sys("pselect error: returned %d", n);## 33 ##src/bcast/dgclibcast4.c## + + len = servlen;## 34 ##src/bcast/dgclibcast4.c## + n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);## 35 ##src/bcast/dgclibcast4.c## + recvline[n] = 0; /* null terminate */## 36 ##src/bcast/dgclibcast4.c## + printf("from %s: %s",## 37 ##src/bcast/dgclibcast4.c## + Sock_ntop_host(preply_addr, len), recvline);## 38 ##src/bcast/dgclibcast4.c## + }## 39 ##src/bcast/dgclibcast4.c## + }## 40 ##src/bcast/dgclibcast4.c## +}## 41 ##src/bcast/dgclibcast4.c## + +static void## 42 ##src/bcast/dgclibcast4.c## +recvfrom_alarm(int signo)## 43 ##src/bcast/dgclibcast4.c## +{## 44 ##src/bcast/dgclibcast4.c## + return; /* just interrupt the recvfrom() */## 45 ##src/bcast/dgclibcast4.c## +}## 46 ##src/bcast/dgclibcast4.c## diff --git a/bcast/dgclibcast5.c b/bcast/dgclibcast5.c new file mode 100644 index 0000000..edfe12c --- /dev/null +++ b/bcast/dgclibcast5.c @@ -0,0 +1,44 @@ +#include "unp.h" +#include + +static void recvfrom_alarm(int); +static sigjmp_buf jmpbuf; + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + const int on = 1; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + socklen_t len; + struct sockaddr *preply_addr; + + preply_addr = Malloc(servlen); + + Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); + + Signal(SIGALRM, recvfrom_alarm); + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + alarm(5); + for ( ; ; ) { + if (sigsetjmp(jmpbuf, 1) != 0) + break; + len = servlen; + n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len); + recvline[n] = 0; /* null terminate */ + printf("from %s: %s", + Sock_ntop_host(preply_addr, len), recvline); + } + } + free(preply_addr); +} + +static void +recvfrom_alarm(int signo) +{ + siglongjmp(jmpbuf, 1); +} diff --git a/bcast/dgclibcast5.lc b/bcast/dgclibcast5.lc new file mode 100644 index 0000000..dfac0b2 --- /dev/null +++ b/bcast/dgclibcast5.lc @@ -0,0 +1,43 @@ +#include "unp.h"## 1 ##src/bcast/dgclibcast5.c## +#include ## 2 ##src/bcast/dgclibcast5.c## + +static void recvfrom_alarm(int);## 3 ##src/bcast/dgclibcast5.c## +static sigjmp_buf jmpbuf;## 4 ##src/bcast/dgclibcast5.c## + +void## 5 ##src/bcast/dgclibcast5.c## +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)## 6 ##src/bcast/dgclibcast5.c## +{## 7 ##src/bcast/dgclibcast5.c## + int n;## 8 ##src/bcast/dgclibcast5.c## + const int on = 1;## 9 ##src/bcast/dgclibcast5.c## + char sendline[MAXLINE], recvline[MAXLINE + 1];## 10 ##src/bcast/dgclibcast5.c## + socklen_t len;## 11 ##src/bcast/dgclibcast5.c## + struct sockaddr *preply_addr;## 12 ##src/bcast/dgclibcast5.c## + + preply_addr = Malloc(servlen);## 13 ##src/bcast/dgclibcast5.c## + + Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));## 14 ##src/bcast/dgclibcast5.c## + + Signal(SIGALRM, recvfrom_alarm);## 15 ##src/bcast/dgclibcast5.c## + + while (Fgets(sendline, MAXLINE, fp) != NULL) {## 16 ##src/bcast/dgclibcast5.c## + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);## 17 ##src/bcast/dgclibcast5.c## + + alarm(5);## 18 ##src/bcast/dgclibcast5.c## + for (;;) {## 19 ##src/bcast/dgclibcast5.c## + if (sigsetjmp(jmpbuf, 1) != 0)## 20 ##src/bcast/dgclibcast5.c## + break;## 21 ##src/bcast/dgclibcast5.c## + len = servlen;## 22 ##src/bcast/dgclibcast5.c## + n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);## 23 ##src/bcast/dgclibcast5.c## + recvline[n] = 0; /* null terminate */## 24 ##src/bcast/dgclibcast5.c## + printf("from %s: %s",## 25 ##src/bcast/dgclibcast5.c## + Sock_ntop_host(preply_addr, len), recvline);## 26 ##src/bcast/dgclibcast5.c## + }## 27 ##src/bcast/dgclibcast5.c## + }## 28 ##src/bcast/dgclibcast5.c## +}## 29 ##src/bcast/dgclibcast5.c## + +static void## 30 ##src/bcast/dgclibcast5.c## +recvfrom_alarm(int signo)## 31 ##src/bcast/dgclibcast5.c## +{## 32 ##src/bcast/dgclibcast5.c## + siglongjmp(jmpbuf, 1);## 33 ##src/bcast/dgclibcast5.c## +}## 34 ##src/bcast/dgclibcast5.c## diff --git a/bcast/dgclibcast6.c b/bcast/dgclibcast6.c new file mode 100644 index 0000000..1e6e1ed --- /dev/null +++ b/bcast/dgclibcast6.c @@ -0,0 +1,63 @@ +#include "unp.h" + +static void recvfrom_alarm(int); +static int pipefd[2]; + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n, maxfdp1; + const int on = 1; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + fd_set rset; + socklen_t len; + struct sockaddr *preply_addr; + + preply_addr = Malloc(servlen); + + Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); + + Pipe(pipefd); + maxfdp1 = max(sockfd, pipefd[0]) + 1; + + FD_ZERO(&rset); + + Signal(SIGALRM, recvfrom_alarm); + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + alarm(5); + for ( ; ; ) { + FD_SET(sockfd, &rset); + FD_SET(pipefd[0], &rset); + if ( (n = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) { + if (errno == EINTR) + continue; + else + err_sys("select error"); + } + + if (FD_ISSET(sockfd, &rset)) { + len = servlen; + n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len); + recvline[n] = 0; /* null terminate */ + printf("from %s: %s", + Sock_ntop_host(preply_addr, len), recvline); + } + + if (FD_ISSET(pipefd[0], &rset)) { + Read(pipefd[0], &n, 1); /* timer expired */ + break; + } + } + } + free(preply_addr); +} + +static void +recvfrom_alarm(int signo) +{ + Write(pipefd[1], "", 1); /* write one null byte to pipe */ + return; +} diff --git a/bcast/dgclibcast6.lc b/bcast/dgclibcast6.lc new file mode 100644 index 0000000..cbd1ac1 --- /dev/null +++ b/bcast/dgclibcast6.lc @@ -0,0 +1,63 @@ +#include "unp.h"## 1 ##src/bcast/dgclibcast6.c## + +static void recvfrom_alarm(int);## 2 ##src/bcast/dgclibcast6.c## +static int pipefd[2];## 3 ##src/bcast/dgclibcast6.c## + +void## 4 ##src/bcast/dgclibcast6.c## +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)## 5 ##src/bcast/dgclibcast6.c## +{## 6 ##src/bcast/dgclibcast6.c## + int n, maxfdp1;## 7 ##src/bcast/dgclibcast6.c## + const int on = 1;## 8 ##src/bcast/dgclibcast6.c## + char sendline[MAXLINE], recvline[MAXLINE + 1];## 9 ##src/bcast/dgclibcast6.c## + fd_set rset;## 10 ##src/bcast/dgclibcast6.c## + socklen_t len;## 11 ##src/bcast/dgclibcast6.c## + struct sockaddr *preply_addr;## 12 ##src/bcast/dgclibcast6.c## + + preply_addr = Malloc(servlen);## 13 ##src/bcast/dgclibcast6.c## + + Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));## 14 ##src/bcast/dgclibcast6.c## + + Pipe(pipefd);## 15 ##src/bcast/dgclibcast6.c## + maxfdp1 = max(sockfd, pipefd[0]) + 1;## 16 ##src/bcast/dgclibcast6.c## + + FD_ZERO(&rset);## 17 ##src/bcast/dgclibcast6.c## + + Signal(SIGALRM, recvfrom_alarm);## 18 ##src/bcast/dgclibcast6.c## + + while (Fgets(sendline, MAXLINE, fp) != NULL) {## 19 ##src/bcast/dgclibcast6.c## + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);## 20 ##src/bcast/dgclibcast6.c## + + alarm(5);## 21 ##src/bcast/dgclibcast6.c## + for (;;) {## 22 ##src/bcast/dgclibcast6.c## + FD_SET(sockfd, &rset);## 23 ##src/bcast/dgclibcast6.c## + FD_SET(pipefd[0], &rset);## 24 ##src/bcast/dgclibcast6.c## + if ((n = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) {## 25 ##src/bcast/dgclibcast6.c## + if (errno == EINTR)## 26 ##src/bcast/dgclibcast6.c## + continue;## 27 ##src/bcast/dgclibcast6.c## + else## 28 ##src/bcast/dgclibcast6.c## + err_sys("select error");## 29 ##src/bcast/dgclibcast6.c## + }## 30 ##src/bcast/dgclibcast6.c## + + if (FD_ISSET(sockfd, &rset)) {## 31 ##src/bcast/dgclibcast6.c## + len = servlen;## 32 ##src/bcast/dgclibcast6.c## + n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr,## 33 ##src/bcast/dgclibcast6.c## + &len);## 34 ##src/bcast/dgclibcast6.c## + recvline[n] = 0; /* null terminate */## 35 ##src/bcast/dgclibcast6.c## + printf("from %s: %s",## 36 ##src/bcast/dgclibcast6.c## + Sock_ntop_host(preply_addr, len), recvline);## 37 ##src/bcast/dgclibcast6.c## + }## 38 ##src/bcast/dgclibcast6.c## + + if (FD_ISSET(pipefd[0], &rset)) {## 39 ##src/bcast/dgclibcast6.c## + Read(pipefd[0], &n, 1); /* timer expired */## 40 ##src/bcast/dgclibcast6.c## + break;## 41 ##src/bcast/dgclibcast6.c## + }## 42 ##src/bcast/dgclibcast6.c## + }## 43 ##src/bcast/dgclibcast6.c## + }## 44 ##src/bcast/dgclibcast6.c## +}## 45 ##src/bcast/dgclibcast6.c## + +static void## 46 ##src/bcast/dgclibcast6.c## +recvfrom_alarm(int signo)## 47 ##src/bcast/dgclibcast6.c## +{## 48 ##src/bcast/dgclibcast6.c## + Write(pipefd[1], "", 1); /* write 1 null byte to pipe */## 49 ##src/bcast/dgclibcast6.c## + return;## 50 ##src/bcast/dgclibcast6.c## +}## 51 ##src/bcast/dgclibcast6.c## diff --git a/bcast/udpcli01.c b/bcast/udpcli01.c new file mode 100644 index 0000000..24a3e48 --- /dev/null +++ b/bcast/udpcli01.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli01 "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(13); /* standard daytime server */ + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/bcast/udpcli02.c b/bcast/udpcli02.c new file mode 100644 index 0000000..b2d1d75 --- /dev/null +++ b/bcast/udpcli02.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli02 "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(13); /* standard daytime server */ + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/bcast/udpcli03.c b/bcast/udpcli03.c new file mode 100644 index 0000000..93d26fd --- /dev/null +++ b/bcast/udpcli03.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli03 "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(13); /* standard daytime server */ + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/bcast/udpcli04.c b/bcast/udpcli04.c new file mode 100644 index 0000000..29dbbee --- /dev/null +++ b/bcast/udpcli04.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli04 "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(13); /* standard daytime server */ + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/bcast/udpcli05.c b/bcast/udpcli05.c new file mode 100644 index 0000000..dd0cad3 --- /dev/null +++ b/bcast/udpcli05.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli05 "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(13); /* standard daytime server */ + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/bcast/udpcli06.c b/bcast/udpcli06.c new file mode 100644 index 0000000..b2d1d75 --- /dev/null +++ b/bcast/udpcli06.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli02 "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(13); /* standard daytime server */ + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..ed2e03b --- /dev/null +++ b/config.guess @@ -0,0 +1,1321 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-03-20' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int dummy(){}" > $dummy.c ; + for c in cc gcc c89 c99 ; do + ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; + if test $? = 0 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + rm -f $dummy.c $dummy.o $dummy.rel ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + eval $set_cc_for_build + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + 2-1307) + UNAME_MACHINE="alphaev68" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy + fi ;; + esac + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i386-pc-interix3 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + rm -f $dummy.c + test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..7bef959 --- /dev/null +++ b/config.h.in @@ -0,0 +1,325 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* CPU, vendor, and operating system */ +#undef CPU_VENDOR_OS + +/* Define to 1 if defines struct addrinfo */ +#undef HAVE_ADDRINFO_STRUCT + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* Define to 1 if you have the `bzero' function. */ +#undef HAVE_BZERO + +/* Define to 1 if the /dev/streams/xtiso/tcp device exists */ +#undef HAVE_DEV_STREAMS_XTISO_TCP + +/* Define to 1 if the /dev/tcp device exists */ +#undef HAVE_DEV_TCP + +/* Define to 1 if the /dev/xti/tcp device exists */ +#undef HAVE_DEV_XTI_TCP + +/* Define to 1 if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `getaddrinfo' function. */ +#undef HAVE_GETADDRINFO + +/* define if getaddrinfo prototype is in */ +#undef HAVE_GETADDRINFO_PROTO + +/* Define to 1 if you have the `gethostbyname2' function. */ +#undef HAVE_GETHOSTBYNAME2 + +/* Define to 1 if you have the `gethostbyname_r' function. */ +#undef HAVE_GETHOSTBYNAME_R + +/* Define to 1 if you have the `gethostname' function. */ +#undef HAVE_GETHOSTNAME + +/* define if gethostname prototype is in */ +#undef HAVE_GETHOSTNAME_PROTO + +/* Define to 1 if you have the `getnameinfo' function. */ +#undef HAVE_GETNAMEINFO + +/* define if getnameinfo prototype is in */ +#undef HAVE_GETNAMEINFO_PROTO + +/* define if getrusage prototype is in */ +#undef HAVE_GETRUSAGE_PROTO + +/* Define to 1 if you have the `hstrerror' function. */ +#undef HAVE_HSTRERROR + +/* define if hstrerror prototype is in */ +#undef HAVE_HSTRERROR_PROTO + +/* Define to 1 if defines struct if_nameindex */ +#undef HAVE_IF_NAMEINDEX_STRUCT + +/* Define to 1 if you have the `if_nametoindex' function. */ +#undef HAVE_IF_NAMETOINDEX + +/* define if if_nametoindex prototype is in */ +#undef HAVE_IF_NAMETOINDEX_PROTO + +/* Define to 1 if you have the `inet6_rth_init' function. */ +#undef HAVE_INET6_RTH_INIT + +/* Define to 1 if you have the `inet_aton' function. */ +#undef HAVE_INET_ATON + +/* define if inet_aton prototype is in */ +#undef HAVE_INET_ATON_PROTO + +/* Define to 1 if you have the `inet_pton' function. */ +#undef HAVE_INET_PTON + +/* define if inet_pton prototype is in */ +#undef HAVE_INET_PTON_PROTO + +/* Define to 1 if you have the `kevent' function. */ +#undef HAVE_KEVENT + +/* Define to 1 if you have the `kqueue' function. */ +#undef HAVE_KQUEUE + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#undef HAVE_LIBPTHREAD + +/* Define to 1 if you have the `pthreads' library (-lpthreads). */ +#undef HAVE_LIBPTHREADS + +/* Define to 1 if you have the `resolv' library (-lresolv). */ +#undef HAVE_LIBRESOLV + +/* Define to 1 if you have the `xti' library (-lxti). */ +#undef HAVE_LIBXTI + +/* Define to 1 if you have the `mkstemp' function. */ +#undef HAVE_MKSTEMP + +/* define if struct msghdr contains the msg_control member */ +#undef HAVE_MSGHDR_MSG_CONTROL + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETCONFIG_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NET_IF_DL_H + +/* Define to 1 if you have the `poll' function. */ +#undef HAVE_POLL + +/* Define to 1 if you have the header file. */ +#undef HAVE_POLL_H + +/* Define to 1 if you have the `pselect' function. */ +#undef HAVE_PSELECT + +/* define if pselect prototype is in */ +#undef HAVE_PSELECT_PROTO + +/* Define to 1 if you have the header file. */ +#undef HAVE_PTHREAD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SIGNAL_H + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* define if snprintf prototype is in */ +#undef HAVE_SNPRINTF_PROTO + +/* Define to 1 if defines struct sockaddr_dl */ +#undef HAVE_SOCKADDR_DL_STRUCT + +/* define if socket address structures have length fields */ +#undef HAVE_SOCKADDR_SA_LEN + +/* Define to 1 if you have the `sockatmark' function. */ +#undef HAVE_SOCKATMARK + +/* define if sockatmark prototype is in */ +#undef HAVE_SOCKATMARK_PROTO + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STROPTS_H + +/* Define to 1 if `ifr_mtu' is member of `struct ifreq'. */ +#undef HAVE_STRUCT_IFREQ_IFR_MTU + +/* Define to 1 if the system has the type `struct sockaddr_storage'. */ +#undef HAVE_STRUCT_SOCKADDR_STORAGE + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_EVENT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_FILIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SYSCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if or defines struct timespec */ +#undef HAVE_TIMESPEC_STRUCT + +/* Define to 1 if you have the header file. */ +#undef HAVE_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* Define to 1 if you have the header file. */ +#undef HAVE_XTI_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_XTI_INET_H + +/* Define to 1 if the system supports IPv4 */ +#undef IPV4 + +/* Define to 1 if the system supports IPv6 */ +#undef IPV6 + +/* Define to 1 if the system supports IPv4 */ +#undef IPv4 + +/* Define to 1 if the system supports IPv6 */ +#undef IPv6 + +/* Define to 1 if the system supports IP Multicast */ +#undef MCAST + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* the size of the sa_family field in a socket address structure */ +#undef SA_FAMILY_T + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Define to 1 if the system supports UNIX domain sockets */ +#undef UNIXDOMAIN + +/* Define to 1 if the system supports UNIX domain sockets */ +#undef UNIXdomain + +/* 16 bit signed type */ +#undef int16_t + +/* 32 bit signed type */ +#undef int32_t + +/* the type of the sa_family struct member */ +#undef sa_family_t + +/* unsigned integer type of the result of the sizeof operator */ +#undef size_t + +/* a type appropriate for address */ +#undef socklen_t + +/* define to __ss_family if sockaddr_storage has that instead of ss_family */ +#undef ss_family + +/* a signed type appropriate for a count of bytes or an error indication */ +#undef ssize_t + +/* scalar type */ +#undef t_scalar_t + +/* unsigned scalar type */ +#undef t_uscalar_t + +/* 16 bit unsigned type */ +#undef uint16_t + +/* 32 bit unsigned type */ +#undef uint32_t + +/* 8-bit unsigned type */ +#undef uint8_t diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..f365797 --- /dev/null +++ b/config.sub @@ -0,0 +1,1443 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-03-07' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dsp16xx \ + | fr30 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el | mips64vr4300 \ + | mips64vr4300el | mips64vr5000 | mips64vr5000el \ + | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ + | mipsisa32 | mipsisa64 \ + | mn10200 | mn10300 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[34] | sh[34]eb | shbe | shle | sh64 \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c54x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ + | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ + | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3d) + basic_machine=alpha-cray + os=-unicos + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + windows32) + basic_machine=i386-pc + os=-windows32-msvcrt + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh3eb | sh4eb) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..87004a5 --- /dev/null +++ b/configure @@ -0,0 +1,9025 @@ +#! /bin/sh +# From configure.in Revision: 1.13 . +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.57. +# +# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="lib/unp.h" +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT RANLIB ac_ct_RANLIB CPP EGREP LIB_OBJS LIBFREE_OBJS LIBGAI_OBJS LIBROUTE_OBJS LIBXTI_OBJS LIBS_XTI LIBUNP LIBUNPXTI LIBUNP_NAME LIBUNPXTI_NAME LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.57. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core core.* *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + + ac_config_headers="$ac_config_headers config.h" + + + +cat >>confdefs.h <<_ACEOF +#define CPU_VENDOR_OS "$host" +_ACEOF + + + +case "$host_os" in +*aix*) CPPFLAGS="$CPPFLAGS -D_ALL_SOURCE" ;; +*osf*) CPPFLAGS="$CPPFLAGS -D_SOCKADDR_LEN" ;; +esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output" >&5 +echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + ''\ + '#include ' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + + + +echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5 +echo $ECHO_N "checking for pthread_create in -lpthread... $ECHO_C" >&6 +if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char pthread_create (); +int +main () +{ +pthread_create (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_pthread_pthread_create=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_pthread_pthread_create=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_create" >&5 +echo "${ECHO_T}$ac_cv_lib_pthread_pthread_create" >&6 +if test $ac_cv_lib_pthread_pthread_create = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBPTHREAD 1 +_ACEOF + + LIBS="-lpthread $LIBS" + +fi + +if test "$ac_cv_lib_pthread_pthread_create" = yes ; then + CFLAGS="$CFLAGS -D_REENTRANT" +else + +echo "$as_me:$LINENO: checking for pthread_create in -lpthreads" >&5 +echo $ECHO_N "checking for pthread_create in -lpthreads... $ECHO_C" >&6 +if test "${ac_cv_lib_pthreads_pthread_create+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthreads $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char pthread_create (); +int +main () +{ +pthread_create (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_pthreads_pthread_create=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_pthreads_pthread_create=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_create" >&5 +echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_create" >&6 +if test $ac_cv_lib_pthreads_pthread_create = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBPTHREADS 1 +_ACEOF + + LIBS="-lpthreads $LIBS" + +fi + + if test "$ac_cv_lib_pthreads_pthread_create" = yes ; then + CFLAGS="$CFLAGS -D_REENTRANT" + fi +fi + + +echo "$as_me:$LINENO: checking for t_open in -lnsl" >&5 +echo $ECHO_N "checking for t_open in -lnsl... $ECHO_C" >&6 +if test "${ac_cv_lib_nsl_t_open+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char t_open (); +int +main () +{ +t_open (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_nsl_t_open=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_nsl_t_open=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_t_open" >&5 +echo "${ECHO_T}$ac_cv_lib_nsl_t_open" >&6 +if test $ac_cv_lib_nsl_t_open = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBNSL 1 +_ACEOF + + LIBS="-lnsl $LIBS" + +fi + +echo "$as_me:$LINENO: checking for library containing socket" >&5 +echo $ECHO_N "checking for library containing socket... $ECHO_C" >&6 +if test "${ac_cv_search_socket+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +ac_cv_search_socket=no +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket (); +int +main () +{ +socket (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_socket="none required" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +if test "$ac_cv_search_socket" = no; then + for ac_lib in socket; do + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket (); +int +main () +{ +socket (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_socket="-l$ac_lib" +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + done +fi +LIBS=$ac_func_search_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_search_socket" >&5 +echo "${ECHO_T}$ac_cv_search_socket" >&6 +if test "$ac_cv_search_socket" != no; then + test "$ac_cv_search_socket" = "none required" || LIBS="$ac_cv_search_socket $LIBS" + +fi + + +echo "$as_me:$LINENO: checking for /usr/local/bind/lib/libbind.a" >&5 +echo $ECHO_N "checking for /usr/local/bind/lib/libbind.a... $ECHO_C" >&6 +if test -f /usr/local/bind/lib/libbind.a ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + LIBS="/usr/local/bind/lib/libbind.a $LIBS" +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + echo "$as_me:$LINENO: checking for $HOME/libbind.a" >&5 +echo $ECHO_N "checking for $HOME/libbind.a... $ECHO_C" >&6 + if test -f $HOME/libbind.a ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + LIBS="$HOME/libbind.a $LIBS" + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + echo "$as_me:$LINENO: checking for $HOME/libresolv.a" >&5 +echo $ECHO_N "checking for $HOME/libresolv.a... $ECHO_C" >&6 + if test -f $HOME/libresolv.a ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + LIBS="$HOME/libresolv.a $LIBS" + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + +echo "$as_me:$LINENO: checking for res_init in -lresolv" >&5 +echo $ECHO_N "checking for res_init in -lresolv... $ECHO_C" >&6 +if test "${ac_cv_lib_resolv_res_init+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lresolv $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char res_init (); +int +main () +{ +res_init (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_resolv_res_init=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_resolv_res_init=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_res_init" >&5 +echo "${ECHO_T}$ac_cv_lib_resolv_res_init" >&6 +if test $ac_cv_lib_resolv_res_init = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBRESOLV 1 +_ACEOF + + LIBS="-lresolv $LIBS" + +fi + + fi + fi +fi + + +echo "$as_me:$LINENO: checking for t_open in -lxti" >&5 +echo $ECHO_N "checking for t_open in -lxti... $ECHO_C" >&6 +if test "${ac_cv_lib_xti_t_open+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lxti $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char t_open (); +int +main () +{ +t_open (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_xti_t_open=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_xti_t_open=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_xti_t_open" >&5 +echo "${ECHO_T}$ac_cv_lib_xti_t_open" >&6 +if test $ac_cv_lib_xti_t_open = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBXTI 1 +_ACEOF + + LIBS="-lxti $LIBS" + +fi + + +echo "$as_me:$LINENO: checking for $HOME/libunp.a" >&5 +echo $ECHO_N "checking for $HOME/libunp.a... $ECHO_C" >&6 +if test -f $HOME/libunp.a ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + LIBUNP="$HOME/libunp.a" + LIBUNP_NAME=$HOME/libunp.a +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + LIBUNP="../libunp.a" + LIBUNP_NAME=../libunp.a +fi + +echo "$as_me:$LINENO: checking for $HOME/libunpxti.a" >&5 +echo $ECHO_N "checking for $HOME/libunpxti.a... $ECHO_C" >&6 +if test -f $HOME/libunpxti.a ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + LIBUNPXTI="$HOME/libunpxti.a" + LIBUNPXTI_NAME=$HOME/libunpxti.a +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + LIBUNPXTI="../libunpxti.a" + LIBUNPXTI_NAME=../libunpxti.a +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +for ac_header in sys/types.h sys/socket.h sys/time.h time.h netinet/in.h arpa/inet.h errno.h fcntl.h netdb.h signal.h stdio.h stdlib.h string.h sys/stat.h sys/uio.h unistd.h sys/wait.h sys/un.h sys/param.h sys/select.h sys/sysctl.h poll.h sys/event.h strings.h sys/ioctl.h sys/filio.h sys/sockio.h pthread.h net/if_dl.h xti.h xti_inet.h netconfig.h netdir.h stropts.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif +#if HAVE_SYS_PARAM_H +# include +#endif + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 +if test "${ac_cv_header_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_time=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_time=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6 +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\_ACEOF +#define TIME_WITH_SYS_TIME 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking if uint8_t defined" >&5 +echo $ECHO_N "checking if uint8_t defined... $ECHO_C" >&6 + if test "${ac_cv_type_uint8_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include "confdefs.h" /* the header built by configure so far */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ERRNO_H +# include +#endif +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_SIGNAL_H +# include +#endif +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_UIO_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_WAIT_H +# include +#endif +#ifdef HAVE_SYS_UN_H +# include +#endif +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_FILIO_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif +#ifdef HAVE_PTHREAD_H +# include +#endif +int +main () +{ + uint8_t foo + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_uint8_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_uint8_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_type_uint8_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint8_t" >&6 + if test $ac_cv_type_uint8_t = no ; then + +cat >>confdefs.h <<\_ACEOF +#define uint8_t unsigned char +_ACEOF + + fi + +echo "$as_me:$LINENO: checking if int16_t defined" >&5 +echo $ECHO_N "checking if int16_t defined... $ECHO_C" >&6 + if test "${ac_cv_type_int16_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include "confdefs.h" /* the header built by configure so far */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ERRNO_H +# include +#endif +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_SIGNAL_H +# include +#endif +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_UIO_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_WAIT_H +# include +#endif +#ifdef HAVE_SYS_UN_H +# include +#endif +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_FILIO_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif +#ifdef HAVE_PTHREAD_H +# include +#endif +int +main () +{ + int16_t foo + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_int16_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_int16_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_type_int16_t" >&5 +echo "${ECHO_T}$ac_cv_type_int16_t" >&6 + if test $ac_cv_type_int16_t = no ; then + +cat >>confdefs.h <<\_ACEOF +#define int16_t short +_ACEOF + + fi + +echo "$as_me:$LINENO: checking if uint16_t defined" >&5 +echo $ECHO_N "checking if uint16_t defined... $ECHO_C" >&6 + if test "${ac_cv_type_uint16_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include "confdefs.h" /* the header built by configure so far */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ERRNO_H +# include +#endif +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_SIGNAL_H +# include +#endif +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_UIO_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_WAIT_H +# include +#endif +#ifdef HAVE_SYS_UN_H +# include +#endif +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_FILIO_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif +#ifdef HAVE_PTHREAD_H +# include +#endif +int +main () +{ + uint16_t foo + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_uint16_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_uint16_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_type_uint16_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint16_t" >&6 + if test $ac_cv_type_uint16_t = no ; then + +cat >>confdefs.h <<\_ACEOF +#define uint16_t unsigned short +_ACEOF + + fi + +echo "$as_me:$LINENO: checking if int32_t defined" >&5 +echo $ECHO_N "checking if int32_t defined... $ECHO_C" >&6 + if test "${ac_cv_type_int32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include "confdefs.h" /* the header built by configure so far */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ERRNO_H +# include +#endif +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_SIGNAL_H +# include +#endif +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_UIO_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_WAIT_H +# include +#endif +#ifdef HAVE_SYS_UN_H +# include +#endif +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_FILIO_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif +#ifdef HAVE_PTHREAD_H +# include +#endif +int +main () +{ + int32_t foo + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_int32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_int32_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_type_int32_t" >&5 +echo "${ECHO_T}$ac_cv_type_int32_t" >&6 + if test $ac_cv_type_int32_t = no ; then + +cat >>confdefs.h <<\_ACEOF +#define int32_t int +_ACEOF + + fi + +echo "$as_me:$LINENO: checking if uint32_t defined" >&5 +echo $ECHO_N "checking if uint32_t defined... $ECHO_C" >&6 + if test "${ac_cv_type_uint32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include "confdefs.h" /* the header built by configure so far */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ERRNO_H +# include +#endif +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_SIGNAL_H +# include +#endif +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_UIO_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_WAIT_H +# include +#endif +#ifdef HAVE_SYS_UN_H +# include +#endif +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_FILIO_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif +#ifdef HAVE_PTHREAD_H +# include +#endif +int +main () +{ + uint32_t foo + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_uint32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_uint32_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_type_uint32_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint32_t" >&6 + if test $ac_cv_type_uint32_t = no ; then + +cat >>confdefs.h <<\_ACEOF +#define uint32_t unsigned int +_ACEOF + + fi + +echo "$as_me:$LINENO: checking if size_t defined" >&5 +echo $ECHO_N "checking if size_t defined... $ECHO_C" >&6 + if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include "confdefs.h" /* the header built by configure so far */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ERRNO_H +# include +#endif +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_SIGNAL_H +# include +#endif +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_UIO_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_WAIT_H +# include +#endif +#ifdef HAVE_SYS_UN_H +# include +#endif +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_FILIO_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif +#ifdef HAVE_PTHREAD_H +# include +#endif +int +main () +{ + size_t foo + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_size_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6 + if test $ac_cv_type_size_t = no ; then + +cat >>confdefs.h <<\_ACEOF +#define size_t unsigned int +_ACEOF + + fi + +echo "$as_me:$LINENO: checking if ssize_t defined" >&5 +echo $ECHO_N "checking if ssize_t defined... $ECHO_C" >&6 + if test "${ac_cv_type_ssize_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include "confdefs.h" /* the header built by configure so far */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ERRNO_H +# include +#endif +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_SIGNAL_H +# include +#endif +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_UIO_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_WAIT_H +# include +#endif +#ifdef HAVE_SYS_UN_H +# include +#endif +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_FILIO_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif +#ifdef HAVE_PTHREAD_H +# include +#endif +int +main () +{ + ssize_t foo + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_ssize_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_ssize_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_type_ssize_t" >&5 +echo "${ECHO_T}$ac_cv_type_ssize_t" >&6 + if test $ac_cv_type_ssize_t = no ; then + +cat >>confdefs.h <<\_ACEOF +#define ssize_t int +_ACEOF + + fi + +echo "$as_me:$LINENO: checking if socklen_t defined" >&5 +echo $ECHO_N "checking if socklen_t defined... $ECHO_C" >&6 + if test "${ac_cv_type_socklen_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include "confdefs.h" /* the header built by configure so far */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ERRNO_H +# include +#endif +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_SIGNAL_H +# include +#endif +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_UIO_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_WAIT_H +# include +#endif +#ifdef HAVE_SYS_UN_H +# include +#endif +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_FILIO_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif +#ifdef HAVE_PTHREAD_H +# include +#endif +int +main () +{ + socklen_t foo + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_socklen_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_socklen_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5 +echo "${ECHO_T}$ac_cv_type_socklen_t" >&6 + if test $ac_cv_type_socklen_t = no ; then + +cat >>confdefs.h <<\_ACEOF +#define socklen_t unsigned int +_ACEOF + + fi + +echo "$as_me:$LINENO: checking if sa_family_t defined" >&5 +echo $ECHO_N "checking if sa_family_t defined... $ECHO_C" >&6 + if test "${ac_cv_type_sa_family_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include "confdefs.h" /* the header built by configure so far */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ERRNO_H +# include +#endif +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_SIGNAL_H +# include +#endif +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_UIO_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_WAIT_H +# include +#endif +#ifdef HAVE_SYS_UN_H +# include +#endif +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_FILIO_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif +#ifdef HAVE_PTHREAD_H +# include +#endif +int +main () +{ + sa_family_t foo + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_sa_family_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_sa_family_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_type_sa_family_t" >&5 +echo "${ECHO_T}$ac_cv_type_sa_family_t" >&6 + if test $ac_cv_type_sa_family_t = no ; then + +cat >>confdefs.h <<\_ACEOF +#define sa_family_t SA_FAMILY_T +_ACEOF + + fi + + +echo "$as_me:$LINENO: checking if t_scalar_t defined" >&5 +echo $ECHO_N "checking if t_scalar_t defined... $ECHO_C" >&6 + if test "${ac_cv_type_t_scalar_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include "confdefs.h" /* the header built by configure so far */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ERRNO_H +# include +#endif +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_SIGNAL_H +# include +#endif +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_UIO_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_WAIT_H +# include +#endif +#ifdef HAVE_SYS_UN_H +# include +#endif +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_FILIO_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif +#ifdef HAVE_PTHREAD_H +# include +#endif +#ifdef HAVE_POLL_H +# include +#endif +#ifdef HAVE_XTI_H +# include +#endif +#ifdef HAVE_NETCONFIG_H +# include +#endif +#ifdef HAVE_NETDIR_H +# include +#endif +#ifdef HAVE_STROPTS_H +# include +#endif +int +main () +{ + t_scalar_t foo + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_t_scalar_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_t_scalar_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_type_t_scalar_t" >&5 +echo "${ECHO_T}$ac_cv_type_t_scalar_t" >&6 + if test $ac_cv_type_t_scalar_t = no ; then + +cat >>confdefs.h <<\_ACEOF +#define t_scalar_t int32_t +_ACEOF + + fi + +echo "$as_me:$LINENO: checking if t_uscalar_t defined" >&5 +echo $ECHO_N "checking if t_uscalar_t defined... $ECHO_C" >&6 + if test "${ac_cv_type_t_uscalar_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include "confdefs.h" /* the header built by configure so far */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ERRNO_H +# include +#endif +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_SIGNAL_H +# include +#endif +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_UIO_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_WAIT_H +# include +#endif +#ifdef HAVE_SYS_UN_H +# include +#endif +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_FILIO_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif +#ifdef HAVE_PTHREAD_H +# include +#endif +#ifdef HAVE_POLL_H +# include +#endif +#ifdef HAVE_XTI_H +# include +#endif +#ifdef HAVE_NETCONFIG_H +# include +#endif +#ifdef HAVE_NETDIR_H +# include +#endif +#ifdef HAVE_STROPTS_H +# include +#endif +int +main () +{ + t_uscalar_t foo + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_t_uscalar_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_t_uscalar_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + + echo "$as_me:$LINENO: result: $ac_cv_type_t_uscalar_t" >&5 +echo "${ECHO_T}$ac_cv_type_t_uscalar_t" >&6 + if test $ac_cv_type_t_uscalar_t = no ; then + +cat >>confdefs.h <<\_ACEOF +#define t_uscalar_t uint32_t +_ACEOF + + fi + + +echo "$as_me:$LINENO: checking for struct sockaddr.sa_len" >&5 +echo $ECHO_N "checking for struct sockaddr.sa_len... $ECHO_C" >&6 +if test "${ac_cv_member_struct_sockaddr_sa_len+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +static struct sockaddr ac_aggr; +if (ac_aggr.sa_len) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_sockaddr_sa_len=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +static struct sockaddr ac_aggr; +if (sizeof ac_aggr.sa_len) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_sockaddr_sa_len=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_member_struct_sockaddr_sa_len=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_sa_len" >&5 +echo "${ECHO_T}$ac_cv_member_struct_sockaddr_sa_len" >&6 +if test $ac_cv_member_struct_sockaddr_sa_len = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SOCKADDR_SA_LEN 1 +_ACEOF + +fi + + +if test $ac_cv_type_sa_family_t = no ; then + if test $ac_cv_member_struct_sockaddr_sa_len = yes ; then + +cat >>confdefs.h <<\_ACEOF +#define SA_FAMILY_T uint8_t +_ACEOF + + else + cat >>confdefs.h <<\_ACEOF +#define SA_FAMILY_T uint16_t +_ACEOF + + fi +fi + +echo "$as_me:$LINENO: checking for struct sockaddr_storage" >&5 +echo $ECHO_N "checking for struct sockaddr_storage... $ECHO_C" >&6 +if test "${ac_cv_type_struct_sockaddr_storage+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +if ((struct sockaddr_storage *) 0) + return 0; +if (sizeof (struct sockaddr_storage)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_struct_sockaddr_storage=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_struct_sockaddr_storage=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_storage" >&5 +echo "${ECHO_T}$ac_cv_type_struct_sockaddr_storage" >&6 +if test $ac_cv_type_struct_sockaddr_storage = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 +_ACEOF + +echo "$as_me:$LINENO: checking for struct sockaddr_storage.ss_family" >&5 +echo $ECHO_N "checking for struct sockaddr_storage.ss_family... $ECHO_C" >&6 +if test "${ac_cv_member_struct_sockaddr_storage_ss_family+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +static struct sockaddr_storage ac_aggr; +if (ac_aggr.ss_family) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_sockaddr_storage_ss_family=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +static struct sockaddr_storage ac_aggr; +if (sizeof ac_aggr.ss_family) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_sockaddr_storage_ss_family=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_member_struct_sockaddr_storage_ss_family=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_storage_ss_family" >&5 +echo "${ECHO_T}$ac_cv_member_struct_sockaddr_storage_ss_family" >&6 +if test $ac_cv_member_struct_sockaddr_storage_ss_family = yes; then + : +else + echo "$as_me:$LINENO: checking for struct sockaddr_storage.__ss_family" >&5 +echo $ECHO_N "checking for struct sockaddr_storage.__ss_family... $ECHO_C" >&6 +if test "${ac_cv_member_struct_sockaddr_storage___ss_family+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +static struct sockaddr_storage ac_aggr; +if (ac_aggr.__ss_family) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_sockaddr_storage___ss_family=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +static struct sockaddr_storage ac_aggr; +if (sizeof ac_aggr.__ss_family) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_sockaddr_storage___ss_family=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_member_struct_sockaddr_storage___ss_family=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_storage___ss_family" >&5 +echo "${ECHO_T}$ac_cv_member_struct_sockaddr_storage___ss_family" >&6 +if test $ac_cv_member_struct_sockaddr_storage___ss_family = yes; then + +cat >>confdefs.h <<\_ACEOF +#define ss_family __ss_family +_ACEOF + +else + { { echo "$as_me:$LINENO: error: cannot find ss_family in sockaddr_storage" >&5 +echo "$as_me: error: cannot find ss_family in sockaddr_storage" >&2;} + { (exit 1); exit 1; }; } +fi + +fi + +fi + + +echo "$as_me:$LINENO: checking for struct msghdr.msg_control" >&5 +echo $ECHO_N "checking for struct msghdr.msg_control... $ECHO_C" >&6 +if test "${ac_cv_member_struct_msghdr_msg_control+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +static struct msghdr ac_aggr; +if (ac_aggr.msg_control) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_msghdr_msg_control=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +static struct msghdr ac_aggr; +if (sizeof ac_aggr.msg_control) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_msghdr_msg_control=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_member_struct_msghdr_msg_control=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_member_struct_msghdr_msg_control" >&5 +echo "${ECHO_T}$ac_cv_member_struct_msghdr_msg_control" >&6 +if test $ac_cv_member_struct_msghdr_msg_control = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_MSGHDR_MSG_CONTROL 1 +_ACEOF + +fi + + +echo "$as_me:$LINENO: checking for struct ifreq.ifr_mtu" >&5 +echo $ECHO_N "checking for struct ifreq.ifr_mtu... $ECHO_C" >&6 +if test "${ac_cv_member_struct_ifreq_ifr_mtu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +static struct ifreq ac_aggr; +if (ac_aggr.ifr_mtu) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_ifreq_ifr_mtu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +static struct ifreq ac_aggr; +if (sizeof ac_aggr.ifr_mtu) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_ifreq_ifr_mtu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_member_struct_ifreq_ifr_mtu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_member_struct_ifreq_ifr_mtu" >&5 +echo "${ECHO_T}$ac_cv_member_struct_ifreq_ifr_mtu" >&6 +if test $ac_cv_member_struct_ifreq_ifr_mtu = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_IFREQ_IFR_MTU 1 +_ACEOF + + +fi + + +echo "$as_me:$LINENO: checking for getaddrinfo function prototype in netdb.h" >&5 +echo $ECHO_N "checking for getaddrinfo function prototype in netdb.h... $ECHO_C" >&6 +if test "${ac_cv_have_getaddrinfo_proto+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "getaddrinfo" >/dev/null 2>&1; then + ac_cv_have_getaddrinfo_proto=yes +else + ac_cv_have_getaddrinfo_proto=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_have_getaddrinfo_proto" >&5 +echo "${ECHO_T}$ac_cv_have_getaddrinfo_proto" >&6 + if test $ac_cv_have_getaddrinfo_proto = yes ; then + ac_tr_func=HAVE_`echo getaddrinfo | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO + cat >>confdefs.h <<_ACEOF +#define $ac_tr_func 1 +_ACEOF + + fi + +echo "$as_me:$LINENO: checking for getnameinfo function prototype in netdb.h" >&5 +echo $ECHO_N "checking for getnameinfo function prototype in netdb.h... $ECHO_C" >&6 +if test "${ac_cv_have_getnameinfo_proto+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "getnameinfo" >/dev/null 2>&1; then + ac_cv_have_getnameinfo_proto=yes +else + ac_cv_have_getnameinfo_proto=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_have_getnameinfo_proto" >&5 +echo "${ECHO_T}$ac_cv_have_getnameinfo_proto" >&6 + if test $ac_cv_have_getnameinfo_proto = yes ; then + ac_tr_func=HAVE_`echo getnameinfo | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO + cat >>confdefs.h <<_ACEOF +#define $ac_tr_func 1 +_ACEOF + + fi + +echo "$as_me:$LINENO: checking for gethostname function prototype in unistd.h" >&5 +echo $ECHO_N "checking for gethostname function prototype in unistd.h... $ECHO_C" >&6 +if test "${ac_cv_have_gethostname_proto+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "gethostname" >/dev/null 2>&1; then + ac_cv_have_gethostname_proto=yes +else + ac_cv_have_gethostname_proto=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_have_gethostname_proto" >&5 +echo "${ECHO_T}$ac_cv_have_gethostname_proto" >&6 + if test $ac_cv_have_gethostname_proto = yes ; then + ac_tr_func=HAVE_`echo gethostname | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO + cat >>confdefs.h <<_ACEOF +#define $ac_tr_func 1 +_ACEOF + + fi + +echo "$as_me:$LINENO: checking for getrusage function prototype in sys/resource.h" >&5 +echo $ECHO_N "checking for getrusage function prototype in sys/resource.h... $ECHO_C" >&6 +if test "${ac_cv_have_getrusage_proto+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "getrusage" >/dev/null 2>&1; then + ac_cv_have_getrusage_proto=yes +else + ac_cv_have_getrusage_proto=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_have_getrusage_proto" >&5 +echo "${ECHO_T}$ac_cv_have_getrusage_proto" >&6 + if test $ac_cv_have_getrusage_proto = yes ; then + ac_tr_func=HAVE_`echo getrusage | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO + cat >>confdefs.h <<_ACEOF +#define $ac_tr_func 1 +_ACEOF + + fi + +echo "$as_me:$LINENO: checking for hstrerror function prototype in netdb.h" >&5 +echo $ECHO_N "checking for hstrerror function prototype in netdb.h... $ECHO_C" >&6 +if test "${ac_cv_have_hstrerror_proto+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "hstrerror" >/dev/null 2>&1; then + ac_cv_have_hstrerror_proto=yes +else + ac_cv_have_hstrerror_proto=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_have_hstrerror_proto" >&5 +echo "${ECHO_T}$ac_cv_have_hstrerror_proto" >&6 + if test $ac_cv_have_hstrerror_proto = yes ; then + ac_tr_func=HAVE_`echo hstrerror | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO + cat >>confdefs.h <<_ACEOF +#define $ac_tr_func 1 +_ACEOF + + fi + +echo "$as_me:$LINENO: checking for if_nametoindex function prototype in net/if.h" >&5 +echo $ECHO_N "checking for if_nametoindex function prototype in net/if.h... $ECHO_C" >&6 +if test "${ac_cv_have_if_nametoindex_proto+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "if_nametoindex" >/dev/null 2>&1; then + ac_cv_have_if_nametoindex_proto=yes +else + ac_cv_have_if_nametoindex_proto=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_have_if_nametoindex_proto" >&5 +echo "${ECHO_T}$ac_cv_have_if_nametoindex_proto" >&6 + if test $ac_cv_have_if_nametoindex_proto = yes ; then + ac_tr_func=HAVE_`echo if_nametoindex | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO + cat >>confdefs.h <<_ACEOF +#define $ac_tr_func 1 +_ACEOF + + fi + +echo "$as_me:$LINENO: checking for inet_aton function prototype in arpa/inet.h" >&5 +echo $ECHO_N "checking for inet_aton function prototype in arpa/inet.h... $ECHO_C" >&6 +if test "${ac_cv_have_inet_aton_proto+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "inet_aton" >/dev/null 2>&1; then + ac_cv_have_inet_aton_proto=yes +else + ac_cv_have_inet_aton_proto=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_have_inet_aton_proto" >&5 +echo "${ECHO_T}$ac_cv_have_inet_aton_proto" >&6 + if test $ac_cv_have_inet_aton_proto = yes ; then + ac_tr_func=HAVE_`echo inet_aton | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO + cat >>confdefs.h <<_ACEOF +#define $ac_tr_func 1 +_ACEOF + + fi + +echo "$as_me:$LINENO: checking for inet_pton function prototype in arpa/inet.h" >&5 +echo $ECHO_N "checking for inet_pton function prototype in arpa/inet.h... $ECHO_C" >&6 +if test "${ac_cv_have_inet_pton_proto+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "inet_pton" >/dev/null 2>&1; then + ac_cv_have_inet_pton_proto=yes +else + ac_cv_have_inet_pton_proto=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_have_inet_pton_proto" >&5 +echo "${ECHO_T}$ac_cv_have_inet_pton_proto" >&6 + if test $ac_cv_have_inet_pton_proto = yes ; then + ac_tr_func=HAVE_`echo inet_pton | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO + cat >>confdefs.h <<_ACEOF +#define $ac_tr_func 1 +_ACEOF + + fi + +echo "$as_me:$LINENO: checking for pselect function prototype in sys/select.h" >&5 +echo $ECHO_N "checking for pselect function prototype in sys/select.h... $ECHO_C" >&6 +if test "${ac_cv_have_pselect_proto+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "pselect" >/dev/null 2>&1; then + ac_cv_have_pselect_proto=yes +else + ac_cv_have_pselect_proto=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_have_pselect_proto" >&5 +echo "${ECHO_T}$ac_cv_have_pselect_proto" >&6 + if test $ac_cv_have_pselect_proto = yes ; then + ac_tr_func=HAVE_`echo pselect | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO + cat >>confdefs.h <<_ACEOF +#define $ac_tr_func 1 +_ACEOF + + fi + +echo "$as_me:$LINENO: checking for snprintf function prototype in stdio.h" >&5 +echo $ECHO_N "checking for snprintf function prototype in stdio.h... $ECHO_C" >&6 +if test "${ac_cv_have_snprintf_proto+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "snprintf" >/dev/null 2>&1; then + ac_cv_have_snprintf_proto=yes +else + ac_cv_have_snprintf_proto=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_have_snprintf_proto" >&5 +echo "${ECHO_T}$ac_cv_have_snprintf_proto" >&6 + if test $ac_cv_have_snprintf_proto = yes ; then + ac_tr_func=HAVE_`echo snprintf | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO + cat >>confdefs.h <<_ACEOF +#define $ac_tr_func 1 +_ACEOF + + fi + +echo "$as_me:$LINENO: checking for sockatmark function prototype in sys/socket.h" >&5 +echo $ECHO_N "checking for sockatmark function prototype in sys/socket.h... $ECHO_C" >&6 +if test "${ac_cv_have_sockatmark_proto+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "sockatmark" >/dev/null 2>&1; then + ac_cv_have_sockatmark_proto=yes +else + ac_cv_have_sockatmark_proto=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_have_sockatmark_proto" >&5 +echo "${ECHO_T}$ac_cv_have_sockatmark_proto" >&6 + if test $ac_cv_have_sockatmark_proto = yes ; then + ac_tr_func=HAVE_`echo sockatmark | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO + cat >>confdefs.h <<_ACEOF +#define $ac_tr_func 1 +_ACEOF + + fi + + + + + + + + + + + + + + + + + + + + + + + + +echo "$as_me:$LINENO: checking for struct addrinfo" >&5 +echo $ECHO_N "checking for struct addrinfo... $ECHO_C" >&6 +if test "${ac_cv_type_struct_addrinfo+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include + +int +main () +{ +if ((struct addrinfo *) 0) + return 0; +if (sizeof (struct addrinfo)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_struct_addrinfo=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_struct_addrinfo=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_struct_addrinfo" >&5 +echo "${ECHO_T}$ac_cv_type_struct_addrinfo" >&6 +if test $ac_cv_type_struct_addrinfo = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ADDRINFO_STRUCT 1 +_ACEOF + +fi + + +echo "$as_me:$LINENO: checking for struct if_nameindex" >&5 +echo $ECHO_N "checking for struct if_nameindex... $ECHO_C" >&6 +if test "${ac_cv_type_struct_if_nameindex+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include + +int +main () +{ +if ((struct if_nameindex *) 0) + return 0; +if (sizeof (struct if_nameindex)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_struct_if_nameindex=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_struct_if_nameindex=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_struct_if_nameindex" >&5 +echo "${ECHO_T}$ac_cv_type_struct_if_nameindex" >&6 +if test $ac_cv_type_struct_if_nameindex = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_IF_NAMEINDEX_STRUCT 1 +_ACEOF + +fi + + +echo "$as_me:$LINENO: checking for struct sockaddr_dl" >&5 +echo $ECHO_N "checking for struct sockaddr_dl... $ECHO_C" >&6 +if test "${ac_cv_type_struct_sockaddr_dl+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include + +int +main () +{ +if ((struct sockaddr_dl *) 0) + return 0; +if (sizeof (struct sockaddr_dl)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_struct_sockaddr_dl=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_struct_sockaddr_dl=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_dl" >&5 +echo "${ECHO_T}$ac_cv_type_struct_sockaddr_dl" >&6 +if test $ac_cv_type_struct_sockaddr_dl = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SOCKADDR_DL_STRUCT 1 +_ACEOF + +fi + + +echo "$as_me:$LINENO: checking for struct timespec" >&5 +echo $ECHO_N "checking for struct timespec... $ECHO_C" >&6 +if test "${ac_cv_type_struct_timespec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#if TIME_WITH_SYS_TIME +#include +#include +#else +#if HAVE_SYS_TIME_H +#include +#else +#include +#endif +#endif + + +int +main () +{ +if ((struct timespec *) 0) + return 0; +if (sizeof (struct timespec)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_struct_timespec=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_struct_timespec=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_struct_timespec" >&5 +echo "${ECHO_T}$ac_cv_type_struct_timespec" >&6 +if test $ac_cv_type_struct_timespec = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_TIMESPEC_STRUCT 1 +_ACEOF + +fi + + +echo "$as_me:$LINENO: checking for /dev/tcp" >&5 +echo $ECHO_N "checking for /dev/tcp... $ECHO_C" >&6 +if test -r /dev/tcp ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DEV_TCP 1 +_ACEOF + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + + echo "$as_me:$LINENO: checking for /dev/xti/tcp" >&5 +echo $ECHO_N "checking for /dev/xti/tcp... $ECHO_C" >&6 + if test -r /dev/xti/tcp ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DEV_XTI_TCP 1 +_ACEOF + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + + echo "$as_me:$LINENO: checking for /dev/streams/xtiso/tcp" >&5 +echo $ECHO_N "checking for /dev/streams/xtiso/tcp... $ECHO_C" >&6 + if test -r /dev/streams/xtiso/tcp ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DEV_STREAMS_XTISO_TCP 1 +_ACEOF + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + fi +fi + + +for ac_func in bzero +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in getaddrinfo +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in gethostname +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in gethostbyname2 +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in gethostbyname_r +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in getnameinfo +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in hstrerror +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in if_nametoindex +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in inet_aton +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in inet_pton +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in inet6_rth_init +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + +for ac_func in kqueue kevent +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in mkstemp +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in poll +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in pselect +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in snprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in sockatmark +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in vsnprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + +echo "$as_me:$LINENO: checking for IPv4 support" >&5 +echo $ECHO_N "checking for IPv4 support... $ECHO_C" >&6 +if test "${ac_cv_ipv4+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_ipv4=no +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# include +# include +# include + /* Make sure the definitions for AF_INET and struct sockaddr_in + * are defined, and that we can actually create an IPv4 TCP socket. + */ + main() + { + int fd; + struct sockaddr_in foo; + fd = socket(AF_INET, SOCK_STREAM, 0); + exit(fd >= 0 ? 0 : 1); + } +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_ipv4=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +(exit $ac_status ) +ac_cv_ipv4=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi + +echo "$as_me:$LINENO: result: $ac_cv_ipv4" >&5 +echo "${ECHO_T}$ac_cv_ipv4" >&6 +if test $ac_cv_ipv4 = yes ; then + +cat >>confdefs.h <<\_ACEOF +#define IPV4 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define IPv4 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for IPv6 support" >&5 +echo $ECHO_N "checking for IPv6 support... $ECHO_C" >&6 +if test "${ac_cv_ipv6+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_ipv6=no +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# include +# include +# include + /* Make sure the definitions for AF_INET6 and struct sockaddr_in6 + * are defined, and that we can actually create an IPv6 TCP socket. + */ + main() + { + int fd; + struct sockaddr_in6 foo; + fd = socket(AF_INET6, SOCK_STREAM, 0); + exit(fd >= 0 ? 0 : 1); + } +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_ipv6=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +(exit $ac_status ) +ac_cv_ipv6=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi + +echo "$as_me:$LINENO: result: $ac_cv_ipv6" >&5 +echo "${ECHO_T}$ac_cv_ipv6" >&6 +if test $ac_cv_ipv6 = yes ; then + +cat >>confdefs.h <<\_ACEOF +#define IPV6 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define IPv6 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for Unix domain sockets" >&5 +echo $ECHO_N "checking for Unix domain sockets... $ECHO_C" >&6 +if test "${ac_cv_unixdomain+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_unixdomain=no +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# include +# include +# include + /* Make sure the definitions for AF_UNIX and struct sockaddr_un + * are defined, and that we can actually create an IPv4 TCP socket. + */ + main() + { + int fd; + struct sockaddr_un foo; + fd = socket(AF_UNIX, SOCK_STREAM, 0); + exit(fd >= 0 ? 0 : 1); + } +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_unixdomain=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +(exit $ac_status ) +ac_cv_unixdomain=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi + +echo "$as_me:$LINENO: result: $ac_cv_unixdomain" >&5 +echo "${ECHO_T}$ac_cv_unixdomain" >&6 +if test $ac_cv_unixdomain = yes ; then + +cat >>confdefs.h <<\_ACEOF +#define UNIXDOMAIN 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define UNIXdomain 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for multicast support" >&5 +echo $ECHO_N "checking for multicast support... $ECHO_C" >&6 +if test "${ac_cv_multicast+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_multicast=no +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# include +# include +# include + main() + { + int fd; + unsigned char flag = 1; + struct sockaddr_in foo; + struct ip_mreq mreq; + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) exit(1); + if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, + (void*)&flag, sizeof(flag)) < 0) + exit(1); + exit(0); + } +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_multicast=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +(exit $ac_status ) +ac_cv_multicast=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi + +echo "$as_me:$LINENO: result: $ac_cv_multicast" >&5 +echo "${ECHO_T}$ac_cv_multicast" >&6 +if test $ac_cv_multicast = yes ; then + +cat >>confdefs.h <<\_ACEOF +#define MCAST 1 +_ACEOF + +fi + +LIB_OBJS= +LIB_OBJS="$LIB_OBJS connect_nonb.o" +LIB_OBJS="$LIB_OBJS connect_timeo.o" +LIB_OBJS="$LIB_OBJS daemon_inetd.o" +LIB_OBJS="$LIB_OBJS daemon_init.o" +LIB_OBJS="$LIB_OBJS dg_cli.o" +LIB_OBJS="$LIB_OBJS dg_echo.o" +LIB_OBJS="$LIB_OBJS error.o" +LIB_OBJS="$LIB_OBJS get_ifi_info.o" +LIB_OBJS="$LIB_OBJS gf_time.o" +LIB_OBJS="$LIB_OBJS host_serv.o" +if test "$ac_cv_func_hstrerror" = no ; then + LIBFREE_OBJS="$LIBFREE_OBJS hstrerror.o" +fi +if test "$ac_cv_func_if_nametoindex" = no ; then + LIB_OBJS="$LIB_OBJS if_nametoindex.o if_indextoname.o if_nameindex.o" +fi +if test "$ac_cv_multicast" = yes ; then + LIB_OBJS="$LIB_OBJS family_to_level.o" + LIB_OBJS="$LIB_OBJS mcast_leave.o mcast_join.o" + LIB_OBJS="$LIB_OBJS mcast_get_if.o mcast_get_loop.o mcast_get_ttl.o" + LIB_OBJS="$LIB_OBJS mcast_set_if.o mcast_set_loop.o mcast_set_ttl.o" +fi +LIB_OBJS="$LIB_OBJS my_addrs.o" +if test "$ac_cv_func_pselect" = no ; then + LIB_OBJS="$LIB_OBJS pselect.o" +fi +LIB_OBJS="$LIB_OBJS read_fd.o" +LIB_OBJS="$LIB_OBJS readline.o" +LIB_OBJS="$LIB_OBJS readn.o" +LIB_OBJS="$LIB_OBJS readable_timeo.o" +LIB_OBJS="$LIB_OBJS rtt.o" +LIB_OBJS="$LIB_OBJS signal.o" +LIB_OBJS="$LIB_OBJS signal_intr.o" +if test "$ac_cv_func_snprintf" = no ; then + LIB_OBJS="$LIB_OBJS snprintf.o" +fi +if test "$ac_cv_func_sockatmark" = no ; then + LIB_OBJS="$LIB_OBJS sockatmark.o" +fi +LIB_OBJS="$LIB_OBJS sock_bind_wild.o" +LIB_OBJS="$LIB_OBJS sock_cmp_addr.o" +LIB_OBJS="$LIB_OBJS sock_cmp_port.o" +LIB_OBJS="$LIB_OBJS sock_ntop.o" +LIB_OBJS="$LIB_OBJS sock_ntop_host.o" +LIB_OBJS="$LIB_OBJS sock_get_port.o" +LIB_OBJS="$LIB_OBJS sock_set_addr.o" +LIB_OBJS="$LIB_OBJS sock_set_port.o" +LIB_OBJS="$LIB_OBJS sock_set_wild.o" +LIB_OBJS="$LIB_OBJS sockfd_to_family.o" +LIB_OBJS="$LIB_OBJS str_cli.o" +LIB_OBJS="$LIB_OBJS str_echo.o" +LIB_OBJS="$LIB_OBJS tcp_connect.o" +LIB_OBJS="$LIB_OBJS tcp_listen.o" +LIB_OBJS="$LIB_OBJS tv_sub.o" +LIB_OBJS="$LIB_OBJS udp_client.o" +LIB_OBJS="$LIB_OBJS udp_connect.o" +LIB_OBJS="$LIB_OBJS udp_server.o" +LIB_OBJS="$LIB_OBJS wraplib.o" +LIB_OBJS="$LIB_OBJS wrapsock.o" +LIB_OBJS="$LIB_OBJS wrapstdio.o" +if test "$ac_cv_header_pthread_h" = yes ; then + LIB_OBJS="$LIB_OBJS wrappthread.o" +fi +LIB_OBJS="$LIB_OBJS wrapunix.o" +LIB_OBJS="$LIB_OBJS write_fd.o" +LIB_OBJS="$LIB_OBJS writen.o" +LIB_OBJS="$LIB_OBJS writable_timeo.o" + +LIBFREE_OBJS= + +LIBFREE_OBJS="$LIBFREE_OBJS in_cksum.o" +if test "$ac_cv_func_inet_aton" = no ; then + LIBFREE_OBJS="$LIBFREE_OBJS inet_aton.o" +fi + +LIBFREE_OBJS="$LIBFREE_OBJS inet_ntop.o inet_pton.o" + +if test "$ac_cv_func_getaddrinfo" = no ; then +LIBGAI_OBJS="getaddrinfo.o getnameinfo.o freeaddrinfo.o gai_strerror.o" +LIBGAI_OBJS="$LIBGAI_OBJS ga_aistruct.o ga_clone.o ga_echeck.o ga_nsearch.o" +LIBGAI_OBJS="$LIBGAI_OBJS ga_port.o ga_serv.o ga_unix.o gn_ipv46.o" +else +LIBGAI_OBJS="" +fi + +LIBROUTE_OBJS="get_rtaddrs.o" +LIBROUTE_OBJS="$LIBROUTE_OBJS if_indextoname.o if_nameindex.o if_nametoindex.o" +LIBROUTE_OBJS="$LIBROUTE_OBJS net_rt_iflist.o net_rt_dump.o" +LIBROUTE_OBJS="$LIBROUTE_OBJS sock_masktop.o" + +LIBXTI_OBJS= +if test "$ac_cv_header_netdir_h" = yes ; then + LIBXTI_OBJS="$LIBXTI_OBJS tcp_connect.o" + LIBXTI_OBJS="$LIBXTI_OBJS tcp_listen.o" + LIBXTI_OBJS="$LIBXTI_OBJS udp_server.o" + LIBXTI_OBJS="$LIBXTI_OBJS udp_client.o" +fi +LIBXTI_OBJS="$LIBXTI_OBJS wrapxti.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_accept.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_flags_str.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_getopt.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_ntop.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_ntop_host.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_rdwr.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_setopt.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_str_opts.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_tlook_str.o" + + + + + + + +LIBS_XTI=`echo $LIBS | sed 's/-lsocket//'` +LIBS=`echo $LIBS | sed 's/-lxti//'` + + + + + + + + + +echo "$as_me:$LINENO: checking for -I$HOME/doc/unp2ev1/src/include" >&5 +echo $ECHO_N "checking for -I$HOME/doc/unp2ev1/src/include... $ECHO_C" >&6 +if test -d $HOME/doc/unp2ev1/src/include ; then + CFLAGS="$CFLAGS -I$HOME/doc/unp2ev1/src/include" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +if test "$ac_cv_c_compiler_gnu" = yes; then + CFLAGS="$CFLAGS -Wall" + fi + +case "$host_os" in +*aix*) CFLAGS="$CFLAGS -D_ALL_SOURCE" ;; +*osf*) CFLAGS="$CFLAGS -D_SOCKADDR_LEN" ;; +*solaris*) if test "$ac_cv_c_compiler_gnu" = yes; then + CFLAGS="$CFLAGS -D__EXTENSIONS__" + else + CFLAGS="$CFLAGS -D__STDC__" + fi ;; +esac + + ac_config_files="$ac_config_files Makefile Make.defines" +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.57. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.57, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + + + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "Make.defines" ) CONFIG_FILES="$CONFIG_FILES Make.defines" ;; + "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@CPP@,$CPP,;t t +s,@EGREP@,$EGREP,;t t +s,@LIB_OBJS@,$LIB_OBJS,;t t +s,@LIBFREE_OBJS@,$LIBFREE_OBJS,;t t +s,@LIBGAI_OBJS@,$LIBGAI_OBJS,;t t +s,@LIBROUTE_OBJS@,$LIBROUTE_OBJS,;t t +s,@LIBXTI_OBJS@,$LIBXTI_OBJS,;t t +s,@LIBS_XTI@,$LIBS_XTI,;t t +s,@LIBUNP@,$LIBUNP,;t t +s,@LIBUNPXTI@,$LIBUNPXTI,;t t +s,@LIBUNP_NAME@,$LIBUNP_NAME,;t t +s,@LIBUNPXTI_NAME@,$LIBUNPXTI_NAME,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + + +if test -d "$host" ; then + cp -p config.h config.cache config.status Makefile Make.defines $host + echo "saving copies in $host/" +fi diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..ef3fbcd --- /dev/null +++ b/configure.in @@ -0,0 +1,716 @@ +dnl +dnl autoconf script for UNP 3/e Volume 1 source code. +dnl Process this file with autoconf to produce a configure script. +dnl +dnl The end result of running configure is the "config.h" file and the +dnl "Make.defines" file in the current directory. These two files are +dnl created from the "config.h.in" and "Make.defines.in" files in the +dnl current directory. +dnl +dnl The header "unp.h" that is in every source directory then does a +dnl #include "../config.h" and the Makefile in each source directory +dnl then does a include of ../Make.defines. +dnl +AC_REVISION($Revision: 1.13 $) +AC_INIT(lib/unp.h) +AC_CANONICAL_HOST +AC_CONFIG_HEADER(config.h) + +dnl The following cpu_vendor_os string goes into config.h. +dnl +AC_DEFINE_UNQUOTED(CPU_VENDOR_OS, "$host", [CPU, vendor, and operating system]) + +dnl ################################################################## +dnl Checks for programs. +dnl + +dnl Some system-specific stuff ... +dnl Some operating systems require additional flags in order to get all +dnl the definitions that we're looking for in some system headers. +dnl The configure script uses both CFLAGS and CPPFLAGS when compiling. +case "$host_os" in +*aix*) CPPFLAGS="$CPPFLAGS -D_ALL_SOURCE" ;; +*osf*) CPPFLAGS="$CPPFLAGS -D_SOCKADDR_LEN" ;; +esac + +AC_PROG_CC +AC_PROG_RANLIB + +dnl ################################################################## +dnl Checks for libraries. +dnl The order of these tests is the *reverse* order of the libraries in +dnl the LIBS variable that is constructed: each new one gets prepended, +dnl not appended. +dnl +dnl We are building three strings here; something like: +dnl LIBS="-lresolv -lsocket -lnsl -lpthread" +dnl LIBS_XTI="-lxti -lresolv -lnsl -lpthread" +dnl LIBUNP="./libunp.a" +dnl LIBUNPXTI="./libunpxti.a" +dnl +dnl If a threads library is found, need to update CFLAGS too. +dnl +AC_CHECK_LIB(pthread, pthread_create) +if test "$ac_cv_lib_pthread_pthread_create" = yes ; then + CFLAGS="$CFLAGS -D_REENTRANT" +else + AC_CHECK_LIB(pthreads, pthread_create) + if test "$ac_cv_lib_pthreads_pthread_create" = yes ; then + CFLAGS="$CFLAGS -D_REENTRANT" + fi +fi + +AC_CHECK_LIB(nsl, t_open) +AC_SEARCH_LIBS(socket, socket) + +dnl Bind 8.1.1 places its library in /usr/local/bind/lib/libbind.a; we check +dnl for it first. Also check for libbind.a in user's home directory. +dnl If there is a libresolv.a in the user's HOME directory, we will use +dnl that instead of -lresolv. Need this for people interested in building +dnl an IPv6-knowledgable resolver, instead of using the system provided +dnl resolver (which is often way out of date). +dnl +AC_MSG_CHECKING(for /usr/local/bind/lib/libbind.a) +if test -f /usr/local/bind/lib/libbind.a ; then + AC_MSG_RESULT(yes) + LIBS="/usr/local/bind/lib/libbind.a $LIBS" +else + AC_MSG_RESULT(no) + AC_MSG_CHECKING(for $HOME/libbind.a) + if test -f $HOME/libbind.a ; then + AC_MSG_RESULT(yes) + LIBS="$HOME/libbind.a $LIBS" + else + AC_MSG_RESULT(no) + AC_MSG_CHECKING(for $HOME/libresolv.a) + if test -f $HOME/libresolv.a ; then + AC_MSG_RESULT(yes) + LIBS="$HOME/libresolv.a $LIBS" + else + AC_MSG_RESULT(no) + AC_CHECK_LIB(resolv, res_init) + fi + fi +fi + +dnl Now check for XTI library. +dnl +AC_CHECK_LIB(xti, t_open) + +dnl We now need to check for our own libraries, but we cannot prepend +dnl them to the LIBS variable, as that variable is used when compiling +dnl programs later in this script, and that would mess things up. +dnl +dnl If the user has a file named $HOME/libunp.a, then use it. +dnl Else store our library in current directory. +dnl I use this because my source directory is NFS mounted from my various +dnl systems, but I have a unique home directory on each system. +dnl +AC_MSG_CHECKING(for $HOME/libunp.a) +if test -f $HOME/libunp.a ; then + AC_MSG_RESULT(yes) + LIBUNP="$HOME/libunp.a" + LIBUNP_NAME=$HOME/libunp.a +else + AC_MSG_RESULT(no, using ./libunp.a) + LIBUNP="../libunp.a" + LIBUNP_NAME=../libunp.a +fi + +dnl If the user has a file named $HOME/libunpxti.a, then use it. +dnl Else store our library in current directory. +dnl Same reasoning as above. +dnl +AC_MSG_CHECKING(for $HOME/libunpxti.a) +if test -f $HOME/libunpxti.a ; then + AC_MSG_RESULT(yes) + LIBUNPXTI="$HOME/libunpxti.a" + LIBUNPXTI_NAME=$HOME/libunpxti.a +else + AC_MSG_RESULT(no, using ./libunpxti.a) + LIBUNPXTI="../libunpxti.a" + LIBUNPXTI_NAME=../libunpxti.a +fi + +dnl ################################################################## +dnl Checks for header files. +dnl +dnl The list of headers in the AC_CHECK_HEADERS macro is the same as in +dnl our "unp.h" header, followed by our "unpxti.h" header. +dnl +AC_HEADER_STDC +dnl +dnl The includes (the 4th argument to AC_CHECK_HEADERS) here are +dnl the defeault set ($ac_includes_default) plus +dnl for on NetBSD and OpenBSD. +AC_CHECK_HEADERS(sys/types.h sys/socket.h sys/time.h time.h netinet/in.h arpa/inet.h errno.h fcntl.h netdb.h signal.h stdio.h stdlib.h string.h sys/stat.h sys/uio.h unistd.h sys/wait.h sys/un.h sys/param.h sys/select.h sys/sysctl.h poll.h sys/event.h strings.h sys/ioctl.h sys/filio.h sys/sockio.h pthread.h net/if_dl.h xti.h xti_inet.h netconfig.h netdir.h stropts.h, [], [], [ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif +#if HAVE_SYS_PARAM_H +# include +#endif]) + +dnl ################################################################## +dnl Checks for typedefs. +dnl +dnl We use our own AC_UNP_CHECK_TYPE macro, instead of AC_CHECK_TYPE, +dnl to #include more headers. Our macro is defined in "aclocal.m4". +dnl +AC_HEADER_TIME +AC_UNP_CHECK_TYPE(uint8_t, unsigned char, 8-bit unsigned type) +AC_UNP_CHECK_TYPE(int16_t, short, 16 bit signed type) +AC_UNP_CHECK_TYPE(uint16_t, unsigned short, 16 bit unsigned type) +AC_UNP_CHECK_TYPE(int32_t, int, 32 bit signed type) +AC_UNP_CHECK_TYPE(uint32_t, unsigned int, 32 bit unsigned type) +AC_UNP_CHECK_TYPE(size_t, unsigned int, unsigned integer type of the result of the sizeof operator) +AC_UNP_CHECK_TYPE(ssize_t, int, a signed type appropriate for a count of bytes or an error indication) +AC_UNP_CHECK_TYPE(socklen_t, unsigned int, a type appropriate for address, hostname, buffer, etc. lengths) +dnl +dnl The SA_FAMILY_T in the following is #defined later, as its definition +dnl depends on whether socket address structures have a length field or not. +dnl +AC_UNP_CHECK_TYPE(sa_family_t, SA_FAMILY_T, the type of the sa_family struct member) + +dnl We also have our own macro to check for XTI definitions, that can +dnl be defined after #include of our "unpxti.h" header. +dnl +AC_UNPXTI_CHECK_TYPE(t_scalar_t, int32_t, scalar type) +AC_UNPXTI_CHECK_TYPE(t_uscalar_t, uint32_t, unsigned scalar type) + +dnl ################################################################## +dnl Check if sockaddr{} has sa_len member. +dnl +AC_CHECK_MEMBER([struct sockaddr.sa_len], + AC_DEFINE(HAVE_SOCKADDR_SA_LEN, 1, define if socket address structures have length fields),,[ +#include +#include ]) + +dnl Now we can complete the definition for sa_family_t, if needed. +dnl The size of this datatype depends whether socket address structures +dnl have a length field or not. +dnl +if test $ac_cv_type_sa_family_t = no ; then + if test $ac_cv_member_struct_sockaddr_sa_len = yes ; then + AC_DEFINE(SA_FAMILY_T, uint8_t, the size of the sa_family field in a socket address structure) + else + AC_DEFINE(SA_FAMILY_T, uint16_t) + fi +fi + +dnl +dnl Check for sockaddr_storage. +dnl If it's present, check for ss_family. +dnl If ss_family isn't there, check for __ss_family and +dnl #define ss_family __ss_family if so. +dnl If neither is there, I don't know what to do. +dnl +AC_CHECK_TYPES([struct sockaddr_storage], + AC_CHECK_MEMBER([struct sockaddr_storage.ss_family],, + AC_CHECK_MEMBER([struct sockaddr_storage.__ss_family], + AC_DEFINE([ss_family],[__ss_family],[define to __ss_family if sockaddr_storage has that instead of ss_family]), + AC_MSG_ERROR([cannot find ss_family in sockaddr_storage]),[ +#include +#include ]),[ +#include +#include ]),,[ +#include +#include ]) + +dnl Check if msghdr{} has msg_control member. +dnl +AC_CHECK_MEMBER([struct msghdr.msg_control], + AC_DEFINE(HAVE_MSGHDR_MSG_CONTROL, 1, define if struct msghdr contains the msg_control member),,[ +#include +#include ]) + +dnl +dnl Check for ifr_mtu in ifreq - some systems have SIOCGIFMTU +dnl but don't have ifr_mtu!! +AC_CHECK_MEMBERS([struct ifreq.ifr_mtu],,, +[#include +#include +#include ]) + +dnl ################################################################## +dnl Check for function prototypes in headers. +dnl AC_CHECK_FUNC_PROTO is our own macro in "aclocal.m4". +dnl +AC_CHECK_FUNC_PROTO(getaddrinfo, netdb.h) +AC_CHECK_FUNC_PROTO(getnameinfo, netdb.h) +AC_CHECK_FUNC_PROTO(gethostname, unistd.h) +AC_CHECK_FUNC_PROTO(getrusage, sys/resource.h) +AC_CHECK_FUNC_PROTO(hstrerror, netdb.h) +AC_CHECK_FUNC_PROTO(if_nametoindex, net/if.h) +AC_CHECK_FUNC_PROTO(inet_aton, arpa/inet.h) +AC_CHECK_FUNC_PROTO(inet_pton, arpa/inet.h) +AC_CHECK_FUNC_PROTO(pselect, sys/select.h) +AC_CHECK_FUNC_PROTO(snprintf, stdio.h) +AC_CHECK_FUNC_PROTO(sockatmark, sys/socket.h) +dnl +dnl autoheader doesn't know how to handle the above, so we have +dnl to help it out. +AH_TEMPLATE(HAVE_GETADDRINFO_PROTO, define if getaddrinfo prototype is in ) +AH_TEMPLATE(HAVE_GETNAMEINFO_PROTO, define if getnameinfo prototype is in ) +AH_TEMPLATE(HAVE_GETHOSTNAME_PROTO, define if gethostname prototype is in ) +AH_TEMPLATE(HAVE_GETRUSAGE_PROTO, define if getrusage prototype is in ) +AH_TEMPLATE(HAVE_HSTRERROR_PROTO, define if hstrerror prototype is in ) +AH_TEMPLATE(HAVE_IF_NAMETOINDEX_PROTO, define if if_nametoindex prototype is in ) +AH_TEMPLATE(HAVE_INET_ATON_PROTO, define if inet_aton prototype is in ) +AH_TEMPLATE(HAVE_INET_PTON_PROTO, define if inet_pton prototype is in ) +AH_TEMPLATE(HAVE_PSELECT_PROTO, define if pselect prototype is in ) +AH_TEMPLATE(HAVE_SNPRINTF_PROTO, define if snprintf prototype is in ) +AH_TEMPLATE(HAVE_SOCKATMARK_PROTO, define if sockatmark prototype is in ) + +dnl ################################################################## +dnl Check for structure definitions. +dnl +AC_CHECK_TYPE(struct addrinfo, + AC_DEFINE(HAVE_ADDRINFO_STRUCT, 1, Define to 1 if defines struct addrinfo),,[ +#include ]) + +dnl +AC_CHECK_TYPE(struct if_nameindex, + AC_DEFINE(HAVE_IF_NAMEINDEX_STRUCT, 1, Define to 1 if defines struct if_nameindex),,[ +#include +#include +#include ]) + +dnl +AC_CHECK_TYPE([struct sockaddr_dl], + AC_DEFINE(HAVE_SOCKADDR_DL_STRUCT, 1, Define to 1 if defines struct sockaddr_dl),,[ +#include +#include +#include ]) + +dnl OpenBSD puts struct timespec in instead of , +dnl thus this complex test. +AC_CHECK_TYPE([struct timespec], + AC_DEFINE(HAVE_TIMESPEC_STRUCT, 1, Define to 1 if or defines struct timespec),,[ +#if TIME_WITH_SYS_TIME +#include +#include +#else +#if HAVE_SYS_TIME_H +#include +#else +#include +#endif +#endif +]) + +dnl ################################################################## +dnl Check for XTI devices. +dnl +AC_MSG_CHECKING(for /dev/tcp) +if test -r /dev/tcp ; then + AC_DEFINE(HAVE_DEV_TCP, 1, Define to 1 if the /dev/tcp device exists) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) + + AC_MSG_CHECKING(for /dev/xti/tcp) + if test -r /dev/xti/tcp ; then + AC_DEFINE(HAVE_DEV_XTI_TCP, 1, Define to 1 if the /dev/xti/tcp device exists) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + + AC_MSG_CHECKING(for /dev/streams/xtiso/tcp) + if test -r /dev/streams/xtiso/tcp ; then + AC_DEFINE(HAVE_DEV_STREAMS_XTISO_TCP, 1, Define to 1 if the /dev/streams/xtiso/tcp device exists) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + fi +fi + +dnl ################################################################## +dnl Checks for library functions. +dnl +AC_CHECK_FUNCS(bzero) +AC_CHECK_FUNCS(getaddrinfo) +AC_CHECK_FUNCS(gethostname) +AC_CHECK_FUNCS(gethostbyname2) +AC_CHECK_FUNCS(gethostbyname_r) +AC_CHECK_FUNCS(getnameinfo) +AC_CHECK_FUNCS(hstrerror) +AC_CHECK_FUNCS(if_nametoindex) +AC_CHECK_FUNCS(inet_aton) +AC_CHECK_FUNCS(inet_pton) +AC_CHECK_FUNCS(inet6_rth_init) +AC_CHECK_FUNCS(kqueue kevent) +AC_CHECK_FUNCS(mkstemp) +AC_CHECK_FUNCS(poll) +AC_CHECK_FUNCS(pselect) +AC_CHECK_FUNCS(snprintf) +AC_CHECK_FUNCS(sockatmark) +AC_CHECK_FUNCS(vsnprintf) + +dnl ################################################################## +dnl Check for system services. + +dnl Let's see if the system really supports IPv4. +dnl +AC_MSG_CHECKING(for IPv4 support) +AC_CACHE_VAL(ac_cv_ipv4, + AC_TRY_RUN([ +# include +# include +# include + /* Make sure the definitions for AF_INET and struct sockaddr_in + * are defined, and that we can actually create an IPv4 TCP socket. + */ + main() + { + int fd; + struct sockaddr_in foo; + fd = socket(AF_INET, SOCK_STREAM, 0); + exit(fd >= 0 ? 0 : 1); + }], + ac_cv_ipv4=yes, + ac_cv_ipv4=no, + ac_cv_ipv4=no)) +AC_MSG_RESULT($ac_cv_ipv4) +if test $ac_cv_ipv4 = yes ; then + AC_DEFINE(IPV4, 1, Define to 1 if the system supports IPv4) + AC_DEFINE(IPv4, 1, Define to 1 if the system supports IPv4) +fi + +dnl Let's see if the system really supports IPv6. +dnl +AC_MSG_CHECKING(for IPv6 support) +AC_CACHE_VAL(ac_cv_ipv6, + AC_TRY_RUN([ +# include +# include +# include + /* Make sure the definitions for AF_INET6 and struct sockaddr_in6 + * are defined, and that we can actually create an IPv6 TCP socket. + */ + main() + { + int fd; + struct sockaddr_in6 foo; + fd = socket(AF_INET6, SOCK_STREAM, 0); + exit(fd >= 0 ? 0 : 1); + }], + ac_cv_ipv6=yes, + ac_cv_ipv6=no, + ac_cv_ipv6=no)) +AC_MSG_RESULT($ac_cv_ipv6) +if test $ac_cv_ipv6 = yes ; then + AC_DEFINE(IPV6, 1, Define to 1 if the system supports IPv6) + AC_DEFINE(IPv6, 1, Define to 1 if the system supports IPv6) +fi + +dnl Let's see if the system really supports Unix domain sockets. +dnl +AC_MSG_CHECKING(for Unix domain sockets) +AC_CACHE_VAL(ac_cv_unixdomain, + AC_TRY_RUN([ +# include +# include +# include + /* Make sure the definitions for AF_UNIX and struct sockaddr_un + * are defined, and that we can actually create an IPv4 TCP socket. + */ + main() + { + int fd; + struct sockaddr_un foo; + fd = socket(AF_UNIX, SOCK_STREAM, 0); + exit(fd >= 0 ? 0 : 1); + }], + ac_cv_unixdomain=yes, + ac_cv_unixdomain=no, + ac_cv_unixdomain=no)) +AC_MSG_RESULT($ac_cv_unixdomain) +if test $ac_cv_unixdomain = yes ; then + AC_DEFINE(UNIXDOMAIN, 1, Define to 1 if the system supports UNIX domain sockets) + AC_DEFINE(UNIXdomain, 1, Define to 1 if the system supports UNIX domain sockets) +fi + +dnl Let's see if the system really supports multicasting. +dnl +AC_MSG_CHECKING(for multicast support) +AC_CACHE_VAL(ac_cv_multicast, + AC_TRY_RUN([ +# include +# include +# include + main() + { + int fd; + unsigned char flag = 1; + struct sockaddr_in foo; + struct ip_mreq mreq; + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) exit(1); + if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, + (void*)&flag, sizeof(flag)) < 0) + exit(1); + exit(0); + }], + ac_cv_multicast=yes, + ac_cv_multicast=no, + ac_cv_multicast=no)) +AC_MSG_RESULT($ac_cv_multicast) +if test $ac_cv_multicast = yes ; then + AC_DEFINE(MCAST, 1, Define to 1 if the system supports IP Multicast) +fi + +dnl ################################################################## +dnl Build the list of object files to build from the source files in +dnl the lib/ directory. +dnl +LIB_OBJS= +LIB_OBJS="$LIB_OBJS connect_nonb.o" +LIB_OBJS="$LIB_OBJS connect_timeo.o" +LIB_OBJS="$LIB_OBJS daemon_inetd.o" +LIB_OBJS="$LIB_OBJS daemon_init.o" +LIB_OBJS="$LIB_OBJS dg_cli.o" +LIB_OBJS="$LIB_OBJS dg_echo.o" +LIB_OBJS="$LIB_OBJS error.o" +LIB_OBJS="$LIB_OBJS get_ifi_info.o" +LIB_OBJS="$LIB_OBJS gf_time.o" +LIB_OBJS="$LIB_OBJS host_serv.o" +if test "$ac_cv_func_hstrerror" = no ; then + LIBFREE_OBJS="$LIBFREE_OBJS hstrerror.o" +fi +if test "$ac_cv_func_if_nametoindex" = no ; then + LIB_OBJS="$LIB_OBJS if_nametoindex.o if_indextoname.o if_nameindex.o" +fi +if test "$ac_cv_multicast" = yes ; then + LIB_OBJS="$LIB_OBJS family_to_level.o" + LIB_OBJS="$LIB_OBJS mcast_leave.o mcast_join.o" + LIB_OBJS="$LIB_OBJS mcast_get_if.o mcast_get_loop.o mcast_get_ttl.o" + LIB_OBJS="$LIB_OBJS mcast_set_if.o mcast_set_loop.o mcast_set_ttl.o" +fi +LIB_OBJS="$LIB_OBJS my_addrs.o" +if test "$ac_cv_func_pselect" = no ; then + LIB_OBJS="$LIB_OBJS pselect.o" +fi +LIB_OBJS="$LIB_OBJS read_fd.o" +LIB_OBJS="$LIB_OBJS readline.o" +LIB_OBJS="$LIB_OBJS readn.o" +LIB_OBJS="$LIB_OBJS readable_timeo.o" +LIB_OBJS="$LIB_OBJS rtt.o" +LIB_OBJS="$LIB_OBJS signal.o" +LIB_OBJS="$LIB_OBJS signal_intr.o" +if test "$ac_cv_func_snprintf" = no ; then + LIB_OBJS="$LIB_OBJS snprintf.o" +fi +if test "$ac_cv_func_sockatmark" = no ; then + LIB_OBJS="$LIB_OBJS sockatmark.o" +fi +LIB_OBJS="$LIB_OBJS sock_bind_wild.o" +LIB_OBJS="$LIB_OBJS sock_cmp_addr.o" +LIB_OBJS="$LIB_OBJS sock_cmp_port.o" +LIB_OBJS="$LIB_OBJS sock_ntop.o" +LIB_OBJS="$LIB_OBJS sock_ntop_host.o" +LIB_OBJS="$LIB_OBJS sock_get_port.o" +LIB_OBJS="$LIB_OBJS sock_set_addr.o" +LIB_OBJS="$LIB_OBJS sock_set_port.o" +LIB_OBJS="$LIB_OBJS sock_set_wild.o" +LIB_OBJS="$LIB_OBJS sockfd_to_family.o" +LIB_OBJS="$LIB_OBJS str_cli.o" +LIB_OBJS="$LIB_OBJS str_echo.o" +LIB_OBJS="$LIB_OBJS tcp_connect.o" +LIB_OBJS="$LIB_OBJS tcp_listen.o" +LIB_OBJS="$LIB_OBJS tv_sub.o" +LIB_OBJS="$LIB_OBJS udp_client.o" +LIB_OBJS="$LIB_OBJS udp_connect.o" +LIB_OBJS="$LIB_OBJS udp_server.o" +LIB_OBJS="$LIB_OBJS wraplib.o" +LIB_OBJS="$LIB_OBJS wrapsock.o" +LIB_OBJS="$LIB_OBJS wrapstdio.o" +if test "$ac_cv_header_pthread_h" = yes ; then + LIB_OBJS="$LIB_OBJS wrappthread.o" +fi +LIB_OBJS="$LIB_OBJS wrapunix.o" +LIB_OBJS="$LIB_OBJS write_fd.o" +LIB_OBJS="$LIB_OBJS writen.o" +LIB_OBJS="$LIB_OBJS writable_timeo.o" + +dnl ################################################################## +dnl Build the list of object files to build from the source files in +dnl the libfree/ directory. +dnl +LIBFREE_OBJS= + +LIBFREE_OBJS="$LIBFREE_OBJS in_cksum.o" +if test "$ac_cv_func_inet_aton" = no ; then + LIBFREE_OBJS="$LIBFREE_OBJS inet_aton.o" +fi + +dnl We always include both inet_ntop() and inet_pton() because some +dnl vendor's implementations are from the Internet Drafts leading to +dnl RFC 1323, and are wrong. +LIBFREE_OBJS="$LIBFREE_OBJS inet_ntop.o inet_pton.o" +dnl if test "$ac_cv_func_inet_pton" = no ; then +dnl LIBFREE_OBJS="$LIBFREE_OBJS inet_pton.o" +dnl fi + +dnl ################################################################## +dnl Build the list of object files to build from the source files in +dnl the libgai/ directory (getaddrinfo() and friends). +dnl +dnl If the system has a getaddrinfo implementation, then +dnl there should be nothing here. +if test "$ac_cv_func_getaddrinfo" = no ; then +LIBGAI_OBJS="getaddrinfo.o getnameinfo.o freeaddrinfo.o gai_strerror.o" +LIBGAI_OBJS="$LIBGAI_OBJS ga_aistruct.o ga_clone.o ga_echeck.o ga_nsearch.o" +LIBGAI_OBJS="$LIBGAI_OBJS ga_port.o ga_serv.o ga_unix.o gn_ipv46.o" +else +LIBGAI_OBJS="" +fi + +dnl ################################################################## +dnl Build the list of object files to build from the source files in +dnl the libroute/ directory (routing socket functions). +dnl +LIBROUTE_OBJS="get_rtaddrs.o" +LIBROUTE_OBJS="$LIBROUTE_OBJS if_indextoname.o if_nameindex.o if_nametoindex.o" +LIBROUTE_OBJS="$LIBROUTE_OBJS net_rt_iflist.o net_rt_dump.o" +LIBROUTE_OBJS="$LIBROUTE_OBJS sock_masktop.o" + +dnl ################################################################## +dnl Build the list of object files to build from the source files in +dnl the libxti/ directory. +dnl Systems that do not provide and do not +dnl support our tcp_XXX and udp_XXX functions. +dnl +LIBXTI_OBJS= +if test "$ac_cv_header_netdir_h" = yes ; then + LIBXTI_OBJS="$LIBXTI_OBJS tcp_connect.o" + LIBXTI_OBJS="$LIBXTI_OBJS tcp_listen.o" + LIBXTI_OBJS="$LIBXTI_OBJS udp_server.o" + LIBXTI_OBJS="$LIBXTI_OBJS udp_client.o" +fi +LIBXTI_OBJS="$LIBXTI_OBJS wrapxti.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_accept.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_flags_str.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_getopt.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_ntop.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_ntop_host.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_rdwr.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_setopt.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_str_opts.o" +LIBXTI_OBJS="$LIBXTI_OBJS xti_tlook_str.o" + +dnl Now make certain that when configure is run, AC_OUTPUT replaces these +dnl strings that we built in shell variables in the output files that +dnl it generates. +dnl +AC_SUBST(LIB_OBJS) +AC_SUBST(LIBFREE_OBJS) +AC_SUBST(LIBGAI_OBJS) +AC_SUBST(LIBROUTE_OBJS) +AC_SUBST(LIBXTI_OBJS) + +dnl We need our own variable LIBS_XTI for linking XTI programs, +dnl but do not want -lsocket in there. +dnl Ditto for -lxti in LIBS. +dnl +LIBS_XTI=`echo $LIBS | sed 's/-lsocket//'` +LIBS=`echo $LIBS | sed 's/-lxti//'` + +AC_SUBST(LIBS_XTI) + +AC_SUBST(LIBUNP) +AC_SUBST(LIBUNPXTI) + +AC_SUBST(LIBUNP_NAME) +AC_SUBST(LIBUNPXTI_NAME) + +dnl ################################################################## +dnl Now that we're doing compiling, modify CFLAGS. +dnl +dnl If the directory $HOME/doc/unp2ev1/src/include exists, the user can +dnl place modified copies of the system's headers in there, with the +dnl function prototypes corrected, as per Posix and X/Open. Lots of +dnl system headers today are missing const qualifiers, they have char* +dnl instead of void*, and so on. +dnl +AC_MSG_CHECKING(for -I$HOME/doc/unp2ev1/src/include) +if test -d $HOME/doc/unp2ev1/src/include ; then + CFLAGS="$CFLAGS -I$HOME/doc/unp2ev1/src/include" + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +dnl If the compiler is gcc, enable all warnings. Main purpose is to +dnl catch any function call where the function has not been prototyped. +dnl +if test "$ac_cv_prog_gcc" = yes; then + CFLAGS="$CFLAGS -Wall" + dnl + dnl These warnings are useful during development, but not to deploy. + dnl CFLAGS="$CFLAGS -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wno-format-extra-args" +fi + +dnl Some system-specific stuff ... +dnl Some operating systems require additional flags in order to get all +dnl the definitions that we're looking for in some system headers. +case "$host_os" in +*aix*) CFLAGS="$CFLAGS -D_ALL_SOURCE" ;; +*osf*) CFLAGS="$CFLAGS -D_SOCKADDR_LEN" ;; +*solaris*) if test "$ac_cv_prog_gcc" = yes; then + CFLAGS="$CFLAGS -D__EXTENSIONS__" + else + CFLAGS="$CFLAGS -D__STDC__" + fi ;; +esac + +dnl ################################################################## +dnl We also create a "Makefile" but it is not used for much. +dnl +AC_OUTPUT(Makefile Make.defines) + +dnl +dnl If a directory exists whose name equals the host +dnl (e.g., sparc-sun-solaris2.5.1), then save the five files that we +dnl create in that directory also. +dnl Quick and dirty to be able to NFS mount this directory on different +dnl systems and move quickly between the systems, without having to +dnl rerun configure each time. +dnl The "myconfig" script in this directory does the move. +dnl +if test -d "$host" ; then + cp -p config.h config.cache config.status Makefile Make.defines $host + echo "saving copies in $host/" +fi diff --git a/debug/Makefile b/debug/Makefile new file mode 100644 index 0000000..bc3eaab --- /dev/null +++ b/debug/Makefile @@ -0,0 +1,32 @@ +include ../Make.defines + +PROGS = qlen backlog test01 test02 test03 test04 test05 test06 + +all: ${PROGS} + +backlog: backlog.o + ${CC} ${CFLAGS} -o $@ backlog.o ${LIBS} + +qlen: qlen.o + ${CC} ${CFLAGS} -o $@ qlen.o ${LIBS_XTI} + +test01: test01.o + ${CC} ${CFLAGS} -o $@ test01.o ${LIBS_XTI} + +test02: test02.o + ${CC} ${CFLAGS} -o $@ test02.o ${LIBS} + +test03: test03.o + ${CC} ${CFLAGS} -o $@ test03.o ${LIBS_XTI} + +test04: test04.o + ${CC} ${CFLAGS} -o $@ test04.o ${LIBS} + +test05: test05.o + ${CC} ${CFLAGS} -o $@ test05.o ${LIBS_XTI} + +test06: test06.o + ${CC} ${CFLAGS} -o $@ test06.o ${LIBS_XTI} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/debug/backlog.c b/debug/backlog.c new file mode 100644 index 0000000..94c1fa4 --- /dev/null +++ b/debug/backlog.c @@ -0,0 +1,99 @@ +#include "unp.h" + +#define PORT 9999 +#define ADDR "127.0.0.1" +#define MAXBACKLOG 100 + + /* globals */ +struct sockaddr_in serv; +pid_t pid; /* of child */ + +int pipefd[2]; +#define pfd pipefd[1] /* parent's end */ +#define cfd pipefd[0] /* child's end */ + + /* function prototypes */ +void do_parent(void); +void do_child(void); + +int +main(int argc, char **argv) +{ + if (argc != 1) + err_quit("usage: backlog"); + + Socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd); + + bzero(&serv, sizeof(serv)); + serv.sin_family = AF_INET; + serv.sin_port = htons(PORT); + Inet_pton(AF_INET, ADDR, &serv.sin_addr); + + if ( (pid = Fork()) == 0) + do_child(); + else + do_parent(); + + exit(0); +} + +void +parent_alrm(int signo) +{ + return; /* just interrupt blocked connect() */ +} + +void +do_parent(void) +{ + int backlog, j, k, junk, fd[MAXBACKLOG + 1]; + + Close(cfd); + Signal(SIGALRM, parent_alrm); + + for (backlog = 0; backlog <= 14; backlog++) { + printf("backlog = %d: ", backlog); + Write(pfd, &backlog, sizeof(int)); /* tell child value */ + Read(pfd, &junk, sizeof(int)); /* wait for child */ + + for (j = 1; j <= MAXBACKLOG; j++) { + fd[j] = Socket(AF_INET, SOCK_STREAM, 0); + alarm(2); + if (connect(fd[j], (SA * ) &serv, sizeof(serv)) < 0) { + if (errno != EINTR) + err_sys("connect error, j = %d", j); + printf("timeout, %d connections completed\n", j-1); + for (k = 1; k <= j; k++) + Close(fd[k]); + break; /* next value of backlog */ + } + alarm(0); + } + if (j > MAXBACKLOG) + printf("%d connections?\n", MAXBACKLOG); + } + backlog = -1; /* tell child we're all done */ + Write(pfd, &backlog, sizeof(int)); +} + +void +do_child(void) +{ + int listenfd, backlog, junk; + const int on = 1; + + Close(pfd); + + Read(cfd, &backlog, sizeof(int)); /* wait for parent */ + while (backlog >= 0) { + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + Bind(listenfd, (SA *) &serv, sizeof(serv)); + Listen(listenfd, backlog); /* start the listen */ + + Write(cfd, &junk, sizeof(int)); /* tell parent */ + + Read(cfd, &backlog, sizeof(int));/* just wait for parent */ + Close(listenfd); /* closes all queued connections, too */ + } +} diff --git a/debug/backlog.lc b/debug/backlog.lc new file mode 100644 index 0000000..f37170c --- /dev/null +++ b/debug/backlog.lc @@ -0,0 +1,99 @@ +#include "unp.h"## 1 ##src/debug/backlog.c## + +#define PORT 9999## 2 ##src/debug/backlog.c## +#define ADDR "127.0.0.1"## 3 ##src/debug/backlog.c## +#define MAXBACKLOG 100## 4 ##src/debug/backlog.c## + + /* globals */## 5 ##src/debug/backlog.c## +struct sockaddr_in serv;## 6 ##src/debug/backlog.c## +pid_t pid; /* of child */## 7 ##src/debug/backlog.c## + +int pipefd[2];## 8 ##src/debug/backlog.c## +#define pfd pipefd[1] /* parent's end */## 9 ##src/debug/backlog.c## +#define cfd pipefd[0] /* child's end */## 10 ##src/debug/backlog.c## + + /* function prototypes */## 11 ##src/debug/backlog.c## +void do_parent(void);## 12 ##src/debug/backlog.c## +void do_child(void);## 13 ##src/debug/backlog.c## + +int## 14 ##src/debug/backlog.c## +main(int argc, char **argv)## 15 ##src/debug/backlog.c## +{## 16 ##src/debug/backlog.c## + if (argc != 1)## 17 ##src/debug/backlog.c## + err_quit("usage: backlog");## 18 ##src/debug/backlog.c## + + Socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd);## 19 ##src/debug/backlog.c## + + bzero(&serv, sizeof(serv));## 20 ##src/debug/backlog.c## + serv.sin_family = AF_INET;## 21 ##src/debug/backlog.c## + serv.sin_port = htons(PORT);## 22 ##src/debug/backlog.c## + Inet_pton(AF_INET, ADDR, &serv.sin_addr);## 23 ##src/debug/backlog.c## + + if ((pid = Fork()) == 0)## 24 ##src/debug/backlog.c## + do_child();## 25 ##src/debug/backlog.c## + else## 26 ##src/debug/backlog.c## + do_parent();## 27 ##src/debug/backlog.c## + + exit(0);## 28 ##src/debug/backlog.c## +}## 29 ##src/debug/backlog.c## + +void## 30 ##src/debug/backlog.c## +parent_alrm(int signo)## 31 ##src/debug/backlog.c## +{## 32 ##src/debug/backlog.c## + return; /* just interrupt blocked connect() */## 33 ##src/debug/backlog.c## +}## 34 ##src/debug/backlog.c## + +void## 35 ##src/debug/backlog.c## +do_parent(void)## 36 ##src/debug/backlog.c## +{## 37 ##src/debug/backlog.c## + int backlog, j, k, junk, fd[MAXBACKLOG + 1];## 38 ##src/debug/backlog.c## + + Close(cfd);## 39 ##src/debug/backlog.c## + Signal(SIGALRM, parent_alrm);## 40 ##src/debug/backlog.c## + + for (backlog = 0; backlog <= 14; backlog++) {## 41 ##src/debug/backlog.c## + printf("backlog = %d: ", backlog);## 42 ##src/debug/backlog.c## + Write(pfd, &backlog, sizeof(int)); /* tell child value */## 43 ##src/debug/backlog.c## + Read(pfd, &junk, sizeof(int)); /* wait for child */## 44 ##src/debug/backlog.c## + + for (j = 1; j <= MAXBACKLOG; j++) {## 45 ##src/debug/backlog.c## + fd[j] = Socket(AF_INET, SOCK_STREAM, 0);## 46 ##src/debug/backlog.c## + alarm(2);## 47 ##src/debug/backlog.c## + if (connect(fd[j], (SA *) &serv, sizeof(serv)) < 0) {## 48 ##src/debug/backlog.c## + if (errno != EINTR)## 49 ##src/debug/backlog.c## + err_sys("connect error, j = %d", j);## 50 ##src/debug/backlog.c## + printf("timeout, %d connections completed\n", j - 1);## 51 ##src/debug/backlog.c## + for (k = 1; k <= j; k++)## 52 ##src/debug/backlog.c## + Close(fd[k]);## 53 ##src/debug/backlog.c## + break; /* next value of backlog */## 54 ##src/debug/backlog.c## + }## 55 ##src/debug/backlog.c## + alarm(0);## 56 ##src/debug/backlog.c## + }## 57 ##src/debug/backlog.c## + if (j > MAXBACKLOG)## 58 ##src/debug/backlog.c## + printf("%d connections?\n", MAXBACKLOG);## 59 ##src/debug/backlog.c## + }## 60 ##src/debug/backlog.c## + backlog = -1; /* tell child we're all done */## 61 ##src/debug/backlog.c## + Write(pfd, &backlog, sizeof(int));## 62 ##src/debug/backlog.c## +}## 63 ##src/debug/backlog.c## + +void## 64 ##src/debug/backlog.c## +do_child(void)## 65 ##src/debug/backlog.c## +{## 66 ##src/debug/backlog.c## + int listenfd, backlog, junk;## 67 ##src/debug/backlog.c## + const int on = 1;## 68 ##src/debug/backlog.c## + + Close(pfd);## 69 ##src/debug/backlog.c## + + Read(cfd, &backlog, sizeof(int)); /* wait for parent */## 70 ##src/debug/backlog.c## + while (backlog >= 0) {## 71 ##src/debug/backlog.c## + listenfd = Socket(AF_INET, SOCK_STREAM, 0);## 72 ##src/debug/backlog.c## + Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 73 ##src/debug/backlog.c## + Bind(listenfd, (SA *) &serv, sizeof(serv));## 74 ##src/debug/backlog.c## + Listen(listenfd, backlog); /* start the listen */## 75 ##src/debug/backlog.c## + + Write(cfd, &junk, sizeof(int)); /* tell parent */## 76 ##src/debug/backlog.c## + + Read(cfd, &backlog, sizeof(int)); /* just wait for parent */## 77 ##src/debug/backlog.c## + Close(listenfd); /* closes all queued connections too */## 78 ##src/debug/backlog.c## + }## 79 ##src/debug/backlog.c## +}## 80 ##src/debug/backlog.c## diff --git a/debug/qlen.c b/debug/qlen.c new file mode 100644 index 0000000..294b9a5 --- /dev/null +++ b/debug/qlen.c @@ -0,0 +1,119 @@ +#include "unpxti.h" + +#define PORT 9999 +#define ADDR "127.0.0.1" +#define MAXBACKLOG 100 + + /* globals */ +struct sockaddr_in serv; +pid_t pid; /* of child */ + +int pipefd[2]; +#define pfd pipefd[1] /* parent's end */ +#define cfd pipefd[0] /* child's end */ + + /* function prototypes */ +void do_parent(void); +void do_child(void); + +int +main(int argc, char **argv) +{ + if (argc != 1) + err_quit("usage: qlen"); + + Socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd); + + bzero(&serv, sizeof(serv)); + serv.sin_family = AF_INET; + serv.sin_port = htons(PORT); + Inet_pton(AF_INET, ADDR, &serv.sin_addr); + + if ( (pid = Fork()) == 0) + do_child(); + else + do_parent(); + + exit(0); +} + +void +parent_alrm(int signo) +{ + return; /* just interrupt blocked connect() */ +} + +/* include qlen */ +void +do_parent(void) +{ + int qlen, j, k, junk, fd[MAXBACKLOG + 1]; + struct t_call tcall; + + Close(cfd); + Signal(SIGALRM, parent_alrm); + + for (qlen = 0; qlen <= 14; qlen++) { + printf("qlen = %d: ", qlen); + Write(pfd, &qlen, sizeof(int)); /* tell child value */ + Read(pfd, &junk, sizeof(int)); /* wait for child */ + + for (j = 0; j <= MAXBACKLOG; j++) { + fd[j] = T_open(XTI_TCP, O_RDWR, NULL); + T_bind(fd[j], NULL, NULL); + + tcall.addr.maxlen = sizeof(serv); + tcall.addr.len = sizeof(serv); + tcall.addr.buf = &serv; + tcall.opt.len = 0; + tcall.udata.len = 0; + + alarm(2); + if (t_connect(fd[j], &tcall, NULL) < 0) { + if (errno != EINTR) + err_xti("t_connect error, j = %d", j); + printf("timeout, %d connections completed\n", j-1); + for (k = 1; k < j; k++) + T_close(fd[k]); + break; /* next value of qlen */ + } + alarm(0); + } + if (j > MAXBACKLOG) + printf("%d connections?\n", MAXBACKLOG); + } + qlen = -1; /* tell child we're all done */ + Write(pfd, &qlen, sizeof(int)); +} + +void +do_child(void) +{ + int listenfd, qlen, junk; + struct t_bind tbind, tbindret; + + Close(pipefd[1]); + + Read(cfd, &qlen, sizeof(int)); /* wait for parent */ + while (qlen >= 0) { + listenfd = T_open(XTI_TCP, O_RDWR, NULL); + + tbind.addr.maxlen = sizeof(serv); + tbind.addr.len = sizeof(serv); + tbind.addr.buf = &serv; + tbind.qlen = qlen; + + tbindret.addr.maxlen = 0; + tbindret.addr.len = 0; + + T_bind(listenfd, &tbind, &tbindret); + printf("returned qlen = %d, ", tbindret.qlen); + fflush(stdout); + + Write(cfd, &junk, sizeof(int)); /* tell parent */ + + Read(cfd, &qlen, sizeof(int)); /* just wait for parent */ + T_close(listenfd); /* closes all queued connections too */ + } +} +/* end qlen */ diff --git a/debug/qlen.lc b/debug/qlen.lc new file mode 100644 index 0000000..1b7cb0d --- /dev/null +++ b/debug/qlen.lc @@ -0,0 +1,119 @@ +#include "unpxti.h"## 1 ##src/debug/qlen.c## + +#define PORT 9999## 2 ##src/debug/qlen.c## +#define ADDR "127.0.0.1"## 3 ##src/debug/qlen.c## +#define MAXBACKLOG 100## 4 ##src/debug/qlen.c## + + /* globals */## 5 ##src/debug/qlen.c## +struct sockaddr_in serv;## 6 ##src/debug/qlen.c## +pid_t pid; /* of child */## 7 ##src/debug/qlen.c## + +int pipefd[2];## 8 ##src/debug/qlen.c## +#define pfd pipefd[1] /* parent's end */## 9 ##src/debug/qlen.c## +#define cfd pipefd[0] /* child's end */## 10 ##src/debug/qlen.c## + + /* function prototypes */## 11 ##src/debug/qlen.c## +void do_parent(void);## 12 ##src/debug/qlen.c## +void do_child(void);## 13 ##src/debug/qlen.c## + +int## 14 ##src/debug/qlen.c## +main(int argc, char **argv)## 15 ##src/debug/qlen.c## +{## 16 ##src/debug/qlen.c## + if (argc != 1)## 17 ##src/debug/qlen.c## + err_quit("usage: qlen");## 18 ##src/debug/qlen.c## + + Socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd);## 19 ##src/debug/qlen.c## + + bzero(&serv, sizeof(serv));## 20 ##src/debug/qlen.c## + serv.sin_family = AF_INET;## 21 ##src/debug/qlen.c## + serv.sin_port = htons(PORT);## 22 ##src/debug/qlen.c## + Inet_pton(AF_INET, ADDR, &serv.sin_addr);## 23 ##src/debug/qlen.c## + + if ((pid = Fork()) == 0)## 24 ##src/debug/qlen.c## + do_child();## 25 ##src/debug/qlen.c## + else## 26 ##src/debug/qlen.c## + do_parent();## 27 ##src/debug/qlen.c## + + exit(0);## 28 ##src/debug/qlen.c## +}## 29 ##src/debug/qlen.c## + +void## 30 ##src/debug/qlen.c## +parent_alrm(int signo)## 31 ##src/debug/qlen.c## +{## 32 ##src/debug/qlen.c## + return; /* just interrupt blocked connect() */## 33 ##src/debug/qlen.c## +}## 34 ##src/debug/qlen.c## + +/* include qlen */ +void## 35 ##src/debug/qlen.c## +do_parent(void)## 36 ##src/debug/qlen.c## +{## 37 ##src/debug/qlen.c## + int qlen, j, k, junk, fd[MAXBACKLOG + 1];## 38 ##src/debug/qlen.c## + struct t_call tcall;## 39 ##src/debug/qlen.c## + + Close(cfd);## 40 ##src/debug/qlen.c## + Signal(SIGALRM, parent_alrm);## 41 ##src/debug/qlen.c## + + for (qlen = 0; qlen <= 14; qlen++) {## 42 ##src/debug/qlen.c## + printf("qlen = %d: ", qlen);## 43 ##src/debug/qlen.c## + Write(pfd, &qlen, sizeof(int)); /* tell child value */## 44 ##src/debug/qlen.c## + Read(pfd, &junk, sizeof(int)); /* wait for child */## 45 ##src/debug/qlen.c## + + for (j = 0; j <= MAXBACKLOG; j++) {## 46 ##src/debug/qlen.c## + fd[j] = T_open(XTI_TCP, O_RDWR, NULL);## 47 ##src/debug/qlen.c## + T_bind(fd[j], NULL, NULL);## 48 ##src/debug/qlen.c## + + tcall.addr.maxlen = sizeof(serv);## 49 ##src/debug/qlen.c## + tcall.addr.len = sizeof(serv);## 50 ##src/debug/qlen.c## + tcall.addr.buf = &serv;## 51 ##src/debug/qlen.c## + tcall.opt.len = 0;## 52 ##src/debug/qlen.c## + tcall.udata.len = 0;## 53 ##src/debug/qlen.c## + + alarm(2);## 54 ##src/debug/qlen.c## + if (t_connect(fd[j], &tcall, NULL) < 0) {## 55 ##src/debug/qlen.c## + if (errno != EINTR)## 56 ##src/debug/qlen.c## + err_xti("t_connect error, j = %d", j);## 57 ##src/debug/qlen.c## + printf("timeout, %d connections completed\n", j - 1);## 58 ##src/debug/qlen.c## + for (k = 1; k < j; k++)## 59 ##src/debug/qlen.c## + T_close(fd[k]);## 60 ##src/debug/qlen.c## + break; /* next value of qlen */## 61 ##src/debug/qlen.c## + }## 62 ##src/debug/qlen.c## + alarm(0);## 63 ##src/debug/qlen.c## + }## 64 ##src/debug/qlen.c## + if (j > MAXBACKLOG)## 65 ##src/debug/qlen.c## + printf("%d connections?\n", MAXBACKLOG);## 66 ##src/debug/qlen.c## + }## 67 ##src/debug/qlen.c## + qlen = -1; /* tell child we're all done */## 68 ##src/debug/qlen.c## + Write(pfd, &qlen, sizeof(int));## 69 ##src/debug/qlen.c## +}## 70 ##src/debug/qlen.c## + +void## 71 ##src/debug/qlen.c## +do_child(void)## 72 ##src/debug/qlen.c## +{## 73 ##src/debug/qlen.c## + int listenfd, qlen, junk;## 74 ##src/debug/qlen.c## + struct t_bind tbind, tbindret;## 75 ##src/debug/qlen.c## + + Close(pipefd[1]);## 76 ##src/debug/qlen.c## + + Read(cfd, &qlen, sizeof(int)); /* wait for parent */## 77 ##src/debug/qlen.c## + while (qlen >= 0) {## 78 ##src/debug/qlen.c## + listenfd = T_open(XTI_TCP, O_RDWR, NULL);## 79 ##src/debug/qlen.c## + + tbind.addr.maxlen = sizeof(serv);## 80 ##src/debug/qlen.c## + tbind.addr.len = sizeof(serv);## 81 ##src/debug/qlen.c## + tbind.addr.buf = &serv;## 82 ##src/debug/qlen.c## + tbind.qlen = qlen;## 83 ##src/debug/qlen.c## + + tbindret.addr.maxlen = 0;## 84 ##src/debug/qlen.c## + tbindret.addr.len = 0;## 85 ##src/debug/qlen.c## + + T_bind(listenfd, &tbind, &tbindret);## 86 ##src/debug/qlen.c## + printf("returned qlen = %d, ", tbindret.qlen);## 87 ##src/debug/qlen.c## + fflush(stdout);## 88 ##src/debug/qlen.c## + + Write(cfd, &junk, sizeof(int)); /* tell parent */## 89 ##src/debug/qlen.c## + + Read(cfd, &qlen, sizeof(int)); /* just wait for parent */## 90 ##src/debug/qlen.c## + T_close(listenfd); /* closes all queued connections too */## 91 ##src/debug/qlen.c## + }## 92 ##src/debug/qlen.c## +}## 93 ##src/debug/qlen.c## +/* end qlen */ diff --git a/debug/test01.c b/debug/test01.c new file mode 100644 index 0000000..1535d1a --- /dev/null +++ b/debug/test01.c @@ -0,0 +1,16 @@ +#include "unpxti.h" + +int +main(int argc, char **argv) +{ + int tfd; + + if (argc != 3) + err_quit("usage: test01 "); + + tfd = Tcp_connect(argv[1], argv[2]); + + t_snd(tfd, "", 1, T_EXPEDITED); + + exit(0); +} diff --git a/debug/test01.lc b/debug/test01.lc new file mode 100644 index 0000000..40a8994 --- /dev/null +++ b/debug/test01.lc @@ -0,0 +1,16 @@ +#include "unpxti.h"## 1 ##src/debug/test01.c## + +int## 2 ##src/debug/test01.c## +main(int argc, char **argv)## 3 ##src/debug/test01.c## +{## 4 ##src/debug/test01.c## + int tfd;## 5 ##src/debug/test01.c## + + if (argc != 3)## 6 ##src/debug/test01.c## + err_quit("usage: test01 ");## 7 ##src/debug/test01.c## + + tfd = Tcp_connect(argv[1], argv[2]);## 8 ##src/debug/test01.c## + + t_snd(tfd, "", 1, T_EXPEDITED);## 9 ##src/debug/test01.c## + + exit(0);## 10 ##src/debug/test01.c## +}## 11 ##src/debug/test01.c## diff --git a/debug/test02.c b/debug/test02.c new file mode 100644 index 0000000..1eab86d --- /dev/null +++ b/debug/test02.c @@ -0,0 +1,19 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int fd; + fd_set exset; + + if (argc != 3) + err_quit("usage: test01 "); + + fd = Tcp_connect(argv[1], argv[2]); + + FD_ZERO(&exset); + FD_SET(fd, &exset); + select(fd+1, NULL, NULL, &exset, NULL); + + exit(0); +} diff --git a/debug/test03.c b/debug/test03.c new file mode 100644 index 0000000..38feda8 --- /dev/null +++ b/debug/test03.c @@ -0,0 +1,28 @@ +#include "unpxti.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd, n, flags; + char buff[MAXLINE]; + struct pollfd fds[1]; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], NULL); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], NULL); + else + err_quit("usage: daytimetcpsrv01 [ ] "); + + connfd = Xti_accept(listenfd, NULL, 0); + + fds[0].fd = connfd; + fds[0].events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI; + for ( ; ; ) { + n = poll(fds, 1, INFTIM); + printf("poll returned %d, revents = 0x%x\n", n, fds[0].revents); + + n = T_rcv(connfd, buff, sizeof(buff), &flags); + printf("received %d bytes, flags = %d\n", n, flags); + } +} diff --git a/debug/test04.c b/debug/test04.c new file mode 100644 index 0000000..4f86b87 --- /dev/null +++ b/debug/test04.c @@ -0,0 +1,64 @@ +#include "unp.h" + +void +sig_alrm(int signo) +{ +} + +int +main(int argc, char **argv) +{ + int sockfd, n; + struct sockaddr_in servaddr; + struct itimerval val; + fd_set rset, wset; + + if (argc != 2) + err_quit("usage: a.out "); + + if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + err_sys("socket error"); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(13); /* echo server */ + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + /* Set interval timer to go off before 3WHS completes */ + Signal(SIGALRM, sig_alrm); + val.it_interval.tv_sec = 0; + val.it_interval.tv_usec = 0; + val.it_value.tv_sec = 0; + val.it_value.tv_usec = 50000; /* 50 ms */ + if (setitimer(ITIMER_REAL, &val, NULL) == -1) + err_sys("setitimer error"); + +again: + if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) { + if (errno == EINTR) { +#ifdef notdef + goto again; /* second call to connect() -> EADDRINUSE */ +#endif +#ifdef notdef + printf("interrupted system call\n"); + exit(0); +#endif + } else + err_sys("connect error"); + } + + FD_ZERO(&rset); + FD_SET(sockfd, &rset); + wset = rset; +sleep(4); + n = Select(sockfd+1, &rset, &wset, NULL, NULL); + printf("select returned %d\n", n); + if (FD_ISSET(sockfd, &rset)) + printf("socket is readable\n"); + if (FD_ISSET(sockfd, &wset)) + printf("socket is writable\n"); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/debug/test05.c b/debug/test05.c new file mode 100644 index 0000000..ab0b41f --- /dev/null +++ b/debug/test05.c @@ -0,0 +1,34 @@ +#include "unpxti.h" + +int listenfd, connfd; + +void +sig_poll(int signo) +{ + int n, flags; + char buff[MAXLINE]; + + printf("SIGPOLL, event = %d\n", t_look(connfd)); + n = T_rcv(connfd, buff, sizeof(buff), &flags); + printf("received %d bytes, flags = %d\n", n, flags); +} + +int +main(int argc, char **argv) +{ + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], NULL); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], NULL); + else + err_quit("usage: test05 [ ] "); + + connfd = Xti_accept(listenfd, NULL, 0); + + Signal(SIGPOLL, sig_poll); + Ioctl(connfd, I_SETSIG, S_RDNORM); + + for ( ; ; ) { + pause(); + } +} diff --git a/debug/test06.c b/debug/test06.c new file mode 100644 index 0000000..0d99456 --- /dev/null +++ b/debug/test06.c @@ -0,0 +1,18 @@ +#include "unpxti.h" + +int +main(int argc, char **argv) +{ + int fd; + struct t_call *tcall; + + fd = T_open(XTI_TCP, O_RDWR, NULL); + + tcall = T_alloc(fd, T_CALL, T_ALL); + printf("first t_alloc OK\n"); + + tcall = T_alloc(fd, T_CALL, T_ADDR | T_OPT | T_UDATA); + printf("second t_alloc OK\n"); + + exit(0); +} diff --git a/debug/unpxti.h b/debug/unpxti.h new file mode 100644 index 0000000..6fe4b18 --- /dev/null +++ b/debug/unpxti.h @@ -0,0 +1,152 @@ +/* include unpxtih1 */ +#ifndef __unp_xti_h +#define __unp_xti_h + +#include "unp.h" + +#include +#ifdef HAVE_XTI_INET_H +# include +#endif +#ifdef HAVE_NETCONFIG_H +# include +#endif +#ifdef HAVE_NETDIR_H +# include +#endif + +#ifdef INFTIM_UNPH +#undef INFTIM /* was not in , undef for */ +#endif + +#include + +/* Provide compatibility with the new names prepended with T_ + in XNS Issue 5, which are not in Posix.1g. */ + +#ifndef T_INET_TCP +#define T_INET_TCP INET_TCP +/* $$.Ic T_INET_TCP$$ */ +#endif +/* end unpxtih1 */ +#ifndef T_INET_UDP +#define T_INET_UDP INET_UDP +#endif +#ifndef T_INET_IP +#define T_INET_IP INET_IP +#endif +#ifndef T_TCP_NODELAY +#define T_TCP_NODELAY TCP_NODELAY +#endif +#ifndef T_TCP_MAXSEG +#define T_TCP_MAXSEG TCP_MAXSEG +#endif +#ifndef T_TCP_KEEPALIVE +#define T_TCP_KEEPALIVE TCP_KEEPALIVE +#endif +#ifndef T_UDP_CHECKSUM +#define T_UDP_CHECKSUM UDP_CHECKSUM +#endif +#ifndef T_IP_OPTIONS +#define T_IP_OPTIONS IP_OPTIONS +#endif +#ifndef T_IP_TOS +#define T_IP_TOS IP_TOS +#endif +#ifndef T_IP_TTL +#define T_IP_TTL IP_TTL +#endif +#ifndef T_IP_REUSEADDR +#define T_IP_REUSEADDR IP_REUSEADDR +#endif +#ifndef T_IP_DONTROUTE +#define T_IP_DONTROUTE IP_DONTROUTE +#endif +/* include unpxtih2 */ +#ifndef T_IP_BROADCAST +#define T_IP_BROADCAST IP_BROADCAST +/* $$.Ic T_IP_BROADCAST$$ */ +#endif + +/* Define the appropriate devices for t_open(). */ +#ifdef HAVE_DEV_TCP +# define XTI_TCP "/dev/tcp" +# define XTI_UDP "/dev/udp" +#endif +#ifdef HAVE_DEV_XTI_TCP +# define XTI_TCP "/dev/xti/tcp" +# define XTI_UDP "/dev/xti/udp" +#endif +#ifdef HAVE_DEV_STREAMS_XTISO_TCP +# define XTI_TCP "/dev/streams/xtiso/tcp+" /* + for XPG4 */ +# define XTI_UDP "/dev/streams/xtiso/udp+" /* + for XPG4 */ +#endif + + /* 4device to t_open() for t_accept(); set by tcp_listen() */ +/* $$.Id xti_serv_dev$$ */ +extern char xti_serv_dev[]; +/* end unpxtih2 */ + +void err_xti(const char *fmt, ...); +void err_xti_ret(const char *fmt, ...); + +int Getmsg(int, struct strbuf *, struct strbuf *, int *); +void Putmsg(int, const struct strbuf *, const struct strbuf *, int); + +#ifdef HAVE_NETCONFIG_H +void *Setnetconfig(void); +void *Setnetpath(void); +#endif + +void *T_alloc(int, int, int); +int T_accept(int, int, struct t_call *); +void T_bind(int, const struct t_bind *, struct t_bind *); +void T_close(int); +void T_connect(int, const struct t_call *, struct t_call *); +void T_free(void *, int); +void T_getprotaddr(int, struct t_bind *, struct t_bind *); +int T_getstate(int); +void T_listen(int, struct t_call *); +int T_look(int); +int T_open(const char *, int, struct t_info *); +void T_optmgmt(int, const struct t_optmgmt *, struct t_optmgmt *); +int T_rcv(int, void *, unsigned int, int *); +void T_rcvdis(int, struct t_discon *); +void T_rcvrel(int); +void T_rcvudata(int, struct t_unitdata *, int *); +void T_rcvuderr(int, struct t_uderr *); +void T_snd(int, void *, unsigned int, int); +void T_sndrel(int); +void T_sndudata(int, struct t_unitdata *); + +int xti_accept(int, struct netbuf *, int); +int xti_getopt(int, int, int, void *, socklen_t *); +char *xti_flags_str(int); +char *xti_tlook_str(int); +char *xti_ntop(const struct netbuf *); +char *xti_ntop_host(const struct netbuf *); +int xti_rdwr(int); +int xti_setopt(int, int, int, void *, socklen_t); + +int Xti_accept(int, struct netbuf *, int); +void Xti_getopt(int, int, int, void *, socklen_t *); +char *Xti_flags_str(int); +char *Xti_tlook_str(int); +char *Xti_ntop(const struct netbuf *); +char *Xti_ntop_host(const struct netbuf *); +void Xti_rdwr(int); +void Xti_setopt(int, int, int, void *, socklen_t); + +char *xti_str_lend(struct t_opthdr *); +char *xti_str_uscalard(struct t_opthdr *); +char *xti_str_uchard(struct t_opthdr *); +char *xti_str_ucharx(struct t_opthdr *); +char *xti_str_yn(t_uscalar_t); +char *xti_str_syng(t_scalar_t); +char *xti_str_uiyn(struct t_opthdr *); +char *xti_str_usyn(struct t_opthdr *); +char *xti_str_linger(struct t_opthdr *); +char *xti_str_kpalive(struct t_opthdr *); +char *xti_str_flags(t_scalar_t); + +#endif /* __unp_xti_h */ diff --git a/icmpd/Makefile b/icmpd/Makefile new file mode 100644 index 0000000..3bf94de --- /dev/null +++ b/icmpd/Makefile @@ -0,0 +1,16 @@ +include ../Make.defines + +OBJS = icmpd.o readable_listen.o readable_conn.o readable_v4.o readable_v6.o + +PROGS = icmpd udpcli01 + +all: ${PROGS} + +icmpd: ${OBJS} + ${CC} ${CFLAGS} -o $@ ${OBJS} ${LIBS} + +udpcli01: udpcli01.o dgcli01.o + ${CC} ${CFLAGS} -o $@ udpcli01.o dgcli01.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/icmpd/dgcli01.c b/icmpd/dgcli01.c new file mode 100644 index 0000000..ae801d6 --- /dev/null +++ b/icmpd/dgcli01.c @@ -0,0 +1,62 @@ +/* include dgcli011 */ +#include "unpicmpd.h" + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int icmpfd, maxfdp1; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + fd_set rset; + ssize_t n; + struct timeval tv; + struct icmpd_err icmpd_err; + struct sockaddr_un sun; + + Sock_bind_wild(sockfd, pservaddr->sa_family); + + icmpfd = Socket(AF_LOCAL, SOCK_STREAM, 0); + sun.sun_family = AF_LOCAL; + strcpy(sun.sun_path, ICMPD_PATH); + Connect(icmpfd, (SA *)&sun, sizeof(sun)); + Write_fd(icmpfd, "1", 1, sockfd); + n = Read(icmpfd, recvline, 1); + if (n != 1 || recvline[0] != '1') + err_quit("error creating icmp socket, n = %d, char = %c", + n, recvline[0]); + + FD_ZERO(&rset); + maxfdp1 = max(sockfd, icmpfd) + 1; +/* end dgcli011 */ + +/* include dgcli012 */ + while (Fgets(sendline, MAXLINE, fp) != NULL) { + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + tv.tv_sec = 5; + tv.tv_usec = 0; + FD_SET(sockfd, &rset); + FD_SET(icmpfd, &rset); + if ( (n = Select(maxfdp1, &rset, NULL, NULL, &tv)) == 0) { + fprintf(stderr, "socket timeout\n"); + continue; + } + + if (FD_ISSET(sockfd, &rset)) { + n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL); + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } + + if (FD_ISSET(icmpfd, &rset)) { + if ( (n = Read(icmpfd, &icmpd_err, sizeof(icmpd_err))) == 0) + err_quit("ICMP daemon terminated"); + else if (n != sizeof(icmpd_err)) + err_quit("n = %d, expected %d", n, sizeof(icmpd_err)); + printf("ICMP error: dest = %s, %s, type = %d, code = %d\n", + Sock_ntop(&icmpd_err.icmpd_dest, icmpd_err.icmpd_len), + strerror(icmpd_err.icmpd_errno), + icmpd_err.icmpd_type, icmpd_err.icmpd_code); + } + } +} +/* end dgcli012 */ diff --git a/icmpd/dgcli01.lc b/icmpd/dgcli01.lc new file mode 100644 index 0000000..f9d7ebc --- /dev/null +++ b/icmpd/dgcli01.lc @@ -0,0 +1,58 @@ +/* include dgcli011 */ +#include "unpicmpd.h"## 1 ##src/icmpd/dgcli01.c## + +void## 2 ##src/icmpd/dgcli01.c## +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)## 3 ##src/icmpd/dgcli01.c## +{## 4 ##src/icmpd/dgcli01.c## + int icmpfd, maxfdp1;## 5 ##src/icmpd/dgcli01.c## + char sendline[MAXLINE], recvline[MAXLINE + 1];## 6 ##src/icmpd/dgcli01.c## + fd_set rset;## 7 ##src/icmpd/dgcli01.c## + ssize_t n;## 8 ##src/icmpd/dgcli01.c## + struct timeval tv;## 9 ##src/icmpd/dgcli01.c## + struct icmpd_err icmpd_err;## 10 ##src/icmpd/dgcli01.c## + + Sock_bind_wild(sockfd, pservaddr->sa_family);## 11 ##src/icmpd/dgcli01.c## + + icmpfd = Tcp_connect("/unix", ICMPD_PATH);## 12 ##src/icmpd/dgcli01.c## + Write_fd(icmpfd, "1", 1, sockfd);## 13 ##src/icmpd/dgcli01.c## + n = Read(icmpfd, recvline, 1);## 14 ##src/icmpd/dgcli01.c## + if (n != 1 || recvline[0] != '1')## 15 ##src/icmpd/dgcli01.c## + err_quit("error creating icmp socket, n = %d, char = %c",## 16 ##src/icmpd/dgcli01.c## + n, recvline[0]);## 17 ##src/icmpd/dgcli01.c## + + FD_ZERO(&rset);## 18 ##src/icmpd/dgcli01.c## + maxfdp1 = max(sockfd, icmpfd) + 1;## 19 ##src/icmpd/dgcli01.c## +/* end dgcli011 */ + +/* include dgcli012 */ + while (Fgets(sendline, MAXLINE, fp) != NULL) {## 20 ##src/icmpd/dgcli01.c## + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);## 21 ##src/icmpd/dgcli01.c## + + tv.tv_sec = 5;## 22 ##src/icmpd/dgcli01.c## + tv.tv_usec = 0;## 23 ##src/icmpd/dgcli01.c## + FD_SET(sockfd, &rset);## 24 ##src/icmpd/dgcli01.c## + FD_SET(icmpfd, &rset);## 25 ##src/icmpd/dgcli01.c## + if ((n = Select(maxfdp1, &rset, NULL, NULL, &tv)) == 0) {## 26 ##src/icmpd/dgcli01.c## + fprintf(stderr, "socket timeout\n");## 27 ##src/icmpd/dgcli01.c## + continue;## 28 ##src/icmpd/dgcli01.c## + }## 29 ##src/icmpd/dgcli01.c## + + if (FD_ISSET(sockfd, &rset)) {## 30 ##src/icmpd/dgcli01.c## + n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);## 31 ##src/icmpd/dgcli01.c## + recvline[n] = 0; /* null terminate */## 32 ##src/icmpd/dgcli01.c## + Fputs(recvline, stdout);## 33 ##src/icmpd/dgcli01.c## + }## 34 ##src/icmpd/dgcli01.c## + + if (FD_ISSET(icmpfd, &rset)) {## 35 ##src/icmpd/dgcli01.c## + if ((n = Read(icmpfd, &icmpd_err, sizeof(icmpd_err))) == 0)## 36 ##src/icmpd/dgcli01.c## + err_quit("ICMP daemon terminated");## 37 ##src/icmpd/dgcli01.c## + else if (n != sizeof(icmpd_err))## 38 ##src/icmpd/dgcli01.c## + err_quit("n = %d, expected %d", n, sizeof(icmpd_err));## 39 ##src/icmpd/dgcli01.c## + printf("ICMP error: dest = %s, %s, type = %d, code = %d\n",## 40 ##src/icmpd/dgcli01.c## + Sock_ntop(&icmpd_err.icmpd_dest, icmpd_err.icmpd_len),## 41 ##src/icmpd/dgcli01.c## + strerror(icmpd_err.icmpd_errno),## 42 ##src/icmpd/dgcli01.c## + icmpd_err.icmpd_type, icmpd_err.icmpd_code);## 43 ##src/icmpd/dgcli01.c## + }## 44 ##src/icmpd/dgcli01.c## + }## 45 ##src/icmpd/dgcli01.c## +}## 46 ##src/icmpd/dgcli01.c## +/* end dgcli012 */ diff --git a/icmpd/icmpd.c b/icmpd/icmpd.c new file mode 100644 index 0000000..e02d2b0 --- /dev/null +++ b/icmpd/icmpd.c @@ -0,0 +1,67 @@ +/* include icmpd1 */ +#include "icmpd.h" + +int +main(int argc, char **argv) +{ + int i, sockfd; + struct sockaddr_un sun; + + if (argc != 1) + err_quit("usage: icmpd"); + + maxi = -1; /* index into client[] array */ + for (i = 0; i < FD_SETSIZE; i++) + client[i].connfd = -1; /* -1 indicates available entry */ + FD_ZERO(&allset); + + fd4 = Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); + FD_SET(fd4, &allset); + maxfd = fd4; + +#ifdef IPV6 + fd6 = Socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + FD_SET(fd6, &allset); + maxfd = max(maxfd, fd6); +#endif + + listenfd = Socket(AF_UNIX, SOCK_STREAM, 0); + sun.sun_family = AF_LOCAL; + strcpy(sun.sun_path, ICMPD_PATH); + unlink(ICMPD_PATH); + Bind(listenfd, (SA *)&sun, sizeof(sun)); + Listen(listenfd, LISTENQ); + FD_SET(listenfd, &allset); + maxfd = max(maxfd, listenfd); +/* end icmpd1 */ + +/* include icmpd2 */ + for ( ; ; ) { + rset = allset; + nready = Select(maxfd+1, &rset, NULL, NULL, NULL); + + if (FD_ISSET(listenfd, &rset)) + if (readable_listen() <= 0) + continue; + + if (FD_ISSET(fd4, &rset)) + if (readable_v4() <= 0) + continue; + +#ifdef IPV6 + if (FD_ISSET(fd6, &rset)) + if (readable_v6() <= 0) + continue; +#endif + + for (i = 0; i <= maxi; i++) { /* check all clients for data */ + if ( (sockfd = client[i].connfd) < 0) + continue; + if (FD_ISSET(sockfd, &rset)) + if (readable_conn(i) <= 0) + break; /* no more readable descriptors */ + } + } + exit(0); +} +/* end icmpd2 */ diff --git a/icmpd/icmpd.h b/icmpd/icmpd.h new file mode 100644 index 0000000..f77e3e0 --- /dev/null +++ b/icmpd/icmpd.h @@ -0,0 +1,19 @@ +#include "unpicmpd.h" + +struct client { + int connfd; /* Unix domain stream socket to client */ + int family; /* AF_INET or AF_INET6 */ + int lport; /* local port bound to client's UDP socket */ + /* network byte ordered */ +} client[FD_SETSIZE]; + + /* 4globals */ +int fd4, fd6, listenfd, maxi, maxfd, nready; +fd_set rset, allset; +struct sockaddr_un cliaddr; + + /* 4function prototypes */ +int readable_conn(int); +int readable_listen(void); +int readable_v4(void); +int readable_v6(void); diff --git a/icmpd/icmpd.lc b/icmpd/icmpd.lc new file mode 100644 index 0000000..9f49428 --- /dev/null +++ b/icmpd/icmpd.lc @@ -0,0 +1,62 @@ +/* include icmpd1 */ +#include "icmpd.h"## 1 ##src/icmpd/icmpd.c## + +int## 2 ##src/icmpd/icmpd.c## +main(int argc, char **argv)## 3 ##src/icmpd/icmpd.c## +{## 4 ##src/icmpd/icmpd.c## + int i, sockfd;## 5 ##src/icmpd/icmpd.c## + + if (argc != 1)## 6 ##src/icmpd/icmpd.c## + err_quit("usage: icmpd");## 7 ##src/icmpd/icmpd.c## + + maxi = -1; /* index into client[] array */## 8 ##src/icmpd/icmpd.c## + for (i = 0; i < FD_SETSIZE; i++)## 9 ##src/icmpd/icmpd.c## + client[i].connfd = -1; /* -1 indicates available entry */## 10 ##src/icmpd/icmpd.c## + FD_ZERO(&allset);## 11 ##src/icmpd/icmpd.c## + + fd4 = Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);## 12 ##src/icmpd/icmpd.c## + FD_SET(fd4, &allset);## 13 ##src/icmpd/icmpd.c## + maxfd = fd4;## 14 ##src/icmpd/icmpd.c## + +#ifdef IPV6## 15 ##src/icmpd/icmpd.c## + fd6 = Socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);## 16 ##src/icmpd/icmpd.c## + FD_SET(fd6, &allset);## 17 ##src/icmpd/icmpd.c## + maxfd = max(maxfd, fd6);## 18 ##src/icmpd/icmpd.c## +#endif## 19 ##src/icmpd/icmpd.c## + + listenfd = Tcp_listen("/unix", ICMPD_PATH, &addrlen);## 20 ##src/icmpd/icmpd.c## + FD_SET(listenfd, &allset);## 21 ##src/icmpd/icmpd.c## + maxfd = max(maxfd, listenfd);## 22 ##src/icmpd/icmpd.c## + cliaddr = Malloc(addrlen);## 23 ##src/icmpd/icmpd.c## +/* end icmpd1 */ + +/* include icmpd2 */ + for (;;) {## 24 ##src/icmpd/icmpd.c## + rset = allset;## 25 ##src/icmpd/icmpd.c## + nready = Select(maxfd + 1, &rset, NULL, NULL, NULL);## 26 ##src/icmpd/icmpd.c## + + if (FD_ISSET(listenfd, &rset))## 27 ##src/icmpd/icmpd.c## + if (readable_listen() <= 0)## 28 ##src/icmpd/icmpd.c## + continue;## 29 ##src/icmpd/icmpd.c## + + if (FD_ISSET(fd4, &rset))## 30 ##src/icmpd/icmpd.c## + if (readable_v4() <= 0)## 31 ##src/icmpd/icmpd.c## + continue;## 32 ##src/icmpd/icmpd.c## + +#ifdef IPV6## 33 ##src/icmpd/icmpd.c## + if (FD_ISSET(fd6, &rset))## 34 ##src/icmpd/icmpd.c## + if (readable_v6() <= 0)## 35 ##src/icmpd/icmpd.c## + continue;## 36 ##src/icmpd/icmpd.c## +#endif## 37 ##src/icmpd/icmpd.c## + + for (i = 0; i <= maxi; i++) { /* check all clients for data */## 38 ##src/icmpd/icmpd.c## + if ((sockfd = client[i].connfd) < 0)## 39 ##src/icmpd/icmpd.c## + continue;## 40 ##src/icmpd/icmpd.c## + if (FD_ISSET(sockfd, &rset))## 41 ##src/icmpd/icmpd.c## + if (readable_conn(i) <= 0)## 42 ##src/icmpd/icmpd.c## + break; /* no more readable descriptors */## 43 ##src/icmpd/icmpd.c## + }## 44 ##src/icmpd/icmpd.c## + }## 45 ##src/icmpd/icmpd.c## + exit(0);## 46 ##src/icmpd/icmpd.c## +}## 47 ##src/icmpd/icmpd.c## +/* end icmpd2 */ diff --git a/icmpd/readable_conn.c b/icmpd/readable_conn.c new file mode 100644 index 0000000..4d4f973 --- /dev/null +++ b/icmpd/readable_conn.c @@ -0,0 +1,56 @@ +/* include readable_conn1 */ +#include "icmpd.h" + +int +readable_conn(int i) +{ + int unixfd, recvfd; + char c; + ssize_t n; + socklen_t len; + struct sockaddr_storage ss; + + unixfd = client[i].connfd; + recvfd = -1; + if ( (n = Read_fd(unixfd, &c, 1, &recvfd)) == 0) { + err_msg("client %d terminated, recvfd = %d", i, recvfd); + goto clientdone; /* client probably terminated */ + } + + /* 4data from client; should be descriptor */ + if (recvfd < 0) { + err_msg("read_fd did not return descriptor"); + goto clienterr; + } +/* end readable_conn1 */ + +/* include readable_conn2 */ + len = sizeof(ss); + if (getsockname(recvfd, (SA *) &ss, &len) < 0) { + err_ret("getsockname error"); + goto clienterr; + } + + client[i].family = ss.ss_family; + if ( (client[i].lport = sock_get_port((SA *)&ss, len)) == 0) { + client[i].lport = sock_bind_wild(recvfd, client[i].family); + if (client[i].lport <= 0) { + err_ret("error binding ephemeral port"); + goto clienterr; + } + } + Write(unixfd, "1", 1); /* tell client all OK */ + Close(recvfd); /* all done with client's UDP socket */ + return(--nready); + +clienterr: + Write(unixfd, "0", 1); /* tell client error occurred */ +clientdone: + Close(unixfd); + if (recvfd >= 0) + Close(recvfd); + FD_CLR(unixfd, &allset); + client[i].connfd = -1; + return(--nready); +} +/* end readable_conn2 */ diff --git a/icmpd/readable_conn.lc b/icmpd/readable_conn.lc new file mode 100644 index 0000000..21be2e7 --- /dev/null +++ b/icmpd/readable_conn.lc @@ -0,0 +1,64 @@ +/* include readable_conn1 */ +#include "icmpd.h"## 1 ##src/icmpd/readable_conn.c## + +int## 2 ##src/icmpd/readable_conn.c## +readable_conn(int i)## 3 ##src/icmpd/readable_conn.c## +{## 4 ##src/icmpd/readable_conn.c## + int unixfd, recvfd;## 5 ##src/icmpd/readable_conn.c## + char c;## 6 ##src/icmpd/readable_conn.c## + ssize_t n;## 7 ##src/icmpd/readable_conn.c## + socklen_t len;## 8 ##src/icmpd/readable_conn.c## + union {## 9 ##src/icmpd/readable_conn.c## + char buf[MAXSOCKADDR];## 10 ##src/icmpd/readable_conn.c## + struct sockaddr sock;## 11 ##src/icmpd/readable_conn.c## + } un;## 12 ##src/icmpd/readable_conn.c## + + unixfd = client[i].connfd;## 13 ##src/icmpd/readable_conn.c## + recvfd = -1;## 14 ##src/icmpd/readable_conn.c## + if ((n = Read_fd(unixfd, &c, 1, &recvfd)) == 0) {## 15 ##src/icmpd/readable_conn.c## + err_msg("client %d terminated, recvfd = %d", i, recvfd);## 16 ##src/icmpd/readable_conn.c## + goto clientdone; /* client probably terminated */## 17 ##src/icmpd/readable_conn.c## + }## 18 ##src/icmpd/readable_conn.c## + + /* 4data from client; should be descriptor */## 19 ##src/icmpd/readable_conn.c## + if (recvfd < 0) {## 20 ##src/icmpd/readable_conn.c## + err_msg("read_fd did not return descriptor");## 21 ##src/icmpd/readable_conn.c## + goto clienterr;## 22 ##src/icmpd/readable_conn.c## + }## 23 ##src/icmpd/readable_conn.c## +/* end readable_conn1 */ + +/* include readable_conn2 */ + len = sizeof(un.buf);## 24 ##src/icmpd/readable_conn.c## + if (getsockname(recvfd, (SA *) un.buf, &len) < 0) {## 25 ##src/icmpd/readable_conn.c## + err_ret("getsockname error");## 26 ##src/icmpd/readable_conn.c## + goto clienterr;## 27 ##src/icmpd/readable_conn.c## + }## 28 ##src/icmpd/readable_conn.c## + + client[i].family = un.sock.sa_family;## 29 ##src/icmpd/readable_conn.c## + if ((client[i].lport = sock_get_port(&un.sock, len)) == 0) {## 30 ##src/icmpd/readable_conn.c## + client[i].lport = sock_bind_wild(recvfd, client[i].family);## 31 ##src/icmpd/readable_conn.c## + if (client[i].lport <= 0) {## 32 ##src/icmpd/readable_conn.c## + err_ret("error binding ephemeral port");## 33 ##src/icmpd/readable_conn.c## + goto clienterr;## 34 ##src/icmpd/readable_conn.c## + }## 35 ##src/icmpd/readable_conn.c## + }## 36 ##src/icmpd/readable_conn.c## + Write(unixfd, "1", 1); /* tell client all OK */## 37 ##src/icmpd/readable_conn.c## + FD_SET(unixfd, &allset);## 38 ##src/icmpd/readable_conn.c## + if (unixfd > maxfd)## 39 ##src/icmpd/readable_conn.c## + maxfd = unixfd;## 40 ##src/icmpd/readable_conn.c## + if (i > maxi)## 41 ##src/icmpd/readable_conn.c## + maxi = i;## 42 ##src/icmpd/readable_conn.c## + Close(recvfd); /* all done with client's UDP socket */## 43 ##src/icmpd/readable_conn.c## + return (--nready);## 44 ##src/icmpd/readable_conn.c## + + clienterr:## 45 ##src/icmpd/readable_conn.c## + Write(unixfd, "0", 1); /* tell client error occurred */## 46 ##src/icmpd/readable_conn.c## + clientdone:## 47 ##src/icmpd/readable_conn.c## + Close(unixfd);## 48 ##src/icmpd/readable_conn.c## + if (recvfd >= 0)## 49 ##src/icmpd/readable_conn.c## + Close(recvfd);## 50 ##src/icmpd/readable_conn.c## + FD_CLR(unixfd, &allset);## 51 ##src/icmpd/readable_conn.c## + client[i].connfd = -1;## 52 ##src/icmpd/readable_conn.c## + return (--nready);## 53 ##src/icmpd/readable_conn.c## +}## 54 ##src/icmpd/readable_conn.c## +/* end readable_conn2 */ diff --git a/icmpd/readable_listen.c b/icmpd/readable_listen.c new file mode 100644 index 0000000..7ec6a52 --- /dev/null +++ b/icmpd/readable_listen.c @@ -0,0 +1,31 @@ +#include "icmpd.h" + +int +readable_listen(void) +{ + int i, connfd; + socklen_t clilen; + + clilen = sizeof(cliaddr); + connfd = Accept(listenfd, (SA *)&cliaddr, &clilen); + + /* 4find first available client[] structure */ + for (i = 0; i < FD_SETSIZE; i++) + if (client[i].connfd < 0) { + client[i].connfd = connfd; /* save descriptor */ + break; + } + if (i == FD_SETSIZE) { + close(connfd); /* can't handle new client, */ + return(--nready); /* rudely close the new connection */ + } + printf("new connection, i = %d, connfd = %d\n", i, connfd); + + FD_SET(connfd, &allset); /* add new descriptor to set */ + if (connfd > maxfd) + maxfd = connfd; /* for select() */ + if (i > maxi) + maxi = i; /* max index in client[] array */ + + return(--nready); +} diff --git a/icmpd/readable_listen.lc b/icmpd/readable_listen.lc new file mode 100644 index 0000000..d65eab1 --- /dev/null +++ b/icmpd/readable_listen.lc @@ -0,0 +1,29 @@ +#include "icmpd.h"## 1 ##src/icmpd/readable_listen.c## + +int## 2 ##src/icmpd/readable_listen.c## +readable_listen(void)## 3 ##src/icmpd/readable_listen.c## +{## 4 ##src/icmpd/readable_listen.c## + int i, connfd;## 5 ##src/icmpd/readable_listen.c## + socklen_t clilen;## 6 ##src/icmpd/readable_listen.c## + + clilen = addrlen;## 7 ##src/icmpd/readable_listen.c## + connfd = Accept(listenfd, cliaddr, &clilen);## 8 ##src/icmpd/readable_listen.c## + + /* 4find first available client[] structure */## 9 ##src/icmpd/readable_listen.c## + for (i = 0; i < FD_SETSIZE; i++)## 10 ##src/icmpd/readable_listen.c## + if (client[i].connfd < 0) {## 11 ##src/icmpd/readable_listen.c## + client[i].connfd = connfd; /* save descriptor */## 12 ##src/icmpd/readable_listen.c## + break;## 13 ##src/icmpd/readable_listen.c## + }## 14 ##src/icmpd/readable_listen.c## + if (i == FD_SETSIZE)## 15 ##src/icmpd/readable_listen.c## + err_quit("too many clients");## 16 ##src/icmpd/readable_listen.c## + printf("new connection, i = %d, connfd = %d\n", i, connfd);## 17 ##src/icmpd/readable_listen.c## + + FD_SET(connfd, &allset); /* add new descriptor to set */## 18 ##src/icmpd/readable_listen.c## + if (connfd > maxfd)## 19 ##src/icmpd/readable_listen.c## + maxfd = connfd; /* for select() */## 20 ##src/icmpd/readable_listen.c## + if (i > maxi)## 21 ##src/icmpd/readable_listen.c## + maxi = i; /* max index in client[] array */## 22 ##src/icmpd/readable_listen.c## + + return (--nready);## 23 ##src/icmpd/readable_listen.c## +}## 24 ##src/icmpd/readable_listen.c## diff --git a/icmpd/readable_v4.c b/icmpd/readable_v4.c new file mode 100644 index 0000000..29f068a --- /dev/null +++ b/icmpd/readable_v4.c @@ -0,0 +1,90 @@ +/* include readable_v41 */ +#include "icmpd.h" +#include +#include +#include +#include + +int +readable_v4(void) +{ + int i, hlen1, hlen2, icmplen, sport; + char buf[MAXLINE]; + char srcstr[INET_ADDRSTRLEN], dststr[INET_ADDRSTRLEN]; + ssize_t n; + socklen_t len; + struct ip *ip, *hip; + struct icmp *icmp; + struct udphdr *udp; + struct sockaddr_in from, dest; + struct icmpd_err icmpd_err; + + len = sizeof(from); + n = Recvfrom(fd4, buf, MAXLINE, 0, (SA *) &from, &len); + + printf("%d bytes ICMPv4 from %s:", + n, Sock_ntop_host((SA *) &from, len)); + + ip = (struct ip *) buf; /* start of IP header */ + hlen1 = ip->ip_hl << 2; /* length of IP header */ + + icmp = (struct icmp *) (buf + hlen1); /* start of ICMP header */ + if ( (icmplen = n - hlen1) < 8) + err_quit("icmplen (%d) < 8", icmplen); + + printf(" type = %d, code = %d\n", icmp->icmp_type, icmp->icmp_code); +/* end readable_v41 */ + +/* include readable_v42 */ + if (icmp->icmp_type == ICMP_UNREACH || + icmp->icmp_type == ICMP_TIMXCEED || + icmp->icmp_type == ICMP_SOURCEQUENCH) { + if (icmplen < 8 + 20 + 8) + err_quit("icmplen (%d) < 8 + 20 + 8", icmplen); + + hip = (struct ip *) (buf + hlen1 + 8); + hlen2 = hip->ip_hl << 2; + printf("\tsrcip = %s, dstip = %s, proto = %d\n", + Inet_ntop(AF_INET, &hip->ip_src, srcstr, sizeof(srcstr)), + Inet_ntop(AF_INET, &hip->ip_dst, dststr, sizeof(dststr)), + hip->ip_p); + if (hip->ip_p == IPPROTO_UDP) { + udp = (struct udphdr *) (buf + hlen1 + 8 + hlen2); + sport = udp->uh_sport; + + /* 4find client's Unix domain socket, send headers */ + for (i = 0; i <= maxi; i++) { + if (client[i].connfd >= 0 && + client[i].family == AF_INET && + client[i].lport == sport) { + + bzero(&dest, sizeof(dest)); + dest.sin_family = AF_INET; +#ifdef HAVE_SOCKADDR_SA_LEN + dest.sin_len = sizeof(dest); +#endif + memcpy(&dest.sin_addr, &hip->ip_dst, + sizeof(struct in_addr)); + dest.sin_port = udp->uh_dport; + + icmpd_err.icmpd_type = icmp->icmp_type; + icmpd_err.icmpd_code = icmp->icmp_code; + icmpd_err.icmpd_len = sizeof(struct sockaddr_in); + memcpy(&icmpd_err.icmpd_dest, &dest, sizeof(dest)); + + /* 4convert type & code to reasonable errno value */ + icmpd_err.icmpd_errno = EHOSTUNREACH; /* default */ + if (icmp->icmp_type == ICMP_UNREACH) { + if (icmp->icmp_code == ICMP_UNREACH_PORT) + icmpd_err.icmpd_errno = ECONNREFUSED; + else if (icmp->icmp_code == ICMP_UNREACH_NEEDFRAG) + icmpd_err.icmpd_errno = EMSGSIZE; + } + Write(client[i].connfd, &icmpd_err, sizeof(icmpd_err)); + } + } + } + } + return(--nready); +} +/* end readable_v42 */ diff --git a/icmpd/readable_v4.lc b/icmpd/readable_v4.lc new file mode 100644 index 0000000..6ae8d5b --- /dev/null +++ b/icmpd/readable_v4.lc @@ -0,0 +1,89 @@ +/* include readable_v41 */ +#include "icmpd.h"## 1 ##src/icmpd/readable_v4.c## +#include ## 2 ##src/icmpd/readable_v4.c## +#include ## 3 ##src/icmpd/readable_v4.c## +#include ## 4 ##src/icmpd/readable_v4.c## +#include ## 5 ##src/icmpd/readable_v4.c## + +int## 6 ##src/icmpd/readable_v4.c## +readable_v4(void)## 7 ##src/icmpd/readable_v4.c## +{## 8 ##src/icmpd/readable_v4.c## + int i, hlen1, hlen2, icmplen, sport;## 9 ##src/icmpd/readable_v4.c## + char buf[MAXLINE];## 10 ##src/icmpd/readable_v4.c## + char srcstr[INET_ADDRSTRLEN], dststr[INET_ADDRSTRLEN];## 11 ##src/icmpd/readable_v4.c## + ssize_t n;## 12 ##src/icmpd/readable_v4.c## + socklen_t len;## 13 ##src/icmpd/readable_v4.c## + struct ip *ip, *hip;## 14 ##src/icmpd/readable_v4.c## + struct icmp *icmp;## 15 ##src/icmpd/readable_v4.c## + struct udphdr *udp;## 16 ##src/icmpd/readable_v4.c## + struct sockaddr_in from, dest;## 17 ##src/icmpd/readable_v4.c## + struct icmpd_err icmpd_err;## 18 ##src/icmpd/readable_v4.c## + + len = sizeof(from);## 19 ##src/icmpd/readable_v4.c## + n = Recvfrom(fd4, buf, MAXLINE, 0, (SA *) &from, &len);## 20 ##src/icmpd/readable_v4.c## + + printf("%d bytes ICMPv4 from %s:", n, Sock_ntop_host((SA *) &from, len));## 21 ##src/icmpd/readable_v4.c## + + ip = (struct ip *) buf; /* start of IP header */## 22 ##src/icmpd/readable_v4.c## + hlen1 = ip->ip_hl << 2; /* length of IP header */## 23 ##src/icmpd/readable_v4.c## + + icmp = (struct icmp *) (buf + hlen1); /* start of ICMP header */## 24 ##src/icmpd/readable_v4.c## + if ((icmplen = n - hlen1) < 8)## 25 ##src/icmpd/readable_v4.c## + err_quit("icmplen (%d) < 8", icmplen);## 26 ##src/icmpd/readable_v4.c## + + printf(" type = %d, code = %d\n", icmp->icmp_type, icmp->icmp_code);## 27 ##src/icmpd/readable_v4.c## +/* end readable_v41 */ + +/* include readable_v42 */ + if (icmp->icmp_type == ICMP_UNREACH ||## 28 ##src/icmpd/readable_v4.c## + icmp->icmp_type == ICMP_TIMXCEED ||## 29 ##src/icmpd/readable_v4.c## + icmp->icmp_type == ICMP_SOURCEQUENCH) {## 30 ##src/icmpd/readable_v4.c## + if (icmplen < 8 + 20 + 8)## 31 ##src/icmpd/readable_v4.c## + err_quit("icmplen (%d) < 8 + 20 + 8", icmplen);## 32 ##src/icmpd/readable_v4.c## + + hip = (struct ip *) (buf + hlen1 + 8);## 33 ##src/icmpd/readable_v4.c## + hlen2 = hip->ip_hl << 2;## 34 ##src/icmpd/readable_v4.c## + printf("\tsrcip = %s, dstip = %s, proto = %d\n",## 35 ##src/icmpd/readable_v4.c## + Inet_ntop(AF_INET, &hip->ip_src, srcstr, sizeof(srcstr)),## 36 ##src/icmpd/readable_v4.c## + Inet_ntop(AF_INET, &hip->ip_dst, dststr, sizeof(dststr)),## 37 ##src/icmpd/readable_v4.c## + hip->ip_p);## 38 ##src/icmpd/readable_v4.c## + if (hip->ip_p == IPPROTO_UDP) {## 39 ##src/icmpd/readable_v4.c## + udp = (struct udphdr *) (buf + hlen1 + 8 + hlen2);## 40 ##src/icmpd/readable_v4.c## + sport = udp->uh_sport;## 41 ##src/icmpd/readable_v4.c## + + /* 4find client's Unix domain socket, send headers */## 42 ##src/icmpd/readable_v4.c## + for (i = 0; i <= maxi; i++) {## 43 ##src/icmpd/readable_v4.c## + if (client[i].connfd >= 0 &&## 44 ##src/icmpd/readable_v4.c## + client[i].family == AF_INET &&## 45 ##src/icmpd/readable_v4.c## + client[i].lport == sport) {## 46 ##src/icmpd/readable_v4.c## + + bzero(&dest, sizeof(dest));## 47 ##src/icmpd/readable_v4.c## + dest.sin_family = AF_INET;## 48 ##src/icmpd/readable_v4.c## +#ifdef HAVE_SOCKADDR_SA_LEN## 49 ##src/icmpd/readable_v4.c## + dest.sin_len = sizeof(dest);## 50 ##src/icmpd/readable_v4.c## +#endif## 51 ##src/icmpd/readable_v4.c## + memcpy(&dest.sin_addr, &hip->ip_dst,## 52 ##src/icmpd/readable_v4.c## + sizeof(struct in_addr));## 53 ##src/icmpd/readable_v4.c## + dest.sin_port = udp->uh_dport;## 54 ##src/icmpd/readable_v4.c## + + icmpd_err.icmpd_type = icmp->icmp_type;## 55 ##src/icmpd/readable_v4.c## + icmpd_err.icmpd_code = icmp->icmp_code;## 56 ##src/icmpd/readable_v4.c## + icmpd_err.icmpd_len = sizeof(struct sockaddr_in);## 57 ##src/icmpd/readable_v4.c## + memcpy(&icmpd_err.icmpd_dest, &dest, sizeof(dest));## 58 ##src/icmpd/readable_v4.c## + + /* 4convert type & code to reasonable errno value */## 59 ##src/icmpd/readable_v4.c## + icmpd_err.icmpd_errno = EHOSTUNREACH; /* default */## 60 ##src/icmpd/readable_v4.c## + if (icmp->icmp_type == ICMP_UNREACH) {## 61 ##src/icmpd/readable_v4.c## + if (icmp->icmp_code == ICMP_UNREACH_PORT)## 62 ##src/icmpd/readable_v4.c## + icmpd_err.icmpd_errno = ECONNREFUSED;## 63 ##src/icmpd/readable_v4.c## + else if (icmp->icmp_code == ICMP_UNREACH_NEEDFRAG)## 64 ##src/icmpd/readable_v4.c## + icmpd_err.icmpd_errno = EMSGSIZE;## 65 ##src/icmpd/readable_v4.c## + }## 66 ##src/icmpd/readable_v4.c## + Write(client[i].connfd, &icmpd_err, sizeof(icmpd_err));## 67 ##src/icmpd/readable_v4.c## + }## 68 ##src/icmpd/readable_v4.c## + }## 69 ##src/icmpd/readable_v4.c## + }## 70 ##src/icmpd/readable_v4.c## + }## 71 ##src/icmpd/readable_v4.c## + return (--nready);## 72 ##src/icmpd/readable_v4.c## +}## 73 ##src/icmpd/readable_v4.c## +/* end readable_v42 */ diff --git a/icmpd/readable_v6.c b/icmpd/readable_v6.c new file mode 100644 index 0000000..48f058d --- /dev/null +++ b/icmpd/readable_v6.c @@ -0,0 +1,93 @@ +/* include readable_v61 */ +#include "icmpd.h" +#include +#include +#include +#include + +#ifdef IPV6 +#include +#include +#endif + +int +readable_v6(void) +{ +#ifdef IPV6 + int i, hlen2, icmp6len, sport; + char buf[MAXLINE]; + char srcstr[INET6_ADDRSTRLEN], dststr[INET6_ADDRSTRLEN]; + ssize_t n; + socklen_t len; + struct ip6_hdr *ip6, *hip6; + struct icmp6_hdr *icmp6; + struct udphdr *udp; + struct sockaddr_in6 from, dest; + struct icmpd_err icmpd_err; + + len = sizeof(from); + n = Recvfrom(fd6, buf, MAXLINE, 0, (SA *) &from, &len); + + printf("%d bytes ICMPv6 from %s:", + n, Sock_ntop_host((SA *) &from, len)); + + icmp6 = (struct icmp6_hdr *) buf; /* start of ICMPv6 header */ + if ( (icmp6len = n) < 8) + err_quit("icmp6len (%d) < 8", icmp6len); + + printf(" type = %d, code = %d\n", icmp6->icmp6_type, icmp6->icmp6_code); +/* end readable_v61 */ + +/* include readable_v62 */ + if (icmp6->icmp6_type == ICMP6_DST_UNREACH || + icmp6->icmp6_type == ICMP6_PACKET_TOO_BIG || + icmp6->icmp6_type == ICMP6_TIME_EXCEEDED) { + if (icmp6len < 8 + 8) + err_quit("icmp6len (%d) < 8 + 8", icmp6len); + + hip6 = (struct ip6_hdr *) (buf + 8); + hlen2 = sizeof(struct ip6_hdr); + printf("\tsrcip = %s, dstip = %s, next hdr = %d\n", + Inet_ntop(AF_INET6, &hip6->ip6_src, srcstr, sizeof(srcstr)), + Inet_ntop(AF_INET6, &hip6->ip6_dst, dststr, sizeof(dststr)), + hip6->ip6_nxt); + if (hip6->ip6_nxt == IPPROTO_UDP) { + udp = (struct udphdr *) (buf + 8 + hlen2); + sport = udp->uh_sport; + + /* 4find client's Unix domain socket, send headers */ + for (i = 0; i <= maxi; i++) { + if (client[i].connfd >= 0 && + client[i].family == AF_INET6 && + client[i].lport == sport) { + + bzero(&dest, sizeof(dest)); + dest.sin6_family = AF_INET6; +#ifdef HAVE_SOCKADDR_SA_LEN + dest.sin6_len = sizeof(dest); +#endif + memcpy(&dest.sin6_addr, &hip6->ip6_dst, + sizeof(struct in6_addr)); + dest.sin6_port = udp->uh_dport; + + icmpd_err.icmpd_type = icmp6->icmp6_type; + icmpd_err.icmpd_code = icmp6->icmp6_code; + icmpd_err.icmpd_len = sizeof(struct sockaddr_in6); + memcpy(&icmpd_err.icmpd_dest, &dest, sizeof(dest)); + + /* 4convert type & code to reasonable errno value */ + icmpd_err.icmpd_errno = EHOSTUNREACH; /* default */ + if (icmp6->icmp6_type == ICMP6_DST_UNREACH && + icmp6->icmp6_code == ICMP6_DST_UNREACH_NOPORT) + icmpd_err.icmpd_errno = ECONNREFUSED; + if (icmp6->icmp6_type == ICMP6_PACKET_TOO_BIG) + icmpd_err.icmpd_errno = EMSGSIZE; + Write(client[i].connfd, &icmpd_err, sizeof(icmpd_err)); + } + } + } + } + return(--nready); +#endif +} +/* end readable_v62 */ diff --git a/icmpd/readable_v6.lc b/icmpd/readable_v6.lc new file mode 100644 index 0000000..0211b50 --- /dev/null +++ b/icmpd/readable_v6.lc @@ -0,0 +1,98 @@ +/* include readable_v61 */ +#include "icmpd.h"## 1 ##src/icmpd/readable_v6.c## +#include ## 2 ##src/icmpd/readable_v6.c## +#include ## 3 ##src/icmpd/readable_v6.c## +#include ## 4 ##src/icmpd/readable_v6.c## +#include ## 5 ##src/icmpd/readable_v6.c## + +#ifdef IPV6## 6 ##src/icmpd/readable_v6.c## +#include ## 7 ##src/icmpd/readable_v6.c## +#include ## 8 ##src/icmpd/readable_v6.c## +#endif## 9 ##src/icmpd/readable_v6.c## + +int## 10 ##src/icmpd/readable_v6.c## +readable_v6(void)## 11 ##src/icmpd/readable_v6.c## +{## 12 ##src/icmpd/readable_v6.c## +#ifdef IPV6## 13 ##src/icmpd/readable_v6.c## + int i, hlen1, hlen2, icmp6len, sport;## 14 ##src/icmpd/readable_v6.c## + char buf[MAXLINE];## 15 ##src/icmpd/readable_v6.c## + char srcstr[INET6_ADDRSTRLEN], dststr[INET6_ADDRSTRLEN];## 16 ##src/icmpd/readable_v6.c## + ssize_t n;## 17 ##src/icmpd/readable_v6.c## + socklen_t len;## 18 ##src/icmpd/readable_v6.c## + struct ip6_hdr *ip6, *hip6;## 19 ##src/icmpd/readable_v6.c## + struct icmp6_hdr *icmp6;## 20 ##src/icmpd/readable_v6.c## + struct udphdr *udp;## 21 ##src/icmpd/readable_v6.c## + struct sockaddr_in6 from, dest;## 22 ##src/icmpd/readable_v6.c## + struct icmpd_err icmpd_err;## 23 ##src/icmpd/readable_v6.c## + + len = sizeof(from);## 24 ##src/icmpd/readable_v6.c## + n = Recvfrom(fd6, buf, MAXLINE, 0, (SA *) &from, &len);## 25 ##src/icmpd/readable_v6.c## + + printf("%d bytes ICMPv6 from %s:", n, Sock_ntop_host((SA *) &from, len));## 26 ##src/icmpd/readable_v6.c## + + ip6 = (struct ip6_hdr *) buf; /* start of IPv6 header */## 27 ##src/icmpd/readable_v6.c## + hlen1 = sizeof(struct ip6_hdr);## 28 ##src/icmpd/readable_v6.c## + if (ip6->ip6_nxt != IPPROTO_ICMPV6)## 29 ##src/icmpd/readable_v6.c## + err_quit("next header not IPPROTO_ICMPV6");## 30 ##src/icmpd/readable_v6.c## + + icmp6 = (struct icmp6_hdr *) (buf + hlen1);## 31 ##src/icmpd/readable_v6.c## + if ((icmp6len = n - hlen1) < 8)## 32 ##src/icmpd/readable_v6.c## + err_quit("icmp6len (%d) < 8", icmp6len);## 33 ##src/icmpd/readable_v6.c## + + printf(" type = %d, code = %d\n", icmp6->icmp6_type, icmp6->icmp6_code);## 34 ##src/icmpd/readable_v6.c## +/* end readable_v61 */ + +/* include readable_v62 */ + if (icmp6->icmp6_type == ICMP6_DST_UNREACH ||## 35 ##src/icmpd/readable_v6.c## + icmp6->icmp6_type == ICMP6_PACKET_TOO_BIG ||## 36 ##src/icmpd/readable_v6.c## + icmp6->icmp6_type == ICMP6_TIME_EXCEEDED) {## 37 ##src/icmpd/readable_v6.c## + if (icmp6len < 8 + 40 + 8)## 38 ##src/icmpd/readable_v6.c## + err_quit("icmp6len (%d) < 8 + 40 + 8", icmp6len);## 39 ##src/icmpd/readable_v6.c## + + hip6 = (struct ip6_hdr *) (buf + hlen1 + 8);## 40 ##src/icmpd/readable_v6.c## + hlen2 = sizeof(struct ip6_hdr);## 41 ##src/icmpd/readable_v6.c## + printf("\tsrcip = %s, dstip = %s, next hdr = %d\n",## 42 ##src/icmpd/readable_v6.c## + Inet_ntop(AF_INET6, &hip6->ip6_src, srcstr, sizeof(srcstr)),## 43 ##src/icmpd/readable_v6.c## + Inet_ntop(AF_INET6, &hip6->ip6_dst, dststr, sizeof(dststr)),## 44 ##src/icmpd/readable_v6.c## + hip6->ip6_nxt);## 45 ##src/icmpd/readable_v6.c## + if (hip6->ip6_nxt == IPPROTO_UDP) {## 46 ##src/icmpd/readable_v6.c## + udp = (struct udphdr *) (buf + hlen1 + 8 + hlen2);## 47 ##src/icmpd/readable_v6.c## + sport = udp->uh_sport;## 48 ##src/icmpd/readable_v6.c## + + /* 4find client's Unix domain socket, send headers */## 49 ##src/icmpd/readable_v6.c## + for (i = 0; i <= maxi; i++) {## 50 ##src/icmpd/readable_v6.c## + if (client[i].connfd >= 0 &&## 51 ##src/icmpd/readable_v6.c## + client[i].family == AF_INET6 &&## 52 ##src/icmpd/readable_v6.c## + client[i].lport == sport) {## 53 ##src/icmpd/readable_v6.c## + + bzero(&dest, sizeof(dest));## 54 ##src/icmpd/readable_v6.c## + dest.sin6_family = AF_INET6;## 55 ##src/icmpd/readable_v6.c## +#ifdef HAVE_SOCKADDR_SA_LEN## 56 ##src/icmpd/readable_v6.c## + dest.sin6_len = sizeof(dest);## 57 ##src/icmpd/readable_v6.c## +#endif## 58 ##src/icmpd/readable_v6.c## + memcpy(&dest.sin6_addr, &hip6->ip6_dst,## 59 ##src/icmpd/readable_v6.c## + sizeof(struct in6_addr));## 60 ##src/icmpd/readable_v6.c## + dest.sin6_port = udp->uh_dport;## 61 ##src/icmpd/readable_v6.c## + + icmpd_err.icmpd_type = icmp6->icmp6_type;## 62 ##src/icmpd/readable_v6.c## + icmpd_err.icmpd_code = icmp6->icmp6_code;## 63 ##src/icmpd/readable_v6.c## + icmpd_err.icmpd_len = sizeof(struct sockaddr_in6);## 64 ##src/icmpd/readable_v6.c## + memcpy(&icmpd_err.icmpd_dest, &dest, sizeof(dest));## 65 ##src/icmpd/readable_v6.c## + + /* 4convert type & code to reasonable errno value */## 66 ##src/icmpd/readable_v6.c## + icmpd_err.icmpd_errno = EHOSTUNREACH; /* default */## 67 ##src/icmpd/readable_v6.c## + if (icmp6->icmp6_type == ICMP6_DST_UNREACH) {## 68 ##src/icmpd/readable_v6.c## + if (icmp6->icmp6_code == ICMP_UNREACH_PORT)## 69 ##src/icmpd/readable_v6.c## + icmpd_err.icmpd_errno = ECONNREFUSED;## 70 ##src/icmpd/readable_v6.c## + else if (icmp6->icmp6_code == ICMP_UNREACH_NEEDFRAG)## 71 ##src/icmpd/readable_v6.c## + icmpd_err.icmpd_errno = EMSGSIZE;## 72 ##src/icmpd/readable_v6.c## + }## 73 ##src/icmpd/readable_v6.c## + Write(client[i].connfd, &icmpd_err, sizeof(icmpd_err));## 74 ##src/icmpd/readable_v6.c## + }## 75 ##src/icmpd/readable_v6.c## + }## 76 ##src/icmpd/readable_v6.c## + }## 77 ##src/icmpd/readable_v6.c## + }## 78 ##src/icmpd/readable_v6.c## + return (--nready);## 79 ##src/icmpd/readable_v6.c## +#endif## 80 ##src/icmpd/readable_v6.c## +}## 81 ##src/icmpd/readable_v6.c## +/* end readable_v62 */ diff --git a/icmpd/script.1 b/icmpd/script.1 new file mode 100644 index 0000000..7e6cd69 --- /dev/null +++ b/icmpd/script.1 @@ -0,0 +1,14 @@ +kalae % ./udpcli01 198.82.204.99 echo +hello, world +ICMP error: type = 11, code = 0 +testing +ICMP error: type = 11, code = 0 + +kalae % ./udpcli01 gemini.tuc.noao.edu echo +hi there +ICMP error: type = 3, code = 3 +hello +socket timeout +testing +ICMP error: type = 3, code = 3 + diff --git a/icmpd/script.2 b/icmpd/script.2 new file mode 100644 index 0000000..3b0542e --- /dev/null +++ b/icmpd/script.2 @@ -0,0 +1,12 @@ +kalae % ./udpcli01 gemini.tuc.noao.edu echo +hi there +ICMPv4 error: dest = 140.252.8.54.1792, type = 3, code = 3 + + +kalae % ./udpcli01 198.82.204.99 echo +hello, world +ICMPv4 error: dest = 198.82.204.99.1792, type = 11, code = 0 +testing +ICMPv4 error: dest = 198.82.204.99.1792, type = 11, code = 0 + + diff --git a/icmpd/script.3 b/icmpd/script.3 new file mode 100644 index 0000000..81ec8ee --- /dev/null +++ b/icmpd/script.3 @@ -0,0 +1,16 @@ +kohala % ./udpcli01 gemini.tuc.noao.edu echo +hello, world +ICMP error: dest = 140.252.1.11.7, type = 3, code = 3 +kohala % +kohala % ./udpcli 198.82.204.99 echo +ksh: ./udpcli: not found +kohala % ./udpcli01 198.82.204.99 echo +hello, world +ICMP error: dest = 198.82.204.99.7, type = 3, code = 3 +kohala % ./udpcli01 192.3.4.5.82.204.99 echo +udp_client error for 192.3.4.5.82.204.99, echo: host nor service provided, or not known +kohala % ./udpcli01 192.3.4.5 echo +hello +ICMP error: dest = 192.3.4.5.7, type = 3, code = 1 + + diff --git a/icmpd/script.4 b/icmpd/script.4 new file mode 100644 index 0000000..cee9ba7 --- /dev/null +++ b/icmpd/script.4 @@ -0,0 +1,12 @@ +kohala % ./udpcli01 192.3.4.5 echo +hi there +socket timeout +and hello +socket timeout +kohala % ./udpcli01 gemini.tuc.noao.edu echo +hello, world +ICMP error: dest = 140.252.4.54.7, Connection refused, type = 3, code = 3 +kohala % ./udpcli01 192.3.4.5 echo +hello +ICMP error: dest = 192.3.4.5.7, No route to host, type = 3, code = 1 + diff --git a/icmpd/udpcli01.c b/icmpd/udpcli01.c new file mode 100644 index 0000000..381d19c --- /dev/null +++ b/icmpd/udpcli01.c @@ -0,0 +1,18 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + socklen_t salen; + struct sockaddr *sa; + + if (argc != 3) + err_quit("usage: udpcli01 "); + + sockfd = Udp_client(argv[1], argv[2], &sa, &salen); + + dg_cli(stdin, sockfd, sa, salen); + + exit(0); +} diff --git a/icmpd/unpicmpd.h b/icmpd/unpicmpd.h new file mode 100644 index 0000000..6fe1469 --- /dev/null +++ b/icmpd/unpicmpd.h @@ -0,0 +1,16 @@ +#ifndef __unpicmp_h +#define __unpicmp_h + +#include "unp.h" + +#define ICMPD_PATH "/tmp/icmpd" /* server's well-known pathname */ + +struct icmpd_err { + int icmpd_errno;/* EHOSTUNREACH, EMSGSIZE, ECONNREFUSED */ + char icmpd_type; /* actual ICMPv[46] type */ + char icmpd_code; /* actual ICMPv[46] code */ + socklen_t icmpd_len; /* length of sockaddr{} that follows */ + struct sockaddr_storage icmpd_dest; /* sockaddr_storage handles any size */ +}; + +#endif /* __unpicmp_h */ diff --git a/inetd/Makefile b/inetd/Makefile new file mode 100644 index 0000000..4c5cf8d --- /dev/null +++ b/inetd/Makefile @@ -0,0 +1,14 @@ +include ../Make.defines + +PROGS = daytimetcpsrv2 daytimetcpsrv3 + +all: ${PROGS} + +daytimetcpsrv2: daytimetcpsrv2.o + ${CC} ${CFLAGS} -o $@ daytimetcpsrv2.o ${LIBS} + +daytimetcpsrv3: daytimetcpsrv3.o + ${CC} ${CFLAGS} -o $@ daytimetcpsrv3.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/inetd/daytimetcpsrv2.c b/inetd/daytimetcpsrv2.c new file mode 100644 index 0000000..dee7617 --- /dev/null +++ b/inetd/daytimetcpsrv2.c @@ -0,0 +1,36 @@ +#include "unp.h" +#include + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + socklen_t addrlen, len; + struct sockaddr *cliaddr; + char buff[MAXLINE]; + time_t ticks; + + if (argc < 2 || argc > 3) + err_quit("usage: daytimetcpsrv2 [ ] "); + + daemon_init(argv[0], 0); + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + + cliaddr = Malloc(addrlen); + + for ( ; ; ) { + len = addrlen; + connfd = Accept(listenfd, cliaddr, &len); + err_msg("connection from %s", Sock_ntop(cliaddr, len)); + + ticks = time(NULL); + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); + Write(connfd, buff, strlen(buff)); + + Close(connfd); + } +} diff --git a/inetd/daytimetcpsrv3.c b/inetd/daytimetcpsrv3.c new file mode 100644 index 0000000..348078f --- /dev/null +++ b/inetd/daytimetcpsrv3.c @@ -0,0 +1,25 @@ +#include "unp.h" +#include + +int +main(int argc, char **argv) +{ + socklen_t len; + struct sockaddr *cliaddr; + char buff[MAXLINE]; + time_t ticks; + + daemon_inetd(argv[0], 0); + + cliaddr = Malloc(sizeof(struct sockaddr_storage)); + len = sizeof(struct sockaddr_storage); + Getpeername(0, cliaddr, &len); + err_msg("connection from %s", Sock_ntop(cliaddr, len)); + + ticks = time(NULL); + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); + Write(0, buff, strlen(buff)); + + Close(0); /* close TCP connection */ + exit(0); +} diff --git a/inetd/daytimetcpsrv3.lc b/inetd/daytimetcpsrv3.lc new file mode 100644 index 0000000..58936b7 --- /dev/null +++ b/inetd/daytimetcpsrv3.lc @@ -0,0 +1,25 @@ +#include "unp.h"## 1 ##src/inetd/daytimetcpsrv3.c## +#include ## 2 ##src/inetd/daytimetcpsrv3.c## + +int## 3 ##src/inetd/daytimetcpsrv3.c## +main(int argc, char **argv)## 4 ##src/inetd/daytimetcpsrv3.c## +{## 5 ##src/inetd/daytimetcpsrv3.c## + socklen_t len;## 6 ##src/inetd/daytimetcpsrv3.c## + struct sockaddr *cliaddr;## 7 ##src/inetd/daytimetcpsrv3.c## + char buff[MAXLINE];## 8 ##src/inetd/daytimetcpsrv3.c## + time_t ticks;## 9 ##src/inetd/daytimetcpsrv3.c## + + daemon_inetd(argv[0], 0);## 10 ##src/inetd/daytimetcpsrv3.c## + + cliaddr = Malloc(MAXSOCKADDR);## 11 ##src/inetd/daytimetcpsrv3.c## + len = MAXSOCKADDR;## 12 ##src/inetd/daytimetcpsrv3.c## + Getpeername(0, cliaddr, &len);## 13 ##src/inetd/daytimetcpsrv3.c## + err_msg("connection from %s", Sock_ntop(cliaddr, len));## 14 ##src/inetd/daytimetcpsrv3.c## + + ticks = time(NULL);## 15 ##src/inetd/daytimetcpsrv3.c## + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));## 16 ##src/inetd/daytimetcpsrv3.c## + Write(0, buff, strlen(buff));## 17 ##src/inetd/daytimetcpsrv3.c## + + Close(0); /* close TCP connection */## 18 ##src/inetd/daytimetcpsrv3.c## + exit(0);## 19 ##src/inetd/daytimetcpsrv3.c## +}## 20 ##src/inetd/daytimetcpsrv3.c## diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..ebc6691 --- /dev/null +++ b/install-sh @@ -0,0 +1,250 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/intro/Makefile b/intro/Makefile new file mode 100644 index 0000000..2d16d4f --- /dev/null +++ b/intro/Makefile @@ -0,0 +1,44 @@ +include ../Make.defines + +PROGS = daytimetcpcli daytimetcpcli1 daytimetcpcli2 daytimetcpcli3 \ + daytimetcpsrv daytimetcpsrv1 daytimetcpsrv2 daytimetcpsrv3 \ + daytimetcpcliv6 daytimetcpsrvv6 \ + byteorder + +all: ${PROGS} + +daytimetcpcli: daytimetcpcli.o + ${CC} ${CFLAGS} -o $@ daytimetcpcli.o ${LIBS} + +daytimetcpcli1: daytimetcpcli1.o + ${CC} ${CFLAGS} -o $@ daytimetcpcli1.o ${LIBS} + +daytimetcpcli2: daytimetcpcli2.o + ${CC} ${CFLAGS} -o $@ daytimetcpcli2.o ${LIBS} + +daytimetcpcli3: daytimetcpcli3.o + ${CC} ${CFLAGS} -o $@ daytimetcpcli3.o ${LIBS} + +daytimetcpsrv: daytimetcpsrv.o + ${CC} ${CFLAGS} -o $@ daytimetcpsrv.o ${LIBS} + +daytimetcpsrv1: daytimetcpsrv1.o + ${CC} ${CFLAGS} -o $@ daytimetcpsrv1.o ${LIBS} + +daytimetcpsrv2: daytimetcpsrv2.o + ${CC} ${CFLAGS} -o $@ daytimetcpsrv2.o ${LIBS} + +daytimetcpsrv3: daytimetcpsrv3.o + ${CC} ${CFLAGS} -o $@ daytimetcpsrv3.o ${LIBS} + +daytimetcpcliv6: daytimetcpcliv6.o + ${CC} ${CFLAGS} -o $@ daytimetcpcliv6.o ${LIBS} + +daytimetcpsrvv6: daytimetcpsrvv6.o + ${CC} ${CFLAGS} -o $@ daytimetcpsrvv6.o ${LIBS} + +byteorder: byteorder.o + ${CC} ${CFLAGS} -o $@ byteorder.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/intro/byteorder.c b/intro/byteorder.c new file mode 100644 index 0000000..beb40fd --- /dev/null +++ b/intro/byteorder.c @@ -0,0 +1,24 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + union { + short s; + char c[sizeof(short)]; + } un; + + un.s = 0x0102; + printf("%s: ", CPU_VENDOR_OS); + if (sizeof(short) == 2) { + if (un.c[0] == 1 && un.c[1] == 2) + printf("big-endian\n"); + else if (un.c[0] == 2 && un.c[1] == 1) + printf("little-endian\n"); + else + printf("unknown\n"); + } else + printf("sizeof(short) = %d\n", sizeof(short)); + + exit(0); +} diff --git a/intro/daytimetcpcli.c b/intro/daytimetcpcli.c new file mode 100644 index 0000000..cc34e3a --- /dev/null +++ b/intro/daytimetcpcli.c @@ -0,0 +1,34 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n; + char recvline[MAXLINE + 1]; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: a.out "); + + if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + err_sys("socket error"); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(13); /* daytime server */ + if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) + err_quit("inet_pton error for %s", argv[1]); + + if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) + err_sys("connect error"); + + while ( (n = read(sockfd, recvline, MAXLINE)) > 0) { + recvline[n] = 0; /* null terminate */ + if (fputs(recvline, stdout) == EOF) + err_sys("fputs error"); + } + if (n < 0) + err_sys("read error"); + + exit(0); +} diff --git a/intro/daytimetcpcli1.c b/intro/daytimetcpcli1.c new file mode 100644 index 0000000..fc10beb --- /dev/null +++ b/intro/daytimetcpcli1.c @@ -0,0 +1,36 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n, counter = 0; + char recvline[MAXLINE + 1]; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: a.out "); + + if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + err_sys("socket error"); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(13); /* daytime server */ + if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) + err_quit("inet_pton error for %s", argv[1]); + + if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) + err_sys("connect error"); + + while ( (n = read(sockfd, recvline, MAXLINE)) > 0) { + counter++; + recvline[n] = 0; /* null terminate */ + if (fputs(recvline, stdout) == EOF) + err_sys("fputs error"); + } + if (n < 0) + err_sys("read error"); + + printf("counter = %d\n", counter); + exit(0); +} diff --git a/intro/daytimetcpcli2.c b/intro/daytimetcpcli2.c new file mode 100644 index 0000000..99e030a --- /dev/null +++ b/intro/daytimetcpcli2.c @@ -0,0 +1,36 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n, counter = 0; + char recvline[MAXLINE + 1]; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: a.out "); + + if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + err_sys("socket error"); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(9999); /* daytime server */ + if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) + err_quit("inet_pton error for %s", argv[1]); + + if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) + err_sys("connect error"); + + while ( (n = read(sockfd, recvline, MAXLINE)) > 0) { + counter++; + recvline[n] = 0; /* null terminate */ + if (fputs(recvline, stdout) == EOF) + err_sys("fputs error"); + } + if (n < 0) + err_sys("read error"); + + printf("counter = %d\n", counter); + exit(0); +} diff --git a/intro/daytimetcpcli3.c b/intro/daytimetcpcli3.c new file mode 100644 index 0000000..bc8444a --- /dev/null +++ b/intro/daytimetcpcli3.c @@ -0,0 +1,40 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n; + socklen_t len; + char recvline[MAXLINE + 1]; + struct sockaddr_in servaddr, cliaddr; + + if (argc != 2) + err_quit("usage: a.out "); + + if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + err_sys("socket error"); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(13); /* daytime server */ + if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) + err_quit("inet_pton error for %s", argv[1]); + + if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) + err_sys("connect error"); + + len = sizeof(cliaddr); + Getsockname(sockfd, (SA *) &cliaddr, &len); + printf("local addr: %s\n", + Sock_ntop((SA *) &cliaddr, sizeof(cliaddr))); + + while ( (n = read(sockfd, recvline, MAXLINE)) > 0) { + recvline[n] = 0; /* null terminate */ + if (fputs(recvline, stdout) == EOF) + err_sys("fputs error"); + } + if (n < 0) + err_sys("read error"); + + exit(0); +} diff --git a/intro/daytimetcpcliv6.c b/intro/daytimetcpcliv6.c new file mode 100644 index 0000000..986198c --- /dev/null +++ b/intro/daytimetcpcliv6.c @@ -0,0 +1,34 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n; + struct sockaddr_in6 servaddr; + char recvline[MAXLINE + 1]; + + if (argc != 2) + err_quit("usage: a.out "); + + if ( (sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) + err_sys("socket error"); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin6_family = AF_INET6; + servaddr.sin6_port = htons(13); /* daytime server */ + if (inet_pton(AF_INET6, argv[1], &servaddr.sin6_addr) <= 0) + err_quit("inet_pton error for %s", argv[1]); + + if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) + err_sys("connect error"); + + while ( (n = read(sockfd, recvline, MAXLINE)) > 0) { + recvline[n] = 0; /* null terminate */ + if (fputs(recvline, stdout) == EOF) + err_sys("fputs error"); + } + if (n < 0) + err_sys("read error"); + + exit(0); +} diff --git a/intro/daytimetcpsrv.c b/intro/daytimetcpsrv.c new file mode 100644 index 0000000..bd225f4 --- /dev/null +++ b/intro/daytimetcpsrv.c @@ -0,0 +1,32 @@ +#include "unp.h" +#include + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + struct sockaddr_in servaddr; + char buff[MAXLINE]; + time_t ticks; + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(13); /* daytime server */ + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + for ( ; ; ) { + connfd = Accept(listenfd, (SA *) NULL, NULL); + + ticks = time(NULL); + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); + Write(connfd, buff, strlen(buff)); + + Close(connfd); + } +} diff --git a/intro/daytimetcpsrv.lc b/intro/daytimetcpsrv.lc new file mode 100644 index 0000000..4d87102 --- /dev/null +++ b/intro/daytimetcpsrv.lc @@ -0,0 +1,32 @@ +#include "unp.h"## 1 ##src/intro/daytimetcpsrv.c## +#include ## 2 ##src/intro/daytimetcpsrv.c## + +int## 3 ##src/intro/daytimetcpsrv.c## +main(int argc, char **argv)## 4 ##src/intro/daytimetcpsrv.c## +{## 5 ##src/intro/daytimetcpsrv.c## + int listenfd, connfd;## 6 ##src/intro/daytimetcpsrv.c## + struct sockaddr_in servaddr;## 7 ##src/intro/daytimetcpsrv.c## + char buff[MAXLINE];## 8 ##src/intro/daytimetcpsrv.c## + time_t ticks;## 9 ##src/intro/daytimetcpsrv.c## + + listenfd = Socket(AF_INET, SOCK_STREAM, 0);## 10 ##src/intro/daytimetcpsrv.c## + + bzero(&servaddr, sizeof(servaddr));## 11 ##src/intro/daytimetcpsrv.c## + servaddr.sin_family = AF_INET;## 12 ##src/intro/daytimetcpsrv.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 13 ##src/intro/daytimetcpsrv.c## + servaddr.sin_port = htons(13); /* daytime server */## 14 ##src/intro/daytimetcpsrv.c## + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));## 15 ##src/intro/daytimetcpsrv.c## + + Listen(listenfd, LISTENQ);## 16 ##src/intro/daytimetcpsrv.c## + + for (;;) {## 17 ##src/intro/daytimetcpsrv.c## + connfd = Accept(listenfd, (SA *) NULL, NULL);## 18 ##src/intro/daytimetcpsrv.c## + + ticks = time(NULL);## 19 ##src/intro/daytimetcpsrv.c## + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));## 20 ##src/intro/daytimetcpsrv.c## + Write(connfd, buff, strlen(buff));## 21 ##src/intro/daytimetcpsrv.c## + + Close(connfd);## 22 ##src/intro/daytimetcpsrv.c## + }## 23 ##src/intro/daytimetcpsrv.c## +}## 24 ##src/intro/daytimetcpsrv.c## diff --git a/intro/daytimetcpsrv1.c b/intro/daytimetcpsrv1.c new file mode 100644 index 0000000..f13fd30 --- /dev/null +++ b/intro/daytimetcpsrv1.c @@ -0,0 +1,37 @@ +#include "unp.h" +#include + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + socklen_t len; + struct sockaddr_in servaddr, cliaddr; + char buff[MAXLINE]; + time_t ticks; + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(13); /* daytime server */ + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + for ( ; ; ) { + len = sizeof(cliaddr); + connfd = Accept(listenfd, (SA *) &cliaddr, &len); + printf("connection from %s, port %d\n", + Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)), + ntohs(cliaddr.sin_port)); + + ticks = time(NULL); + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); + Write(connfd, buff, strlen(buff)); + + Close(connfd); + } +} diff --git a/intro/daytimetcpsrv2.c b/intro/daytimetcpsrv2.c new file mode 100644 index 0000000..9c5cd14 --- /dev/null +++ b/intro/daytimetcpsrv2.c @@ -0,0 +1,33 @@ +#include "unp.h" +#include + +int +main(int argc, char **argv) +{ + int listenfd, connfd, i; + struct sockaddr_in servaddr; + char buff[MAXLINE]; + time_t ticks; + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(9999); + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + for ( ; ; ) { + connfd = Accept(listenfd, (SA *) NULL, NULL); + + ticks = time(NULL); + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); + for (i = 0; i < strlen(buff); i++) + Write(connfd, &buff[i], 1); + + Close(connfd); + } +} diff --git a/intro/daytimetcpsrv3.c b/intro/daytimetcpsrv3.c new file mode 100644 index 0000000..c958bca --- /dev/null +++ b/intro/daytimetcpsrv3.c @@ -0,0 +1,37 @@ +#include "unp.h" +#include + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + socklen_t len; + struct sockaddr_in servaddr, cliaddr; + char buff[MAXLINE]; + time_t ticks; + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(9999); /* daytime server */ + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + for ( ; ; ) { + len = sizeof(cliaddr); + connfd = Accept(listenfd, (SA *) &cliaddr, &len); + printf("connection from %s, port %d\n", + Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)), + ntohs(cliaddr.sin_port)); + + ticks = time(NULL); + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); + Write(connfd, buff, strlen(buff)); + + Close(connfd); + } +} diff --git a/intro/daytimetcpsrvv6.c b/intro/daytimetcpsrvv6.c new file mode 100644 index 0000000..c11f384 --- /dev/null +++ b/intro/daytimetcpsrvv6.c @@ -0,0 +1,36 @@ +#include "unp.h" +#include + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + socklen_t len; + char buff[MAXLINE]; + time_t ticks; + struct sockaddr_in6 servaddr, cliaddr; + + listenfd = Socket(AF_INET6, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin6_family = AF_INET6; + servaddr.sin6_addr = in6addr_any; + servaddr.sin6_port = htons(13); /* daytime server */ + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + for ( ; ; ) { + len = sizeof(cliaddr); + connfd = Accept(listenfd, (SA *) &cliaddr, &len); + printf("connection from %s\n", + Sock_ntop((SA *) &cliaddr, len)); + + ticks = time(NULL); + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); + Write(connfd, buff, strlen(buff)); + + Close(connfd); + } +} diff --git a/intro/truss.solaris.2.6 b/intro/truss.solaris.2.6 new file mode 100644 index 0000000..65bea8b --- /dev/null +++ b/intro/truss.solaris.2.6 @@ -0,0 +1,8 @@ +so_socket(2, 2, 0, "", 1) = 3 +connect(3, 0xEFFFE8C8, 16) = 0 +read(3, " F r i A p r 4 1".., 4096) = 26 +ioctl(1, TCGETA, 0xEFFFE69C) = 0 +write(1, " F r i A p r 4 1".., 26) = 26 +read(3, 0xEFFFE8D8, 4096) = 0 +llseek(0, 0, SEEK_CUR) = 179866 +_exit(0) diff --git a/intro/truss.unixware.2.1 b/intro/truss.unixware.2.1 new file mode 100644 index 0000000..c64430b --- /dev/null +++ b/intro/truss.unixware.2.1 @@ -0,0 +1,102 @@ +execve("./daytimetcpcli", 0x08047BA8, 0x08047BB4) argc = 2 +open("/usr/lib/libsocket.so.2", O_RDONLY, 0) = 3 +fxstat(2, 3, 0x0804794C) = 0 +mmap(0x00000000, 4096, PROT_READ, MAP_SHARED, 3, 0) = 0xBFF9E000 +mmap(0x00000000, 98280, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xBFF85000 +mmap(0xBFF9A000, 6888, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 81920) = 0xBFF9A000 +open("/dev/zero", O_RDONLY, 027777756064) = 4 +mmap(0xBFF9C000, 4072, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 4, 0) = 0xBFF9C000 +close(3) = 0 +munmap(0xBFF9E000, 4096) = 0 +open("/usr/lib/libresolv.so.1", O_RDONLY, 0) = 3 +fxstat(2, 3, 0x0804794C) = 0 +mmap(0x00000000, 4096, PROT_READ, MAP_SHARED, 3, 0) = 0xBFF9E000 +mmap(0x00000000, 31060, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xBFF7C000 +mmap(0xBFF82000, 3604, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 20480) = 0xBFF82000 +mmap(0xBFF83000, 2388, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 4, 0) = 0xBFF83000 +close(3) = 0 +munmap(0xBFF9E000, 4096) = 0 +open("/usr/lib/libnsl.so.1", O_RDONLY, 0) = 3 +fxstat(2, 3, 0x0804794C) = 0 +mmap(0x00000000, 4096, PROT_READ, MAP_SHARED, 3, 0) = 0xBFF9E000 +mmap(0x00000000, 248004, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xBFF3E000 +mmap(0xBFF77000, 6456, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 229376) = 0xBFF77000 +mmap(0xBFF79000, 6340, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 4, 0) = 0xBFF79000 +close(3) = 0 +munmap(0xBFF9E000, 4096) = 0 +mmap(0x00000000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE, 4, 0) = 0xBFF9E000 +open("/usr/lib/libnsl.so.1", O_RDONLY, 0) = 3 +fxstat(2, 3, 0x0804794C) = 0 +close(3) = 0 +open("/usr/lib/libsocket.so.2", O_RDONLY, 0) = 3 +fxstat(2, 3, 0x0804794C) = 0 +close(3) = 0 +open("/usr/lib/libnsl.so.1", O_RDONLY, 0) = 3 +fxstat(2, 3, 0x0804794C) = 0 +close(3) = 0 +close(4) = 0 +brk(0x0804B52C) = 0 +open("/etc/netconfig", O_RDONLY, 0666) = 3 +ioctl(3, TCGETA, 0x080465E6) Err#25 ENOTTY +ioctl(3, I_GETTP, 0x00000000) Err#25 ENOTTY +fxstat(2, 3, 0x08046614) = 0 +brk(0x0804E52C) = 0 +read(3, " t c p\t t p i _ c o t s".., 8192) = 806 +read(3, 0x0804A6B8, 8192) = 0 +lseek(3, 0, 0) = 0 +read(3, " t c p\t t p i _ c o t s".., 8192) = 806 +brk(0x0804F52C) = 0 +brk(0x0805052C) = 0 +read(3, 0x0804A6B8, 8192) = 0 +close(3) = 0 +open("/dev/tcp", O_RDWR, 027776333624) = 3 +ioctl(3, I_FIND, "sockmod") = 0 +ioctl(3, I_PUSH, "sockmod") = 0 +ioctl(3, I_SETCLTIME, 0x08046B50) = 0 +ioctl(3, I_SWROPT, 0x00000002) = 0 +sigfillset(0xBFFFEBE4) = 0 +sigprocmask(SIG_BLOCK, 0x08046AD8, 0x08046AE8) = 0 +ioctl(3, I_STR, 0x08046AA0) = 0 + cmd=(('I'<<8)|101) timout=-1 len=28 dp=0x08046AF8 + \0 @\0\010\0\0\0 h01\0\080\0\0\002\0\0\0\0\0\0\0\0\0\0\0 +sigprocmask(SIG_SETMASK, 0x08046AE8, 0x00000000) = 0 +ioctl(3, I_GETSIG, 0x08046B18) Err#22 EINVAL +sigprocmask(SIG_BLOCK, 0x08046B20, 0x08046B30) = 0 +ioctl(3, I_STR, 0x08046AE0) = 0 + cmd=TI_OPTMGMT timout=-1 len=32 dp=0x0804ABA8 + 16\0\0\010\0\0\010\0\0\004\0\0\0FFFF\0\00110\0\004\0\0\0\0 `\0\0 +sigprocmask(SIG_SETMASK, 0x08046B30, 0x00000000) = 0 +sigprocmask(SIG_BLOCK, 0x08046B0C, 0x08046B1C) = 0 +ioctl(3, I_STR, 0x08046ACC) = 0 + cmd=TI_OPTMGMT timout=-1 len=32 dp=0x0804ABA8 + 16\0\0\010\0\0\010\0\0\004\0\0\0FFFF\0\00210\0\004\0\0\0\0 `\0\0 +sigprocmask(SIG_SETMASK, 0x08046B1C, 0x00000000) = 0 +fcntl(3, F_GETFL, 0x00000000) = 2 +sigprocmask(SIG_BLOCK, 0x08046828, 0x08046838) = 0 +ioctl(3, I_STR, 0x080467E4) = 0 + cmd=TI_BIND timout=-1 len=32 dp=0x0804ABA8 + 11\0\0\010\0\0\010\0\0\0\0\0\0\002\004 1\0\0\0\0\0\0\0\0\0\0\0\0 +sigprocmask(SIG_SETMASK, 0x08046838, 0x00000000) = 0 +sigprocmask(SIG_BLOCK, 0x080469B0, 0x080469C0) = 0 +putmsg(3, 0x08046958, 0x00000000, 0) = 0 + ctl: maxlen=428 len=36 buf=0x0804ABA8 +fcntl(3, F_GETFL, 0x00000000) = 2 +getmsg(3, 0x08046924, 0x08046918, 0x08046934) = 0 + ctl: maxlen=428 len=8 buf=0x0804ABA8 + dat: maxlen=128 len=-1 buf=0x08046898 +fcntl(3, F_GETFL, 0x00000000) = 2 +getmsg(3, 0x08046964, 0x08046958, 0x0804697C) = 0 + ctl: maxlen=428 len=56 buf=0x0804ABA8 + dat: maxlen=128 len=-1 buf=0x080468D8 +sigprocmask(SIG_SETMASK, 0x080469C0, 0x00000000) = 0 +getmsg(3, 0x08046AEC, 0x08046AE0, 0x08046B14) = 0 + ctl: maxlen=428 len=8 buf=0x0804ABA8 + dat: maxlen=4096 len=26 buf=0x08046BB0 +ioctl(1, TCGETA, 0x08046A9A) = 0 + iflag=0002406 oflag=0000005 cflag=0002275 lflag=0000053 line=0 + cc: 177 034 010 025 004 000 000 000 +write(1, " F r i A p r 4 0".., 26) = 26 +getmsg(3, 0x08046AEC, 0x08046AE0, 0x08046B14) = 0 + ctl: maxlen=428 len=-1 buf=0x0804ABA8 + dat: maxlen=4096 len=0 buf=0x08046BB0 +_exit(0) diff --git a/ioctl/Makefile b/ioctl/Makefile new file mode 100644 index 0000000..94dbb31 --- /dev/null +++ b/ioctl/Makefile @@ -0,0 +1,23 @@ +include ../Make.defines + +PROGS = lsif01 lsif02 prifinfo prmac + +all: ${PROGS} + +lsif01: lsif01.o + ${CC} ${CFLAGS} -o $@ lsif01.o ${LIBS} + +lsif02: lsif02.o + ${CC} ${CFLAGS} -o $@ lsif02.o ${LIBS} + +prifinfo: prifinfo.o + ${CC} ${CFLAGS} -o $@ prifinfo.o ${LIBS} + +prmac: prmac.o + ${CC} ${CFLAGS} -o $@ prmac.o ${LIBS} + +test1: test1.o + ${CC} ${CFLAGS} -o $@ test1.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/ioctl/Progs.siocgifconf b/ioctl/Progs.siocgifconf new file mode 100644 index 0000000..30288f3 --- /dev/null +++ b/ioctl/Progs.siocgifconf @@ -0,0 +1,93 @@ + if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0) +./games/hunt/hunt/hunt.c + i = ioctl(sock, SIOCGIFCONF, (char *)&ifc); +./lib/libc/net/getifaddrs.c + if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { +./lib/librpc/rpc/get_myaddress.c + if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) { +./lib/librpc/rpc/pmap_rmt.c + ioc.ic_cmd = SIOCGIFCONF; + m = ioctl(s, SIOCGIFCONF, (caddr_t) & ifconf); + report(LOG_ERR, "ioctl SIOCGIFCONF"); +./libexec/bootpd/bootpd/getif.c + if (ioctl(fd, SIOCGIFCONF, (char *) &ifc) < 0 || + report(LOG_ERR, "getether: SIOCGIFCONF: %s", get_errmsg); +./libexec/bootpd/bootptest/getether.c +#ifdef OSIOCGIFCONF + if (ioctl(fd, OSIOCGIFCONF, (char *)&ifc) < 0 || + (void) strcpy(errbuf, "bpf: ioctl(OSIOCGIFCONF): %m"); + if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 || + (void) strcpy(errbuf, "bpf: ioctl(SIOCGIFCONF): %m"); +./libexec/rbootd/bpf.c +#define SCO_SIOCGIFCONF 0xc0084911 + if ((r = ioctl(f, SIOCGIFCONF, &bifc)) == -1) { + case SCO_SIOCGIFCONF: +./sco/emulator/sco_sockops.c + case SIOCGIFCONF: + case OSIOCGIFCONF: + if (cmd == OSIOCGIFCONF) { +./sys/net/if.c + case SIOCGIFCONF_X25: +./sys/netccitt/pk_usrreq.c + if (ioctl(sk, SIOCGIFCONF, (caddr_t) &ifc) < 0) +./usr.sbin/amd/amd/wire.c + if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0) { +./usr.sbin/named/named/ns_main.c + if (ioctl(fd, SIOCGIFCONF, (caddr_t)&ifc) < 0 || + err(FATAL, "init_all: SIOCGIFCONF: %s", strerror(errno)); + We must instead get all the interfaces with SIOCGIFCONF + if (ioctl(fd, SIOCGIFCONF, (caddr_t)&ifc) < 0 || +./usr.sbin/rarpd/rarpd.c +#ifdef SIOCGIFCONF +#ifdef SIOCGIFCONF + if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) +./usr.sbin/sendmail/src/conf.c + if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 || + (void)sprintf(errbuf, "SIOCGIFCONF: %s", pcap_strerror(errno)); +./usr.sbin/tcpdump/libpcap/inet.c + if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) { +./usr.sbin/timed/timed/timed.c + ioc.ic_cmd = SIOCGIFCONF; + if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0) { +#ifdef SIOCGIFCONF +#endif /* SIOCGIFCONF */ +./usr.sbin/xntp/xntpd/ntp_io.c +#if ((defined(SVR4) && !defined(sun)) || defined(ISC)) && defined(SIOCGIFCONF) +#define SYSV_SIOCGIFCONF +#ifdef SYSV_SIOCGIFCONF +/* Deal with different SIOCGIFCONF ioctl semantics on SYSV, SVR4 */ + if (cmd == SIOCGIFCONF) + /* SIOCGIFCONF is somewhat brain damaged on ISC. The argument + if (ret >= 0 && cmd == SIOCGIFCONF) +#else /* SYSV_SIOCGIFCONF */ +#endif /* SYSV_SIOCGIFCONF */ +#if defined(STREAMSCONN) && !defined(SYSV_SIOCGIFCONF) && !defined(NCR) +#ifdef SIOCGIFCONF + if (ifioctl (fd, SIOCGIFCONF, (char *) &ifc) < 0) + * this is ugly but SIOCGIFCONF returns decnet addresses in +#else /* SIOCGIFCONF */ +#endif /* SIOCGIFCONF else */ +#endif /* STREAMSCONN && !SYSV_SIOCGIFCONF else */ +./X11/xc/programs/xdm/auth.c +#if ((defined(SVR4) && !defined(sun) && !defined(NCR)) || defined(ISC)) && defined(SIOCGIFCONF) +/* Deal with different SIOCGIFCONF ioctl semantics on these OSs */ + if (cmd == SIOCGIFCONF) + /* SIOCGIFCONF is somewhat brain damaged on ISC. The argument + if (ret >= 0 && cmd == SIOCGIFCONF) +#else /* ((SVR4 && !sun && !NCR) || ISC) && SIOCGIFCONF */ +#endif /* ((SVR4 && !sun) || ISC) && SIOCGIFCONF */ + if (ifioctl (socketFD, (int) SIOCGIFCONF, (char *) &ifc) < 0) +./X11/xc/programs/xdm/chooser.c +#if ((defined(SVR4) && !defined(sun) && !defined(NCR)) || defined(ISC)) && defined(SIOCGIFCONF) +/* Deal with different SIOCGIFCONF ioctl semantics on these OSs */ + if (cmd == SIOCGIFCONF) + /* SIOCGIFCONF is somewhat brain damaged on ISC. The argument + if (ret >= 0 && cmd == SIOCGIFCONF) +#else /* ((SVR4 && !sun) || ISC) && SIOCGIFCONF */ +#endif /* ((SVR4 && !sun) || ISC) && SIOCGIFCONF */ +#if !defined(SIOCGIFCONF) || (defined (hpux) && ! defined (HAS_IFREQ)) + if (ifioctl (fd, (int) SIOCGIFCONF, (pointer) &ifc) < 0) +./X11/xc/programs/Xserver/os/access.c +#if !defined(SIOCGIFCONF) || (defined (hpux) && ! defined (HAS_IFREQ)) + if (ioctl (fd, (int) SIOCGIFCONF, (pointer) &ifc) < 0) +./X11/xc/workInProgress/lbx/programs/lbxproxy/os/access.c diff --git a/ioctl/Script.solaris b/ioctl/Script.solaris new file mode 100644 index 0000000..0801961 --- /dev/null +++ b/ioctl/Script.solaris @@ -0,0 +1,28 @@ +kohala % ./prifinfo 4 1 +trying len = 64 +ioctl error +trying len = 96 +ioctl error +trying len = 128 +ioctl error +trying len = 160 +ioctl error +trying len = 192 +returned len = 160 +trying len = 224 +returned len = 160 +success, len = 160 +lo0: + IP addr: 127.0.0.1 +le0: + IP addr: 206.62.226.33 + broadcast addr: 206.62.226.63 +le0:1: + IP addr: 140.252.13.47 + broadcast addr: 140.252.13.63 +le0:2: + IP addr: 140.252.13.48 + broadcast addr: 140.252.13.63 +le0:3: + IP addr: 140.252.13.49 + broadcast addr: 140.252.13.63 diff --git a/ioctl/lsif01.c b/ioctl/lsif01.c new file mode 100644 index 0000000..ed77acf --- /dev/null +++ b/ioctl/lsif01.c @@ -0,0 +1,42 @@ +#include "unp.h" + +#include + +int +main(int argc, char **argv) +{ + int sockfd, len; + char *ptr, buf[2048], addrstr[INET_ADDRSTRLEN]; + struct ifconf ifc; + struct ifreq *ifr; + struct sockaddr_in *sinptr; + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + ifc.ifc_len = sizeof(buf); + ifc.ifc_req = (struct ifreq *) buf; + Ioctl(sockfd, SIOCGIFCONF, &ifc); + + for (ptr = buf; ptr < buf + ifc.ifc_len; ) { + ifr = (struct ifreq *) ptr; + len = sizeof(struct sockaddr); +#ifdef HAVE_SOCKADDR_SA_LEN + if (ifr->ifr_addr.sa_len > len) + len = ifr->ifr_addr.sa_len; /* length > 16 */ +#endif + ptr += sizeof(ifr->ifr_name) + len; /* for next one in buffer */ + + switch (ifr->ifr_addr.sa_family) { + case AF_INET: + sinptr = (struct sockaddr_in *) &ifr->ifr_addr; + printf("%s\t%s\n", ifr->ifr_name, + Inet_ntop(AF_INET, &sinptr->sin_addr, addrstr, sizeof(addrstr))); + break; + + default: + printf("%s\n", ifr->ifr_name); + break; + } + } + exit(0); +} diff --git a/ioctl/lsif02.c b/ioctl/lsif02.c new file mode 100644 index 0000000..4bb0dd6 --- /dev/null +++ b/ioctl/lsif02.c @@ -0,0 +1,88 @@ +#include "unp.h" + +#include +#ifdef HAVE_SOCKADDR_DL_STRUCT +#include +#include +#endif + +int +main(int argc, char **argv) +{ + int sockfd, len; + char *ptr, buf[2048], addrstr[INET_ADDRSTRLEN]; + struct ifconf ifc; + struct ifreq *ifr; + struct sockaddr_in *sinptr; + + if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + err_sys("socket error"); + + ifc.ifc_len = sizeof(buf); + ifc.ifc_req = (struct ifreq *) buf; + if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) + err_sys("ioctl SIOCGIFCONF error"); + + for (ptr = buf; ptr < buf + ifc.ifc_len; ) { + ifr = (struct ifreq *) ptr; + len = sizeof(struct sockaddr); +#ifdef HAVE_SOCKADDR_SA_LEN + if (ifr->ifr_addr.sa_len > len) + len = ifr->ifr_addr.sa_len; /* length > 16 */ +#endif + ptr += sizeof(ifr->ifr_name) + len; /* for next one in buffer */ + + switch (ifr->ifr_addr.sa_family) { + case AF_INET: + sinptr = (struct sockaddr_in *) &ifr->ifr_addr; + printf("%s\t%s\n", ifr->ifr_name, + Inet_ntop(AF_INET, &sinptr->sin_addr, addrstr, sizeof(addrstr))); + break; + +#ifdef AF_INET6 + case AF_INET6: { + struct sockaddr_in6 *sin6ptr; + char addr6str[INET6_ADDRSTRLEN]; + + sin6ptr = (struct sockaddr_in6 *) &ifr->ifr_addr; + printf("%s\t%s\n", ifr->ifr_name, + Inet_ntop(AF_INET6, &sin6ptr->sin6_addr, addr6str, sizeof(addr6str))); + break; + } +#endif + +#ifdef HAVE_SOCKADDR_DL_STRUCT + case AF_LINK: { + struct sockaddr_dl *sdlptr; + char str[18]; + char *etherprint(const u_char *, char *); + + sdlptr = (struct sockaddr_dl *) &ifr->ifr_addr; + printf("%s", ifr->ifr_name); + if (sdlptr->sdl_index) + printf("\t", sdlptr->sdl_index); + if (sdlptr->sdl_type == IFT_ETHER && sdlptr->sdl_alen) + printf("\t%s", etherprint((u_char *) LLADDR(sdlptr), str)); + putchar('\n'); + break; + } +#endif + + default: + printf("%s\n", ifr->ifr_name); + break; + } + } + exit(0); +} + +#ifdef HAVE_SOCKADDR_DL_STRUCT +char * +etherprint(const u_char eaddr[6], char string[18]) +{ + snprintf(string, 18, "%02x:%02x:%02x:%02x:%02x:%02x", + eaddr[0], eaddr[1], eaddr[2], eaddr[3], eaddr[4], eaddr[5] ); + string[17] = '\0'; + return(string); +} +#endif diff --git a/ioctl/prifinfo.c b/ioctl/prifinfo.c new file mode 100644 index 0000000..846f6dc --- /dev/null +++ b/ioctl/prifinfo.c @@ -0,0 +1,61 @@ +#include "unpifi.h" + +int +main(int argc, char **argv) +{ + struct ifi_info *ifi, *ifihead; + struct sockaddr *sa; + u_char *ptr; + int i, family, doaliases; + + if (argc != 3) + err_quit("usage: prifinfo "); + + if (strcmp(argv[1], "inet4") == 0) + family = AF_INET; +#ifdef IPv6 + else if (strcmp(argv[1], "inet6") == 0) + family = AF_INET6; +#endif + else + err_quit("invalid "); + doaliases = atoi(argv[2]); + + for (ifihead = ifi = Get_ifi_info(family, doaliases); + ifi != NULL; ifi = ifi->ifi_next) { + printf("%s: ", ifi->ifi_name); + if (ifi->ifi_index != 0) + printf("(%d) ", ifi->ifi_index); + printf("<"); +/* *INDENT-OFF* */ + if (ifi->ifi_flags & IFF_UP) printf("UP "); + if (ifi->ifi_flags & IFF_BROADCAST) printf("BCAST "); + if (ifi->ifi_flags & IFF_MULTICAST) printf("MCAST "); + if (ifi->ifi_flags & IFF_LOOPBACK) printf("LOOP "); + if (ifi->ifi_flags & IFF_POINTOPOINT) printf("P2P "); + printf(">\n"); +/* *INDENT-ON* */ + + if ( (i = ifi->ifi_hlen) > 0) { + ptr = ifi->ifi_haddr; + do { + printf("%s%x", (i == ifi->ifi_hlen) ? " " : ":", *ptr++); + } while (--i > 0); + printf("\n"); + } + if (ifi->ifi_mtu != 0) + printf(" MTU: %d\n", ifi->ifi_mtu); + + if ( (sa = ifi->ifi_addr) != NULL) + printf(" IP addr: %s\n", + Sock_ntop_host(sa, sizeof(*sa))); + if ( (sa = ifi->ifi_brdaddr) != NULL) + printf(" broadcast addr: %s\n", + Sock_ntop_host(sa, sizeof(*sa))); + if ( (sa = ifi->ifi_dstaddr) != NULL) + printf(" destination addr: %s\n", + Sock_ntop_host(sa, sizeof(*sa))); + } + free_ifi_info(ifihead); + exit(0); +} diff --git a/ioctl/prifinfo.lc b/ioctl/prifinfo.lc new file mode 100644 index 0000000..2b08c73 --- /dev/null +++ b/ioctl/prifinfo.lc @@ -0,0 +1,53 @@ +#include "unpifi.h"## 1 ##src/ioctl/prifinfo.c## + +int## 2 ##src/ioctl/prifinfo.c## +main(int argc, char **argv)## 3 ##src/ioctl/prifinfo.c## +{## 4 ##src/ioctl/prifinfo.c## + struct ifi_info *ifi, *ifihead;## 5 ##src/ioctl/prifinfo.c## + struct sockaddr *sa;## 6 ##src/ioctl/prifinfo.c## + u_char *ptr;## 7 ##src/ioctl/prifinfo.c## + int i, family, doaliases;## 8 ##src/ioctl/prifinfo.c## + + if (argc != 3)## 9 ##src/ioctl/prifinfo.c## + err_quit("usage: prifinfo ");## 10 ##src/ioctl/prifinfo.c## + + if (strcmp(argv[1], "inet4") == 0)## 11 ##src/ioctl/prifinfo.c## + family = AF_INET;## 12 ##src/ioctl/prifinfo.c## +#ifdef IPV6## 13 ##src/ioctl/prifinfo.c## + else if (strcmp(argv[1], "inet6") == 0)## 14 ##src/ioctl/prifinfo.c## + family = AF_INET6;## 15 ##src/ioctl/prifinfo.c## +#endif## 16 ##src/ioctl/prifinfo.c## + else## 17 ##src/ioctl/prifinfo.c## + err_quit("invalid ");## 18 ##src/ioctl/prifinfo.c## + doaliases = atoi(argv[2]);## 19 ##src/ioctl/prifinfo.c## + + for (ifihead = ifi = Get_ifi_info(family, doaliases);## 20 ##src/ioctl/prifinfo.c## + ifi != NULL; ifi = ifi->ifi_next) {## 21 ##src/ioctl/prifinfo.c## + printf("%s: (%d) <", ifi->ifi_name, ifi->ifi_index);## 22 ##src/ioctl/prifinfo.c## + if (ifi->ifi_flags & IFF_UP) printf("UP ");## 23 ##src/ioctl/prifinfo.c## + if (ifi->ifi_flags & IFF_BROADCAST) printf("BCAST ");## 24 ##src/ioctl/prifinfo.c## + if (ifi->ifi_flags & IFF_MULTICAST) printf("MCAST ");## 25 ##src/ioctl/prifinfo.c## + if (ifi->ifi_flags & IFF_LOOPBACK) printf("LOOP ");## 26 ##src/ioctl/prifinfo.c## + if (ifi->ifi_flags & IFF_POINTOPOINT) printf("P2P ");## 27 ##src/ioctl/prifinfo.c## + printf(">\n");## 28 ##src/ioctl/prifinfo.c## + + if ((i = ifi->ifi_hlen) > 0) {## 29 ##src/ioctl/prifinfo.c## + ptr = ifi->ifi_haddr;## 30 ##src/ioctl/prifinfo.c## + do {## 31 ##src/ioctl/prifinfo.c## + printf("%s%x", (i == ifi->ifi_hlen) ? " " : ":", *ptr++);## 32 ##src/ioctl/prifinfo.c## + } while (--i > 0);## 33 ##src/ioctl/prifinfo.c## + printf("\n");## 34 ##src/ioctl/prifinfo.c## + }## 35 ##src/ioctl/prifinfo.c## + + if ((sa = ifi->ifi_addr) != NULL)## 36 ##src/ioctl/prifinfo.c## + printf(" IP addr: %s\n", Sock_ntop_host(sa, sizeof(*sa)));## 37 ##src/ioctl/prifinfo.c## + if ((sa = ifi->ifi_brdaddr) != NULL)## 38 ##src/ioctl/prifinfo.c## + printf(" broadcast addr: %s\n",## 39 ##src/ioctl/prifinfo.c## + Sock_ntop_host(sa, sizeof(*sa)));## 40 ##src/ioctl/prifinfo.c## + if ((sa = ifi->ifi_dstaddr) != NULL)## 41 ##src/ioctl/prifinfo.c## + printf(" destination addr: %s\n",## 42 ##src/ioctl/prifinfo.c## + Sock_ntop_host(sa, sizeof(*sa)));## 43 ##src/ioctl/prifinfo.c## + }## 44 ##src/ioctl/prifinfo.c## + free_ifi_info(ifihead);## 45 ##src/ioctl/prifinfo.c## + exit(0);## 46 ##src/ioctl/prifinfo.c## +}## 47 ##src/ioctl/prifinfo.c## diff --git a/ioctl/prmac.c b/ioctl/prmac.c new file mode 100644 index 0000000..f2b6a89 --- /dev/null +++ b/ioctl/prmac.c @@ -0,0 +1,30 @@ +#include "unpifi.h" +#include + +int +main(int argc, char **argv) +{ + int sockfd; + struct ifi_info *ifi; + unsigned char *ptr; + struct arpreq arpreq; + struct sockaddr_in *sin; + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + for (ifi = get_ifi_info(AF_INET, 0); ifi != NULL; ifi = ifi->ifi_next) { + printf("%s: ", Sock_ntop(ifi->ifi_addr, sizeof(struct sockaddr_in))); + + sin = (struct sockaddr_in *) &arpreq.arp_pa; + memcpy(sin, ifi->ifi_addr, sizeof(struct sockaddr_in)); + + if (ioctl(sockfd, SIOCGARP, &arpreq) < 0) { + err_ret("ioctl SIOCGARP"); + continue; + } + + ptr = &arpreq.arp_ha.sa_data[0]; + printf("%x:%x:%x:%x:%x:%x\n", *ptr, *(ptr+1), + *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)); + } + exit(0); +} diff --git a/ioctl/test1.c b/ioctl/test1.c new file mode 100644 index 0000000..c5e0c36 --- /dev/null +++ b/ioctl/test1.c @@ -0,0 +1,19 @@ +#include "unp.h" +#include + +int +main(int argc, char **argv) +{ + int i, sockfd, numif; + char buf[1024]; + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + numif = 999; + Ioctl(sockfd, SIOCGIFNUM, &numif); + printf("numif = %d\n", numif); + + i = ioctl(sockfd, SIOCGHIWAT, &buf); + printf("i = %d, errno = %d\n", i, errno); + exit(0); +} diff --git a/ipopts/Makefile b/ipopts/Makefile new file mode 100644 index 0000000..adbc2e0 --- /dev/null +++ b/ipopts/Makefile @@ -0,0 +1,22 @@ +include ../Make.defines + +PROGS = tcpcli01 tcpserv01 + +all: ${PROGS} + +tcpcli01: tcpcli01.o sourceroute.o + ${CC} ${CFLAGS} -o $@ tcpcli01.o sourceroute.o ${LIBS} + +tcpserv01: tcpserv01.o sourceroute.o sigchldwaitpid.o + ${CC} ${CFLAGS} -o $@ tcpserv01.o sourceroute.o sigchldwaitpid.o \ + ${LIBS} + +udpcli01: udpcli01.o + ${CC} ${CFLAGS} -o $@ udpcli01.o ${LIBS} + +udpserv01: udpserv01.o sourceroute6.o dgechoprintroute.o + ${CC} ${CFLAGS} -o $@ udpserv01.o sourceroute6.o dgechoprintroute.o ${LIBS} + + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/ipopts/dgechoprintroute.c b/ipopts/dgechoprintroute.c new file mode 100644 index 0000000..1dcae5a --- /dev/null +++ b/ipopts/dgechoprintroute.c @@ -0,0 +1,41 @@ +#include "unp.h" + +void +dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen) +{ + int n; + char mesg[MAXLINE]; + int on; + char control[MAXLINE]; + struct msghdr msg; + struct cmsghdr *cmsg; + struct iovec iov[1]; + + on = 1; + Setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVRTHDR, &on, sizeof(on)); + + bzero(&msg, sizeof(msg)); + iov[0].iov_base = mesg; + msg.msg_name = pcliaddr; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + msg.msg_control = control; + for ( ; ; ) { + msg.msg_namelen = clilen; + msg.msg_controllen = sizeof(control); + iov[0].iov_len = MAXLINE; + n = Recvmsg(sockfd, &msg, 0); + + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level == IPPROTO_IPV6 && + cmsg->cmsg_type == IPV6_RTHDR) { + inet6_srcrt_print(CMSG_DATA(cmsg)); + Inet6_rth_reverse(CMSG_DATA(cmsg), CMSG_DATA(cmsg)); + } + } + + iov[0].iov_len = n; + Sendmsg(sockfd, &msg, 0); + } +} diff --git a/ipopts/sigchldwaitpid.c b/ipopts/sigchldwaitpid.c new file mode 100644 index 0000000..5fa9cbf --- /dev/null +++ b/ipopts/sigchldwaitpid.c @@ -0,0 +1,13 @@ +#include "unp.h" + +void +sig_chld(int signo) +{ + pid_t pid; + int stat; + + while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) { + printf("child %d terminated\n", pid); + } + return; +} diff --git a/ipopts/sourceroute.c b/ipopts/sourceroute.c new file mode 100644 index 0000000..9673d0c --- /dev/null +++ b/ipopts/sourceroute.c @@ -0,0 +1,82 @@ +/* include inet_srcrt_init */ +#include "unp.h" +#include +#include + +static u_char *optr; /* pointer into options being formed */ +static u_char *lenptr; /* pointer to length byte in SRR option */ +static int ocnt; /* count of # addresses */ + +u_char * +inet_srcrt_init(int type) +{ + optr = Malloc(44); /* NOP, code, len, ptr, up to 10 addresses */ + bzero(optr, 44); /* guarantees EOLs at end */ + ocnt = 0; + *optr++ = IPOPT_NOP; /* NOP for alignment */ + *optr++ = type ? IPOPT_SSRR : IPOPT_LSRR; + lenptr = optr++; /* we fill in length later */ + *optr++ = 4; /* offset to first address */ + + return(optr - 4); /* pointer for setsockopt() */ +} +/* end inet_srcrt_init */ + +/* include inet_srcrt_add */ +int +inet_srcrt_add(char *hostptr) +{ + int len; + struct addrinfo *ai; + struct sockaddr_in *sin; + + if (ocnt > 9) + err_quit("too many source routes with: %s", hostptr); + + ai = Host_serv(hostptr, NULL, AF_INET, 0); + sin = (struct sockaddr_in *) ai->ai_addr; + memcpy(optr, &sin->sin_addr, sizeof(struct in_addr)); + freeaddrinfo(ai); + + optr += sizeof(struct in_addr); + ocnt++; + len = 3 + (ocnt * sizeof(struct in_addr)); + *lenptr = len; + return(len + 1); /* size for setsockopt() */ +} +/* end inet_srcrt_add */ + +/* include inet_srcrt_print */ +void +inet_srcrt_print(u_char *ptr, int len) +{ + u_char c; + char str[INET_ADDRSTRLEN]; + struct in_addr hop1; + + memcpy(&hop1, ptr, sizeof(struct in_addr)); + ptr += sizeof(struct in_addr); + + while ( (c = *ptr++) == IPOPT_NOP) + ; /* skip any leading NOPs */ + + if (c == IPOPT_LSRR) + printf("received LSRR: "); + else if (c == IPOPT_SSRR) + printf("received SSRR: "); + else { + printf("received option type %d\n", c); + return; + } + printf("%s ", Inet_ntop(AF_INET, &hop1, str, sizeof(str))); + + len = *ptr++ - sizeof(struct in_addr); /* subtract dest IP addr */ + ptr++; /* skip over pointer */ + while (len > 0) { + printf("%s ", Inet_ntop(AF_INET, ptr, str, sizeof(str))); + ptr += sizeof(struct in_addr); + len -= sizeof(struct in_addr); + } + printf("\n"); +} +/* end inet_srcrt_print */ diff --git a/ipopts/sourceroute.lc b/ipopts/sourceroute.lc new file mode 100644 index 0000000..cb7bb7a --- /dev/null +++ b/ipopts/sourceroute.lc @@ -0,0 +1,83 @@ +/* include inet_srcrt_init */ +#include "unp.h"## 1 ##src/ipopts/sourceroute.c## +#include ## 2 ##src/ipopts/sourceroute.c## +#include ## 3 ##src/ipopts/sourceroute.c## + +static u_char *optr; /* pointer into options being formed */## 4 ##src/ipopts/sourceroute.c## +static u_char *lenptr; /* pointer to length byte in SRR option */## 5 ##src/ipopts/sourceroute.c## +static int ocnt; /* count of # addresses */## 6 ##src/ipopts/sourceroute.c## + +u_char *## 7 ##src/ipopts/sourceroute.c## +inet_srcrt_init(void)## 8 ##src/ipopts/sourceroute.c## +{## 9 ##src/ipopts/sourceroute.c## + optr = Malloc(44); /* NOP, code, len, ptr, up to 10 addresses */## 10 ##src/ipopts/sourceroute.c## + bzero(optr, 44); /* guarantees EOLs at end */## 11 ##src/ipopts/sourceroute.c## + ocnt = 0;## 12 ##src/ipopts/sourceroute.c## + return (optr); /* pointer for setsockopt() */## 13 ##src/ipopts/sourceroute.c## +}## 14 ##src/ipopts/sourceroute.c## +/* end inet_srcrt_init */ + +/* include inet_srcrt_add */ +int## 15 ##src/ipopts/sourceroute.c## +inet_srcrt_add(char *hostptr, int type)## 16 ##src/ipopts/sourceroute.c## +{## 17 ##src/ipopts/sourceroute.c## + int len;## 18 ##src/ipopts/sourceroute.c## + struct addrinfo *ai;## 19 ##src/ipopts/sourceroute.c## + struct sockaddr_in *sin;## 20 ##src/ipopts/sourceroute.c## + + if (ocnt > 9)## 21 ##src/ipopts/sourceroute.c## + err_quit("too many source routes with: %s", hostptr);## 22 ##src/ipopts/sourceroute.c## + + if (ocnt == 0) {## 23 ##src/ipopts/sourceroute.c## + *optr++ = IPOPT_NOP; /* NOP for alignment */## 24 ##src/ipopts/sourceroute.c## + *optr++ = type ? IPOPT_SSRR : IPOPT_LSRR;## 25 ##src/ipopts/sourceroute.c## + lenptr = optr++; /* we fill in the length later */## 26 ##src/ipopts/sourceroute.c## + *optr++ = 4; /* offset to first address */## 27 ##src/ipopts/sourceroute.c## + }## 28 ##src/ipopts/sourceroute.c## + + ai = Host_serv(hostptr, "", AF_INET, 0);## 29 ##src/ipopts/sourceroute.c## + sin = (struct sockaddr_in *) ai->ai_addr;## 30 ##src/ipopts/sourceroute.c## + memcpy(optr, &sin->sin_addr, sizeof(struct in_addr));## 31 ##src/ipopts/sourceroute.c## + freeaddrinfo(ai);## 32 ##src/ipopts/sourceroute.c## + + optr += sizeof(struct in_addr);## 33 ##src/ipopts/sourceroute.c## + ocnt++;## 34 ##src/ipopts/sourceroute.c## + len = 3 + (ocnt * sizeof(struct in_addr));## 35 ##src/ipopts/sourceroute.c## + *lenptr = len;## 36 ##src/ipopts/sourceroute.c## + return (len + 1); /* size for setsockopt() */## 37 ##src/ipopts/sourceroute.c## +}## 38 ##src/ipopts/sourceroute.c## +/* end inet_srcrt_add */ + +/* include inet_srcrt_print */ +void## 39 ##src/ipopts/sourceroute.c## +inet_srcrt_print(u_char *ptr, int len)## 40 ##src/ipopts/sourceroute.c## +{## 41 ##src/ipopts/sourceroute.c## + u_char c;## 42 ##src/ipopts/sourceroute.c## + char str[INET_ADDRSTRLEN];## 43 ##src/ipopts/sourceroute.c## + struct in_addr hop1;## 44 ##src/ipopts/sourceroute.c## + + memcpy(&hop1, ptr, sizeof(struct in_addr));## 45 ##src/ipopts/sourceroute.c## + ptr += sizeof(struct in_addr);## 46 ##src/ipopts/sourceroute.c## + + while ((c = *ptr++) == IPOPT_NOP) ; /* skip any leading NOPs */## 47 ##src/ipopts/sourceroute.c## + + if (c == IPOPT_LSRR)## 48 ##src/ipopts/sourceroute.c## + printf("received LSRR: ");## 49 ##src/ipopts/sourceroute.c## + else if (c == IPOPT_SSRR)## 50 ##src/ipopts/sourceroute.c## + printf("received SSRR: ");## 51 ##src/ipopts/sourceroute.c## + else {## 52 ##src/ipopts/sourceroute.c## + printf("received option type %d\n", c);## 53 ##src/ipopts/sourceroute.c## + return;## 54 ##src/ipopts/sourceroute.c## + }## 55 ##src/ipopts/sourceroute.c## + printf("%s ", Inet_ntop(AF_INET, &hop1, str, sizeof(str)));## 56 ##src/ipopts/sourceroute.c## + + len = *ptr++ - sizeof(struct in_addr); /* subtract dest IP addr */## 57 ##src/ipopts/sourceroute.c## + ptr++; /* skip over pointer */## 58 ##src/ipopts/sourceroute.c## + while (len > 0) {## 59 ##src/ipopts/sourceroute.c## + printf("%s ", Inet_ntop(AF_INET, ptr, str, sizeof(str)));## 60 ##src/ipopts/sourceroute.c## + ptr += sizeof(struct in_addr);## 61 ##src/ipopts/sourceroute.c## + len -= sizeof(struct in_addr);## 62 ##src/ipopts/sourceroute.c## + }## 63 ##src/ipopts/sourceroute.c## + printf("\n");## 64 ##src/ipopts/sourceroute.c## +}## 65 ##src/ipopts/sourceroute.c## +/* end inet_srcrt_print */ diff --git a/ipopts/sourceroute6.c b/ipopts/sourceroute6.c new file mode 100644 index 0000000..e6e0cce --- /dev/null +++ b/ipopts/sourceroute6.c @@ -0,0 +1,15 @@ +#include "unp.h" + +void +inet6_srcrt_print(void *ptr) +{ + int i, segments; + char str[INET6_ADDRSTRLEN]; + + segments = Inet6_rth_segments(ptr); + printf("received source route: "); + for (i = 0; i < segments; i++) + printf("%s ", Inet_ntop(AF_INET6, Inet6_rth_getaddr(ptr, i), + str, sizeof(str))); + printf("\n"); +} diff --git a/ipopts/tcpcli01.c b/ipopts/tcpcli01.c new file mode 100644 index 0000000..27ebd71 --- /dev/null +++ b/ipopts/tcpcli01.c @@ -0,0 +1,58 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int c, sockfd, len = 0; + u_char *ptr = NULL; + struct addrinfo *ai; + + if (argc < 2) + err_quit("usage: tcpcli01 [ -[gG] ... ] "); + + opterr = 0; /* don't want getopt() writing to stderr */ + while ( (c = getopt(argc, argv, "gG")) != -1) { + switch (c) { + case 'g': /* loose source route */ + if (ptr) + err_quit("can't use both -g and -G"); + ptr = inet_srcrt_init(0); + break; + + case 'G': /* strict source route */ + if (ptr) + err_quit("can't use both -g and -G"); + ptr = inet_srcrt_init(1); + break; + + case '?': + err_quit("unrecognized option: %c", c); + } + } + + if (ptr) + while (optind < argc-1) + len = inet_srcrt_add(argv[optind++]); + else + if (optind < argc-1) + err_quit("need -g or -G to specify route"); + + if (optind != argc-1) + err_quit("missing "); + + ai = Host_serv(argv[optind], SERV_PORT_STR, AF_INET, SOCK_STREAM); + + sockfd = Socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + + if (ptr) { + len = inet_srcrt_add(argv[optind]); /* dest at end */ + Setsockopt(sockfd, IPPROTO_IP, IP_OPTIONS, ptr, len); + free(ptr); + } + + Connect(sockfd, ai->ai_addr, ai->ai_addrlen); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/ipopts/tcpserv01.c b/ipopts/tcpserv01.c new file mode 100644 index 0000000..04274fd --- /dev/null +++ b/ipopts/tcpserv01.c @@ -0,0 +1,51 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + u_char *opts; + pid_t childpid; + socklen_t clilen, len; + struct sockaddr_in cliaddr, servaddr; + void sig_chld(int); + + opts = Malloc(44); + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + Signal(SIGCHLD, sig_chld); + + for ( ; ; ) { + clilen = sizeof(cliaddr); + if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) { + if (errno == EINTR) + continue; /* back to for() */ + else + err_sys("accept error"); + } + + len = 44; + Getsockopt(connfd, IPPROTO_IP, IP_OPTIONS, opts, &len); + if (len > 0) { + printf("received IP options, len = %d\n", len); + inet_srcrt_print(opts, len); + } + + if ( (childpid = Fork()) == 0) { /* child process */ + Close(listenfd); /* close listening socket */ + str_echo(connfd); /* process the request */ + exit(0); + } + Close(connfd); /* parent closes connected socket */ + } +} diff --git a/ipopts/udpcli01.c b/ipopts/udpcli01.c new file mode 100644 index 0000000..4a5a7ed --- /dev/null +++ b/ipopts/udpcli01.c @@ -0,0 +1,38 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int c, sockfd, len = 0; + u_char *ptr = NULL; + void *rth; + struct addrinfo *ai; + + if (argc < 2) + err_quit("usage: udpcli01 [ ... ] "); + + if (argc > 2) { + int i; + + len = Inet6_rth_space(IPV6_RTHDR_TYPE_0, argc-2); + ptr = Malloc(len); + Inet6_rth_init(ptr, len, IPV6_RTHDR_TYPE_0, argc-2); + for (i = 1; i < argc-1; i++) { + ai = Host_serv(argv[i], NULL, AF_INET6, 0); + Inet6_rth_add(ptr, &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr); + } + } + + ai = Host_serv(argv[argc-1], SERV_PORT_STR, AF_INET6, SOCK_DGRAM); + + sockfd = Socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + + if (ptr) { + Setsockopt(sockfd, IPPROTO_IPV6, IPV6_RTHDR, ptr, len); + free(ptr); + } + + dg_cli(stdin, sockfd, ai->ai_addr, ai->ai_addrlen); /* do it all */ + + exit(0); +} diff --git a/ipopts/udpserv01.c b/ipopts/udpserv01.c new file mode 100644 index 0000000..8915f16 --- /dev/null +++ b/ipopts/udpserv01.c @@ -0,0 +1,19 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in6 servaddr, cliaddr; + + sockfd = Socket(AF_INET6, SOCK_DGRAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin6_family = AF_INET6; + servaddr.sin6_addr = in6addr_any; + servaddr.sin6_port = htons(SERV_PORT); + + Bind(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr)); +} diff --git a/key/Makefile b/key/Makefile new file mode 100644 index 0000000..4709357 --- /dev/null +++ b/key/Makefile @@ -0,0 +1,15 @@ +include ../Make.defines + +PROGS = dump register add +OBJS = printsadbmsg.o name.o + +all: ${PROGS} + +dump: dump.o ${OBJS} + ${CC} ${CFLAGS} -o $@ $@.o ${OBJS} ${LIBS} + +register: register.o ${OBJS} + ${CC} ${CFLAGS} -o $@ $@.o ${OBJS} ${LIBS} + +add: add.o ${OBJS} + ${CC} ${CFLAGS} -o $@ $@.o ${OBJS} ${LIBS} diff --git a/key/add.c b/key/add.c new file mode 100644 index 0000000..a9cd814 --- /dev/null +++ b/key/add.c @@ -0,0 +1,181 @@ +#include "unp.h" +#include + +int +salen(struct sockaddr *sa) +{ +#ifdef HAVE_SOCKADDR_SA_LEN + return sa->sa_len; +#else + switch (sa->sa_family) { + case AF_INET: + return sizeof(struct sockaddr_in); +#ifdef IPV6 + case AF_INET6: + return sizeof(struct sockaddr_in6); +#endif + default: + return 0; /* XXX */ + } +#endif +} + +int +prefix_all(struct sockaddr *sa) +{ + switch (sa->sa_family) { + case AF_INET: + return 32; +#ifdef IPV6 + case AF_INET6: + return 128; +#endif + default: + return 0; /* XXX */ + } +} + +/* include sadb_add */ +void +sadb_add(struct sockaddr *src, struct sockaddr *dst, int type, int alg, + int spi, int keybits, unsigned char *keydata) +{ + int s; + char buf[4096], *p; /* XXX */ + struct sadb_msg *msg; + struct sadb_sa *saext; + struct sadb_address *addrext; + struct sadb_key *keyext; + int len; + int mypid; + + s = Socket(PF_KEY, SOCK_RAW, PF_KEY_V2); + + mypid = getpid(); + + /* Build and write SADB_ADD request */ + bzero(&buf, sizeof(buf)); + p = buf; + msg = (struct sadb_msg *)p; + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = SADB_ADD; + msg->sadb_msg_satype = type; + msg->sadb_msg_pid = getpid(); + len = sizeof(*msg); + p += sizeof(*msg); + + saext = (struct sadb_sa *)p; + saext->sadb_sa_len = sizeof(*saext) / 8; + saext->sadb_sa_exttype = SADB_EXT_SA; + saext->sadb_sa_spi = htonl(spi); + saext->sadb_sa_replay = 0; /* no replay protection with static keys */ + saext->sadb_sa_state = SADB_SASTATE_MATURE; + saext->sadb_sa_auth = alg; + saext->sadb_sa_encrypt = SADB_EALG_NONE; + saext->sadb_sa_flags = 0; + len += saext->sadb_sa_len * 8; + p += saext->sadb_sa_len * 8; + + addrext = (struct sadb_address *)p; + addrext->sadb_address_len = (sizeof(*addrext) + salen(src) + 7) / 8; + addrext->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; + addrext->sadb_address_proto = 0; /* any protocol */ + addrext->sadb_address_prefixlen = prefix_all(src); + addrext->sadb_address_reserved = 0; + memcpy(addrext + 1, src, salen(src)); + len += addrext->sadb_address_len * 8; + p += addrext->sadb_address_len * 8; + + addrext = (struct sadb_address *)p; + addrext->sadb_address_len = (sizeof(*addrext) + salen(dst) + 7) / 8; + addrext->sadb_address_exttype = SADB_EXT_ADDRESS_DST; + addrext->sadb_address_proto = 0; /* any protocol */ + addrext->sadb_address_prefixlen = prefix_all(dst); + addrext->sadb_address_reserved = 0; + memcpy(addrext + 1, dst, salen(dst)); + len += addrext->sadb_address_len * 8; + p += addrext->sadb_address_len * 8; + + keyext = (struct sadb_key *)p; + /* "+7" handles alignment requirements */ + keyext->sadb_key_len = (sizeof(*keyext) + (keybits / 8) + 7) / 8; + keyext->sadb_key_exttype = SADB_EXT_KEY_AUTH; + keyext->sadb_key_bits = keybits; + keyext->sadb_key_reserved = 0; + memcpy(keyext + 1, keydata, keybits / 8); + len += keyext->sadb_key_len * 8; + p += keyext->sadb_key_len * 8; + + msg->sadb_msg_len = len / 8; + printf("Sending add message:\n"); + print_sadb_msg(buf, len); + Write(s, buf, len); + + printf("\nReply returned:\n"); + /* Read and print SADB_ADD reply, discarding any others */ + for (;;) { + int msglen; + struct sadb_msg *msgp; + + msglen = Read(s, &buf, sizeof(buf)); + msgp = (struct sadb_msg *)&buf; + if (msgp->sadb_msg_pid == mypid && + msgp->sadb_msg_type == SADB_ADD) { + print_sadb_msg(msgp, msglen); + break; + } + } + close(s); +} +/* end sadb_add */ + +int +main(int argc, char **argv) +{ + struct addrinfo hints, *src, *dst; + unsigned char *p, *keydata, *kp; + char *ep; + int ret, len, i; + int satype, alg, keybits; + + bzero(&hints, sizeof(hints)); + if ((ret = getaddrinfo(argv[1], NULL, &hints, &src)) != 0) { + err_quit("%s: %s\n", argv[1], gai_strerror(ret)); + } + if ((ret = getaddrinfo(argv[2], NULL, &hints, &dst)) != 0) { + err_quit("%s: %s\n", argv[2], gai_strerror(ret)); + } + if (src->ai_family != dst->ai_family) { + err_quit("%s and %s not same addr family\n", argv[1], argv[2]); + } + satype = SADB_SATYPE_AH; + if ((alg = getsaalgbyname(satype, argv[3])) < 0) { + err_quit("Unknown SA type / algorithm pair ah/%s\n", argv[3]); + } + keybits = strtoul(argv[4], &ep, 0); + if (ep == argv[4] || *ep != '\0' || (keybits % 8) != 0) { + err_quit("Invalid number of bits %s\n", argv[4]); + } + p = argv[5]; + if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) + p += 2; + len = strlen(p); + kp = keydata = malloc(keybits / 8); + for (i = 0; i < keybits; i += 8) { + int c; + + if (len < 2) { + err_quit("%s: not enough bytes (expected %d)\n", argv[5], keybits / 8); + } + if (sscanf(p, "%2x", &c) != 1) { + err_quit("%s contains invalid hex digit\n", argv[5]); + } + *kp++ = c; + p += 2; + len -= 2; + } + if (len > 0) { + err_quit("%s: too many bytes (expected %d)\n", argv[5], keybits / 8); + } + sadb_add(src->ai_addr, dst->ai_addr, satype, alg, 0x9876, keybits, keydata); +} diff --git a/key/dump.c b/key/dump.c new file mode 100644 index 0000000..25ba3c6 --- /dev/null +++ b/key/dump.c @@ -0,0 +1,63 @@ +#include "unp.h" +#include + +/* include sadb_dump */ +void +sadb_dump(int type) +{ + int s; + char buf[4096]; + struct sadb_msg msg; + int goteof; + + s = Socket(PF_KEY, SOCK_RAW, PF_KEY_V2); + + /* Build and write SADB_DUMP request */ + bzero(&msg, sizeof(msg)); + msg.sadb_msg_version = PF_KEY_V2; + msg.sadb_msg_type = SADB_DUMP; + msg.sadb_msg_satype = type; + msg.sadb_msg_len = sizeof(msg) / 8; + msg.sadb_msg_pid = getpid(); + printf("Sending dump message:\n"); + print_sadb_msg(&msg, sizeof(msg)); + Write(s, &msg, sizeof(msg)); + + printf("\nMessages returned:\n"); + /* Read and print SADB_DUMP replies until done */ + goteof = 0; + while (goteof == 0) { + int msglen; + struct sadb_msg *msgp; + + msglen = Read(s, &buf, sizeof(buf)); + msgp = (struct sadb_msg *)&buf; + print_sadb_msg(msgp, msglen); + if (msgp->sadb_msg_seq == 0) + goteof = 1; + } + close(s); +} + +int +main(int argc, char **argv) +{ + int satype = SADB_SATYPE_UNSPEC; + int c; + + opterr = 0; /* don't want getopt() writing to stderr */ + while ( (c = getopt(argc, argv, "t:")) != -1) { + switch (c) { + case 't': + if ((satype = getsatypebyname(optarg)) == -1) + err_quit("invalid -t option %s", optarg); + break; + + default: + err_quit("unrecognized option: %c", c); + } + } + + sadb_dump(satype); +} +/* end sadb_dump */ diff --git a/key/name.c b/key/name.c new file mode 100644 index 0000000..b39cd39 --- /dev/null +++ b/key/name.c @@ -0,0 +1,59 @@ +#include "unp.h" +#include + +struct idlist { + int val; + const char *name; +}; + +static struct idlist satype[] = { + { SADB_SATYPE_UNSPEC, "unspec" }, + { SADB_SATYPE_AH, "ah" }, + { SADB_SATYPE_ESP, "esp" }, + { SADB_SATYPE_RSVP, "rsvp" }, + { SADB_SATYPE_OSPFV2, "ospfv2" }, + { SADB_SATYPE_RIPV2, "ripv2" }, + { SADB_SATYPE_MIP, "mip" }, + { 0, NULL } }; + +static struct idlist ahalg[] = { + { SADB_AALG_NONE, "none" }, + { SADB_AALG_MD5HMAC, "HMAC-MD5-96" }, + { SADB_AALG_SHA1HMAC, "HMAC-SHA-1-96" }, + { 0, NULL } }; + +static struct idlist espalg[] = { + { SADB_EALG_NONE, "none" }, + { SADB_EALG_DESCBC, "DES-CBC" }, + { SADB_EALG_3DESCBC, "3DES-CBC" }, + { SADB_EALG_NULL, "NULL" }, + { 0, NULL } }; + +int +idlistlookup(char *name, struct idlist *il) +{ + for (; il->name != NULL; il++) { + if (strcmp(name, il->name) == 0) + return il->val; + } + return -1; +} + +int +getsatypebyname(char *name) +{ + return idlistlookup(name, satype); +} + +int +getsaalgbyname(int type, char *name) +{ + switch (type) { + case SADB_SATYPE_AH: + return idlistlookup(name, ahalg); + case SADB_SATYPE_ESP: + return idlistlookup(name, espalg); + default: + return -1; + } +} diff --git a/key/printsadbmsg.c b/key/printsadbmsg.c new file mode 100644 index 0000000..76ab4d6 --- /dev/null +++ b/key/printsadbmsg.c @@ -0,0 +1,297 @@ +#include "unp.h" +#include + +const char * +get_sadb_msg_type(int type) +{ + static char buf[100]; + switch (type) { + case SADB_RESERVED: return "Reserved"; + case SADB_GETSPI: return "Get SPI"; + case SADB_UPDATE: return "Update"; + case SADB_ADD: return "Add"; + case SADB_DELETE: return "Delete"; + case SADB_GET: return "Get"; + case SADB_ACQUIRE: return "Acquire"; + case SADB_REGISTER: return "Register"; + case SADB_EXPIRE: return "Expire"; + case SADB_FLUSH: return "Flush"; + case SADB_DUMP: return "Dump"; + default: sprintf(buf, "[Unknown type %d]", type); + return buf; + } +} + +const char * +get_sadb_satype(int type) +{ + static char buf[100]; + switch (type) { + case SADB_SATYPE_UNSPEC: return "Unspecified"; + case SADB_SATYPE_AH: return "IPsec AH"; + case SADB_SATYPE_ESP: return "IPsec ESP"; + case SADB_SATYPE_RSVP: return "RSVP"; + case SADB_SATYPE_OSPFV2: return "OSPFv2"; + case SADB_SATYPE_RIPV2: return "RIPv2"; + case SADB_SATYPE_MIP: return "Mobile IP"; + default: sprintf(buf, "[Unknown satype %d]", type); + return buf; + } +} + +const char * +get_auth_alg(int alg) +{ + static char buf[100]; + switch (alg) { + case SADB_AALG_NONE: return "None"; + case SADB_AALG_MD5HMAC: return "HMAC-MD5"; + case SADB_AALG_SHA1HMAC: return "HMAC-SHA-1"; +#ifdef SADB_X_AALG_MD5 + case SADB_X_AALG_MD5: return "Keyed MD5"; +#endif +#ifdef SADB_X_AALG_SHA + case SADB_X_AALG_SHA: return "Keyed SHA-1"; +#endif +#ifdef SADB_X_AALG_NULL + case SADB_X_AALG_NULL: return "Null"; +#endif +#ifdef SADB_X_AALG_SHA2_256 + case SADB_X_AALG_SHA2_256: return "SHA2-256"; +#endif +#ifdef SADB_X_AALG_SHA2_384 + case SADB_X_AALG_SHA2_384: return "SHA2-384"; +#endif +#ifdef SADB_X_AALG_SHA2_512 + case SADB_X_AALG_SHA2_512: return "SHA2-512"; +#endif + default: sprintf(buf, "[Unknown authentication algorithm %d]", alg); + return buf; + } +} + +const char * +get_encrypt_alg(int alg) +{ + static char buf[100]; + switch (alg) { + case SADB_EALG_NONE: return "None"; + case SADB_EALG_DESCBC: return "DES-CBC"; + case SADB_EALG_3DESCBC: return "3DES-CBC"; + case SADB_EALG_NULL: return "Null"; +#ifdef SADB_X_EALG_CAST128CBC + case SADB_X_EALG_CAST128CBC: return "CAST128-CBC"; +#endif +#ifdef SADB_X_EALG_BLOWFISHCBC + case SADB_X_EALG_BLOWFISHCBC: return "Blowfish-CBC"; +#endif +#ifdef SADB_X_EALG_AES + case SADB_X_EALG_AES: return "AES"; +#endif + default: sprintf(buf, "[Unknown encryption algorithm %d]", alg); + return buf; + } +} + +const char * +get_sa_state(int state) +{ + static char buf[100]; + switch (state) { + case SADB_SASTATE_LARVAL: return "Larval"; + case SADB_SASTATE_MATURE: return "Mature"; + case SADB_SASTATE_DYING: return "Dying"; + case SADB_SASTATE_DEAD: return "Dead"; + default: sprintf(buf, "[Unknown SA state %d]", state); + return buf; + } +} + +const char * +get_sadb_alg_type(int alg, int authenc) +{ + if (authenc == SADB_EXT_SUPPORTED_AUTH) { + return get_auth_alg(alg); + } else { + return get_encrypt_alg(alg); + } +} + +void +sa_print(struct sadb_ext *ext) +{ + struct sadb_sa *sa = (struct sadb_sa *)ext; + printf(" SA: SPI=%d Replay Window=%d State=%s\n", + sa->sadb_sa_spi, sa->sadb_sa_replay, + get_sa_state(sa->sadb_sa_state)); + printf(" Authentication Algorithm: %s\n", + get_auth_alg(sa->sadb_sa_auth)); + printf(" Encryption Algorithm: %s\n", + get_encrypt_alg(sa->sadb_sa_encrypt)); + if (sa->sadb_sa_flags & SADB_SAFLAGS_PFS) + printf(" Perfect Forward Secrecy\n"); +} + +void +supported_print(struct sadb_ext *ext) +{ + struct sadb_supported *sup = (struct sadb_supported *)ext; + struct sadb_alg *alg; + int len; + + printf(" Supported %s algorithms:\n", + sup->sadb_supported_exttype == SADB_EXT_SUPPORTED_AUTH ? + "authentication" : + "encryption"); + len = sup->sadb_supported_len * 8; + len -= sizeof(*sup); + if (len == 0) { + printf(" None\n"); + return; + } + for (alg = (struct sadb_alg *)(sup + 1); len>0; len -= sizeof(*alg), alg++) { + printf(" %s ivlen %d bits %d-%d\n", + get_sadb_alg_type(alg->sadb_alg_id, sup->sadb_supported_exttype), + alg->sadb_alg_ivlen, alg->sadb_alg_minbits, alg->sadb_alg_maxbits); + } +} + +void +lifetime_print(struct sadb_ext *ext) +{ + struct sadb_lifetime *life = (struct sadb_lifetime *)ext; + + printf(" %s lifetime:\n", + life->sadb_lifetime_exttype == SADB_EXT_LIFETIME_CURRENT ? + "Current" : + life->sadb_lifetime_exttype == SADB_EXT_LIFETIME_HARD ? + "Hard" : + "Soft"); + printf(" %d allocations, %d bytes", life->sadb_lifetime_allocations, + life->sadb_lifetime_bytes); + if (life->sadb_lifetime_exttype == SADB_EXT_LIFETIME_CURRENT) { + time_t t; + struct tmp *tm; + char buf[100]; + + /* absolute times */ + t = life->sadb_lifetime_addtime; + tm = localtime(&t); + strftime(buf, sizeof(buf), "%c", tm); + printf("\n added at %s, ", buf); + if (life->sadb_lifetime_usetime == 0) { + printf("never used\n"); + } else { + t = life->sadb_lifetime_usetime; + tm = localtime(&t); + strftime(buf, sizeof(buf), "%c", tm); + printf("first used at %s\n", buf); + } + } else { + printf("%d addtime, %d usetime\n", life->sadb_lifetime_addtime, + life->sadb_lifetime_usetime); + } +} + +void +address_print(struct sadb_ext *ext) +{ + struct sadb_address *addr = (struct sadb_address *)ext; + struct sockaddr *sa; + + printf(" %s address: ", + addr->sadb_address_exttype == SADB_EXT_ADDRESS_SRC ? + "Source" : + addr->sadb_address_exttype == SADB_EXT_ADDRESS_DST ? + "Dest" : + "Proxy"); + sa = (struct sockaddr *)(addr + 1); + printf(" %s", sock_ntop(sa, addr->sadb_address_len * 8 - sizeof(*addr))); + if (addr->sadb_address_prefixlen == 0) + printf(" "); + else + printf("/%d ", addr->sadb_address_prefixlen); + switch (addr->sadb_address_proto) { + case IPPROTO_UDP: printf("(UDP)"); break; + case IPPROTO_TCP: printf("(TCP)"); break; + case 0: break; + default: printf("(IP proto %d)", addr->sadb_address_proto); + break; + } + printf("\n"); +} + +void +key_print(struct sadb_ext *ext) +{ + struct sadb_key *key = (struct sadb_key *)ext; + int bits; + unsigned char *p; + + printf(" %s key, %d bits: 0x", + key->sadb_key_exttype == SADB_EXT_KEY_AUTH ? + "Authentication" : "Encryption", + key->sadb_key_bits); + for (p = (unsigned char *)(key + 1), bits = key->sadb_key_bits; + bits > 0; p++, bits -= 8) + printf("%02x", *p); + printf("\n"); +} + +void +print_sadb_msg(struct sadb_msg *msg, int msglen) +{ + struct sadb_ext *ext; + + if (msglen != msg->sadb_msg_len * 8) { + err_msg("SADB Message length (%d) doesn't match msglen (%d)\n", + msg->sadb_msg_len * 8, msglen); + return; + } + if (msg->sadb_msg_version != PF_KEY_V2) { + err_msg("SADB Message version not PF_KEY_V2\n"); + return; + } + printf("SADB Message %s, errno %d, satype %s, seq %d, pid %d\n", + get_sadb_msg_type(msg->sadb_msg_type), msg->sadb_msg_errno, + get_sadb_satype(msg->sadb_msg_satype), msg->sadb_msg_seq, + msg->sadb_msg_pid); + if (msg->sadb_msg_errno != 0) + printf(" errno %s\n", strerror(msg->sadb_msg_errno)); + if (msglen == sizeof(struct sadb_msg)) + return; /* no extensions */ + msglen -= sizeof(struct sadb_msg); + ext = (struct sadb_ext *)(msg + 1); + while (msglen > 0) { + switch (ext->sadb_ext_type) { + case SADB_EXT_RESERVED: printf(" Reserved Extension\n"); break; + case SADB_EXT_SA: sa_print(ext); break; + case SADB_EXT_LIFETIME_CURRENT: + case SADB_EXT_LIFETIME_HARD: + case SADB_EXT_LIFETIME_SOFT: + lifetime_print(ext); break; + case SADB_EXT_ADDRESS_SRC: + case SADB_EXT_ADDRESS_DST: + case SADB_EXT_ADDRESS_PROXY: + address_print(ext); break; + case SADB_EXT_KEY_AUTH: + case SADB_EXT_KEY_ENCRYPT: + key_print(ext); break; + case SADB_EXT_IDENTITY_SRC: + case SADB_EXT_IDENTITY_DST: + printf(" [identity...]\n"); break; + case SADB_EXT_SENSITIVITY: + printf(" [sensitivity...]\n"); break; + case SADB_EXT_PROPOSAL: + printf(" [proposal...]\n"); break; + case SADB_EXT_SUPPORTED_AUTH: + case SADB_EXT_SUPPORTED_ENCRYPT: + supported_print(ext); break; + case SADB_EXT_SPIRANGE: + printf(" [spirange...]\n"); break; + default: printf(" [unknown extension %d]\n", ext->sadb_ext_type); + } + msglen -= ext->sadb_ext_len << 3; + ext = (char *)ext + (ext->sadb_ext_len << 3); + } +} diff --git a/key/register.c b/key/register.c new file mode 100644 index 0000000..64620b5 --- /dev/null +++ b/key/register.c @@ -0,0 +1,71 @@ +#include "unp.h" +#include + +/* include sadb_register */ +void +sadb_register(int type) +{ + int s; + char buf[4096]; /* XXX */ + struct sadb_msg msg; + int goteof; + int mypid; + + s = Socket(PF_KEY, SOCK_RAW, PF_KEY_V2); + + mypid = getpid(); + + /* Build and write SADB_REGISTER request */ + bzero(&msg, sizeof(msg)); + msg.sadb_msg_version = PF_KEY_V2; + msg.sadb_msg_type = SADB_REGISTER; + msg.sadb_msg_satype = type; + msg.sadb_msg_len = sizeof(msg) / 8; + msg.sadb_msg_pid = mypid; + printf("Sending register message:\n"); + print_sadb_msg(&msg, sizeof(msg)); + Write(s, &msg, sizeof(msg)); + + printf("\nReply returned:\n"); + /* Read and print SADB_REGISTER reply, discarding any others */ + for (;;) { + int msglen; + struct sadb_msg *msgp; + + msglen = Read(s, &buf, sizeof(buf)); + msgp = (struct sadb_msg *)&buf; + if (msgp->sadb_msg_pid == mypid && + msgp->sadb_msg_type == SADB_REGISTER) { + print_sadb_msg(msgp, msglen); + break; + } + } + close(s); +} +/* end sadb_register */ + +int +main(int argc, char **argv) +{ + int satype = SADB_SATYPE_UNSPEC; + int c; + + opterr = 0; /* don't want getopt() writing to stderr */ + while ( (c = getopt(argc, argv, "t:")) != -1) { + switch (c) { + case 't': + if ((satype = getsatypebyname(optarg)) == -1) + err_quit("invalid -t option %s", optarg); + break; + + default: + err_quit("unrecognized option: %c", c); + } + } + + if (satype == SADB_SATYPE_UNSPEC) { + err_quit("must specify SA type"); + } + + sadb_register(satype); +} diff --git a/key/unp.h b/key/unp.h new file mode 100644 index 0000000..45669cf --- /dev/null +++ b/key/unp.h @@ -0,0 +1,467 @@ +/* include unph */ +/* Our own header. Tabs are set for 4 spaces, not 8 */ + +#ifndef __unp_h +#define __unp_h + +#include "../config.h" /* configuration options for current OS */ + /* "../config.h" is generated by configure */ + +/* If anything changes in the following list of #includes, must change + acsite.m4 also, for configure's tests. */ + +#include /* basic system data types */ +#include /* basic socket definitions */ +#include /* timeval{} for select() */ +#include /* timespec{} for pselect() */ +#include /* sockaddr_in{} and other Internet defns */ +#include /* inet(3) functions */ +#include +#include /* for nonblocking */ +#include +#include +#include +#include +#include +#include /* for S_xxx file mode constants */ +#include /* for iovec{} and readv/writev */ +#include +#include +#include /* for Unix domain sockets */ + +#ifdef HAVE_SYS_SELECT_H +# include /* for convenience */ +#endif + +#ifdef HAVE_SYS_SYSCTL_H +# include +#endif + +#ifdef HAVE_POLL_H +# include /* for convenience */ +#endif + +#ifdef HAVE_STRINGS_H +# include /* for convenience */ +#endif + +/* Three headers are normally needed for socket/file ioctl's: + * , , and . + */ +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_FILIO_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif + +#ifdef HAVE_PTHREAD_H +# include +#endif + +#ifdef HAVE_NET_IF_DL_H +# include +#endif + +/* OSF/1 actually disables recv() and send() in */ +#ifdef __osf__ +#undef recv +#undef send +#define recv(a,b,c,d) recvfrom(a,b,c,d,0,0) +#define send(a,b,c,d) sendto(a,b,c,d,0,0) +#endif + +#ifndef INADDR_NONE +/* $$.Ic INADDR_NONE$$ */ +#define INADDR_NONE 0xffffffff /* should have been in */ +#endif + +#ifndef SHUT_RD /* these three Posix.1g names are quite new */ +#define SHUT_RD 0 /* shutdown for reading */ +#define SHUT_WR 1 /* shutdown for writing */ +#define SHUT_RDWR 2 /* shutdown for reading and writing */ +/* $$.Ic SHUT_RD$$ */ +/* $$.Ic SHUT_WR$$ */ +/* $$.Ic SHUT_RDWR$$ */ +#endif + +/* *INDENT-OFF* */ +#ifndef INET_ADDRSTRLEN +/* $$.Ic INET_ADDRSTRLEN$$ */ +#define INET_ADDRSTRLEN 16 /* "ddd.ddd.ddd.ddd\0" + 1234567890123456 */ +#endif + +/* Define following even if IPv6 not supported, so we can always allocate + an adequately-sized buffer, without #ifdefs in the code. */ +#ifndef INET6_ADDRSTRLEN +/* $$.Ic INET6_ADDRSTRLEN$$ */ +#define INET6_ADDRSTRLEN 46 /* max size of IPv6 address string: + "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx" or + "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd\0" + 1234567890123456789012345678901234567890123456 */ +#endif +/* *INDENT-ON* */ + +/* Define bzero() as a macro if it's not in standard C library. */ +#ifndef HAVE_BZERO +#define bzero(ptr,n) memset(ptr, 0, n) +/* $$.If bzero$$ */ +/* $$.If memset$$ */ +#endif + +/* Older resolvers do not have gethostbyname2() */ +#ifndef HAVE_GETHOSTBYNAME2 +#define gethostbyname2(host,family) gethostbyname((host)) +#endif + +/* The structure returned by recvfrom_flags() */ +struct in_pktinfo { + struct in_addr ipi_addr; /* dst IPv4 address */ + int ipi_ifindex;/* received interface index */ +}; +/* $$.It in_pktinfo$$ */ +/* $$.Ib ipi_addr$$ */ +/* $$.Ib ipi_ifindex$$ */ + +/* We need the newer CMSG_LEN() and CMSG_SPACE() macros, but few + implementations support them today. These two macros really need + an ALIGN() macro, but each implementation does this differently. */ +#ifndef CMSG_LEN +/* $$.Ic CMSG_LEN$$ */ +#define CMSG_LEN(size) (sizeof(struct cmsghdr) + (size)) +#endif +#ifndef CMSG_SPACE +/* $$.Ic CMSG_SPACE$$ */ +#define CMSG_SPACE(size) (sizeof(struct cmsghdr) + (size)) +#endif + +/* Posix.1g requires the SUN_LEN() macro but not all implementations DefinE + it (yet). Note that this 4.4BSD macro works regardless whether there is + a length field or not. */ +#ifndef SUN_LEN +/* $$.Im SUN_LEN$$ */ +# define SUN_LEN(su) \ + (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) +#endif + +/* Posix.1g renames "Unix domain" as "local IPC". + But not all systems DefinE AF_LOCAL and PF_LOCAL (yet). */ +#ifndef AF_LOCAL +#define AF_LOCAL AF_UNIX +#endif +#ifndef PF_LOCAL +#define PF_LOCAL PF_UNIX +#endif + +/* Posix.1g requires that an #include of DefinE INFTIM, but many + systems still DefinE it in . We don't want to include + all the streams stuff if it's not needed, so we just DefinE INFTIM here. + This is the standard value, but there's no guarantee it is -1. */ +#ifndef INFTIM +#define INFTIM (-1) /* infinite poll timeout */ +/* $$.Ic INFTIM$$ */ +#ifdef HAVE_POLL_H +#define INFTIM_UNPH /* tell unpxti.h we defined it */ +#endif +#endif + +/* Following could be derived from SOMAXCONN in , but many + kernels still #define it as 5, while actually supporting many more */ +#define LISTENQ 1024 /* 2nd argument to listen() */ + +/* Miscellaneous constants */ +#define MAXLINE 4096 /* max text line length */ +#define MAXSOCKADDR 128 /* max socket address structure size */ +#define BUFFSIZE 8192 /* buffer size for reads and writes */ + +/* Define some port number that can be used for client-servers */ +#define SERV_PORT 9877 /* TCP and UDP client-servers */ +#define SERV_PORT_STR "9877" /* TCP and UDP client-servers */ +#define UNIXSTR_PATH "/tmp/unix.str" /* Unix domain stream cli-serv */ +#define UNIXDG_PATH "/tmp/unix.dg" /* Unix domain datagram cli-serv */ +/* $$.ix [LISTENQ]~constant,~definition~of$$ */ +/* $$.ix [MAXLINE]~constant,~definition~of$$ */ +/* $$.ix [MAXSOCKADDR]~constant,~definition~of$$ */ +/* $$.ix [BUFFSIZE]~constant,~definition~of$$ */ +/* $$.ix [SERV_PORT]~constant,~definition~of$$ */ +/* $$.ix [UNIXSTR_PATH]~constant,~definition~of$$ */ +/* $$.ix [UNIXDG_PATH]~constant,~definition~of$$ */ + +/* Following shortens all the type casts of pointer arguments */ +#define SA struct sockaddr + +#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) + /* default file access permissions for new files */ +#define DIR_MODE (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH) + /* default permissions for new directories */ + +typedef void Sigfunc(int); /* for signal handlers */ + +#define min(a,b) ((a) < (b) ? (a) : (b)) +#define max(a,b) ((a) > (b) ? (a) : (b)) + +#ifndef HAVE_ADDRINFO_STRUCT +# include "../lib/addrinfo.h" +#endif + +#ifndef HAVE_IF_NAMEINDEX_STRUCT +struct if_nameindex { + unsigned int if_index; /* 1, 2, ... */ + char *if_name; /* null terminated name: "le0", ... */ +}; +/* $$.It if_nameindex$$ */ +/* $$.Ib if_index$$ */ +/* $$.Ib if_name$$ */ +#endif + +#ifndef HAVE_TIMESPEC_STRUCT +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* and nanoseconds */ +}; +/* $$.It timespec$$ */ +/* $$.Ib tv_sec$$ */ +/* $$.Ib tv_nsec$$ */ +#endif +/* end unph */ + + /* prototypes for our own library functions */ +int connect_nonb(int, const SA *, socklen_t, int); +int connect_timeo(int, const SA *, socklen_t, int); +void daemon_init(const char *, int); +void daemon_inetd(const char *, int); +void dg_cli(FILE *, int, const SA *, socklen_t); +void dg_echo(int, SA *, socklen_t); +int family_to_level(int); +char *gf_time(void); +void heartbeat_cli(int, int, int); +void heartbeat_serv(int, int, int); +struct addrinfo *host_serv(const char *, const char *, int, int); +int inet_srcrt_add(char *, int); +u_char *inet_srcrt_init(void); +void inet_srcrt_print(u_char *, int); +char **my_addrs(int *); +int readable_timeo(int, int); +ssize_t readline(int, void *, size_t); +ssize_t readn(int, void *, size_t); +ssize_t read_fd(int, void *, size_t, int *); +ssize_t recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *, + struct in_pktinfo *); +Sigfunc *signal_intr(int, Sigfunc *); +int sock_bind_wild(int, int); +int sock_cmp_addr(const SA *, const SA *, socklen_t); +int sock_cmp_port(const SA *, const SA *, socklen_t); +int sock_get_port(const SA *, socklen_t); +void sock_set_addr(SA *, socklen_t, const void *); +void sock_set_port(SA *, socklen_t, int); +void sock_set_wild(SA *, socklen_t); +char *sock_ntop(const SA *, socklen_t); +char *sock_ntop_host(const SA *, socklen_t); +int sockfd_to_family(int); +void str_echo(int); +void str_cli(FILE *, int); +int tcp_connect(const char *, const char *); +int tcp_listen(const char *, const char *, socklen_t *); +void tv_sub(struct timeval *, struct timeval *); +int udp_client(const char *, const char *, void **, socklen_t *); +int udp_connect(const char *, const char *); +int udp_server(const char *, const char *, socklen_t *); +int writable_timeo(int, int); +ssize_t writen(int, const void *, size_t); +ssize_t write_fd(int, void *, size_t, int); + +#ifdef MCAST +int mcast_leave(int, const SA *, socklen_t); +int mcast_join(int, const SA *, socklen_t, const char *, u_int); +int mcast_leave_source_group(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen); +int mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen, + const char *ifname, u_int ifindex); +int mcast_block_source(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen); +int mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen); +int mcast_get_if(int); +int mcast_get_loop(int); +int mcast_get_ttl(int); +int mcast_set_if(int, const char *, u_int); +int mcast_set_loop(int, int); +int mcast_set_ttl(int, int); + +void Mcast_leave(int, const SA *, socklen_t); +void Mcast_join(int, const SA *, socklen_t, const char *, u_int); +void Mcast_leave_source_group(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen); +void Mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen, + const char *ifname, u_int ifindex); +void Mcast_block_source(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen); +void Mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen); +int Mcast_get_if(int); +int Mcast_get_loop(int); +int Mcast_get_ttl(int); +void Mcast_set_if(int, const char *, u_int); +void Mcast_set_loop(int, int); +void Mcast_set_ttl(int, int); +#endif + +unsigned short in_cksum(unsigned short *, int); + +#ifndef HAVE_GETADDRINFO_PROTO +int getaddrinfo(const char *, const char *, const struct addrinfo *, + struct addrinfo **); +void freeaddrinfo(struct addrinfo *); +char *gai_strerror(int); +#endif + +#ifndef HAVE_GETNAMEINFO_PROTO +int getnameinfo(const SA *, socklen_t, char *, size_t, char *, size_t, int); +#endif + +#ifndef HAVE_GETHOSTNAME_PROTO +int gethostname(char *, int); +#endif + +#ifndef HAVE_HSTRERROR_PROTO +const char *hstrerror(int); +#endif + +#ifndef HAVE_IF_NAMETOINDEX_PROTO +unsigned int if_nametoindex(const char *); +char *if_indextoname(unsigned int, char *); +void if_freenameindex(struct if_nameindex *); +struct if_nameindex *if_nameindex(void); +#endif + +#ifndef HAVE_INET_PTON_PROTO +int inet_pton(int, const char *, void *); +const char *inet_ntop(int, const void *, char *, size_t); +#endif + +#ifndef HAVE_INET_ATON_PROTO +int inet_aton(const char *, struct in_addr *); +#endif + +#ifndef HAVE_ISFDTYPE_PROTO +int isfdtype(int, int); +#endif + +#ifndef HAVE_PSELECT_PROTO +int pselect(int, fd_set *, fd_set *, fd_set *, + const struct timespec *, const sigset_t *); +#endif + +#ifndef HAVE_SOCKATMARK_PROTO +int sockatmark(int); +#endif + +#ifndef HAVE_SNPRINTF_PROTO +int snprintf(char *, size_t, const char *, ...); +#endif + + /* prototypes for our own library wrapper functions */ +void Connect_timeo(int, const SA *, socklen_t, int); +int Family_to_level(int); +struct addrinfo *Host_serv(const char *, const char *, int, int); +const char *Inet_ntop(int, const void *, char *, size_t); +void Inet_pton(int, const char *, void *); +char *If_indextoname(unsigned int, char *); +unsigned int If_nametoindex(const char *); +struct if_nameindex *If_nameindex(void); +char **My_addrs(int *); +ssize_t Read_fd(int, void *, size_t, int *); +int Readable_timeo(int, int); +ssize_t Recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *, + struct in_pktinfo *); +Sigfunc *Signal(int, Sigfunc *); +Sigfunc *Signal_intr(int, Sigfunc *); +int Sock_bind_wild(int, int); +char *Sock_ntop(const SA *, socklen_t); +char *Sock_ntop_host(const SA *, socklen_t); +int Sockfd_to_family(int); +int Tcp_connect(const char *, const char *); +int Tcp_listen(const char *, const char *, socklen_t *); +int Udp_client(const char *, const char *, void **, socklen_t *); +int Udp_connect(const char *, const char *); +int Udp_server(const char *, const char *, socklen_t *); +ssize_t Write_fd(int, void *, size_t, int); +int Writable_timeo(int, int); + + /* prototypes for our Unix wrapper functions: see {Sec errors} */ +void *Calloc(size_t, size_t); +void Close(int); +void Dup2(int, int); +int Fcntl(int, int, int); +void Gettimeofday(struct timeval *, void *); +int Ioctl(int, int, void *); +pid_t Fork(void); +void *Malloc(size_t); +int Mkstemp(char *); +void *Mmap(void *, size_t, int, int, int, off_t); +int Open(const char *, int, mode_t); +void Pipe(int *fds); +ssize_t Read(int, void *, size_t); +void Sigaddset(sigset_t *, int); +void Sigdelset(sigset_t *, int); +void Sigemptyset(sigset_t *); +void Sigfillset(sigset_t *); +int Sigismember(const sigset_t *, int); +void Sigpending(sigset_t *); +void Sigprocmask(int, const sigset_t *, sigset_t *); +char *Strdup(const char *); +long Sysconf(int); +void Sysctl(int *, u_int, void *, size_t *, void *, size_t); +void Unlink(const char *); +pid_t Wait(int *); +pid_t Waitpid(pid_t, int *, int); +void Write(int, void *, size_t); + + /* prototypes for our stdio wrapper functions: see {Sec errors} */ +void Fclose(FILE *); +FILE *Fdopen(int, const char *); +char *Fgets(char *, int, FILE *); +FILE *Fopen(const char *, const char *); +void Fputs(const char *, FILE *); + + /* prototypes for our socket wrapper functions: see {Sec errors} */ +int Accept(int, SA *, socklen_t *); +void Bind(int, const SA *, socklen_t); +void Connect(int, const SA *, socklen_t); +void Getpeername(int, SA *, socklen_t *); +void Getsockname(int, SA *, socklen_t *); +void Getsockopt(int, int, int, void *, socklen_t *); +int Isfdtype(int, int); +void Listen(int, int); +#ifdef HAVE_POLL +int Poll(struct pollfd *, unsigned long, int); +#endif +ssize_t Readline(int, void *, size_t); +ssize_t Readn(int, void *, size_t); +ssize_t Recv(int, void *, size_t, int); +ssize_t Recvfrom(int, void *, size_t, int, SA *, socklen_t *); +ssize_t Recvmsg(int, struct msghdr *, int); +int Select(int, fd_set *, fd_set *, fd_set *, struct timeval *); +void Send(int, const void *, size_t, int); +void Sendto(int, const void *, size_t, int, const SA *, socklen_t); +void Sendmsg(int, const struct msghdr *, int); +void Setsockopt(int, int, int, const void *, socklen_t); +void Shutdown(int, int); +int Sockatmark(int); +int Socket(int, int, int); +void Socketpair(int, int, int, int *); +void Writen(int, void *, size_t); + +void err_dump(const char *, ...); +void err_msg(const char *, ...); +void err_quit(const char *, ...); +void err_ret(const char *, ...); +void err_sys(const char *, ...); + +#endif /* __unp_h */ diff --git a/lib/Makefile b/lib/Makefile new file mode 100644 index 0000000..fa97028 --- /dev/null +++ b/lib/Makefile @@ -0,0 +1,8 @@ +include ../Make.defines + +all: ${LIB_OBJS} + ar rv ${LIBUNP_NAME} $? + ${RANLIB} ${LIBUNP_NAME} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/lib/addrinfo.h b/lib/addrinfo.h new file mode 100644 index 0000000..7cef135 --- /dev/null +++ b/lib/addrinfo.h @@ -0,0 +1,48 @@ +#ifndef __addrinfo_h +#define __addrinfo_h + +/* + * Everything here really belongs in . + * These defines are separate for now, to avoid having to modify the + * system's header. + */ + +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for host */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; + + /* following for getaddrinfo() */ +#define AI_PASSIVE 1 /* socket is intended for bind() + listen() */ +#define AI_CANONNAME 2 /* return canonical name */ + + /* following for getnameinfo() */ +#define NI_MAXHOST 1025 /* max hostname returned */ +#define NI_MAXSERV 32 /* max service name returned */ + +#define NI_NOFQDN 1 /* do not return FQDN */ +#define NI_NUMERICHOST 2 /* return numeric form of hostname */ +#define NI_NAMEREQD 4 /* return error if hostname not found */ +#define NI_NUMERICSERV 8 /* return numeric form of service name */ +#define NI_DGRAM 16 /* datagram service for getservbyname() */ + + /* error returns */ +#define EAI_ADDRFAMILY 1 /* address family for host not supported */ +#define EAI_AGAIN 2 /* temporary failure in name resolution */ +#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ +#define EAI_FAIL 4 /* non-recoverable failure in name resolution */ +#define EAI_FAMILY 5 /* ai_family not supported */ +#define EAI_MEMORY 6 /* memory allocation failure */ +#define EAI_NODATA 7 /* no address associated with host */ +#define EAI_NONAME 8 /* host nor service provided, or not known */ +#define EAI_SERVICE 9 /* service not supported for ai_socktype */ +#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ +#define EAI_SYSTEM 11 /* system error returned in errno */ + +#endif /* __addrinfo_h */ diff --git a/lib/connect_nonb.c b/lib/connect_nonb.c new file mode 100644 index 0000000..53a92e7 --- /dev/null +++ b/lib/connect_nonb.c @@ -0,0 +1,53 @@ +#include "unp.h" + +int +connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec) +{ + int flags, n, error; + socklen_t len; + fd_set rset, wset; + struct timeval tval; + + flags = Fcntl(sockfd, F_GETFL, 0); + Fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); + + error = 0; + if ( (n = connect(sockfd, saptr, salen)) < 0) + if (errno != EINPROGRESS) + return(-1); + + /* Do whatever we want while the connect is taking place. */ + + if (n == 0) + goto done; /* connect completed immediately */ + + FD_ZERO(&rset); + FD_SET(sockfd, &rset); + wset = rset; + tval.tv_sec = nsec; + tval.tv_usec = 0; + + if ( (n = Select(sockfd+1, &rset, &wset, NULL, + nsec ? &tval : NULL)) == 0) { + close(sockfd); /* timeout */ + errno = ETIMEDOUT; + return(-1); + } + + if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) { + len = sizeof(error); + if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) + return(-1); /* Solaris pending error */ + } else + err_quit("select error: sockfd not set"); + +done: + Fcntl(sockfd, F_SETFL, flags); /* restore file status flags */ + + if (error) { + close(sockfd); /* just in case */ + errno = error; + return(-1); + } + return(0); +} diff --git a/lib/connect_nonb.lc b/lib/connect_nonb.lc new file mode 100644 index 0000000..79f4749 --- /dev/null +++ b/lib/connect_nonb.lc @@ -0,0 +1,53 @@ +#include "unp.h"## 1 ##src/lib/connect_nonb.c## + +int## 2 ##src/lib/connect_nonb.c## +connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec)## 3 ##src/lib/connect_nonb.c## +{## 4 ##src/lib/connect_nonb.c## + int flags, n, error;## 5 ##src/lib/connect_nonb.c## + socklen_t len;## 6 ##src/lib/connect_nonb.c## + fd_set rset, wset;## 7 ##src/lib/connect_nonb.c## + struct timeval tval;## 8 ##src/lib/connect_nonb.c## + + flags = Fcntl(sockfd, F_GETFL, 0);## 9 ##src/lib/connect_nonb.c## + Fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);## 10 ##src/lib/connect_nonb.c## + + error = 0;## 11 ##src/lib/connect_nonb.c## + if ((n = connect(sockfd, saptr, salen)) < 0)## 12 ##src/lib/connect_nonb.c## + if (errno != EINPROGRESS)## 13 ##src/lib/connect_nonb.c## + return (-1);## 14 ##src/lib/connect_nonb.c## + + /* Do whatever we want while the connect is taking place. */## 15 ##src/lib/connect_nonb.c## + + if (n == 0)## 16 ##src/lib/connect_nonb.c## + goto done; /* connect completed immediately */## 17 ##src/lib/connect_nonb.c## + + FD_ZERO(&rset);## 18 ##src/lib/connect_nonb.c## + FD_SET(sockfd, &rset);## 19 ##src/lib/connect_nonb.c## + wset = rset;## 20 ##src/lib/connect_nonb.c## + tval.tv_sec = nsec;## 21 ##src/lib/connect_nonb.c## + tval.tv_usec = 0;## 22 ##src/lib/connect_nonb.c## + + if ((n = Select(sockfd + 1, &rset, &wset, NULL,## 23 ##src/lib/connect_nonb.c## + nsec ? &tval : NULL)) == 0) {## 24 ##src/lib/connect_nonb.c## + close(sockfd); /* timeout */## 25 ##src/lib/connect_nonb.c## + errno = ETIMEDOUT;## 26 ##src/lib/connect_nonb.c## + return (-1);## 27 ##src/lib/connect_nonb.c## + }## 28 ##src/lib/connect_nonb.c## + + if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {## 29 ##src/lib/connect_nonb.c## + len = sizeof(error);## 30 ##src/lib/connect_nonb.c## + if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)## 31 ##src/lib/connect_nonb.c## + return (-1); /* Solaris pending error */## 32 ##src/lib/connect_nonb.c## + } else## 33 ##src/lib/connect_nonb.c## + err_quit("select error: sockfd not set");## 34 ##src/lib/connect_nonb.c## + + done:## 35 ##src/lib/connect_nonb.c## + Fcntl(sockfd, F_SETFL, flags); /* restore file status flags */## 36 ##src/lib/connect_nonb.c## + + if (error) {## 37 ##src/lib/connect_nonb.c## + close(sockfd); /* just in case */## 38 ##src/lib/connect_nonb.c## + errno = error;## 39 ##src/lib/connect_nonb.c## + return (-1);## 40 ##src/lib/connect_nonb.c## + }## 41 ##src/lib/connect_nonb.c## + return (0);## 42 ##src/lib/connect_nonb.c## +}## 43 ##src/lib/connect_nonb.c## diff --git a/lib/connect_timeo.c b/lib/connect_timeo.c new file mode 100644 index 0000000..5693ee9 --- /dev/null +++ b/lib/connect_timeo.c @@ -0,0 +1,39 @@ +/* include connect_timeo */ +#include "unp.h" + +static void connect_alarm(int); + +int +connect_timeo(int sockfd, const SA *saptr, socklen_t salen, int nsec) +{ + Sigfunc *sigfunc; + int n; + + sigfunc = Signal(SIGALRM, connect_alarm); + if (alarm(nsec) != 0) + err_msg("connect_timeo: alarm was already set"); + + if ( (n = connect(sockfd, saptr, salen)) < 0) { + close(sockfd); + if (errno == EINTR) + errno = ETIMEDOUT; + } + alarm(0); /* turn off the alarm */ + Signal(SIGALRM, sigfunc); /* restore previous signal handler */ + + return(n); +} + +static void +connect_alarm(int signo) +{ + return; /* just interrupt the connect() */ +} +/* end connect_timeo */ + +void +Connect_timeo(int fd, const SA *sa, socklen_t salen, int sec) +{ + if (connect_timeo(fd, sa, salen, sec) < 0) + err_sys("connect_timeo error"); +} diff --git a/lib/connect_timeo.lc b/lib/connect_timeo.lc new file mode 100644 index 0000000..847ab4a --- /dev/null +++ b/lib/connect_timeo.lc @@ -0,0 +1,39 @@ +/* include connect_timeo */ +#include "unp.h"## 1 ##src/lib/connect_timeo.c## + +static void connect_alarm(int);## 2 ##src/lib/connect_timeo.c## + +int## 3 ##src/lib/connect_timeo.c## +connect_timeo(int sockfd, const SA *saptr, socklen_t salen, int nsec)## 4 ##src/lib/connect_timeo.c## +{## 5 ##src/lib/connect_timeo.c## + Sigfunc *sigfunc;## 6 ##src/lib/connect_timeo.c## + int n;## 7 ##src/lib/connect_timeo.c## + + sigfunc = Signal(SIGALRM, connect_alarm);## 8 ##src/lib/connect_timeo.c## + if (alarm(nsec) != 0)## 9 ##src/lib/connect_timeo.c## + err_msg("connect_timeo: alarm was already set");## 10 ##src/lib/connect_timeo.c## + + if ((n = connect(sockfd, saptr, salen)) < 0) {## 11 ##src/lib/connect_timeo.c## + close(sockfd);## 12 ##src/lib/connect_timeo.c## + if (errno == EINTR)## 13 ##src/lib/connect_timeo.c## + errno = ETIMEDOUT;## 14 ##src/lib/connect_timeo.c## + }## 15 ##src/lib/connect_timeo.c## + alarm(0); /* turn off the alarm */## 16 ##src/lib/connect_timeo.c## + Signal(SIGALRM, sigfunc); /* restore previous signal handler */## 17 ##src/lib/connect_timeo.c## + + return (n);## 18 ##src/lib/connect_timeo.c## +}## 19 ##src/lib/connect_timeo.c## + +static void## 20 ##src/lib/connect_timeo.c## +connect_alarm(int signo)## 21 ##src/lib/connect_timeo.c## +{## 22 ##src/lib/connect_timeo.c## + return; /* just interrupt the connect() */## 23 ##src/lib/connect_timeo.c## +}## 24 ##src/lib/connect_timeo.c## +/* end connect_timeo */ + +void## 25 ##src/lib/connect_timeo.c## +Connect_timeo(int fd, const SA *sa, socklen_t salen, int sec)## 26 ##src/lib/connect_timeo.c## +{## 27 ##src/lib/connect_timeo.c## + if (connect_timeo(fd, sa, salen, sec) < 0)## 28 ##src/lib/connect_timeo.c## + err_sys("connect_timeo error");## 29 ##src/lib/connect_timeo.c## +}## 30 ##src/lib/connect_timeo.c## diff --git a/lib/daemon_inetd.c b/lib/daemon_inetd.c new file mode 100644 index 0000000..ada76e0 --- /dev/null +++ b/lib/daemon_inetd.c @@ -0,0 +1,11 @@ +#include "unp.h" +#include + +extern int daemon_proc; /* defined in error.c */ + +void +daemon_inetd(const char *pname, int facility) +{ + daemon_proc = 1; /* for our err_XXX() functions */ + openlog(pname, LOG_PID, facility); +} diff --git a/lib/daemon_inetd.lc b/lib/daemon_inetd.lc new file mode 100644 index 0000000..d593dc4 --- /dev/null +++ b/lib/daemon_inetd.lc @@ -0,0 +1,11 @@ +#include "unp.h"## 1 ##src/lib/daemon_inetd.c## +#include ## 2 ##src/lib/daemon_inetd.c## + +extern int daemon_proc; /* defined in error.c */## 3 ##src/lib/daemon_inetd.c## + +void## 4 ##src/lib/daemon_inetd.c## +daemon_inetd(const char *pname, int facility)## 5 ##src/lib/daemon_inetd.c## +{## 6 ##src/lib/daemon_inetd.c## + daemon_proc = 1; /* for our err_XXX() functions */## 7 ##src/lib/daemon_inetd.c## + openlog(pname, LOG_PID, facility);## 8 ##src/lib/daemon_inetd.c## +}## 9 ##src/lib/daemon_inetd.c## diff --git a/lib/daemon_init.c b/lib/daemon_init.c new file mode 100644 index 0000000..53dfa89 --- /dev/null +++ b/lib/daemon_init.c @@ -0,0 +1,48 @@ +#include "unp.h" +#include + +#define MAXFD 64 + +extern int daemon_proc; /* defined in error.c */ + +int +daemon_init(const char *pname, int facility) +{ + int i; + pid_t pid; + + if ( (pid = Fork()) < 0) + return (-1); + else if (pid) + _exit(0); /* parent terminates */ + + /* child 1 continues... */ + + if (setsid() < 0) /* become session leader */ + return (-1); + + Signal(SIGHUP, SIG_IGN); + if ( (pid = Fork()) < 0) + return (-1); + else if (pid) + _exit(0); /* child 1 terminates */ + + /* child 2 continues... */ + + daemon_proc = 1; /* for err_XXX() functions */ + + chdir("/"); /* change working directory */ + + /* close off file descriptors */ + for (i = 0; i < MAXFD; i++) + close(i); + + /* redirect stdin, stdout, and stderr to /dev/null */ + open("/dev/null", O_RDONLY); + open("/dev/null", O_RDWR); + open("/dev/null", O_RDWR); + + openlog(pname, LOG_PID, facility); + + return (0); /* success */ +} diff --git a/lib/dg_cli.c b/lib/dg_cli.c new file mode 100644 index 0000000..b3e9fbd --- /dev/null +++ b/lib/dg_cli.c @@ -0,0 +1,18 @@ +#include "unp.h" + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL); + + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } +} diff --git a/lib/dg_echo.c b/lib/dg_echo.c new file mode 100644 index 0000000..03af97a --- /dev/null +++ b/lib/dg_echo.c @@ -0,0 +1,16 @@ +#include "unp.h" + +void +dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen) +{ + int n; + socklen_t len; + char mesg[MAXLINE]; + + for ( ; ; ) { + len = clilen; + n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len); + + Sendto(sockfd, mesg, n, 0, pcliaddr, len); + } +} diff --git a/lib/error.c b/lib/error.c new file mode 100644 index 0000000..3e1b63c --- /dev/null +++ b/lib/error.c @@ -0,0 +1,109 @@ +#include "unp.h" + +#include /* ANSI C header file */ +#include /* for syslog() */ + +int daemon_proc; /* set nonzero by daemon_init() */ + +static void err_doit(int, int, const char *, va_list); + +/* Nonfatal error related to system call + * Print message and return */ + +void +err_ret(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(1, LOG_INFO, fmt, ap); + va_end(ap); + return; +} + +/* Fatal error related to system call + * Print message and terminate */ + +void +err_sys(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(1, LOG_ERR, fmt, ap); + va_end(ap); + exit(1); +} + +/* Fatal error related to system call + * Print message, dump core, and terminate */ + +void +err_dump(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(1, LOG_ERR, fmt, ap); + va_end(ap); + abort(); /* dump core and terminate */ + exit(1); /* shouldn't get here */ +} + +/* Nonfatal error unrelated to system call + * Print message and return */ + +void +err_msg(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(0, LOG_INFO, fmt, ap); + va_end(ap); + return; +} + +/* Fatal error unrelated to system call + * Print message and terminate */ + +void +err_quit(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(0, LOG_ERR, fmt, ap); + va_end(ap); + exit(1); +} + +/* Print message and return to caller + * Caller specifies "errnoflag" and "level" */ + +static void +err_doit(int errnoflag, int level, const char *fmt, va_list ap) +{ + int errno_save, n; + char buf[MAXLINE + 1]; + + errno_save = errno; /* value caller might want printed */ +#ifdef HAVE_VSNPRINTF + vsnprintf(buf, MAXLINE, fmt, ap); /* safe */ +#else + vsprintf(buf, fmt, ap); /* not safe */ +#endif + n = strlen(buf); + if (errnoflag) + snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save)); + strcat(buf, "\n"); + + if (daemon_proc) { + syslog(level, buf); + } else { + fflush(stdout); /* in case stdout and stderr are the same */ + fputs(buf, stderr); + fflush(stderr); + } + return; +} diff --git a/lib/family_to_level.c b/lib/family_to_level.c new file mode 100644 index 0000000..413c58b --- /dev/null +++ b/lib/family_to_level.c @@ -0,0 +1,27 @@ +#include "unp.h" + +int +family_to_level(int family) +{ + switch (family) { + case AF_INET: + return IPPROTO_IP; +#ifdef IPV6 + case AF_INET6: + return IPPROTO_IPV6; +#endif + default: + return -1; + } +} + +int +Family_to_level(int family) +{ + int rc; + + if ( (rc = family_to_level(family)) < 0) + err_sys("family_to_level error"); + + return(rc); +} diff --git a/lib/get_ifi_info.c b/lib/get_ifi_info.c new file mode 100644 index 0000000..4859ff1 --- /dev/null +++ b/lib/get_ifi_info.c @@ -0,0 +1,194 @@ +/* include get_ifi_info1 */ +#include "unpifi.h" + +struct ifi_info * +get_ifi_info(int family, int doaliases) +{ + struct ifi_info *ifi, *ifihead, **ifipnext; + int sockfd, len, lastlen, flags, myflags, idx = 0, hlen = 0; + char *ptr, *buf, lastname[IFNAMSIZ], *cptr, *haddr, *sdlname; + struct ifconf ifc; + struct ifreq *ifr, ifrcopy; + struct sockaddr_in *sinptr; + struct sockaddr_in6 *sin6ptr; + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + lastlen = 0; + len = 100 * sizeof(struct ifreq); /* initial buffer size guess */ + for ( ; ; ) { + buf = Malloc(len); + ifc.ifc_len = len; + ifc.ifc_buf = buf; + if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { + if (errno != EINVAL || lastlen != 0) + err_sys("ioctl error"); + } else { + if (ifc.ifc_len == lastlen) + break; /* success, len has not changed */ + lastlen = ifc.ifc_len; + } + len += 10 * sizeof(struct ifreq); /* increment */ + free(buf); + } + ifihead = NULL; + ifipnext = &ifihead; + lastname[0] = 0; + sdlname = NULL; +/* end get_ifi_info1 */ + +/* include get_ifi_info2 */ + for (ptr = buf; ptr < buf + ifc.ifc_len; ) { + ifr = (struct ifreq *) ptr; + +#ifdef HAVE_SOCKADDR_SA_LEN + len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len); +#else + switch (ifr->ifr_addr.sa_family) { +#ifdef IPV6 + case AF_INET6: + len = sizeof(struct sockaddr_in6); + break; +#endif + case AF_INET: + default: + len = sizeof(struct sockaddr); + break; + } +#endif /* HAVE_SOCKADDR_SA_LEN */ + ptr += sizeof(ifr->ifr_name) + len; /* for next one in buffer */ + +#ifdef HAVE_SOCKADDR_DL_STRUCT + /* assumes that AF_LINK precedes AF_INET or AF_INET6 */ + if (ifr->ifr_addr.sa_family == AF_LINK) { + struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr; + sdlname = ifr->ifr_name; + idx = sdl->sdl_index; + haddr = sdl->sdl_data + sdl->sdl_nlen; + hlen = sdl->sdl_alen; + } +#endif + + if (ifr->ifr_addr.sa_family != family) + continue; /* ignore if not desired address family */ + + myflags = 0; + if ( (cptr = strchr(ifr->ifr_name, ':')) != NULL) + *cptr = 0; /* replace colon with null */ + if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) { + if (doaliases == 0) + continue; /* already processed this interface */ + myflags = IFI_ALIAS; + } + memcpy(lastname, ifr->ifr_name, IFNAMSIZ); + + ifrcopy = *ifr; + Ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy); + flags = ifrcopy.ifr_flags; + if ((flags & IFF_UP) == 0) + continue; /* ignore if interface not up */ +/* end get_ifi_info2 */ + +/* include get_ifi_info3 */ + ifi = Calloc(1, sizeof(struct ifi_info)); + *ifipnext = ifi; /* prev points to this new one */ + ifipnext = &ifi->ifi_next; /* pointer to next one goes here */ + + ifi->ifi_flags = flags; /* IFF_xxx values */ + ifi->ifi_myflags = myflags; /* IFI_xxx values */ +#if defined(SIOCGIFMTU) && defined(HAVE_STRUCT_IFREQ_IFR_MTU) + Ioctl(sockfd, SIOCGIFMTU, &ifrcopy); + ifi->ifi_mtu = ifrcopy.ifr_mtu; +#else + ifi->ifi_mtu = 0; +#endif + memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME); + ifi->ifi_name[IFI_NAME-1] = '\0'; + /* If the sockaddr_dl is from a different interface, ignore it */ + if (sdlname == NULL || strcmp(sdlname, ifr->ifr_name) != 0) + idx = hlen = 0; + ifi->ifi_index = idx; + ifi->ifi_hlen = hlen; + if (ifi->ifi_hlen > IFI_HADDR) + ifi->ifi_hlen = IFI_HADDR; + if (hlen) + memcpy(ifi->ifi_haddr, haddr, ifi->ifi_hlen); +/* end get_ifi_info3 */ +/* include get_ifi_info4 */ + switch (ifr->ifr_addr.sa_family) { + case AF_INET: + sinptr = (struct sockaddr_in *) &ifr->ifr_addr; + ifi->ifi_addr = Calloc(1, sizeof(struct sockaddr_in)); + memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in)); + +#ifdef SIOCGIFBRDADDR + if (flags & IFF_BROADCAST) { + Ioctl(sockfd, SIOCGIFBRDADDR, &ifrcopy); + sinptr = (struct sockaddr_in *) &ifrcopy.ifr_broadaddr; + ifi->ifi_brdaddr = Calloc(1, sizeof(struct sockaddr_in)); + memcpy(ifi->ifi_brdaddr, sinptr, sizeof(struct sockaddr_in)); + } +#endif + +#ifdef SIOCGIFDSTADDR + if (flags & IFF_POINTOPOINT) { + Ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy); + sinptr = (struct sockaddr_in *) &ifrcopy.ifr_dstaddr; + ifi->ifi_dstaddr = Calloc(1, sizeof(struct sockaddr_in)); + memcpy(ifi->ifi_dstaddr, sinptr, sizeof(struct sockaddr_in)); + } +#endif + break; + + case AF_INET6: + sin6ptr = (struct sockaddr_in6 *) &ifr->ifr_addr; + ifi->ifi_addr = Calloc(1, sizeof(struct sockaddr_in6)); + memcpy(ifi->ifi_addr, sin6ptr, sizeof(struct sockaddr_in6)); + +#ifdef SIOCGIFDSTADDR + if (flags & IFF_POINTOPOINT) { + Ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy); + sin6ptr = (struct sockaddr_in6 *) &ifrcopy.ifr_dstaddr; + ifi->ifi_dstaddr = Calloc(1, sizeof(struct sockaddr_in6)); + memcpy(ifi->ifi_dstaddr, sin6ptr, sizeof(struct sockaddr_in6)); + } +#endif + break; + + default: + break; + } + } + free(buf); + return(ifihead); /* pointer to first structure in linked list */ +} +/* end get_ifi_info4 */ + +/* include free_ifi_info */ +void +free_ifi_info(struct ifi_info *ifihead) +{ + struct ifi_info *ifi, *ifinext; + + for (ifi = ifihead; ifi != NULL; ifi = ifinext) { + if (ifi->ifi_addr != NULL) + free(ifi->ifi_addr); + if (ifi->ifi_brdaddr != NULL) + free(ifi->ifi_brdaddr); + if (ifi->ifi_dstaddr != NULL) + free(ifi->ifi_dstaddr); + ifinext = ifi->ifi_next; /* can't fetch ifi_next after free() */ + free(ifi); /* the ifi_info{} itself */ + } +} +/* end free_ifi_info */ + +struct ifi_info * +Get_ifi_info(int family, int doaliases) +{ + struct ifi_info *ifi; + + if ( (ifi = get_ifi_info(family, doaliases)) == NULL) + err_quit("get_ifi_info error"); + return(ifi); +} diff --git a/lib/get_ifi_info.lc b/lib/get_ifi_info.lc new file mode 100644 index 0000000..5b9ad7e --- /dev/null +++ b/lib/get_ifi_info.lc @@ -0,0 +1,189 @@ +/* include get_ifi_info1 */ +#include "unpifi.h"## 1 ##src/lib/get_ifi_info.c## + +struct ifi_info *## 2 ##src/lib/get_ifi_info.c## +get_ifi_info(int family, int doaliases)## 3 ##src/lib/get_ifi_info.c## +{## 4 ##src/lib/get_ifi_info.c## + struct ifi_info *ifi, *ifihead, **ifipnext;## 5 ##src/lib/get_ifi_info.c## + int sockfd, len, lastlen, flags, myflags, idx = 0, hlen = 0;## 6 ##src/lib/get_ifi_info.c## + char *ptr, *buf, lastname[IFNAMSIZ], *cptr, *haddr;## 7 ##src/lib/get_ifi_info.c## + struct ifconf ifc;## 8 ##src/lib/get_ifi_info.c## + struct ifreq *ifr, ifrcopy;## 9 ##src/lib/get_ifi_info.c## + struct sockaddr_in *sinptr;## 10 ##src/lib/get_ifi_info.c## + struct sockaddr_in6 *sin6ptr;## 11 ##src/lib/get_ifi_info.c## + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0);## 12 ##src/lib/get_ifi_info.c## + + lastlen = 0;## 13 ##src/lib/get_ifi_info.c## + len = 100 * sizeof(struct ifreq); /* initial buffer size guess */## 14 ##src/lib/get_ifi_info.c## + for (;;) {## 15 ##src/lib/get_ifi_info.c## + buf = Malloc(len);## 16 ##src/lib/get_ifi_info.c## + ifc.ifc_len = len;## 17 ##src/lib/get_ifi_info.c## + ifc.ifc_buf = buf;## 18 ##src/lib/get_ifi_info.c## + if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {## 19 ##src/lib/get_ifi_info.c## + if (errno != EINVAL || lastlen != 0)## 20 ##src/lib/get_ifi_info.c## + err_sys("ioctl error");## 21 ##src/lib/get_ifi_info.c## + } else {## 22 ##src/lib/get_ifi_info.c## + if (ifc.ifc_len == lastlen)## 23 ##src/lib/get_ifi_info.c## + break; /* success, len has not changed */## 24 ##src/lib/get_ifi_info.c## + lastlen = ifc.ifc_len;## 25 ##src/lib/get_ifi_info.c## + }## 26 ##src/lib/get_ifi_info.c## + len += 10 * sizeof(struct ifreq); /* increment */## 27 ##src/lib/get_ifi_info.c## + free(buf);## 28 ##src/lib/get_ifi_info.c## + }## 29 ##src/lib/get_ifi_info.c## + ifihead = NULL;## 30 ##src/lib/get_ifi_info.c## + ifipnext = &ifihead;## 31 ##src/lib/get_ifi_info.c## + lastname[0] = 0;## 32 ##src/lib/get_ifi_info.c## +/* end get_ifi_info1 */ + +/* include get_ifi_info2 */ + for (ptr = buf; ptr < buf + ifc.ifc_len;) {## 33 ##src/lib/get_ifi_info.c## + ifr = (struct ifreq *) ptr;## 34 ##src/lib/get_ifi_info.c## + +#ifdef HAVE_SOCKADDR_SA_LEN## 35 ##src/lib/get_ifi_info.c## + len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);## 36 ##src/lib/get_ifi_info.c## +#else## 37 ##src/lib/get_ifi_info.c## + switch (ifr->ifr_addr.sa_family) {## 38 ##src/lib/get_ifi_info.c## +#ifdef IPV6## 39 ##src/lib/get_ifi_info.c## + case AF_INET6:## 40 ##src/lib/get_ifi_info.c## + len = sizeof(struct sockaddr_in6);## 41 ##src/lib/get_ifi_info.c## + break;## 42 ##src/lib/get_ifi_info.c## +#endif## 43 ##src/lib/get_ifi_info.c## + case AF_INET:## 44 ##src/lib/get_ifi_info.c## + default:## 45 ##src/lib/get_ifi_info.c## + len = sizeof(struct sockaddr);## 46 ##src/lib/get_ifi_info.c## + break;## 47 ##src/lib/get_ifi_info.c## + }## 48 ##src/lib/get_ifi_info.c## +#endif /* HAVE_SOCKADDR_SA_LEN */## 49 ##src/lib/get_ifi_info.c## + ptr += sizeof(ifr->ifr_name) + len; /* for next one in buffer */## 50 ##src/lib/get_ifi_info.c## + +#ifdef HAVE_SOCKADDR_DL## 51 ##src/lib/get_ifi_info.c## + /* assumes that AF_LINK precedes AF_INET or AF_INET6 */## 52 ##src/lib/get_ifi_info.c## + if (ifr->ifr_addr.sa_family == AF_LINK) {## 53 ##src/lib/get_ifi_info.c## + struct sockaddr_dl *sdl = (struct sockaddr_dl *) &ifr->ifr_addr;## 54 ##src/lib/get_ifi_info.c## + idx = sdl->sdl_index;## 55 ##src/lib/get_ifi_info.c## + haddr = sdl->sdl_data + sdl->sdl_nlen;## 56 ##src/lib/get_ifi_info.c## + hlen = sdl->sdl_alen;## 57 ##src/lib/get_ifi_info.c## + }## 58 ##src/lib/get_ifi_info.c## +#endif## 59 ##src/lib/get_ifi_info.c## + + if (ifr->ifr_addr.sa_family != family)## 60 ##src/lib/get_ifi_info.c## + continue; /* ignore if not desired address family */## 61 ##src/lib/get_ifi_info.c## + + myflags = 0;## 62 ##src/lib/get_ifi_info.c## + if ((cptr = strchr(ifr->ifr_name, ':')) != NULL)## 63 ##src/lib/get_ifi_info.c## + *cptr = 0; /* replace colon with null */## 64 ##src/lib/get_ifi_info.c## + if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {## 65 ##src/lib/get_ifi_info.c## + if (doaliases == 0)## 66 ##src/lib/get_ifi_info.c## + continue; /* already processed this interface */## 67 ##src/lib/get_ifi_info.c## + myflags = IFI_ALIAS;## 68 ##src/lib/get_ifi_info.c## + }## 69 ##src/lib/get_ifi_info.c## + memcpy(lastname, ifr->ifr_name, IFNAMSIZ);## 70 ##src/lib/get_ifi_info.c## + + ifrcopy = *ifr;## 71 ##src/lib/get_ifi_info.c## + Ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);## 72 ##src/lib/get_ifi_info.c## + flags = ifrcopy.ifr_flags;## 73 ##src/lib/get_ifi_info.c## + if ((flags & IFF_UP) == 0)## 74 ##src/lib/get_ifi_info.c## + continue; /* ignore if interface not up */## 75 ##src/lib/get_ifi_info.c## + + ifi = Calloc(1, sizeof(struct ifi_info));## 76 ##src/lib/get_ifi_info.c## + *ifipnext = ifi; /* prev points to this new one */## 77 ##src/lib/get_ifi_info.c## + ifipnext = &ifi->ifi_next; /* pointer to next one goes here */## 78 ##src/lib/get_ifi_info.c## + + ifi->ifi_flags = flags; /* IFF_xxx values */## 79 ##src/lib/get_ifi_info.c## + ifi->ifi_myflags = myflags; /* IFI_xxx values */## 80 ##src/lib/get_ifi_info.c## + ifi->ifi_index = idx;## 81 ##src/lib/get_ifi_info.c## + memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME);## 82 ##src/lib/get_ifi_info.c## + ifi->ifi_hlen = hlen;## 83 ##src/lib/get_ifi_info.c## + if (ifi->ifi_hlen > IFI_HADDR)## 84 ##src/lib/get_ifi_info.c## + ifi->ifi_hlen = IFI_HADDR;## 85 ##src/lib/get_ifi_info.c## + memcpy(ifi->ifi_haddr, haddr, ifi->ifi_hlen);## 86 ##src/lib/get_ifi_info.c## + ifi->ifi_name[IFI_NAME - 1] = '\0';## 87 ##src/lib/get_ifi_info.c## + idx = hlen = 0;## 88 ##src/lib/get_ifi_info.c## +/* end get_ifi_info2 */ +/* include get_ifi_info3 */ + switch (ifr->ifr_addr.sa_family) {## 89 ##src/lib/get_ifi_info.c## + case AF_INET:## 90 ##src/lib/get_ifi_info.c## + sinptr = (struct sockaddr_in *) &ifr->ifr_addr;## 91 ##src/lib/get_ifi_info.c## + if (ifi->ifi_addr == NULL) {## 92 ##src/lib/get_ifi_info.c## + ifi->ifi_addr = Calloc(1, sizeof(struct sockaddr_in));## 93 ##src/lib/get_ifi_info.c## + memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in));## 94 ##src/lib/get_ifi_info.c## + +#ifdef SIOCGIFBRDADDR## 95 ##src/lib/get_ifi_info.c## + if (flags & IFF_BROADCAST) {## 96 ##src/lib/get_ifi_info.c## + Ioctl(sockfd, SIOCGIFBRDADDR, &ifrcopy);## 97 ##src/lib/get_ifi_info.c## + sinptr = (struct sockaddr_in *) &ifrcopy.ifr_broadaddr;## 98 ##src/lib/get_ifi_info.c## + ifi->ifi_brdaddr = Calloc(1, sizeof(struct sockaddr_in));## 99 ##src/lib/get_ifi_info.c## + memcpy(ifi->ifi_brdaddr, sinptr,##100 ##src/lib/get_ifi_info.c## + sizeof(struct sockaddr_in));##101 ##src/lib/get_ifi_info.c## + }##102 ##src/lib/get_ifi_info.c## +#endif##103 ##src/lib/get_ifi_info.c## + +#ifdef SIOCGIFDSTADDR##104 ##src/lib/get_ifi_info.c## + if (flags & IFF_POINTOPOINT) {##105 ##src/lib/get_ifi_info.c## + Ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy);##106 ##src/lib/get_ifi_info.c## + sinptr = (struct sockaddr_in *) &ifrcopy.ifr_dstaddr;##107 ##src/lib/get_ifi_info.c## + ifi->ifi_dstaddr = Calloc(1, sizeof(struct sockaddr_in));##108 ##src/lib/get_ifi_info.c## + memcpy(ifi->ifi_dstaddr, sinptr,##109 ##src/lib/get_ifi_info.c## + sizeof(struct sockaddr_in));##110 ##src/lib/get_ifi_info.c## + }##111 ##src/lib/get_ifi_info.c## +#endif##112 ##src/lib/get_ifi_info.c## + }##113 ##src/lib/get_ifi_info.c## + break;##114 ##src/lib/get_ifi_info.c## + + case AF_INET6:##115 ##src/lib/get_ifi_info.c## + sin6ptr = (struct sockaddr_in6 *) &ifr->ifr_addr;##116 ##src/lib/get_ifi_info.c## + if (ifi->ifi_addr == NULL) {##117 ##src/lib/get_ifi_info.c## + ifi->ifi_addr = Calloc(1, sizeof(struct sockaddr_in6));##118 ##src/lib/get_ifi_info.c## + memcpy(ifi->ifi_addr, sin6ptr, sizeof(struct sockaddr_in6));##119 ##src/lib/get_ifi_info.c## + +#ifdef SIOCGIFDSTADDR##120 ##src/lib/get_ifi_info.c## + if (flags & IFF_POINTOPOINT) {##121 ##src/lib/get_ifi_info.c## + Ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy);##122 ##src/lib/get_ifi_info.c## + sin6ptr = (struct sockaddr_in6 *) &ifrcopy.ifr_dstaddr;##123 ##src/lib/get_ifi_info.c## + ifi->ifi_dstaddr =##124 ##src/lib/get_ifi_info.c## + Calloc(1, sizeof(struct sockaddr_in6));##125 ##src/lib/get_ifi_info.c## + memcpy(ifi->ifi_dstaddr, sin6ptr,##126 ##src/lib/get_ifi_info.c## + sizeof(struct sockaddr_in6));##127 ##src/lib/get_ifi_info.c## + }##128 ##src/lib/get_ifi_info.c## +#endif##129 ##src/lib/get_ifi_info.c## + }##130 ##src/lib/get_ifi_info.c## + break;##131 ##src/lib/get_ifi_info.c## + + default:##132 ##src/lib/get_ifi_info.c## + break;##133 ##src/lib/get_ifi_info.c## + }##134 ##src/lib/get_ifi_info.c## + }##135 ##src/lib/get_ifi_info.c## + free(buf);##136 ##src/lib/get_ifi_info.c## + return (ifihead); /* pointer to first structure in linked list */##137 ##src/lib/get_ifi_info.c## +}##138 ##src/lib/get_ifi_info.c## +/* end get_ifi_info3 */ + +/* include free_ifi_info */ +void##139 ##src/lib/get_ifi_info.c## +free_ifi_info(struct ifi_info *ifihead)##140 ##src/lib/get_ifi_info.c## +{##141 ##src/lib/get_ifi_info.c## + struct ifi_info *ifi, *ifinext;##142 ##src/lib/get_ifi_info.c## + + for (ifi = ifihead; ifi != NULL; ifi = ifinext) {##143 ##src/lib/get_ifi_info.c## + if (ifi->ifi_addr != NULL)##144 ##src/lib/get_ifi_info.c## + free(ifi->ifi_addr);##145 ##src/lib/get_ifi_info.c## + if (ifi->ifi_brdaddr != NULL)##146 ##src/lib/get_ifi_info.c## + free(ifi->ifi_brdaddr);##147 ##src/lib/get_ifi_info.c## + if (ifi->ifi_dstaddr != NULL)##148 ##src/lib/get_ifi_info.c## + free(ifi->ifi_dstaddr);##149 ##src/lib/get_ifi_info.c## + ifinext = ifi->ifi_next; /* can't fetch ifi_next after free() */##150 ##src/lib/get_ifi_info.c## + free(ifi); /* the ifi_info{} itself */##151 ##src/lib/get_ifi_info.c## + }##152 ##src/lib/get_ifi_info.c## +}##153 ##src/lib/get_ifi_info.c## +/* end free_ifi_info */ + +struct ifi_info *##154 ##src/lib/get_ifi_info.c## +Get_ifi_info(int family, int doaliases)##155 ##src/lib/get_ifi_info.c## +{##156 ##src/lib/get_ifi_info.c## + struct ifi_info *ifi;##157 ##src/lib/get_ifi_info.c## + + if ((ifi = get_ifi_info(family, doaliases)) == NULL)##158 ##src/lib/get_ifi_info.c## + err_quit("get_ifi_info error");##159 ##src/lib/get_ifi_info.c## + return (ifi);##160 ##src/lib/get_ifi_info.c## +}##161 ##src/lib/get_ifi_info.c## diff --git a/lib/gf_time.c b/lib/gf_time.c new file mode 100644 index 0000000..56aa524 --- /dev/null +++ b/lib/gf_time.c @@ -0,0 +1,23 @@ +#include "unp.h" +#include + +char * +gf_time(void) +{ + struct timeval tv; + time_t t; + static char str[30]; + char *ptr; + + if (gettimeofday(&tv, NULL) < 0) + err_sys("gettimeofday error"); + + t = tv.tv_sec; /* POSIX says tv.tv_sec is time_t; some BSDs don't agree. */ + ptr = ctime(&t); + strcpy(str, &ptr[11]); + /* Fri Sep 13 00:00:00 1986\n\0 */ + /* 0123456789012345678901234 5 */ + snprintf(str+8, sizeof(str)-8, ".%06ld", tv.tv_usec); + + return(str); +} diff --git a/lib/host_serv.c b/lib/host_serv.c new file mode 100644 index 0000000..553ce45 --- /dev/null +++ b/lib/host_serv.c @@ -0,0 +1,47 @@ +/* include host_serv */ +#include "unp.h" + +struct addrinfo * +host_serv(const char *host, const char *serv, int family, int socktype) +{ + int n; + struct addrinfo hints, *res; + + bzero(&hints, sizeof(struct addrinfo)); + hints.ai_flags = AI_CANONNAME; /* always return canonical name */ + hints.ai_family = family; /* AF_UNSPEC, AF_INET, AF_INET6, etc. */ + hints.ai_socktype = socktype; /* 0, SOCK_STREAM, SOCK_DGRAM, etc. */ + + if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0) + return(NULL); + + return(res); /* return pointer to first on linked list */ +} +/* end host_serv */ + +/* + * There is no easy way to pass back the integer return code from + * getaddrinfo() in the function above, short of adding another argument + * that is a pointer, so the easiest way to provide the wrapper function + * is just to duplicate the simple function as we do here. + */ + +struct addrinfo * +Host_serv(const char *host, const char *serv, int family, int socktype) +{ + int n; + struct addrinfo hints, *res; + + bzero(&hints, sizeof(struct addrinfo)); + hints.ai_flags = AI_CANONNAME; /* always return canonical name */ + hints.ai_family = family; /* 0, AF_INET, AF_INET6, etc. */ + hints.ai_socktype = socktype; /* 0, SOCK_STREAM, SOCK_DGRAM, etc. */ + + if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0) + err_quit("host_serv error for %s, %s: %s", + (host == NULL) ? "(no hostname)" : host, + (serv == NULL) ? "(no service name)" : serv, + gai_strerror(n)); + + return(res); /* return pointer to first on linked list */ +} diff --git a/lib/host_serv.lc b/lib/host_serv.lc new file mode 100644 index 0000000..77e241d --- /dev/null +++ b/lib/host_serv.lc @@ -0,0 +1,47 @@ +/* include host_serv */ +#include "unp.h"## 1 ##src/lib/host_serv.c## + +struct addrinfo *## 2 ##src/lib/host_serv.c## +host_serv(const char *host, const char *serv, int family, int socktype)## 3 ##src/lib/host_serv.c## +{## 4 ##src/lib/host_serv.c## + int n;## 5 ##src/lib/host_serv.c## + struct addrinfo hints, *res;## 6 ##src/lib/host_serv.c## + + bzero(&hints, sizeof(struct addrinfo));## 7 ##src/lib/host_serv.c## + hints.ai_flags = AI_CANONNAME; /* always return canonical name */## 8 ##src/lib/host_serv.c## + hints.ai_family = family; /* AF_UNSPEC, AF_INET, AF_INET6, etc. */## 9 ##src/lib/host_serv.c## + hints.ai_socktype = socktype; /* 0, SOCK_STREAM, SOCK_DGRAM, etc. */## 10 ##src/lib/host_serv.c## + + if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)## 11 ##src/lib/host_serv.c## + return (NULL);## 12 ##src/lib/host_serv.c## + + return (res); /* return pointer to first on linked list */## 13 ##src/lib/host_serv.c## +}## 14 ##src/lib/host_serv.c## +/* end host_serv */ + +/*## 15 ##src/lib/host_serv.c## + * There is no easy way to pass back the integer return code from## 16 ##src/lib/host_serv.c## + * getaddrinfo() in the function above, short of adding another argument## 17 ##src/lib/host_serv.c## + * that is a pointer, so the easiest way to provide the wrapper function## 18 ##src/lib/host_serv.c## + * is just to duplicate the simple function as we do here.## 19 ##src/lib/host_serv.c## + */## 20 ##src/lib/host_serv.c## + +struct addrinfo *## 21 ##src/lib/host_serv.c## +Host_serv(const char *host, const char *serv, int family, int socktype)## 22 ##src/lib/host_serv.c## +{## 23 ##src/lib/host_serv.c## + int n;## 24 ##src/lib/host_serv.c## + struct addrinfo hints, *res;## 25 ##src/lib/host_serv.c## + + bzero(&hints, sizeof(struct addrinfo));## 26 ##src/lib/host_serv.c## + hints.ai_flags = AI_CANONNAME; /* always return canonical name */## 27 ##src/lib/host_serv.c## + hints.ai_family = family; /* 0, AF_INET, AF_INET6, etc. */## 28 ##src/lib/host_serv.c## + hints.ai_socktype = socktype; /* 0, SOCK_STREAM, SOCK_DGRAM, etc. */## 29 ##src/lib/host_serv.c## + + if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)## 30 ##src/lib/host_serv.c## + err_quit("host_serv error for %s, %s: %s",## 31 ##src/lib/host_serv.c## + (host == NULL) ? "(no hostname)" : host,## 32 ##src/lib/host_serv.c## + (serv == NULL) ? "(no service name)" : serv,## 33 ##src/lib/host_serv.c## + gai_strerror(n));## 34 ##src/lib/host_serv.c## + + return (res); /* return pointer to first on linked list */## 35 ##src/lib/host_serv.c## +}## 36 ##src/lib/host_serv.c## diff --git a/lib/hstrerror.c b/lib/hstrerror.c new file mode 100644 index 0000000..92d2b92 --- /dev/null +++ b/lib/hstrerror.c @@ -0,0 +1,30 @@ +/* + * Return a string containing some additional information after a + * host name or address lookup error - gethostbyname() or gethostbyaddr(). + * + * This is only compiled if the local host does not provide it--recent + * versions of BIND supply this function. + */ + +#include "unp.h" + +const char * +hstrerror(int err) +{ + if (err == 0) + return("no error"); + + if (err == HOST_NOT_FOUND) + return("Unknown host"); + + if (err == TRY_AGAIN) + return("Hostname lookup failure"); + + if (err == NO_RECOVERY) + return("Unknown server error"); + + if (err == NO_DATA) + return("No address associated with name"); + + return("unknown error"); +} diff --git a/lib/if_indextoname.c b/lib/if_indextoname.c new file mode 100644 index 0000000..255e33e --- /dev/null +++ b/lib/if_indextoname.c @@ -0,0 +1,23 @@ +#include "unp.h" + +/* + * This is a placeholder if the system does not provide this RFC 2133 + * function. If routing sockets with sysctl() are provided, then the + * if_XXX() functions in the libroute/ directory will replace these. + */ + +char * +if_indextoname(unsigned int index, char *name) +{ + return(NULL); +} + +char * +If_indextoname(unsigned int index, char *name) +{ + char *ptr; + + if ( (ptr = if_indextoname(index, name)) == NULL) + err_quit("if_indextoname error for %d", index); + return(ptr); +} diff --git a/lib/if_nameindex.c b/lib/if_nameindex.c new file mode 100644 index 0000000..3519faf --- /dev/null +++ b/lib/if_nameindex.c @@ -0,0 +1,28 @@ +#include "unp.h" + +/* + * This is a placeholder if the system does not provide this RFC 2133 + * function. If routing sockets with sysctl() are provided, then the + * if_XXX() functions in the libroute/ directory will replace these. + */ + +struct if_nameindex * +if_nameindex(void) +{ + return(NULL); +} + +void +if_freenameindex(struct if_nameindex *ptr) +{ +} + +struct if_nameindex * +If_nameindex(void) +{ + struct if_nameindex *ifptr; + + if ( (ifptr = if_nameindex()) == NULL) + err_quit("if_nameindex error"); + return(ifptr); +} diff --git a/lib/if_nametoindex.c b/lib/if_nametoindex.c new file mode 100644 index 0000000..87276f6 --- /dev/null +++ b/lib/if_nametoindex.c @@ -0,0 +1,23 @@ +#include "unp.h" + +/* + * This is a placeholder if the system does not provide this RFC 2133 + * function. If routing sockets with sysctl() are provided, then the + * if_XXX() functions in the libroute/ directory will replace these. + */ + +unsigned int +if_nametoindex(const char *name) +{ + return(0); +} + +unsigned int +If_nametoindex(const char *name) +{ + int index; + + if ( (index = if_nametoindex(name)) == 0) + err_quit("if_nametoindex error for %s", name); + return(index); +} diff --git a/lib/in6addr_any.c b/lib/in6addr_any.c new file mode 100644 index 0000000..ea62e9f --- /dev/null +++ b/lib/in6addr_any.c @@ -0,0 +1,5 @@ +#include "unp.h" + +#ifdef IPV6 +const struct in6_addr in6addr_any; +#endif diff --git a/lib/mcast_get_if.c b/lib/mcast_get_if.c new file mode 100644 index 0000000..da6a528 --- /dev/null +++ b/lib/mcast_get_if.c @@ -0,0 +1,39 @@ +#include "unp.h" + +int +mcast_get_if(int sockfd) +{ + switch (sockfd_to_family(sockfd)) { + case AF_INET: { + /* TODO: similar to mcast_set_if() */ + return(-1); + } + +#ifdef IPV6 + case AF_INET6: { + u_int idx; + socklen_t len; + + len = sizeof(idx); + if (getsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_IF, + &idx, &len) < 0) + return(-1); + return(idx); + } +#endif + + default: + errno = EAFNOSUPPORT; + return(-1); + } +} + +int +Mcast_get_if(int sockfd) +{ + int rc; + + if ( (rc = mcast_get_if(sockfd)) < 0) + err_sys("mcast_get_if error"); + return(rc); +} diff --git a/lib/mcast_get_loop.c b/lib/mcast_get_loop.c new file mode 100644 index 0000000..553abe2 --- /dev/null +++ b/lib/mcast_get_loop.c @@ -0,0 +1,45 @@ +#include "unp.h" + +int +mcast_get_loop(int sockfd) +{ + switch (sockfd_to_family(sockfd)) { + case AF_INET: { + u_char flag; + socklen_t len; + + len = sizeof(flag); + if (getsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, + &flag, &len) < 0) + return(-1); + return(flag); + } + +#ifdef IPV6 + case AF_INET6: { + u_int flag; + socklen_t len; + + len = sizeof(flag); + if (getsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, + &flag, &len) < 0) + return(-1); + return(flag); + } +#endif + + default: + errno = EAFNOSUPPORT; + return(-1); + } +} + +int +Mcast_get_loop(int sockfd) +{ + int rc; + + if ( (rc = mcast_get_loop(sockfd)) < 0) + err_sys("mcast_get_loop error"); + return(rc); +} diff --git a/lib/mcast_get_ttl.c b/lib/mcast_get_ttl.c new file mode 100644 index 0000000..b3fe107 --- /dev/null +++ b/lib/mcast_get_ttl.c @@ -0,0 +1,45 @@ +#include "unp.h" + +int +mcast_get_ttl(int sockfd) +{ + switch (sockfd_to_family(sockfd)) { + case AF_INET: { + u_char ttl; + socklen_t len; + + len = sizeof(ttl); + if (getsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, + &ttl, &len) < 0) + return(-1); + return(ttl); + } + +#ifdef IPV6 + case AF_INET6: { + int hop; + socklen_t len; + + len = sizeof(hop); + if (getsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, + &hop, &len) < 0) + return(-1); + return(hop); + } +#endif + + default: + errno = EAFNOSUPPORT; + return(-1); + } +} + +int +Mcast_get_ttl(int sockfd) +{ + int rc; + + if ( (rc = mcast_get_ttl(sockfd)) < 0) + err_sys("mcast_get_ttl error"); + return(rc); +} diff --git a/lib/mcast_join.c b/lib/mcast_join.c new file mode 100644 index 0000000..26a6375 --- /dev/null +++ b/lib/mcast_join.c @@ -0,0 +1,287 @@ +/* include mcast_join1 */ +#include "unp.h" +#include + +int +mcast_join(int sockfd, const SA *grp, socklen_t grplen, + const char *ifname, u_int ifindex) +{ +#ifdef MCAST_JOIN_GROUP + struct group_req req; + if (ifindex > 0) { + req.gr_interface = ifindex; + } else if (ifname != NULL) { + if ( (req.gr_interface = if_nametoindex(ifname)) == 0) { + errno = ENXIO; /* i/f name not found */ + return(-1); + } + } else + req.gr_interface = 0; + if (grplen > sizeof(req.gr_group)) { + errno = EINVAL; + return -1; + } + memcpy(&req.gr_group, grp, grplen); + return (setsockopt(sockfd, family_to_level(grp->sa_family), + MCAST_JOIN_GROUP, &req, sizeof(req))); +#else +/* end mcast_join1 */ + +/* include mcast_join2 */ + switch (grp->sa_family) { + case AF_INET: { + struct ip_mreq mreq; + struct ifreq ifreq; + + memcpy(&mreq.imr_multiaddr, + &((const struct sockaddr_in *) grp)->sin_addr, + sizeof(struct in_addr)); + + if (ifindex > 0) { + if (if_indextoname(ifindex, ifreq.ifr_name) == NULL) { + errno = ENXIO; /* i/f index not found */ + return(-1); + } + goto doioctl; + } else if (ifname != NULL) { + strncpy(ifreq.ifr_name, ifname, IFNAMSIZ); +doioctl: + if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0) + return(-1); + memcpy(&mreq.imr_interface, + &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr, + sizeof(struct in_addr)); + } else + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + + return(setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, + &mreq, sizeof(mreq))); + } +/* end mcast_join2 */ + +/* include mcast_join3 */ +#ifdef IPV6 +#ifndef IPV6_JOIN_GROUP /* APIv0 compatibility */ +#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP +#endif + case AF_INET6: { + struct ipv6_mreq mreq6; + + memcpy(&mreq6.ipv6mr_multiaddr, + &((const struct sockaddr_in6 *) grp)->sin6_addr, + sizeof(struct in6_addr)); + + if (ifindex > 0) { + mreq6.ipv6mr_interface = ifindex; + } else if (ifname != NULL) { + if ( (mreq6.ipv6mr_interface = if_nametoindex(ifname)) == 0) { + errno = ENXIO; /* i/f name not found */ + return(-1); + } + } else + mreq6.ipv6mr_interface = 0; + + return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP, + &mreq6, sizeof(mreq6))); + } +#endif + + default: + errno = EAFNOSUPPORT; + return(-1); + } +#endif +} +/* end mcast_join3 */ + +void +Mcast_join(int sockfd, const SA *grp, socklen_t grplen, + const char *ifname, u_int ifindex) +{ + if (mcast_join(sockfd, grp, grplen, ifname, ifindex) < 0) + err_sys("mcast_join error"); +} + +int +mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen, + const char *ifname, u_int ifindex) +{ +#ifdef MCAST_JOIN_SOURCE_GROUP + struct group_source_req req; + if (ifindex > 0) { + req.gsr_interface = ifindex; + } else if (ifname != NULL) { + if ( (req.gsr_interface = if_nametoindex(ifname)) == 0) { + errno = ENXIO; /* i/f name not found */ + return(-1); + } + } else + req.gsr_interface = 0; + if (grplen > sizeof(req.gsr_group) || srclen > sizeof(req.gsr_source)) { + errno = EINVAL; + return -1; + } + memcpy(&req.gsr_group, grp, grplen); + memcpy(&req.gsr_source, src, srclen); + return (setsockopt(sockfd, family_to_level(grp->sa_family), + MCAST_JOIN_SOURCE_GROUP, &req, sizeof(req))); +#else + switch (grp->sa_family) { +#ifdef IP_ADD_SOURCE_MEMBERSHIP + case AF_INET: { + struct ip_mreq_source mreq; + struct ifreq ifreq; + + memcpy(&mreq.imr_multiaddr, + &((struct sockaddr_in *) grp)->sin_addr, + sizeof(struct in_addr)); + memcpy(&mreq.imr_sourceaddr, + &((struct sockaddr_in *) src)->sin_addr, + sizeof(struct in_addr)); + + if (ifindex > 0) { + if (if_indextoname(ifindex, ifreq.ifr_name) == NULL) { + errno = ENXIO; /* i/f index not found */ + return(-1); + } + goto doioctl; + } else if (ifname != NULL) { + strncpy(ifreq.ifr_name, ifname, IFNAMSIZ); +doioctl: + if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0) + return(-1); + memcpy(&mreq.imr_interface, + &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr, + sizeof(struct in_addr)); + } else + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + + return(setsockopt(sockfd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, + &mreq, sizeof(mreq))); + } +#endif + +#ifdef IPV6 + case AF_INET6: /* IPv6 source-specific API is MCAST_JOIN_SOURCE_GROUP */ +#endif + default: + errno = EAFNOSUPPORT; + return(-1); + } +#endif +} + +void +Mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen, + const char *ifname, u_int ifindex) +{ + if (mcast_join_source_group(sockfd, src, srclen, grp, grplen, + ifname, ifindex) < 0) + err_sys("mcast_join_source_group error"); +} + +int +mcast_block_source(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen) +{ +#ifdef MCAST_BLOCK_SOURCE + struct group_source_req req; + req.gsr_interface = 0; + if (grplen > sizeof(req.gsr_group) || srclen > sizeof(req.gsr_source)) { + errno = EINVAL; + return -1; + } + memcpy(&req.gsr_group, grp, grplen); + memcpy(&req.gsr_source, src, srclen); + return (setsockopt(sockfd, family_to_level(grp->sa_family), + MCAST_BLOCK_SOURCE, &req, sizeof(req))); +#else + switch (grp->sa_family) { +#ifdef IP_BLOCK_SOURCE + case AF_INET: { + struct ip_mreq_source mreq; + + memcpy(&mreq.imr_multiaddr, + &((struct sockaddr_in *) grp)->sin_addr, + sizeof(struct in_addr)); + memcpy(&mreq.imr_sourceaddr, + &((struct sockaddr_in *) src)->sin_addr, + sizeof(struct in_addr)); + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + + return(setsockopt(sockfd, IPPROTO_IP, IP_BLOCK_SOURCE, + &mreq, sizeof(mreq))); + } +#endif + +#ifdef IPV6 + case AF_INET6: /* IPv6 source-specific API is MCAST_BLOCK_SOURCE */ +#endif + default: + errno = EAFNOSUPPORT; + return(-1); + } +#endif +} + +void +Mcast_block_source(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen) +{ + if (mcast_block_source(sockfd, src, srclen, grp, grplen) < 0) + err_sys("mcast_block_source error"); +} + +int +mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen) +{ +#ifdef MCAST_UNBLOCK_SOURCE + struct group_source_req req; + req.gsr_interface = 0; + if (grplen > sizeof(req.gsr_group) || srclen > sizeof(req.gsr_source)) { + errno = EINVAL; + return -1; + } + memcpy(&req.gsr_group, grp, grplen); + memcpy(&req.gsr_source, src, srclen); + return (setsockopt(sockfd, family_to_level(grp->sa_family), + MCAST_UNBLOCK_SOURCE, &req, sizeof(req))); +#else + switch (grp->sa_family) { +#ifdef IP_UNBLOCK_SOURCE + case AF_INET: { + struct ip_mreq_source mreq; + + memcpy(&mreq.imr_multiaddr, + &((struct sockaddr_in *) grp)->sin_addr, + sizeof(struct in_addr)); + memcpy(&mreq.imr_sourceaddr, + &((struct sockaddr_in *) src)->sin_addr, + sizeof(struct in_addr)); + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + + return(setsockopt(sockfd, IPPROTO_IP, IP_UNBLOCK_SOURCE, + &mreq, sizeof(mreq))); + } +#endif + +#ifdef IPV6 + case AF_INET6: /* IPv6 source-specific API is MCAST_UNBLOCK_SOURCE */ +#endif + default: + errno = EAFNOSUPPORT; + return(-1); + } +#endif +} + +void +Mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen) +{ + if (mcast_unblock_source(sockfd, src, srclen, grp, grplen) < 0) + err_sys("mcast_unblock_source error"); +} diff --git a/lib/mcast_join.lc b/lib/mcast_join.lc new file mode 100644 index 0000000..9c4b02e --- /dev/null +++ b/lib/mcast_join.lc @@ -0,0 +1,271 @@ +/* include mcast_join1 */ +#include "unp.h"## 1 ##src/lib/mcast_join.c## +#include ## 2 ##src/lib/mcast_join.c## + +int## 3 ##src/lib/mcast_join.c## +mcast_join(int sockfd, const SA *grp, socklen_t grplen,## 4 ##src/lib/mcast_join.c## + const char *ifname, u_int ifindex)## 5 ##src/lib/mcast_join.c## +{## 6 ##src/lib/mcast_join.c## +#ifdef MCAST_JOIN_GROUP## 7 ##src/lib/mcast_join.c## + struct group_req req;## 8 ##src/lib/mcast_join.c## + if (ifindex > 0) {## 9 ##src/lib/mcast_join.c## + req.gr_interface = ifindex;## 10 ##src/lib/mcast_join.c## + } else if (ifname != NULL) {## 11 ##src/lib/mcast_join.c## + if ((req.gr_interface = if_nametoindex(ifname)) == 0) {## 12 ##src/lib/mcast_join.c## + errno = ENXIO; /* i/f name not found */## 13 ##src/lib/mcast_join.c## + return (-1);## 14 ##src/lib/mcast_join.c## + }## 15 ##src/lib/mcast_join.c## + } else## 16 ##src/lib/mcast_join.c## + req.gr_interface = 0;## 17 ##src/lib/mcast_join.c## + memcpy(&req.gr_group, grp, grplen);## 18 ##src/lib/mcast_join.c## + return (setsockopt(sockfd, family_to_level(grp->sa_family),## 19 ##src/lib/mcast_join.c## + MCAST_JOIN_GROUP, &req, sizeof(req)));## 20 ##src/lib/mcast_join.c## +/* end mcast_join1 */ +#else## 21 ##src/lib/mcast_join.c## + +/* include mcast_join2 */ + switch (grp->sa_family) {## 22 ##src/lib/mcast_join.c## + case AF_INET:{## 23 ##src/lib/mcast_join.c## + struct ip_mreq mreq;## 24 ##src/lib/mcast_join.c## + struct ifreq ifreq;## 25 ##src/lib/mcast_join.c## + + memcpy(&mreq.imr_multiaddr,## 26 ##src/lib/mcast_join.c## + &((const struct sockaddr_in *) grp)->sin_addr,## 27 ##src/lib/mcast_join.c## + sizeof(struct in_addr));## 28 ##src/lib/mcast_join.c## + + if (ifindex > 0) {## 29 ##src/lib/mcast_join.c## + if (if_indextoname(ifindex, ifreq.ifr_name) == NULL) {## 30 ##src/lib/mcast_join.c## + errno = ENXIO; /* i/f index not found */## 31 ##src/lib/mcast_join.c## + return (-1);## 32 ##src/lib/mcast_join.c## + }## 33 ##src/lib/mcast_join.c## + goto doioctl;## 34 ##src/lib/mcast_join.c## + } else if (ifname != NULL) {## 35 ##src/lib/mcast_join.c## + strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);## 36 ##src/lib/mcast_join.c## + doioctl:## 37 ##src/lib/mcast_join.c## + if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0)## 38 ##src/lib/mcast_join.c## + return (-1);## 39 ##src/lib/mcast_join.c## + memcpy(&mreq.imr_interface,## 40 ##src/lib/mcast_join.c## + &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr,## 41 ##src/lib/mcast_join.c## + sizeof(struct in_addr));## 42 ##src/lib/mcast_join.c## + } else## 43 ##src/lib/mcast_join.c## + mreq.imr_interface.s_addr = htonl(INADDR_ANY);## 44 ##src/lib/mcast_join.c## + + return (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,## 45 ##src/lib/mcast_join.c## + &mreq, sizeof(mreq)));## 46 ##src/lib/mcast_join.c## + }## 47 ##src/lib/mcast_join.c## +/* end mcast_join2 */ + +/* include mcast_join3 */ +#ifdef IPV6## 48 ##src/lib/mcast_join.c## +#ifndef IPV6_JOIN_GROUP /* APIv0 compatibility */## 49 ##src/lib/mcast_join.c## +#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP## 50 ##src/lib/mcast_join.c## +#endif## 51 ##src/lib/mcast_join.c## + case AF_INET6:{## 52 ##src/lib/mcast_join.c## + struct ipv6_mreq mreq6;## 53 ##src/lib/mcast_join.c## + + memcpy(&mreq6.ipv6mr_multiaddr,## 54 ##src/lib/mcast_join.c## + &((const struct sockaddr_in6 *) grp)->sin6_addr,## 55 ##src/lib/mcast_join.c## + sizeof(struct in6_addr));## 56 ##src/lib/mcast_join.c## + + if (ifindex > 0) {## 57 ##src/lib/mcast_join.c## + mreq6.ipv6mr_interface = ifindex;## 58 ##src/lib/mcast_join.c## + } else if (ifname != NULL) {## 59 ##src/lib/mcast_join.c## + if ((mreq6.ipv6mr_interface = if_nametoindex(ifname)) == 0) {## 60 ##src/lib/mcast_join.c## + errno = ENXIO; /* i/f name not found */## 61 ##src/lib/mcast_join.c## + return (-1);## 62 ##src/lib/mcast_join.c## + }## 63 ##src/lib/mcast_join.c## + } else## 64 ##src/lib/mcast_join.c## + mreq6.ipv6mr_interface = 0;## 65 ##src/lib/mcast_join.c## + + return (setsockopt(sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP,## 66 ##src/lib/mcast_join.c## + &mreq6, sizeof(mreq6)));## 67 ##src/lib/mcast_join.c## + }## 68 ##src/lib/mcast_join.c## +#endif## 69 ##src/lib/mcast_join.c## + + default:## 70 ##src/lib/mcast_join.c## + errno = EPROTONOSUPPORT;## 71 ##src/lib/mcast_join.c## + return (-1);## 72 ##src/lib/mcast_join.c## + }## 73 ##src/lib/mcast_join.c## +#endif## 74 ##src/lib/mcast_join.c## +}## 75 ##src/lib/mcast_join.c## +/* end mcast_join3 */ + +void## 76 ##src/lib/mcast_join.c## +Mcast_join(int sockfd, const SA *grp, socklen_t grplen,## 77 ##src/lib/mcast_join.c## + const char *ifname, u_int ifindex)## 78 ##src/lib/mcast_join.c## +{## 79 ##src/lib/mcast_join.c## + if (mcast_join(sockfd, grp, grplen, ifname, ifindex) < 0)## 80 ##src/lib/mcast_join.c## + err_sys("mcast_join error");## 81 ##src/lib/mcast_join.c## +}## 82 ##src/lib/mcast_join.c## + +int## 83 ##src/lib/mcast_join.c## +mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen,## 84 ##src/lib/mcast_join.c## + const SA *grp, socklen_t grplen,## 85 ##src/lib/mcast_join.c## + const char *ifname, u_int ifindex)## 86 ##src/lib/mcast_join.c## +{## 87 ##src/lib/mcast_join.c## +#ifdef MCAST_JOIN_SOURCE_GROUP## 88 ##src/lib/mcast_join.c## + struct group_source_req req;## 89 ##src/lib/mcast_join.c## + if (ifindex > 0) {## 90 ##src/lib/mcast_join.c## + req.gr_interface = ifindex;## 91 ##src/lib/mcast_join.c## + } else if (ifname != NULL) {## 92 ##src/lib/mcast_join.c## + if ((req.gr_interface = if_nametoindex(ifname)) == 0) {## 93 ##src/lib/mcast_join.c## + errno = ENXIO; /* i/f name not found */## 94 ##src/lib/mcast_join.c## + return (-1);## 95 ##src/lib/mcast_join.c## + }## 96 ##src/lib/mcast_join.c## + } else## 97 ##src/lib/mcast_join.c## + req.gr_interface = 0;## 98 ##src/lib/mcast_join.c## + memcpy(&req.gr_group, grp, grplen);## 99 ##src/lib/mcast_join.c## + memcpy(&req.gr_src, src, srclen);##100 ##src/lib/mcast_join.c## + return (setsockopt(sockfd, family_to_level(grp->sa_family),##101 ##src/lib/mcast_join.c## + MCAST_JOIN_SOURCE_GROUP, &req, sizeof(req)));##102 ##src/lib/mcast_join.c## +#else##103 ##src/lib/mcast_join.c## + switch (grp->sa_family) {##104 ##src/lib/mcast_join.c## +#ifdef IP_ADD_SOURCE_MEMBERSHIP##105 ##src/lib/mcast_join.c## + case AF_INET:{##106 ##src/lib/mcast_join.c## + struct ip_mreq_source mreq;##107 ##src/lib/mcast_join.c## + struct ifreq ifreq;##108 ##src/lib/mcast_join.c## + + memcpy(&mreq.imr_multiaddr,##109 ##src/lib/mcast_join.c## + &((struct sockaddr_in *) grp)->sin_addr,##110 ##src/lib/mcast_join.c## + sizeof(struct in_addr));##111 ##src/lib/mcast_join.c## + memcpy(&mreq.imr_sourceaddr,##112 ##src/lib/mcast_join.c## + &((struct sockaddr_in *) src)->sin_addr,##113 ##src/lib/mcast_join.c## + sizeof(struct in_addr));##114 ##src/lib/mcast_join.c## + + if (ifindex > 0) {##115 ##src/lib/mcast_join.c## + if (if_indextoname(ifindex, ifreq.ifr_name) == NULL) {##116 ##src/lib/mcast_join.c## + errno = ENXIO; /* i/f index not found */##117 ##src/lib/mcast_join.c## + return (-1);##118 ##src/lib/mcast_join.c## + }##119 ##src/lib/mcast_join.c## + goto doioctl;##120 ##src/lib/mcast_join.c## + } else if (ifname != NULL) {##121 ##src/lib/mcast_join.c## + strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);##122 ##src/lib/mcast_join.c## + doioctl:##123 ##src/lib/mcast_join.c## + if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0)##124 ##src/lib/mcast_join.c## + return (-1);##125 ##src/lib/mcast_join.c## + memcpy(&mreq.imr_interface,##126 ##src/lib/mcast_join.c## + &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr,##127 ##src/lib/mcast_join.c## + sizeof(struct in_addr));##128 ##src/lib/mcast_join.c## + } else##129 ##src/lib/mcast_join.c## + mreq.imr_interface.s_addr = htonl(INADDR_ANY);##130 ##src/lib/mcast_join.c## + + return (setsockopt(sockfd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP,##131 ##src/lib/mcast_join.c## + &mreq, sizeof(mreq)));##132 ##src/lib/mcast_join.c## + }##133 ##src/lib/mcast_join.c## +#endif##134 ##src/lib/mcast_join.c## + +#ifdef IPV6##135 ##src/lib/mcast_join.c## + case AF_INET6: /* IPv6 source-specific API is MCAST_JOIN_SOURCE_GROUP */##136 ##src/lib/mcast_join.c## +#endif##137 ##src/lib/mcast_join.c## + default:##138 ##src/lib/mcast_join.c## + errno = EPROTONOSUPPORT;##139 ##src/lib/mcast_join.c## + return (-1);##140 ##src/lib/mcast_join.c## + }##141 ##src/lib/mcast_join.c## +#endif##142 ##src/lib/mcast_join.c## +}##143 ##src/lib/mcast_join.c## + +void##144 ##src/lib/mcast_join.c## +Mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen,##145 ##src/lib/mcast_join.c## + const SA *grp, socklen_t grplen,##146 ##src/lib/mcast_join.c## + const char *ifname, u_int ifindex)##147 ##src/lib/mcast_join.c## +{##148 ##src/lib/mcast_join.c## + if (mcast_join_source_group(sockfd, src, srclen, grp, grplen,##149 ##src/lib/mcast_join.c## + ifname, ifindex) < 0)##150 ##src/lib/mcast_join.c## + err_sys("mcast_join_source_group error");##151 ##src/lib/mcast_join.c## +}##152 ##src/lib/mcast_join.c## + +int##153 ##src/lib/mcast_join.c## +mcast_block_source(int sockfd, const SA *src, socklen_t srclen,##154 ##src/lib/mcast_join.c## + const SA *grp, socklen_t grplen)##155 ##src/lib/mcast_join.c## +{##156 ##src/lib/mcast_join.c## +#ifdef MCAST_BLOCK_SOURCE##157 ##src/lib/mcast_join.c## + struct group_source_req req;##158 ##src/lib/mcast_join.c## + req.gr_interface = 0;##159 ##src/lib/mcast_join.c## + memcpy(&req.gr_group, grp, grplen);##160 ##src/lib/mcast_join.c## + memcpy(&req.gr_src, src, srclen);##161 ##src/lib/mcast_join.c## + return (setsockopt(sockfd, family_to_level(grp->sa_family),##162 ##src/lib/mcast_join.c## + MCAST_BLOCK_SOURCE, &req, sizeof(req)));##163 ##src/lib/mcast_join.c## +#else##164 ##src/lib/mcast_join.c## + switch (grp->sa_family) {##165 ##src/lib/mcast_join.c## +#ifdef IP_BLOCK_SOURCE##166 ##src/lib/mcast_join.c## + case AF_INET:{##167 ##src/lib/mcast_join.c## + struct ip_mreq_source mreq;##168 ##src/lib/mcast_join.c## + + memcpy(&mreq.imr_multiaddr,##169 ##src/lib/mcast_join.c## + &((struct sockaddr_in *) grp)->sin_addr,##170 ##src/lib/mcast_join.c## + sizeof(struct in_addr));##171 ##src/lib/mcast_join.c## + memcpy(&mreq.imr_sourceaddr,##172 ##src/lib/mcast_join.c## + &((struct sockaddr_in *) src)->sin_addr,##173 ##src/lib/mcast_join.c## + sizeof(struct in_addr));##174 ##src/lib/mcast_join.c## + mreq.imr_interface.s_addr = htonl(INADDR_ANY);##175 ##src/lib/mcast_join.c## + + return (setsockopt(sockfd, IPPROTO_IP, IP_BLOCK_SOURCE,##176 ##src/lib/mcast_join.c## + &mreq, sizeof(mreq)));##177 ##src/lib/mcast_join.c## + }##178 ##src/lib/mcast_join.c## +#endif##179 ##src/lib/mcast_join.c## + +#ifdef IPV6##180 ##src/lib/mcast_join.c## + case AF_INET6: /* IPv6 source-specific API is MCAST_BLOCK_SOURCE */##181 ##src/lib/mcast_join.c## +#endif##182 ##src/lib/mcast_join.c## + default:##183 ##src/lib/mcast_join.c## + errno = EPROTONOSUPPORT;##184 ##src/lib/mcast_join.c## + return (-1);##185 ##src/lib/mcast_join.c## + }##186 ##src/lib/mcast_join.c## +#endif##187 ##src/lib/mcast_join.c## +}##188 ##src/lib/mcast_join.c## + +void##189 ##src/lib/mcast_join.c## +Mcast_block_source(int sockfd, const SA *src, socklen_t srclen,##190 ##src/lib/mcast_join.c## + const SA *grp, socklen_t grplen)##191 ##src/lib/mcast_join.c## +{##192 ##src/lib/mcast_join.c## + if (mcast_block_source(sockfd, src, srclen, grp, grplen) < 0)##193 ##src/lib/mcast_join.c## + err_sys("mcast_block_source error");##194 ##src/lib/mcast_join.c## +}##195 ##src/lib/mcast_join.c## + +int##196 ##src/lib/mcast_join.c## +mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen,##197 ##src/lib/mcast_join.c## + const SA *grp, socklen_t grplen)##198 ##src/lib/mcast_join.c## +{##199 ##src/lib/mcast_join.c## +#ifdef MCAST_UNBLOCK_SOURCE##200 ##src/lib/mcast_join.c## + struct group_source_req req;##201 ##src/lib/mcast_join.c## + req.gr_interface = 0;##202 ##src/lib/mcast_join.c## + memcpy(&req.gr_group, grp, grplen);##203 ##src/lib/mcast_join.c## + memcpy(&req.gr_src, src, srclen);##204 ##src/lib/mcast_join.c## + return (setsockopt(sockfd, family_to_level(grp->sa_family),##205 ##src/lib/mcast_join.c## + MCAST_UNBLOCK_SOURCE, &req, sizeof(req)));##206 ##src/lib/mcast_join.c## +#else##207 ##src/lib/mcast_join.c## + switch (grp->sa_family) {##208 ##src/lib/mcast_join.c## +#ifdef IP_UNBLOCK_SOURCE##209 ##src/lib/mcast_join.c## + case AF_INET:{##210 ##src/lib/mcast_join.c## + struct ip_mreq_source mreq;##211 ##src/lib/mcast_join.c## + + memcpy(&mreq.imr_multiaddr,##212 ##src/lib/mcast_join.c## + &((struct sockaddr_in *) grp)->sin_addr,##213 ##src/lib/mcast_join.c## + sizeof(struct in_addr));##214 ##src/lib/mcast_join.c## + memcpy(&mreq.imr_sourceaddr,##215 ##src/lib/mcast_join.c## + &((struct sockaddr_in *) src)->sin_addr,##216 ##src/lib/mcast_join.c## + sizeof(struct in_addr));##217 ##src/lib/mcast_join.c## + mreq.imr_interface.s_addr = htonl(INADDR_ANY);##218 ##src/lib/mcast_join.c## + + return (setsockopt(sockfd, IPPROTO_IP, IP_UNBLOCK_SOURCE,##219 ##src/lib/mcast_join.c## + &mreq, sizeof(mreq)));##220 ##src/lib/mcast_join.c## + }##221 ##src/lib/mcast_join.c## +#endif##222 ##src/lib/mcast_join.c## + +#ifdef IPV6##223 ##src/lib/mcast_join.c## + case AF_INET6: /* IPv6 source-specific API is MCAST_UNBLOCK_SOURCE */##224 ##src/lib/mcast_join.c## +#endif##225 ##src/lib/mcast_join.c## + default:##226 ##src/lib/mcast_join.c## + errno = EPROTONOSUPPORT;##227 ##src/lib/mcast_join.c## + return (-1);##228 ##src/lib/mcast_join.c## + }##229 ##src/lib/mcast_join.c## +#endif##230 ##src/lib/mcast_join.c## +}##231 ##src/lib/mcast_join.c## + +void##232 ##src/lib/mcast_join.c## +Mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen,##233 ##src/lib/mcast_join.c## + const SA *grp, socklen_t grplen)##234 ##src/lib/mcast_join.c## +{##235 ##src/lib/mcast_join.c## + if (mcast_unblock_source(sockfd, src, srclen, grp, grplen) < 0)##236 ##src/lib/mcast_join.c## + err_sys("mcast_unblock_source error");##237 ##src/lib/mcast_join.c## +}##238 ##src/lib/mcast_join.c## diff --git a/lib/mcast_leave.c b/lib/mcast_leave.c new file mode 100644 index 0000000..b899512 --- /dev/null +++ b/lib/mcast_leave.c @@ -0,0 +1,109 @@ +#include "unp.h" + +int +mcast_leave(int sockfd, const SA *grp, socklen_t grplen) +{ +#ifdef MCAST_JOIN_GROUP + struct group_req req; + req.gr_interface = 0; + if (grplen > sizeof(req.gr_group)) { + errno = EINVAL; + return -1; + } + memcpy(&req.gr_group, grp, grplen); + return (setsockopt(sockfd, family_to_level(grp->sa_family), + MCAST_LEAVE_GROUP, &req, sizeof(req))); +#else + switch (grp->sa_family) { + case AF_INET: { + struct ip_mreq mreq; + + memcpy(&mreq.imr_multiaddr, + &((const struct sockaddr_in *) grp)->sin_addr, + sizeof(struct in_addr)); + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + return(setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, + &mreq, sizeof(mreq))); + } + +#ifdef IPV6 +#ifndef IPV6_LEAVE_GROUP /* APIv0 compatibility */ +#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP +#endif + case AF_INET6: { + struct ipv6_mreq mreq6; + + memcpy(&mreq6.ipv6mr_multiaddr, + &((const struct sockaddr_in6 *) grp)->sin6_addr, + sizeof(struct in6_addr)); + mreq6.ipv6mr_interface = 0; + return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, + &mreq6, sizeof(mreq6))); + } +#endif + + default: + errno = EAFNOSUPPORT; + return(-1); + } +#endif +} + +void +Mcast_leave(int sockfd, const SA *grp, socklen_t grplen) +{ + if (mcast_leave(sockfd, grp, grplen) < 0) + err_sys("mcast_leave error"); +} + +int +mcast_leave_source_group(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen) +{ +#ifdef MCAST_LEAVE_SOURCE_GROUP + struct group_source_req req; + req.gsr_interface = 0; + if (grplen > sizeof(req.gsr_group) || srclen > sizeof(req.gsr_source)) { + errno = EINVAL; + return -1; + } + memcpy(&req.gsr_group, grp, grplen); + memcpy(&req.gsr_source, src, srclen); + return (setsockopt(sockfd, family_to_level(grp->sa_family), + MCAST_LEAVE_SOURCE_GROUP, &req, sizeof(req))); +#else + switch (grp->sa_family) { +#ifdef IP_DROP_SOURCE_MEMBERSHIP + case AF_INET: { + struct ip_mreq_source mreq; + + memcpy(&mreq.imr_multiaddr, + &((struct sockaddr_in *) grp)->sin_addr, + sizeof(struct in_addr)); + memcpy(&mreq.imr_sourceaddr, + &((struct sockaddr_in *) src)->sin_addr, + sizeof(struct in_addr)); + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + + return(setsockopt(sockfd, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP, + &mreq, sizeof(mreq))); + } +#endif + +#ifdef IPV6 + case AF_INET6: /* IPv6 source-specific API is MCAST_LEAVE_SOURCE_GROUP */ +#endif + default: + errno = EAFNOSUPPORT; + return(-1); + } +#endif +} + +void +Mcast_leave_source_group(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen) +{ + if (mcast_leave_source_group(sockfd, src, srclen, grp, grplen) < 0) + err_sys("mcast_leave_source_group error"); +} diff --git a/lib/mcast_set_if.c b/lib/mcast_set_if.c new file mode 100644 index 0000000..87bf450 --- /dev/null +++ b/lib/mcast_set_if.c @@ -0,0 +1,63 @@ +#include "unp.h" +#include + +int +mcast_set_if(int sockfd, const char *ifname, u_int ifindex) +{ + switch (sockfd_to_family(sockfd)) { + case AF_INET: { + struct in_addr inaddr; + struct ifreq ifreq; + + if (ifindex > 0) { + if (if_indextoname(ifindex, ifreq.ifr_name) == NULL) { + errno = ENXIO; /* i/f index not found */ + return(-1); + } + goto doioctl; + } else if (ifname != NULL) { + strncpy(ifreq.ifr_name, ifname, IFNAMSIZ); +doioctl: + if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0) + return(-1); + memcpy(&inaddr, + &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr, + sizeof(struct in_addr)); + } else + inaddr.s_addr = htonl(INADDR_ANY); /* remove prev. set default */ + + return(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF, + &inaddr, sizeof(struct in_addr))); + } + +#ifdef IPV6 + case AF_INET6: { + u_int idx; + + if ( (idx = ifindex) == 0) { + if (ifname == NULL) { + errno = EINVAL; /* must supply either index or name */ + return(-1); + } + if ( (idx = if_nametoindex(ifname)) == 0) { + errno = ENXIO; /* i/f name not found */ + return(-1); + } + } + return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_IF, + &idx, sizeof(idx))); + } +#endif + + default: + errno = EAFNOSUPPORT; + return(-1); + } +} + +void +Mcast_set_if(int sockfd, const char *ifname, u_int ifindex) +{ + if (mcast_set_if(sockfd, ifname, ifindex) < 0) + err_sys("mcast_set_if error"); +} diff --git a/lib/mcast_set_loop.c b/lib/mcast_set_loop.c new file mode 100644 index 0000000..ed0505a --- /dev/null +++ b/lib/mcast_set_loop.c @@ -0,0 +1,38 @@ +/* include mcast_set_loop */ +#include "unp.h" + +int +mcast_set_loop(int sockfd, int onoff) +{ + switch (sockfd_to_family(sockfd)) { + case AF_INET: { + u_char flag; + + flag = onoff; + return(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, + &flag, sizeof(flag))); + } + +#ifdef IPV6 + case AF_INET6: { + u_int flag; + + flag = onoff; + return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, + &flag, sizeof(flag))); + } +#endif + + default: + errno = EAFNOSUPPORT; + return(-1); + } +} +/* end mcast_set_loop */ + +void +Mcast_set_loop(int sockfd, int onoff) +{ + if (mcast_set_loop(sockfd, onoff) < 0) + err_sys("mcast_set_loop error"); +} diff --git a/lib/mcast_set_loop.lc b/lib/mcast_set_loop.lc new file mode 100644 index 0000000..ddca361 --- /dev/null +++ b/lib/mcast_set_loop.lc @@ -0,0 +1,38 @@ +/* include mcast_set_loop */ +#include "unp.h"## 1 ##src/lib/mcast_set_loop.c## + +int## 2 ##src/lib/mcast_set_loop.c## +mcast_set_loop(int sockfd, int onoff)## 3 ##src/lib/mcast_set_loop.c## +{## 4 ##src/lib/mcast_set_loop.c## + switch (sockfd_to_family(sockfd)) {## 5 ##src/lib/mcast_set_loop.c## + case AF_INET:{## 6 ##src/lib/mcast_set_loop.c## + u_char flag;## 7 ##src/lib/mcast_set_loop.c## + + flag = onoff;## 8 ##src/lib/mcast_set_loop.c## + return (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP,## 9 ##src/lib/mcast_set_loop.c## + &flag, sizeof(flag)));## 10 ##src/lib/mcast_set_loop.c## + }## 11 ##src/lib/mcast_set_loop.c## + +#ifdef IPV6## 12 ##src/lib/mcast_set_loop.c## + case AF_INET6:{## 13 ##src/lib/mcast_set_loop.c## + u_int flag;## 14 ##src/lib/mcast_set_loop.c## + + flag = onoff;## 15 ##src/lib/mcast_set_loop.c## + return (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,## 16 ##src/lib/mcast_set_loop.c## + &flag, sizeof(flag)));## 17 ##src/lib/mcast_set_loop.c## + }## 18 ##src/lib/mcast_set_loop.c## +#endif## 19 ##src/lib/mcast_set_loop.c## + + default:## 20 ##src/lib/mcast_set_loop.c## + errno = EPROTONOSUPPORT;## 21 ##src/lib/mcast_set_loop.c## + return (-1);## 22 ##src/lib/mcast_set_loop.c## + }## 23 ##src/lib/mcast_set_loop.c## +}## 24 ##src/lib/mcast_set_loop.c## +/* end mcast_set_loop */ + +void## 25 ##src/lib/mcast_set_loop.c## +Mcast_set_loop(int sockfd, int onoff)## 26 ##src/lib/mcast_set_loop.c## +{## 27 ##src/lib/mcast_set_loop.c## + if (mcast_set_loop(sockfd, onoff) < 0)## 28 ##src/lib/mcast_set_loop.c## + err_sys("mcast_set_loop error");## 29 ##src/lib/mcast_set_loop.c## +}## 30 ##src/lib/mcast_set_loop.c## diff --git a/lib/mcast_set_ttl.c b/lib/mcast_set_ttl.c new file mode 100644 index 0000000..a3b110f --- /dev/null +++ b/lib/mcast_set_ttl.c @@ -0,0 +1,36 @@ +#include "unp.h" + +int +mcast_set_ttl(int sockfd, int val) +{ + switch (sockfd_to_family(sockfd)) { + case AF_INET: { + u_char ttl; + + ttl = val; + return(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, + &ttl, sizeof(ttl))); + } + +#ifdef IPV6 + case AF_INET6: { + int hop; + + hop = val; + return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, + &hop, sizeof(hop))); + } +#endif + + default: + errno = EAFNOSUPPORT; + return(-1); + } +} + +void +Mcast_set_ttl(int sockfd, int val) +{ + if (mcast_set_ttl(sockfd, val) < 0) + err_sys("mcast_set_ttl error"); +} diff --git a/lib/my_addrs.c b/lib/my_addrs.c new file mode 100644 index 0000000..e059e1c --- /dev/null +++ b/lib/my_addrs.c @@ -0,0 +1,30 @@ +/* include my_addrs */ +#include "unp.h" +#include + +char ** +my_addrs(int *addrtype) +{ + struct hostent *hptr; + struct utsname myname; + + if (uname(&myname) < 0) + return(NULL); + + if ( (hptr = gethostbyname(myname.nodename)) == NULL) + return(NULL); + + *addrtype = hptr->h_addrtype; + return(hptr->h_addr_list); +} +/* end my_addrs */ + +char ** +My_addrs(int *pfamily) +{ + char **pptr; + + if ( (pptr = my_addrs(pfamily)) == NULL) + err_sys("my_addrs error"); + return(pptr); +} diff --git a/lib/my_addrs.lc b/lib/my_addrs.lc new file mode 100644 index 0000000..2911735 --- /dev/null +++ b/lib/my_addrs.lc @@ -0,0 +1,30 @@ +/* include my_addrs */ +#include "unp.h"## 1 ##src/lib/my_addrs.c## +#include ## 2 ##src/lib/my_addrs.c## + +char **## 3 ##src/lib/my_addrs.c## +my_addrs(int *addrtype)## 4 ##src/lib/my_addrs.c## +{## 5 ##src/lib/my_addrs.c## + struct hostent *hptr;## 6 ##src/lib/my_addrs.c## + struct utsname myname;## 7 ##src/lib/my_addrs.c## + + if (uname(&myname) < 0)## 8 ##src/lib/my_addrs.c## + return (NULL);## 9 ##src/lib/my_addrs.c## + + if ((hptr = gethostbyname(myname.nodename)) == NULL)## 10 ##src/lib/my_addrs.c## + return (NULL);## 11 ##src/lib/my_addrs.c## + + *addrtype = hptr->h_addrtype;## 12 ##src/lib/my_addrs.c## + return (hptr->h_addr_list);## 13 ##src/lib/my_addrs.c## +}## 14 ##src/lib/my_addrs.c## +/* end my_addrs */ + +char **## 15 ##src/lib/my_addrs.c## +My_addrs(int *pfamily)## 16 ##src/lib/my_addrs.c## +{## 17 ##src/lib/my_addrs.c## + char **pptr;## 18 ##src/lib/my_addrs.c## + + if ((pptr = my_addrs(pfamily)) == NULL)## 19 ##src/lib/my_addrs.c## + err_sys("my_addrs error");## 20 ##src/lib/my_addrs.c## + return (pptr);## 21 ##src/lib/my_addrs.c## +}## 22 ##src/lib/my_addrs.c## diff --git a/lib/pselect.c b/lib/pselect.c new file mode 100644 index 0000000..db89f57 --- /dev/null +++ b/lib/pselect.c @@ -0,0 +1,31 @@ +/* + * This is *not* a complete implementation of the Posix.1g pselect() + * function. For atomicity this must be implemented within the kernel, + * with the sigprocmask/select/sigprocmask performed as a single atomic + * operation. + * This is just a quick hack to allow simple programs using it to compile. + * Using such programs with this hack will probably lead to race conditions. + */ +/* include pselect */ +#include "unp.h" + +int +pselect(int nfds, fd_set *rset, fd_set *wset, fd_set *xset, + const struct timespec *ts, const sigset_t *sigmask) +{ + int n; + struct timeval tv; + sigset_t savemask; + + if (ts != NULL) { + tv.tv_sec = ts->tv_sec; + tv.tv_usec = ts->tv_nsec / 1000; /* nanosec -> microsec */ + } + + sigprocmask(SIG_SETMASK, sigmask, &savemask); /* caller's mask */ + n = select(nfds, rset, wset, xset, (ts == NULL) ? NULL : &tv); + sigprocmask(SIG_SETMASK, &savemask, NULL); /* restore mask */ + + return(n); +} +/* end pselect */ diff --git a/lib/pselect.lc b/lib/pselect.lc new file mode 100644 index 0000000..67bf3cb --- /dev/null +++ b/lib/pselect.lc @@ -0,0 +1,31 @@ +/*## 1 ##src/lib/pselect.c## + * This is *not* a complete implementation of the Posix.1g pselect()## 2 ##src/lib/pselect.c## + * function. For atomicity this must be implemented within the kernel,## 3 ##src/lib/pselect.c## + * with the sigprocmask/select/sigprocmask performed as a single atomic## 4 ##src/lib/pselect.c## + * operation.## 5 ##src/lib/pselect.c## + * This is just a quick hack to allow simple programs using it to compile.## 6 ##src/lib/pselect.c## + * Using such programs with this hack will probably lead to race conditions.## 7 ##src/lib/pselect.c## + */## 8 ##src/lib/pselect.c## +/* include pselect */ +#include "unp.h"## 9 ##src/lib/pselect.c## + +int## 10 ##src/lib/pselect.c## +pselect(int nfds, fd_set *rset, fd_set *wset, fd_set *xset,## 11 ##src/lib/pselect.c## + const struct timespec *ts, const sigset_t *sigmask)## 12 ##src/lib/pselect.c## +{## 13 ##src/lib/pselect.c## + int n;## 14 ##src/lib/pselect.c## + struct timeval tv;## 15 ##src/lib/pselect.c## + sigset_t savemask;## 16 ##src/lib/pselect.c## + + if (ts != NULL) {## 17 ##src/lib/pselect.c## + tv.tv_sec = ts->tv_sec;## 18 ##src/lib/pselect.c## + tv.tv_usec = ts->tv_nsec / 1000; /* nanosec -> microsec */## 19 ##src/lib/pselect.c## + }## 20 ##src/lib/pselect.c## + + sigprocmask(SIG_SETMASK, sigmask, &savemask); /* caller's mask */## 21 ##src/lib/pselect.c## + n = select(nfds, rset, wset, xset, (ts == NULL) ? NULL : &tv);## 22 ##src/lib/pselect.c## + sigprocmask(SIG_SETMASK, &savemask, NULL); /* restore mask */## 23 ##src/lib/pselect.c## + + return (n);## 24 ##src/lib/pselect.c## +}## 25 ##src/lib/pselect.c## +/* end pselect */ diff --git a/lib/read_fd.c b/lib/read_fd.c new file mode 100644 index 0000000..f2a17f6 --- /dev/null +++ b/lib/read_fd.c @@ -0,0 +1,70 @@ +/* include read_fd */ +#include "unp.h" + +ssize_t +read_fd(int fd, void *ptr, size_t nbytes, int *recvfd) +{ + struct msghdr msg; + struct iovec iov[1]; + ssize_t n; + +#ifdef HAVE_MSGHDR_MSG_CONTROL + union { + struct cmsghdr cm; + char control[CMSG_SPACE(sizeof(int))]; + } control_un; + struct cmsghdr *cmptr; + + msg.msg_control = control_un.control; + msg.msg_controllen = sizeof(control_un.control); +#else + int newfd; + + msg.msg_accrights = (caddr_t) &newfd; + msg.msg_accrightslen = sizeof(int); +#endif + + msg.msg_name = NULL; + msg.msg_namelen = 0; + + iov[0].iov_base = ptr; + iov[0].iov_len = nbytes; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + if ( (n = recvmsg(fd, &msg, 0)) <= 0) + return(n); + +#ifdef HAVE_MSGHDR_MSG_CONTROL + if ( (cmptr = CMSG_FIRSTHDR(&msg)) != NULL && + cmptr->cmsg_len == CMSG_LEN(sizeof(int))) { + if (cmptr->cmsg_level != SOL_SOCKET) + err_quit("control level != SOL_SOCKET"); + if (cmptr->cmsg_type != SCM_RIGHTS) + err_quit("control type != SCM_RIGHTS"); + *recvfd = *((int *) CMSG_DATA(cmptr)); + } else + *recvfd = -1; /* descriptor was not passed */ +#else +/* *INDENT-OFF* */ + if (msg.msg_accrightslen == sizeof(int)) + *recvfd = newfd; + else + *recvfd = -1; /* descriptor was not passed */ +/* *INDENT-ON* */ +#endif + + return(n); +} +/* end read_fd */ + +ssize_t +Read_fd(int fd, void *ptr, size_t nbytes, int *recvfd) +{ + ssize_t n; + + if ( (n = read_fd(fd, ptr, nbytes, recvfd)) < 0) + err_sys("read_fd error"); + + return(n); +} diff --git a/lib/read_fd.lc b/lib/read_fd.lc new file mode 100644 index 0000000..afe0c47 --- /dev/null +++ b/lib/read_fd.lc @@ -0,0 +1,68 @@ +/* include read_fd */ +#include "unp.h"## 1 ##src/lib/read_fd.c## + +ssize_t## 2 ##src/lib/read_fd.c## +read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)## 3 ##src/lib/read_fd.c## +{## 4 ##src/lib/read_fd.c## + struct msghdr msg;## 5 ##src/lib/read_fd.c## + struct iovec iov[1];## 6 ##src/lib/read_fd.c## + ssize_t n;## 7 ##src/lib/read_fd.c## + +#ifdef HAVE_MSGHDR_MSG_CONTROL## 8 ##src/lib/read_fd.c## + union {## 9 ##src/lib/read_fd.c## + struct cmsghdr cm;## 10 ##src/lib/read_fd.c## + char control[CMSG_SPACE(sizeof(int))];## 11 ##src/lib/read_fd.c## + } control_un;## 12 ##src/lib/read_fd.c## + struct cmsghdr *cmptr;## 13 ##src/lib/read_fd.c## + + msg.msg_control = control_un.control;## 14 ##src/lib/read_fd.c## + msg.msg_controllen = sizeof(control_un.control);## 15 ##src/lib/read_fd.c## +#else## 16 ##src/lib/read_fd.c## + int newfd;## 17 ##src/lib/read_fd.c## + + msg.msg_accrights = (caddr_t) & newfd;## 18 ##src/lib/read_fd.c## + msg.msg_accrightslen = sizeof(int);## 19 ##src/lib/read_fd.c## +#endif## 20 ##src/lib/read_fd.c## + + msg.msg_name = NULL;## 21 ##src/lib/read_fd.c## + msg.msg_namelen = 0;## 22 ##src/lib/read_fd.c## + + iov[0].iov_base = ptr;## 23 ##src/lib/read_fd.c## + iov[0].iov_len = nbytes;## 24 ##src/lib/read_fd.c## + msg.msg_iov = iov;## 25 ##src/lib/read_fd.c## + msg.msg_iovlen = 1;## 26 ##src/lib/read_fd.c## + + if ((n = recvmsg(fd, &msg, 0)) <= 0)## 27 ##src/lib/read_fd.c## + return (n);## 28 ##src/lib/read_fd.c## + +#ifdef HAVE_MSGHDR_MSG_CONTROL## 29 ##src/lib/read_fd.c## + if ((cmptr = CMSG_FIRSTHDR(&msg)) != NULL &&## 30 ##src/lib/read_fd.c## + cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {## 31 ##src/lib/read_fd.c## + if (cmptr->cmsg_level != SOL_SOCKET)## 32 ##src/lib/read_fd.c## + err_quit("control level != SOL_SOCKET");## 33 ##src/lib/read_fd.c## + if (cmptr->cmsg_type != SCM_RIGHTS)## 34 ##src/lib/read_fd.c## + err_quit("control type != SCM_RIGHTS");## 35 ##src/lib/read_fd.c## + *recvfd = *((int *) CMSG_DATA(cmptr));## 36 ##src/lib/read_fd.c## + } else## 37 ##src/lib/read_fd.c## + *recvfd = -1; /* descriptor was not passed */## 38 ##src/lib/read_fd.c## +#else## 39 ##src/lib/read_fd.c## + if (msg.msg_accrightslen == sizeof(int))## 40 ##src/lib/read_fd.c## + *recvfd = newfd;## 41 ##src/lib/read_fd.c## + else## 42 ##src/lib/read_fd.c## + *recvfd = -1; /* descriptor was not passed */## 43 ##src/lib/read_fd.c## +#endif## 44 ##src/lib/read_fd.c## + + return (n);## 45 ##src/lib/read_fd.c## +}## 46 ##src/lib/read_fd.c## +/* end read_fd */ + +ssize_t## 47 ##src/lib/read_fd.c## +Read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)## 48 ##src/lib/read_fd.c## +{## 49 ##src/lib/read_fd.c## + ssize_t n;## 50 ##src/lib/read_fd.c## + + if ((n = read_fd(fd, ptr, nbytes, recvfd)) < 0)## 51 ##src/lib/read_fd.c## + err_sys("read_fd error");## 52 ##src/lib/read_fd.c## + + return (n);## 53 ##src/lib/read_fd.c## +}## 54 ##src/lib/read_fd.c## diff --git a/lib/readable_timeo.c b/lib/readable_timeo.c new file mode 100644 index 0000000..c6ee3d8 --- /dev/null +++ b/lib/readable_timeo.c @@ -0,0 +1,29 @@ +/* include readable_timeo */ +#include "unp.h" + +int +readable_timeo(int fd, int sec) +{ + fd_set rset; + struct timeval tv; + + FD_ZERO(&rset); + FD_SET(fd, &rset); + + tv.tv_sec = sec; + tv.tv_usec = 0; + + return(select(fd+1, &rset, NULL, NULL, &tv)); + /* 4> 0 if descriptor is readable */ +} +/* end readable_timeo */ + +int +Readable_timeo(int fd, int sec) +{ + int n; + + if ( (n = readable_timeo(fd, sec)) < 0) + err_sys("readable_timeo error"); + return(n); +} diff --git a/lib/readable_timeo.lc b/lib/readable_timeo.lc new file mode 100644 index 0000000..2c9fb4b --- /dev/null +++ b/lib/readable_timeo.lc @@ -0,0 +1,29 @@ +/* include readable_timeo */ +#include "unp.h"## 1 ##src/lib/readable_timeo.c## + +int## 2 ##src/lib/readable_timeo.c## +readable_timeo(int fd, int sec)## 3 ##src/lib/readable_timeo.c## +{## 4 ##src/lib/readable_timeo.c## + fd_set rset;## 5 ##src/lib/readable_timeo.c## + struct timeval tv;## 6 ##src/lib/readable_timeo.c## + + FD_ZERO(&rset);## 7 ##src/lib/readable_timeo.c## + FD_SET(fd, &rset);## 8 ##src/lib/readable_timeo.c## + + tv.tv_sec = sec;## 9 ##src/lib/readable_timeo.c## + tv.tv_usec = 0;## 10 ##src/lib/readable_timeo.c## + + return (select(fd + 1, &rset, NULL, NULL, &tv));## 11 ##src/lib/readable_timeo.c## + /* 4> 0 if descriptor is readable */## 12 ##src/lib/readable_timeo.c## +}## 13 ##src/lib/readable_timeo.c## +/* end readable_timeo */ + +int## 14 ##src/lib/readable_timeo.c## +Readable_timeo(int fd, int sec)## 15 ##src/lib/readable_timeo.c## +{## 16 ##src/lib/readable_timeo.c## + int n;## 17 ##src/lib/readable_timeo.c## + + if ((n = readable_timeo(fd, sec)) < 0)## 18 ##src/lib/readable_timeo.c## + err_sys("readable_timeo error");## 19 ##src/lib/readable_timeo.c## + return (n);## 20 ##src/lib/readable_timeo.c## +}## 21 ##src/lib/readable_timeo.c## diff --git a/lib/readline.c b/lib/readline.c new file mode 100644 index 0000000..040cfe5 --- /dev/null +++ b/lib/readline.c @@ -0,0 +1,68 @@ +/* include readline */ +#include "unp.h" + +static int read_cnt; +static char *read_ptr; +static char read_buf[MAXLINE]; + +static ssize_t +my_read(int fd, char *ptr) +{ + + if (read_cnt <= 0) { +again: + if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) { + if (errno == EINTR) + goto again; + return(-1); + } else if (read_cnt == 0) + return(0); + read_ptr = read_buf; + } + + read_cnt--; + *ptr = *read_ptr++; + return(1); +} + +ssize_t +readline(int fd, void *vptr, size_t maxlen) +{ + ssize_t n, rc; + char c, *ptr; + + ptr = vptr; + for (n = 1; n < maxlen; n++) { + if ( (rc = my_read(fd, &c)) == 1) { + *ptr++ = c; + if (c == '\n') + break; /* newline is stored, like fgets() */ + } else if (rc == 0) { + *ptr = 0; + return(n - 1); /* EOF, n - 1 bytes were read */ + } else + return(-1); /* error, errno set by read() */ + } + + *ptr = 0; /* null terminate like fgets() */ + return(n); +} + +ssize_t +readlinebuf(void **vptrptr) +{ + if (read_cnt) + *vptrptr = read_ptr; + return(read_cnt); +} +/* end readline */ + +ssize_t +Readline(int fd, void *ptr, size_t maxlen) +{ + ssize_t n; + + if ( (n = readline(fd, ptr, maxlen)) < 0) + err_sys("readline error"); + return(n); +} diff --git a/lib/readline.lc b/lib/readline.lc new file mode 100644 index 0000000..7653b3f --- /dev/null +++ b/lib/readline.lc @@ -0,0 +1,68 @@ +/* include readline */ +#include "unp.h"## 1 ##src/lib/readline.c## + +static int read_cnt;## 2 ##src/lib/readline.c## +static char *read_ptr;## 3 ##src/lib/readline.c## +static char read_buf[MAXLINE];## 4 ##src/lib/readline.c## + +static ssize_t## 5 ##src/lib/readline.c## +my_read(int fd, char *ptr)## 6 ##src/lib/readline.c## +{## 7 ##src/lib/readline.c## + + if (read_cnt <= 0) {## 8 ##src/lib/readline.c## + again:## 9 ##src/lib/readline.c## + if ((read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {## 10 ##src/lib/readline.c## + if (errno == EINTR)## 11 ##src/lib/readline.c## + goto again;## 12 ##src/lib/readline.c## + return (-1);## 13 ##src/lib/readline.c## + } else if (read_cnt == 0)## 14 ##src/lib/readline.c## + return (0);## 15 ##src/lib/readline.c## + read_ptr = read_buf;## 16 ##src/lib/readline.c## + }## 17 ##src/lib/readline.c## + + read_cnt--;## 18 ##src/lib/readline.c## + *ptr = *read_ptr++;## 19 ##src/lib/readline.c## + return (1);## 20 ##src/lib/readline.c## +}## 21 ##src/lib/readline.c## + +ssize_t## 22 ##src/lib/readline.c## +readline(int fd, void *vptr, size_t maxlen)## 23 ##src/lib/readline.c## +{## 24 ##src/lib/readline.c## + ssize_t n, rc;## 25 ##src/lib/readline.c## + char c, *ptr;## 26 ##src/lib/readline.c## + + ptr = vptr;## 27 ##src/lib/readline.c## + for (n = 1; n < maxlen; n++) {## 28 ##src/lib/readline.c## + if ((rc = my_read(fd, &c)) == 1) {## 29 ##src/lib/readline.c## + *ptr++ = c;## 30 ##src/lib/readline.c## + if (c == '\n')## 31 ##src/lib/readline.c## + break; /* newline is stored, like fgets() */## 32 ##src/lib/readline.c## + } else if (rc == 0) {## 33 ##src/lib/readline.c## + *ptr = 0;## 34 ##src/lib/readline.c## + return (n - 1); /* EOF, n - 1 bytes were read */## 35 ##src/lib/readline.c## + } else## 36 ##src/lib/readline.c## + return (-1); /* error, errno set by read() */## 37 ##src/lib/readline.c## + }## 38 ##src/lib/readline.c## + + *ptr = 0; /* null terminate like fgets() */## 39 ##src/lib/readline.c## + return (n);## 40 ##src/lib/readline.c## +}## 41 ##src/lib/readline.c## + +ssize_t## 42 ##src/lib/readline.c## +readlinebuf(void **vptrptr)## 43 ##src/lib/readline.c## +{## 44 ##src/lib/readline.c## + if (read_cnt)## 45 ##src/lib/readline.c## + *vptrptr = read_ptr;## 46 ##src/lib/readline.c## + return (read_cnt);## 47 ##src/lib/readline.c## +}## 48 ##src/lib/readline.c## +/* end readline */ + +ssize_t## 49 ##src/lib/readline.c## +Readline(int fd, void *ptr, size_t maxlen)## 50 ##src/lib/readline.c## +{## 51 ##src/lib/readline.c## + ssize_t n;## 52 ##src/lib/readline.c## + + if ((n = readline(fd, ptr, maxlen)) < 0)## 53 ##src/lib/readline.c## + err_sys("readline error");## 54 ##src/lib/readline.c## + return (n);## 55 ##src/lib/readline.c## +}## 56 ##src/lib/readline.c## diff --git a/lib/readn.c b/lib/readn.c new file mode 100644 index 0000000..54e7fc5 --- /dev/null +++ b/lib/readn.c @@ -0,0 +1,37 @@ +/* include readn */ +#include "unp.h" + +ssize_t /* Read "n" bytes from a descriptor. */ +readn(int fd, void *vptr, size_t n) +{ + size_t nleft; + ssize_t nread; + char *ptr; + + ptr = vptr; + nleft = n; + while (nleft > 0) { + if ( (nread = read(fd, ptr, nleft)) < 0) { + if (errno == EINTR) + nread = 0; /* and call read() again */ + else + return(-1); + } else if (nread == 0) + break; /* EOF */ + + nleft -= nread; + ptr += nread; + } + return(n - nleft); /* return >= 0 */ +} +/* end readn */ + +ssize_t +Readn(int fd, void *ptr, size_t nbytes) +{ + ssize_t n; + + if ( (n = readn(fd, ptr, nbytes)) < 0) + err_sys("readn error"); + return(n); +} diff --git a/lib/readn.lc b/lib/readn.lc new file mode 100644 index 0000000..9bf845f --- /dev/null +++ b/lib/readn.lc @@ -0,0 +1,37 @@ +/* include readn */ +#include "unp.h"## 1 ##src/lib/readn.c## + +ssize_t /* Read "n" bytes from a descriptor. */## 2 ##src/lib/readn.c## +readn(int fd, void *vptr, size_t n)## 3 ##src/lib/readn.c## +{## 4 ##src/lib/readn.c## + size_t nleft;## 5 ##src/lib/readn.c## + ssize_t nread;## 6 ##src/lib/readn.c## + char *ptr;## 7 ##src/lib/readn.c## + + ptr = vptr;## 8 ##src/lib/readn.c## + nleft = n;## 9 ##src/lib/readn.c## + while (nleft > 0) {## 10 ##src/lib/readn.c## + if ((nread = read(fd, ptr, nleft)) < 0) {## 11 ##src/lib/readn.c## + if (errno == EINTR)## 12 ##src/lib/readn.c## + nread = 0; /* and call read() again */## 13 ##src/lib/readn.c## + else## 14 ##src/lib/readn.c## + return (-1);## 15 ##src/lib/readn.c## + } else if (nread == 0)## 16 ##src/lib/readn.c## + break; /* EOF */## 17 ##src/lib/readn.c## + + nleft -= nread;## 18 ##src/lib/readn.c## + ptr += nread;## 19 ##src/lib/readn.c## + }## 20 ##src/lib/readn.c## + return (n - nleft); /* return >= 0 */## 21 ##src/lib/readn.c## +}## 22 ##src/lib/readn.c## +/* end readn */ + +ssize_t## 23 ##src/lib/readn.c## +Readn(int fd, void *ptr, size_t nbytes)## 24 ##src/lib/readn.c## +{## 25 ##src/lib/readn.c## + ssize_t n;## 26 ##src/lib/readn.c## + + if ((n = readn(fd, ptr, nbytes)) < 0)## 27 ##src/lib/readn.c## + err_sys("readn error");## 28 ##src/lib/readn.c## + return (n);## 29 ##src/lib/readn.c## +}## 30 ##src/lib/readn.c## diff --git a/lib/rtt.c b/lib/rtt.c new file mode 100644 index 0000000..d912380 --- /dev/null +++ b/lib/rtt.c @@ -0,0 +1,135 @@ +/* include rtt1 */ +#include "unprtt.h" + +int rtt_d_flag = 0; /* debug flag; can be set by caller */ + +/* + * Calculate the RTO value based on current estimators: + * smoothed RTT plus four times the deviation + */ +#define RTT_RTOCALC(ptr) ((ptr)->rtt_srtt + (4.0 * (ptr)->rtt_rttvar)) + +static float +rtt_minmax(float rto) +{ + if (rto < RTT_RXTMIN) + rto = RTT_RXTMIN; + else if (rto > RTT_RXTMAX) + rto = RTT_RXTMAX; + return(rto); +} + +void +rtt_init(struct rtt_info *ptr) +{ + struct timeval tv; + + Gettimeofday(&tv, NULL); + ptr->rtt_base = tv.tv_sec; /* # sec since 1/1/1970 at start */ + + ptr->rtt_rtt = 0; + ptr->rtt_srtt = 0; + ptr->rtt_rttvar = 0.75; + ptr->rtt_rto = rtt_minmax(RTT_RTOCALC(ptr)); + /* first RTO at (srtt + (4 * rttvar)) = 3 seconds */ +} +/* end rtt1 */ + +/* + * Return the current timestamp. + * Our timestamps are 32-bit integers that count milliseconds since + * rtt_init() was called. + */ + +/* include rtt_ts */ +uint32_t +rtt_ts(struct rtt_info *ptr) +{ + uint32_t ts; + struct timeval tv; + + Gettimeofday(&tv, NULL); + ts = ((tv.tv_sec - ptr->rtt_base) * 1000) + (tv.tv_usec / 1000); + return(ts); +} + +void +rtt_newpack(struct rtt_info *ptr) +{ + ptr->rtt_nrexmt = 0; +} + +int +rtt_start(struct rtt_info *ptr) +{ + return((int) (ptr->rtt_rto + 0.5)); /* round float to int */ + /* 4return value can be used as: alarm(rtt_start(&foo)) */ +} +/* end rtt_ts */ + +/* + * A response was received. + * Stop the timer and update the appropriate values in the structure + * based on this packet's RTT. We calculate the RTT, then update the + * estimators of the RTT and its mean deviation. + * This function should be called right after turning off the + * timer with alarm(0), or right after a timeout occurs. + */ + +/* include rtt_stop */ +void +rtt_stop(struct rtt_info *ptr, uint32_t ms) +{ + double delta; + + ptr->rtt_rtt = ms / 1000.0; /* measured RTT in seconds */ + + /* + * Update our estimators of RTT and mean deviation of RTT. + * See Jacobson's SIGCOMM '88 paper, Appendix A, for the details. + * We use floating point here for simplicity. + */ + + delta = ptr->rtt_rtt - ptr->rtt_srtt; + ptr->rtt_srtt += delta / 8; /* g = 1/8 */ + + if (delta < 0.0) + delta = -delta; /* |delta| */ + + ptr->rtt_rttvar += (delta - ptr->rtt_rttvar) / 4; /* h = 1/4 */ + + ptr->rtt_rto = rtt_minmax(RTT_RTOCALC(ptr)); +} +/* end rtt_stop */ + +/* + * A timeout has occurred. + * Return -1 if it's time to give up, else return 0. + */ + +/* include rtt_timeout */ +int +rtt_timeout(struct rtt_info *ptr) +{ + ptr->rtt_rto *= 2; /* next RTO */ + + if (++ptr->rtt_nrexmt > RTT_MAXNREXMT) + return(-1); /* time to give up for this packet */ + return(0); +} +/* end rtt_timeout */ + +/* + * Print debugging information on stderr, if the "rtt_d_flag" is nonzero. + */ + +void +rtt_debug(struct rtt_info *ptr) +{ + if (rtt_d_flag == 0) + return; + + fprintf(stderr, "rtt = %.3f, srtt = %.3f, rttvar = %.3f, rto = %.3f\n", + ptr->rtt_rtt, ptr->rtt_srtt, ptr->rtt_rttvar, ptr->rtt_rto); + fflush(stderr); +} diff --git a/lib/rtt.lc b/lib/rtt.lc new file mode 100644 index 0000000..5bf9b40 --- /dev/null +++ b/lib/rtt.lc @@ -0,0 +1,135 @@ +/* include rtt1 */ +#include "unprtt.h"## 1 ##src/lib/rtt.c## + +int rtt_d_flag = 0; /* debug flag; can be set nonzero by caller */## 2 ##src/lib/rtt.c## + +/*## 3 ##src/lib/rtt.c## + * Calculate the RTO value based on current estimators:## 4 ##src/lib/rtt.c## + * smoothed RTT plus four times the deviation.## 5 ##src/lib/rtt.c## + */## 6 ##src/lib/rtt.c## +#define RTT_RTOCALC(ptr) ((ptr)->rtt_srtt + (4.0 * (ptr)->rtt_rttvar))## 7 ##src/lib/rtt.c## + +static float## 8 ##src/lib/rtt.c## +rtt_minmax(float rto)## 9 ##src/lib/rtt.c## +{## 10 ##src/lib/rtt.c## + if (rto < RTT_RXTMIN)## 11 ##src/lib/rtt.c## + rto = RTT_RXTMIN;## 12 ##src/lib/rtt.c## + else if (rto > RTT_RXTMAX)## 13 ##src/lib/rtt.c## + rto = RTT_RXTMAX;## 14 ##src/lib/rtt.c## + return (rto);## 15 ##src/lib/rtt.c## +}## 16 ##src/lib/rtt.c## + +void## 17 ##src/lib/rtt.c## +rtt_init(struct rtt_info *ptr)## 18 ##src/lib/rtt.c## +{## 19 ##src/lib/rtt.c## + struct timeval tv;## 20 ##src/lib/rtt.c## + + Gettimeofday(&tv, NULL);## 21 ##src/lib/rtt.c## + ptr->rtt_base = tv.tv_sec; /* #sec since 1/1/1970 at start */## 22 ##src/lib/rtt.c## + + ptr->rtt_rtt = 0;## 23 ##src/lib/rtt.c## + ptr->rtt_srtt = 0;## 24 ##src/lib/rtt.c## + ptr->rtt_rttvar = 0.75;## 25 ##src/lib/rtt.c## + ptr->rtt_rto = rtt_minmax(RTT_RTOCALC(ptr));## 26 ##src/lib/rtt.c## + /* first RTO at (srtt + (4 * rttvar)) = 3 seconds */## 27 ##src/lib/rtt.c## +}## 28 ##src/lib/rtt.c## +/* end rtt1 */ + +/*## 29 ##src/lib/rtt.c## + * Return the current timestamp.## 30 ##src/lib/rtt.c## + * Our timestamps are 32-bit integers that count milliseconds since## 31 ##src/lib/rtt.c## + * rtt_init() was called.## 32 ##src/lib/rtt.c## + */## 33 ##src/lib/rtt.c## + +/* include rtt_ts */ +uint32_t## 34 ##src/lib/rtt.c## +rtt_ts(struct rtt_info *ptr)## 35 ##src/lib/rtt.c## +{## 36 ##src/lib/rtt.c## + uint32_t ts;## 37 ##src/lib/rtt.c## + struct timeval tv;## 38 ##src/lib/rtt.c## + + Gettimeofday(&tv, NULL);## 39 ##src/lib/rtt.c## + ts = ((tv.tv_sec - ptr->rtt_base) * 1000) + (tv.tv_usec / 1000);## 40 ##src/lib/rtt.c## + return (ts);## 41 ##src/lib/rtt.c## +}## 42 ##src/lib/rtt.c## + +void## 43 ##src/lib/rtt.c## +rtt_newpack(struct rtt_info *ptr)## 44 ##src/lib/rtt.c## +{## 45 ##src/lib/rtt.c## + ptr->rtt_nrexmt = 0;## 46 ##src/lib/rtt.c## +}## 47 ##src/lib/rtt.c## + +int## 48 ##src/lib/rtt.c## +rtt_start(struct rtt_info *ptr)## 49 ##src/lib/rtt.c## +{## 50 ##src/lib/rtt.c## + return ((int) (ptr->rtt_rto + 0.5)); /* round float to int */## 51 ##src/lib/rtt.c## + /* 4return value can be used as: alarm(rtt_start(&foo)) */## 52 ##src/lib/rtt.c## +}## 53 ##src/lib/rtt.c## +/* end rtt_ts */ + +/*## 54 ##src/lib/rtt.c## + * A response was received.## 55 ##src/lib/rtt.c## + * Stop the timer and update the appropriate values in the structure## 56 ##src/lib/rtt.c## + * based on this packet's RTT. We calculate the RTT, then update the## 57 ##src/lib/rtt.c## + * estimators of the RTT and its mean deviation.## 58 ##src/lib/rtt.c## + * This function should be called right after turning off the## 59 ##src/lib/rtt.c## + * timer with alarm(0), or right after a timeout occurs.## 60 ##src/lib/rtt.c## + */## 61 ##src/lib/rtt.c## + +/* include rtt_stop */ +void## 62 ##src/lib/rtt.c## +rtt_stop(struct rtt_info *ptr, uint32_t ms)## 63 ##src/lib/rtt.c## +{## 64 ##src/lib/rtt.c## + double delta;## 65 ##src/lib/rtt.c## + + ptr->rtt_rtt = ms / 1000.0; /* measured RTT in seconds */## 66 ##src/lib/rtt.c## + + /* ## 67 ##src/lib/rtt.c## + * Update our estimators of RTT and mean deviation of RTT.## 68 ##src/lib/rtt.c## + * See Jacobson's SIGCOMM '88 paper, Appendix A, for the details.## 69 ##src/lib/rtt.c## + * We use floating point here for simplicity.## 70 ##src/lib/rtt.c## + */## 71 ##src/lib/rtt.c## + + delta = ptr->rtt_rtt - ptr->rtt_srtt;## 72 ##src/lib/rtt.c## + ptr->rtt_srtt += delta / 8; /* g = 1/8 */## 73 ##src/lib/rtt.c## + + if (delta < 0.0)## 74 ##src/lib/rtt.c## + delta = -delta; /* |delta| */## 75 ##src/lib/rtt.c## + + ptr->rtt_rttvar += (delta - ptr->rtt_rttvar) / 4; /* h = 1/4 */## 76 ##src/lib/rtt.c## + + ptr->rtt_rto = rtt_minmax(RTT_RTOCALC(ptr));## 77 ##src/lib/rtt.c## +}## 78 ##src/lib/rtt.c## +/* end rtt_stop */ + +/*## 79 ##src/lib/rtt.c## + * A timeout has occurred.## 80 ##src/lib/rtt.c## + * Return -1 if it's time to give up, else return 0.## 81 ##src/lib/rtt.c## + */## 82 ##src/lib/rtt.c## + +/* include rtt_timeout */ +int## 83 ##src/lib/rtt.c## +rtt_timeout(struct rtt_info *ptr)## 84 ##src/lib/rtt.c## +{## 85 ##src/lib/rtt.c## + ptr->rtt_rto *= 2; /* next RTO */## 86 ##src/lib/rtt.c## + + if (++ptr->rtt_nrexmt > RTT_MAXNREXMT)## 87 ##src/lib/rtt.c## + return (-1); /* time to give up for this packet */## 88 ##src/lib/rtt.c## + return (0);## 89 ##src/lib/rtt.c## +}## 90 ##src/lib/rtt.c## +/* end rtt_timeout */ + +/*## 91 ##src/lib/rtt.c## + * Print debugging information on stderr, if the "rtt_d_flag" is nonzero.## 92 ##src/lib/rtt.c## + */## 93 ##src/lib/rtt.c## + +void## 94 ##src/lib/rtt.c## +rtt_debug(struct rtt_info *ptr)## 95 ##src/lib/rtt.c## +{## 96 ##src/lib/rtt.c## + if (rtt_d_flag == 0)## 97 ##src/lib/rtt.c## + return;## 98 ##src/lib/rtt.c## + + fprintf(stderr, "rtt = %.3f, srtt = %.3f, rttvar = %.3f, rto = %.3f\n",## 99 ##src/lib/rtt.c## + ptr->rtt_rtt, ptr->rtt_srtt, ptr->rtt_rttvar, ptr->rtt_rto);##100 ##src/lib/rtt.c## + fflush(stderr);##101 ##src/lib/rtt.c## +}##102 ##src/lib/rtt.c## diff --git a/lib/signal.c b/lib/signal.c new file mode 100644 index 0000000..52932ff --- /dev/null +++ b/lib/signal.c @@ -0,0 +1,35 @@ +/* include signal */ +#include "unp.h" + +Sigfunc * +signal(int signo, Sigfunc *func) +{ + struct sigaction act, oact; + + act.sa_handler = func; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + if (signo == SIGALRM) { +#ifdef SA_INTERRUPT + act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */ +#endif + } else { +#ifdef SA_RESTART + act.sa_flags |= SA_RESTART; /* SVR4, 44BSD */ +#endif + } + if (sigaction(signo, &act, &oact) < 0) + return(SIG_ERR); + return(oact.sa_handler); +} +/* end signal */ + +Sigfunc * +Signal(int signo, Sigfunc *func) /* for our signal() function */ +{ + Sigfunc *sigfunc; + + if ( (sigfunc = signal(signo, func)) == SIG_ERR) + err_sys("signal error"); + return(sigfunc); +} diff --git a/lib/signal.lc b/lib/signal.lc new file mode 100644 index 0000000..de48817 --- /dev/null +++ b/lib/signal.lc @@ -0,0 +1,35 @@ +/* include signal */ +#include "unp.h"## 1 ##src/lib/signal.c## + +Sigfunc *## 2 ##src/lib/signal.c## +signal(int signo, Sigfunc *func)## 3 ##src/lib/signal.c## +{## 4 ##src/lib/signal.c## + struct sigaction act, oact;## 5 ##src/lib/signal.c## + + act.sa_handler = func;## 6 ##src/lib/signal.c## + sigemptyset(&act.sa_mask);## 7 ##src/lib/signal.c## + act.sa_flags = 0;## 8 ##src/lib/signal.c## + if (signo == SIGALRM) {## 9 ##src/lib/signal.c## +#ifdef SA_INTERRUPT## 10 ##src/lib/signal.c## + act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */## 11 ##src/lib/signal.c## +#endif## 12 ##src/lib/signal.c## + } else {## 13 ##src/lib/signal.c## +#ifdef SA_RESTART## 14 ##src/lib/signal.c## + act.sa_flags |= SA_RESTART; /* SVR4, 44BSD */## 15 ##src/lib/signal.c## +#endif## 16 ##src/lib/signal.c## + }## 17 ##src/lib/signal.c## + if (sigaction(signo, &act, &oact) < 0)## 18 ##src/lib/signal.c## + return (SIG_ERR);## 19 ##src/lib/signal.c## + return (oact.sa_handler);## 20 ##src/lib/signal.c## +}## 21 ##src/lib/signal.c## +/* end signal */ + +Sigfunc *## 22 ##src/lib/signal.c## +Signal(int signo, Sigfunc *func)## 23 ##src/lib/signal.c## +{ /* for our signal() function */## 24 ##src/lib/signal.c## + Sigfunc *sigfunc;## 25 ##src/lib/signal.c## + + if ((sigfunc = signal(signo, func)) == SIG_ERR)## 26 ##src/lib/signal.c## + err_sys("signal error");## 27 ##src/lib/signal.c## + return (sigfunc);## 28 ##src/lib/signal.c## +}## 29 ##src/lib/signal.c## diff --git a/lib/signal_intr.c b/lib/signal_intr.c new file mode 100644 index 0000000..2fa1103 --- /dev/null +++ b/lib/signal_intr.c @@ -0,0 +1,29 @@ +/* include signal_intr */ +#include "unp.h" + +Sigfunc * +signal_intr(int signo, Sigfunc *func) +{ + struct sigaction act, oact; + + act.sa_handler = func; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; +#ifdef SA_INTERRUPT /* SunOS */ + act.sa_flags |= SA_INTERRUPT; +#endif + if (sigaction(signo, &act, &oact) < 0) + return(SIG_ERR); + return(oact.sa_handler); +} +/* end signal_intr */ + +Sigfunc * +Signal_intr(int signo, Sigfunc *func) +{ + Sigfunc *sigfunc; + + if ( (sigfunc = signal_intr(signo, func)) == SIG_ERR) + err_sys("signal_intr error"); + return(sigfunc); +} diff --git a/lib/snprintf.c b/lib/snprintf.c new file mode 100644 index 0000000..27c3361 --- /dev/null +++ b/lib/snprintf.c @@ -0,0 +1,27 @@ +/* + * Throughout the book I use snprintf() because it's safer than sprintf(). + * But as of the time of this writing, not all systems provide this + * function. The function below should only be built on those systems + * that do not provide a real snprintf(). + * The function below just acts like sprintf(); it is not safe, but it + * tries to detect overflow. + */ + +#include "unp.h" + +#include /* ANSI C header file */ + +int +snprintf(char *buf, size_t size, const char *fmt, ...) +{ + int n; + va_list ap; + + va_start(ap, fmt); + vsprintf(buf, fmt, ap); /* Sigh, some vsprintf's return ptr, not length */ + n = strlen(buf); + va_end(ap); + if (n >= size) + err_quit("snprintf: '%s' overflowed array", fmt); + return(n); +} diff --git a/lib/sock_bind_wild.c b/lib/sock_bind_wild.c new file mode 100644 index 0000000..6c4b223 --- /dev/null +++ b/lib/sock_bind_wild.c @@ -0,0 +1,55 @@ +#include "unp.h" + +int +sock_bind_wild(int sockfd, int family) +{ + socklen_t len; + + switch (family) { + case AF_INET: { + struct sockaddr_in sin; + + bzero(&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_ANY); + sin.sin_port = htons(0); /* bind ephemeral port */ + + if (bind(sockfd, (SA *) &sin, sizeof(sin)) < 0) + return(-1); + len = sizeof(sin); + if (getsockname(sockfd, (SA *) &sin, &len) < 0) + return(-1); + return(sin.sin_port); + } + +#ifdef IPV6 + case AF_INET6: { + struct sockaddr_in6 sin6; + + bzero(&sin6, sizeof(sin6)); + sin6.sin6_family = AF_INET6; + sin6.sin6_addr = in6addr_any; + sin6.sin6_port = htons(0); /* bind ephemeral port */ + + if (bind(sockfd, (SA *) &sin6, sizeof(sin6)) < 0) + return(-1); + len = sizeof(sin6); + if (getsockname(sockfd, (SA *) &sin6, &len) < 0) + return(-1); + return(sin6.sin6_port); + } +#endif + } + return(-1); +} + +int +Sock_bind_wild(int sockfd, int family) +{ + int port; + + if ( (port = sock_bind_wild(sockfd, family)) < 0) + err_sys("sock_bind_wild error"); + + return(port); +} diff --git a/lib/sock_cmp_addr.c b/lib/sock_cmp_addr.c new file mode 100644 index 0000000..ee84969 --- /dev/null +++ b/lib/sock_cmp_addr.c @@ -0,0 +1,43 @@ +#include "unp.h" + +#ifdef HAVE_SOCKADDR_DL_STRUCT +#include +#endif + +int +sock_cmp_addr(const struct sockaddr *sa1, const struct sockaddr *sa2, + socklen_t salen) +{ + if (sa1->sa_family != sa2->sa_family) + return(-1); + + switch (sa1->sa_family) { + case AF_INET: { + return(memcmp( &((struct sockaddr_in *) sa1)->sin_addr, + &((struct sockaddr_in *) sa2)->sin_addr, + sizeof(struct in_addr))); + } + +#ifdef IPV6 + case AF_INET6: { + return(memcmp( &((struct sockaddr_in6 *) sa1)->sin6_addr, + &((struct sockaddr_in6 *) sa2)->sin6_addr, + sizeof(struct in6_addr))); + } +#endif + +#ifdef AF_UNIX + case AF_UNIX: { + return(strcmp( ((struct sockaddr_un *) sa1)->sun_path, + ((struct sockaddr_un *) sa2)->sun_path)); + } +#endif + +#ifdef HAVE_SOCKADDR_DL_STRUCT + case AF_LINK: { + return(-1); /* no idea what to compare here ? */ + } +#endif + } + return (-1); +} diff --git a/lib/sock_cmp_port.c b/lib/sock_cmp_port.c new file mode 100644 index 0000000..1e106e8 --- /dev/null +++ b/lib/sock_cmp_port.c @@ -0,0 +1,29 @@ +#include "unp.h" + +#ifdef HAVE_SOCKADDR_DL_STRUCT +#include +#endif + +int +sock_cmp_port(const struct sockaddr *sa1, const struct sockaddr *sa2, + socklen_t salen) +{ + if (sa1->sa_family != sa2->sa_family) + return(-1); + + switch (sa1->sa_family) { + case AF_INET: { + return( ((struct sockaddr_in *) sa1)->sin_port == + ((struct sockaddr_in *) sa2)->sin_port); + } + +#ifdef IPV6 + case AF_INET6: { + return( ((struct sockaddr_in6 *) sa1)->sin6_port == + ((struct sockaddr_in6 *) sa2)->sin6_port); + } +#endif + + } + return (-1); +} diff --git a/lib/sock_get_port.c b/lib/sock_get_port.c new file mode 100644 index 0000000..fe08b25 --- /dev/null +++ b/lib/sock_get_port.c @@ -0,0 +1,23 @@ +#include "unp.h" + +int +sock_get_port(const struct sockaddr *sa, socklen_t salen) +{ + switch (sa->sa_family) { + case AF_INET: { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; + + return(sin->sin_port); + } + +#ifdef IPV6 + case AF_INET6: { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; + + return(sin6->sin6_port); + } +#endif + } + + return(-1); /* ??? */ +} diff --git a/lib/sock_ntop.c b/lib/sock_ntop.c new file mode 100644 index 0000000..698147e --- /dev/null +++ b/lib/sock_ntop.c @@ -0,0 +1,86 @@ +#include "unp.h" + +#ifdef HAVE_SOCKADDR_DL_STRUCT +#include +#endif + +/* include sock_ntop */ +char * +sock_ntop(const struct sockaddr *sa, socklen_t salen) +{ + char portstr[8]; + static char str[128]; /* Unix domain is largest */ + + switch (sa->sa_family) { + case AF_INET: { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; + + if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == NULL) + return(NULL); + if (ntohs(sin->sin_port) != 0) { + snprintf(portstr, sizeof(portstr), ":%d", ntohs(sin->sin_port)); + strcat(str, portstr); + } + return(str); + } +/* end sock_ntop */ + +#ifdef IPV6 + case AF_INET6: { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; + + str[0] = '['; + if (inet_ntop(AF_INET6, &sin6->sin6_addr, str + 1, sizeof(str) - 1) == NULL) + return(NULL); + if (ntohs(sin6->sin6_port) != 0) { + snprintf(portstr, sizeof(portstr), "]:%d", ntohs(sin6->sin6_port)); + strcat(str, portstr); + return(str); + } + return (str + 1); + } +#endif + +#ifdef AF_UNIX + case AF_UNIX: { + struct sockaddr_un *unp = (struct sockaddr_un *) sa; + + /* OK to have no pathname bound to the socket: happens on + every connect() unless client calls bind() first. */ + if (unp->sun_path[0] == 0) + strcpy(str, "(no pathname bound)"); + else + snprintf(str, sizeof(str), "%s", unp->sun_path); + return(str); + } +#endif + +#ifdef HAVE_SOCKADDR_DL_STRUCT + case AF_LINK: { + struct sockaddr_dl *sdl = (struct sockaddr_dl *) sa; + + if (sdl->sdl_nlen > 0) + snprintf(str, sizeof(str), "%*s (index %d)", + sdl->sdl_nlen, &sdl->sdl_data[0], sdl->sdl_index); + else + snprintf(str, sizeof(str), "AF_LINK, index=%d", sdl->sdl_index); + return(str); + } +#endif + default: + snprintf(str, sizeof(str), "sock_ntop: unknown AF_xxx: %d, len %d", + sa->sa_family, salen); + return(str); + } + return (NULL); +} + +char * +Sock_ntop(const struct sockaddr *sa, socklen_t salen) +{ + char *ptr; + + if ( (ptr = sock_ntop(sa, salen)) == NULL) + err_sys("sock_ntop error"); /* inet_ntop() sets errno */ + return(ptr); +} diff --git a/lib/sock_ntop.lc b/lib/sock_ntop.lc new file mode 100644 index 0000000..1210330 --- /dev/null +++ b/lib/sock_ntop.lc @@ -0,0 +1,90 @@ +#include "unp.h"## 1 ##src/lib/sock_ntop.c## + +#ifdef HAVE_SOCKADDR_DL_STRUCT## 2 ##src/lib/sock_ntop.c## +#include ## 3 ##src/lib/sock_ntop.c## +#endif## 4 ##src/lib/sock_ntop.c## + +/* include sock_ntop */ +char *## 5 ##src/lib/sock_ntop.c## +sock_ntop(const struct sockaddr *sa, socklen_t salen)## 6 ##src/lib/sock_ntop.c## +{## 7 ##src/lib/sock_ntop.c## + char portstr[8];## 8 ##src/lib/sock_ntop.c## + static char str[128]; /* Unix domain is largest */## 9 ##src/lib/sock_ntop.c## + + switch (sa->sa_family) {## 10 ##src/lib/sock_ntop.c## + case AF_INET:{## 11 ##src/lib/sock_ntop.c## + struct sockaddr_in *sin = (struct sockaddr_in *) sa;## 12 ##src/lib/sock_ntop.c## + + if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == NULL)## 13 ##src/lib/sock_ntop.c## + return (NULL);## 14 ##src/lib/sock_ntop.c## + if (ntohs(sin->sin_port) != 0) {## 15 ##src/lib/sock_ntop.c## + snprintf(portstr, sizeof(portstr), ":%d",## 16 ##src/lib/sock_ntop.c## + ntohs(sin->sin_port));## 17 ##src/lib/sock_ntop.c## + strcat(str, portstr);## 18 ##src/lib/sock_ntop.c## + }## 19 ##src/lib/sock_ntop.c## + return (str);## 20 ##src/lib/sock_ntop.c## + }## 21 ##src/lib/sock_ntop.c## +/* end sock_ntop */ + +#ifdef IPV6## 22 ##src/lib/sock_ntop.c## + case AF_INET6:{## 23 ##src/lib/sock_ntop.c## + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;## 24 ##src/lib/sock_ntop.c## + + str[0] = '[';## 25 ##src/lib/sock_ntop.c## + if (inet_ntop## 26 ##src/lib/sock_ntop.c## + (AF_INET6, &sin6->sin6_addr, str + 1,## 27 ##src/lib/sock_ntop.c## + sizeof(str) - 1) == NULL)## 28 ##src/lib/sock_ntop.c## + return (NULL);## 29 ##src/lib/sock_ntop.c## + if (ntohs(sin6->sin6_port) != 0) {## 30 ##src/lib/sock_ntop.c## + snprintf(portstr, sizeof(portstr), "]:%d",## 31 ##src/lib/sock_ntop.c## + ntohs(sin6->sin6_port));## 32 ##src/lib/sock_ntop.c## + strcat(str, portstr);## 33 ##src/lib/sock_ntop.c## + return (str);## 34 ##src/lib/sock_ntop.c## + }## 35 ##src/lib/sock_ntop.c## + return (str + 1);## 36 ##src/lib/sock_ntop.c## + }## 37 ##src/lib/sock_ntop.c## +#endif## 38 ##src/lib/sock_ntop.c## + +#ifdef AF_UNIX## 39 ##src/lib/sock_ntop.c## + case AF_UNIX:{## 40 ##src/lib/sock_ntop.c## + struct sockaddr_un *unp = (struct sockaddr_un *) sa;## 41 ##src/lib/sock_ntop.c## + + /* OK to have no pathname bound to the socket: happens on every connect() unless client calls bind() first. */## 42 ##src/lib/sock_ntop.c## + if (unp->sun_path[0] == 0)## 43 ##src/lib/sock_ntop.c## + strcpy(str, "(no pathname bound)");## 44 ##src/lib/sock_ntop.c## + else## 45 ##src/lib/sock_ntop.c## + snprintf(str, sizeof(str), "%s", unp->sun_path);## 46 ##src/lib/sock_ntop.c## + return (str);## 47 ##src/lib/sock_ntop.c## + }## 48 ##src/lib/sock_ntop.c## +#endif## 49 ##src/lib/sock_ntop.c## + +#ifdef HAVE_SOCKADDR_DL_STRUCT## 50 ##src/lib/sock_ntop.c## + case AF_LINK:{## 51 ##src/lib/sock_ntop.c## + struct sockaddr_dl *sdl = (struct sockaddr_dl *) sa;## 52 ##src/lib/sock_ntop.c## + + if (sdl->sdl_nlen > 0)## 53 ##src/lib/sock_ntop.c## + snprintf(str, sizeof(str), "%*s (index %d)",## 54 ##src/lib/sock_ntop.c## + sdl->sdl_nlen, &sdl->sdl_data[0], sdl->sdl_index);## 55 ##src/lib/sock_ntop.c## + else## 56 ##src/lib/sock_ntop.c## + snprintf(str, sizeof(str), "AF_LINK, index=%d",## 57 ##src/lib/sock_ntop.c## + sdl->sdl_index);## 58 ##src/lib/sock_ntop.c## + return (str);## 59 ##src/lib/sock_ntop.c## + }## 60 ##src/lib/sock_ntop.c## +#endif## 61 ##src/lib/sock_ntop.c## + default:## 62 ##src/lib/sock_ntop.c## + snprintf(str, sizeof(str), "sock_ntop: unknown AF_xxx: %d, len %d",## 63 ##src/lib/sock_ntop.c## + sa->sa_family, salen);## 64 ##src/lib/sock_ntop.c## + return (str);## 65 ##src/lib/sock_ntop.c## + }## 66 ##src/lib/sock_ntop.c## + return (NULL);## 67 ##src/lib/sock_ntop.c## +}## 68 ##src/lib/sock_ntop.c## + +char *## 69 ##src/lib/sock_ntop.c## +Sock_ntop(const struct sockaddr *sa, socklen_t salen)## 70 ##src/lib/sock_ntop.c## +{## 71 ##src/lib/sock_ntop.c## + char *ptr;## 72 ##src/lib/sock_ntop.c## + + if ((ptr = sock_ntop(sa, salen)) == NULL)## 73 ##src/lib/sock_ntop.c## + err_sys("sock_ntop error"); /* inet_ntop() sets errno */## 74 ##src/lib/sock_ntop.c## + return (ptr);## 75 ##src/lib/sock_ntop.c## +}## 76 ##src/lib/sock_ntop.c## diff --git a/lib/sock_ntop_host.c b/lib/sock_ntop_host.c new file mode 100644 index 0000000..801bc2c --- /dev/null +++ b/lib/sock_ntop_host.c @@ -0,0 +1,73 @@ +#include "unp.h" + +#ifdef HAVE_SOCKADDR_DL_STRUCT +#include +#endif + +char * +sock_ntop_host(const struct sockaddr *sa, socklen_t salen) +{ + static char str[128]; /* Unix domain is largest */ + + switch (sa->sa_family) { + case AF_INET: { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; + + if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == NULL) + return(NULL); + return(str); + } + +#ifdef IPV6 + case AF_INET6: { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; + + if (inet_ntop(AF_INET6, &sin6->sin6_addr, str, sizeof(str)) == NULL) + return(NULL); + return(str); + } +#endif + +#ifdef AF_UNIX + case AF_UNIX: { + struct sockaddr_un *unp = (struct sockaddr_un *) sa; + + /* OK to have no pathname bound to the socket: happens on + every connect() unless client calls bind() first. */ + if (unp->sun_path[0] == 0) + strcpy(str, "(no pathname bound)"); + else + snprintf(str, sizeof(str), "%s", unp->sun_path); + return(str); + } +#endif + +#ifdef HAVE_SOCKADDR_DL_STRUCT + case AF_LINK: { + struct sockaddr_dl *sdl = (struct sockaddr_dl *) sa; + + if (sdl->sdl_nlen > 0) + snprintf(str, sizeof(str), "%*s", + sdl->sdl_nlen, &sdl->sdl_data[0]); + else + snprintf(str, sizeof(str), "AF_LINK, index=%d", sdl->sdl_index); + return(str); + } +#endif + default: + snprintf(str, sizeof(str), "sock_ntop_host: unknown AF_xxx: %d, len %d", + sa->sa_family, salen); + return(str); + } + return (NULL); +} + +char * +Sock_ntop_host(const struct sockaddr *sa, socklen_t salen) +{ + char *ptr; + + if ( (ptr = sock_ntop_host(sa, salen)) == NULL) + err_sys("sock_ntop_host error"); /* inet_ntop() sets errno */ + return(ptr); +} diff --git a/lib/sock_set_addr.c b/lib/sock_set_addr.c new file mode 100644 index 0000000..f2abe31 --- /dev/null +++ b/lib/sock_set_addr.c @@ -0,0 +1,25 @@ +#include "unp.h" + +void +sock_set_addr(struct sockaddr *sa, socklen_t salen, const void *addr) +{ + switch (sa->sa_family) { + case AF_INET: { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; + + memcpy(&sin->sin_addr, addr, sizeof(struct in_addr)); + return; + } + +#ifdef IPV6 + case AF_INET6: { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; + + memcpy(&sin6->sin6_addr, addr, sizeof(struct in6_addr)); + return; + } +#endif + } + + return; +} diff --git a/lib/sock_set_port.c b/lib/sock_set_port.c new file mode 100644 index 0000000..5bcdefa --- /dev/null +++ b/lib/sock_set_port.c @@ -0,0 +1,25 @@ +#include "unp.h" + +void +sock_set_port(struct sockaddr *sa, socklen_t salen, int port) +{ + switch (sa->sa_family) { + case AF_INET: { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; + + sin->sin_port = port; + return; + } + +#ifdef IPV6 + case AF_INET6: { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; + + sin6->sin6_port = port; + return; + } +#endif + } + + return; +} diff --git a/lib/sock_set_wild.c b/lib/sock_set_wild.c new file mode 100644 index 0000000..201392a --- /dev/null +++ b/lib/sock_set_wild.c @@ -0,0 +1,29 @@ +#include "unp.h" + +void +sock_set_wild(struct sockaddr *sa, socklen_t salen) +{ + const void *wildptr; + + switch (sa->sa_family) { + case AF_INET: { + static struct in_addr in4addr_any; + + in4addr_any.s_addr = htonl(INADDR_ANY); + wildptr = &in4addr_any; + break; + } + +#ifdef IPV6 + case AF_INET6: { + wildptr = &in6addr_any; + break; + } +#endif + + default: + return; + } + sock_set_addr(sa, salen, wildptr); + return; +} diff --git a/lib/sockatmark.c b/lib/sockatmark.c new file mode 100644 index 0000000..f115f5d --- /dev/null +++ b/lib/sockatmark.c @@ -0,0 +1,11 @@ +#include "unp.h" + +int +sockatmark(int fd) +{ + int flag; + + if (ioctl(fd, SIOCATMARK, &flag) < 0) + return(-1); + return(flag != 0); +} diff --git a/lib/sockfd_to_family.c b/lib/sockfd_to_family.c new file mode 100644 index 0000000..d925a0f --- /dev/null +++ b/lib/sockfd_to_family.c @@ -0,0 +1,26 @@ +/* include sockfd_to_family */ +#include "unp.h" + +int +sockfd_to_family(int sockfd) +{ + struct sockaddr_storage ss; + socklen_t len; + + len = sizeof(ss); + if (getsockname(sockfd, (SA *) &ss, &len) < 0) + return(-1); + return(ss.ss_family); +} +/* end sockfd_to_family */ + +int +Sockfd_to_family(int sockfd) +{ + int rc; + + if ( (rc = sockfd_to_family(sockfd)) < 0) + err_sys("sockfd_to_family error"); + + return(rc); +} diff --git a/lib/sockfd_to_family.lc b/lib/sockfd_to_family.lc new file mode 100644 index 0000000..48beea0 --- /dev/null +++ b/lib/sockfd_to_family.lc @@ -0,0 +1,26 @@ +/* include sockfd_to_family */ +#include "unp.h"## 1 ##src/lib/sockfd_to_family.c## + +int## 2 ##src/lib/sockfd_to_family.c## +sockfd_to_family(int sockfd)## 3 ##src/lib/sockfd_to_family.c## +{## 4 ##src/lib/sockfd_to_family.c## + struct sockaddr_storage ss;## 5 ##src/lib/sockfd_to_family.c## + socklen_t len;## 6 ##src/lib/sockfd_to_family.c## + + len = sizeof(ss);## 7 ##src/lib/sockfd_to_family.c## + if (getsockname(sockfd, (SA *) &ss, &len) < 0)## 8 ##src/lib/sockfd_to_family.c## + return (-1);## 9 ##src/lib/sockfd_to_family.c## + return (ss.ss_family);## 10 ##src/lib/sockfd_to_family.c## +}## 11 ##src/lib/sockfd_to_family.c## +/* end sockfd_to_family */ + +int## 12 ##src/lib/sockfd_to_family.c## +Sockfd_to_family(int sockfd)## 13 ##src/lib/sockfd_to_family.c## +{## 14 ##src/lib/sockfd_to_family.c## + int rc;## 15 ##src/lib/sockfd_to_family.c## + + if ((rc = sockfd_to_family(sockfd)) < 0)## 16 ##src/lib/sockfd_to_family.c## + err_sys("sockfd_to_family error");## 17 ##src/lib/sockfd_to_family.c## + + return (rc);## 18 ##src/lib/sockfd_to_family.c## +}## 19 ##src/lib/sockfd_to_family.c## diff --git a/lib/str_cli.c b/lib/str_cli.c new file mode 100644 index 0000000..ea0f9da --- /dev/null +++ b/lib/str_cli.c @@ -0,0 +1,17 @@ +#include "unp.h" + +void +str_cli(FILE *fp, int sockfd) +{ + char sendline[MAXLINE], recvline[MAXLINE]; + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Writen(sockfd, sendline, strlen(sendline)); + + if (Readline(sockfd, recvline, MAXLINE) == 0) + err_quit("str_cli: server terminated prematurely"); + + Fputs(recvline, stdout); + } +} diff --git a/lib/str_cli.lc b/lib/str_cli.lc new file mode 100644 index 0000000..0c8b17e --- /dev/null +++ b/lib/str_cli.lc @@ -0,0 +1,17 @@ +#include "unp.h"## 1 ##src/lib/str_cli.c## + +void## 2 ##src/lib/str_cli.c## +str_cli(FILE *fp, int sockfd)## 3 ##src/lib/str_cli.c## +{## 4 ##src/lib/str_cli.c## + char sendline[MAXLINE], recvline[MAXLINE];## 5 ##src/lib/str_cli.c## + + while (Fgets(sendline, MAXLINE, fp) != NULL) {## 6 ##src/lib/str_cli.c## + + Writen(sockfd, sendline, strlen(sendline));## 7 ##src/lib/str_cli.c## + + if (Readline(sockfd, recvline, MAXLINE) == 0)## 8 ##src/lib/str_cli.c## + err_quit("str_cli: server terminated prematurely");## 9 ##src/lib/str_cli.c## + + Fputs(recvline, stdout);## 10 ##src/lib/str_cli.c## + }## 11 ##src/lib/str_cli.c## +}## 12 ##src/lib/str_cli.c## diff --git a/lib/str_echo.c b/lib/str_echo.c new file mode 100644 index 0000000..dab6613 --- /dev/null +++ b/lib/str_echo.c @@ -0,0 +1,17 @@ +#include "unp.h" + +void +str_echo(int sockfd) +{ + ssize_t n; + char buf[MAXLINE]; + +again: + while ( (n = read(sockfd, buf, MAXLINE)) > 0) + Writen(sockfd, buf, n); + + if (n < 0 && errno == EINTR) + goto again; + else if (n < 0) + err_sys("str_echo: read error"); +} diff --git a/lib/str_echo.lc b/lib/str_echo.lc new file mode 100644 index 0000000..49b79b7 --- /dev/null +++ b/lib/str_echo.lc @@ -0,0 +1,17 @@ +#include "unp.h"## 1 ##src/lib/str_echo.c## + +void## 2 ##src/lib/str_echo.c## +str_echo(int sockfd)## 3 ##src/lib/str_echo.c## +{## 4 ##src/lib/str_echo.c## + ssize_t n;## 5 ##src/lib/str_echo.c## + char buf[MAXLINE];## 6 ##src/lib/str_echo.c## + + again:## 7 ##src/lib/str_echo.c## + while ((n = read(sockfd, buf, MAXLINE)) > 0)## 8 ##src/lib/str_echo.c## + Writen(sockfd, buf, n);## 9 ##src/lib/str_echo.c## + + if (n < 0 && errno == EINTR)## 10 ##src/lib/str_echo.c## + goto again;## 11 ##src/lib/str_echo.c## + else if (n < 0)## 12 ##src/lib/str_echo.c## + err_sys("str_echo: read error");## 13 ##src/lib/str_echo.c## +}## 14 ##src/lib/str_echo.c## diff --git a/lib/tcp_connect.c b/lib/tcp_connect.c new file mode 100644 index 0000000..30e9bcd --- /dev/null +++ b/lib/tcp_connect.c @@ -0,0 +1,49 @@ +/* include tcp_connect */ +#include "unp.h" + +int +tcp_connect(const char *host, const char *serv) +{ + int sockfd, n; + struct addrinfo hints, *res, *ressave; + + bzero(&hints, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0) + err_quit("tcp_connect error for %s, %s: %s", + host, serv, gai_strerror(n)); + ressave = res; + + do { + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (sockfd < 0) + continue; /* ignore this one */ + + if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0) + break; /* success */ + + Close(sockfd); /* ignore this one */ + } while ( (res = res->ai_next) != NULL); + + if (res == NULL) /* errno set from final connect() */ + err_sys("tcp_connect error for %s, %s", host, serv); + + freeaddrinfo(ressave); + + return(sockfd); +} +/* end tcp_connect */ + +/* + * We place the wrapper function here, not in wraplib.c, because some + * XTI programs need to include wraplib.c, and it also defines + * a Tcp_connect() function. + */ + +int +Tcp_connect(const char *host, const char *serv) +{ + return(tcp_connect(host, serv)); +} diff --git a/lib/tcp_connect.lc b/lib/tcp_connect.lc new file mode 100644 index 0000000..989f60d --- /dev/null +++ b/lib/tcp_connect.lc @@ -0,0 +1,49 @@ +/* include tcp_connect */ +#include "unp.h"## 1 ##src/lib/tcp_connect.c## + +int## 2 ##src/lib/tcp_connect.c## +tcp_connect(const char *host, const char *serv)## 3 ##src/lib/tcp_connect.c## +{## 4 ##src/lib/tcp_connect.c## + int sockfd, n;## 5 ##src/lib/tcp_connect.c## + struct addrinfo hints, *res, *ressave;## 6 ##src/lib/tcp_connect.c## + + bzero(&hints, sizeof(struct addrinfo));## 7 ##src/lib/tcp_connect.c## + hints.ai_family = AF_UNSPEC;## 8 ##src/lib/tcp_connect.c## + hints.ai_socktype = SOCK_STREAM;## 9 ##src/lib/tcp_connect.c## + + if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)## 10 ##src/lib/tcp_connect.c## + err_quit("tcp_connect error for %s, %s: %s",## 11 ##src/lib/tcp_connect.c## + host, serv, gai_strerror(n));## 12 ##src/lib/tcp_connect.c## + ressave = res;## 13 ##src/lib/tcp_connect.c## + + do {## 14 ##src/lib/tcp_connect.c## + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);## 15 ##src/lib/tcp_connect.c## + if (sockfd < 0)## 16 ##src/lib/tcp_connect.c## + continue; /* ignore this one */## 17 ##src/lib/tcp_connect.c## + + if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)## 18 ##src/lib/tcp_connect.c## + break; /* success */## 19 ##src/lib/tcp_connect.c## + + Close(sockfd); /* ignore this one */## 20 ##src/lib/tcp_connect.c## + } while ((res = res->ai_next) != NULL);## 21 ##src/lib/tcp_connect.c## + + if (res == NULL) /* errno set from final connect() */## 22 ##src/lib/tcp_connect.c## + err_sys("tcp_connect error for %s, %s", host, serv);## 23 ##src/lib/tcp_connect.c## + + freeaddrinfo(ressave);## 24 ##src/lib/tcp_connect.c## + + return (sockfd);## 25 ##src/lib/tcp_connect.c## +}## 26 ##src/lib/tcp_connect.c## +/* end tcp_connect */ + +/*## 27 ##src/lib/tcp_connect.c## + * We place the wrapper function here, not in wraplib.c, because some## 28 ##src/lib/tcp_connect.c## + * XTI programs need to include wraplib.c, and it also defines## 29 ##src/lib/tcp_connect.c## + * a Tcp_connect() function.## 30 ##src/lib/tcp_connect.c## + */## 31 ##src/lib/tcp_connect.c## + +int## 32 ##src/lib/tcp_connect.c## +Tcp_connect(const char *host, const char *serv)## 33 ##src/lib/tcp_connect.c## +{## 34 ##src/lib/tcp_connect.c## + return (tcp_connect(host, serv));## 35 ##src/lib/tcp_connect.c## +}## 36 ##src/lib/tcp_connect.c## diff --git a/lib/tcp_listen.c b/lib/tcp_listen.c new file mode 100644 index 0000000..2f5755c --- /dev/null +++ b/lib/tcp_listen.c @@ -0,0 +1,57 @@ +/* include tcp_listen */ +#include "unp.h" + +int +tcp_listen(const char *host, const char *serv, socklen_t *addrlenp) +{ + int listenfd, n; + const int on = 1; + struct addrinfo hints, *res, *ressave; + + bzero(&hints, sizeof(struct addrinfo)); + hints.ai_flags = AI_PASSIVE; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0) + err_quit("tcp_listen error for %s, %s: %s", + host, serv, gai_strerror(n)); + ressave = res; + + do { + listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (listenfd < 0) + continue; /* error, try next one */ + + Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + if (bind(listenfd, res->ai_addr, res->ai_addrlen) == 0) + break; /* success */ + + Close(listenfd); /* bind error, close and try next one */ + } while ( (res = res->ai_next) != NULL); + + if (res == NULL) /* errno from final socket() or bind() */ + err_sys("tcp_listen error for %s, %s", host, serv); + + Listen(listenfd, LISTENQ); + + if (addrlenp) + *addrlenp = res->ai_addrlen; /* return size of protocol address */ + + freeaddrinfo(ressave); + + return(listenfd); +} +/* end tcp_listen */ + +/* + * We place the wrapper function here, not in wraplib.c, because some + * XTI programs need to include wraplib.c, and it also defines + * a Tcp_listen() function. + */ + +int +Tcp_listen(const char *host, const char *serv, socklen_t *addrlenp) +{ + return(tcp_listen(host, serv, addrlenp)); +} diff --git a/lib/tcp_listen.lc b/lib/tcp_listen.lc new file mode 100644 index 0000000..874e303 --- /dev/null +++ b/lib/tcp_listen.lc @@ -0,0 +1,58 @@ +/* include tcp_listen */ +#include "unp.h"## 1 ##src/lib/tcp_listen.c## + +int## 2 ##src/lib/tcp_listen.c## +tcp_listen(const char *host, const char *serv, socklen_t *addrlenp)## 3 ##src/lib/tcp_listen.c## +{## 4 ##src/lib/tcp_listen.c## + int listenfd, n;## 5 ##src/lib/tcp_listen.c## + const int on = 1;## 6 ##src/lib/tcp_listen.c## + struct addrinfo hints, *res, *ressave;## 7 ##src/lib/tcp_listen.c## + + bzero(&hints, sizeof(struct addrinfo));## 8 ##src/lib/tcp_listen.c## + hints.ai_flags = AI_PASSIVE;## 9 ##src/lib/tcp_listen.c## + hints.ai_family = AF_UNSPEC;## 10 ##src/lib/tcp_listen.c## + hints.ai_socktype = SOCK_STREAM;## 11 ##src/lib/tcp_listen.c## + + if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)## 12 ##src/lib/tcp_listen.c## + err_quit("tcp_listen error for %s, %s: %s",## 13 ##src/lib/tcp_listen.c## + host, serv, gai_strerror(n));## 14 ##src/lib/tcp_listen.c## + ressave = res;## 15 ##src/lib/tcp_listen.c## + + do {## 16 ##src/lib/tcp_listen.c## + listenfd =## 17 ##src/lib/tcp_listen.c## + socket(res->ai_family, res->ai_socktype, res->ai_protocol);## 18 ##src/lib/tcp_listen.c## + if (listenfd < 0)## 19 ##src/lib/tcp_listen.c## + continue; /* error, try next one */## 20 ##src/lib/tcp_listen.c## + + Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 21 ##src/lib/tcp_listen.c## + if (bind(listenfd, res->ai_addr, res->ai_addrlen) == 0)## 22 ##src/lib/tcp_listen.c## + break; /* success */## 23 ##src/lib/tcp_listen.c## + + Close(listenfd); /* bind error, close and try next one */## 24 ##src/lib/tcp_listen.c## + } while ((res = res->ai_next) != NULL);## 25 ##src/lib/tcp_listen.c## + + if (res == NULL) /* errno from final socket() or bind() */## 26 ##src/lib/tcp_listen.c## + err_sys("tcp_listen error for %s, %s", host, serv);## 27 ##src/lib/tcp_listen.c## + + Listen(listenfd, LISTENQ);## 28 ##src/lib/tcp_listen.c## + + if (addrlenp)## 29 ##src/lib/tcp_listen.c## + *addrlenp = res->ai_addrlen; /* return size of protocol address */## 30 ##src/lib/tcp_listen.c## + + freeaddrinfo(ressave);## 31 ##src/lib/tcp_listen.c## + + return (listenfd);## 32 ##src/lib/tcp_listen.c## +}## 33 ##src/lib/tcp_listen.c## +/* end tcp_listen */ + +/*## 34 ##src/lib/tcp_listen.c## + * We place the wrapper function here, not in wraplib.c, because some## 35 ##src/lib/tcp_listen.c## + * XTI programs need to include wraplib.c, and it also defines## 36 ##src/lib/tcp_listen.c## + * a Tcp_listen() function.## 37 ##src/lib/tcp_listen.c## + */## 38 ##src/lib/tcp_listen.c## + +int## 39 ##src/lib/tcp_listen.c## +Tcp_listen(const char *host, const char *serv, socklen_t *addrlenp)## 40 ##src/lib/tcp_listen.c## +{## 41 ##src/lib/tcp_listen.c## + return (tcp_listen(host, serv, addrlenp));## 42 ##src/lib/tcp_listen.c## +}## 43 ##src/lib/tcp_listen.c## diff --git a/lib/tv_sub.c b/lib/tv_sub.c new file mode 100644 index 0000000..7ad7830 --- /dev/null +++ b/lib/tv_sub.c @@ -0,0 +1,11 @@ +#include "unp.h" + +void +tv_sub(struct timeval *out, struct timeval *in) +{ + if ( (out->tv_usec -= in->tv_usec) < 0) { /* out -= in */ + --out->tv_sec; + out->tv_usec += 1000000; + } + out->tv_sec -= in->tv_sec; +} diff --git a/lib/udp_client.c b/lib/udp_client.c new file mode 100644 index 0000000..abe780f --- /dev/null +++ b/lib/udp_client.c @@ -0,0 +1,42 @@ +/* include udp_client */ +#include "unp.h" + +int +udp_client(const char *host, const char *serv, SA **saptr, socklen_t *lenp) +{ + int sockfd, n; + struct addrinfo hints, *res, *ressave; + + bzero(&hints, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + + if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0) + err_quit("udp_client error for %s, %s: %s", + host, serv, gai_strerror(n)); + ressave = res; + + do { + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (sockfd >= 0) + break; /* success */ + } while ( (res = res->ai_next) != NULL); + + if (res == NULL) /* errno set from final socket() */ + err_sys("udp_client error for %s, %s", host, serv); + + *saptr = Malloc(res->ai_addrlen); + memcpy(*saptr, res->ai_addr, res->ai_addrlen); + *lenp = res->ai_addrlen; + + freeaddrinfo(ressave); + + return(sockfd); +} +/* end udp_client */ + +int +Udp_client(const char *host, const char *serv, SA **saptr, socklen_t *lenptr) +{ + return(udp_client(host, serv, saptr, lenptr)); +} diff --git a/lib/udp_client.lc b/lib/udp_client.lc new file mode 100644 index 0000000..055ccc9 --- /dev/null +++ b/lib/udp_client.lc @@ -0,0 +1,42 @@ +/* include udp_client */ +#include "unp.h"## 1 ##src/lib/udp_client.c## + +int## 2 ##src/lib/udp_client.c## +udp_client(const char *host, const char *serv, SA **saptr, socklen_t *lenp)## 3 ##src/lib/udp_client.c## +{## 4 ##src/lib/udp_client.c## + int sockfd, n;## 5 ##src/lib/udp_client.c## + struct addrinfo hints, *res, *ressave;## 6 ##src/lib/udp_client.c## + + bzero(&hints, sizeof(struct addrinfo));## 7 ##src/lib/udp_client.c## + hints.ai_family = AF_UNSPEC;## 8 ##src/lib/udp_client.c## + hints.ai_socktype = SOCK_DGRAM;## 9 ##src/lib/udp_client.c## + + if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)## 10 ##src/lib/udp_client.c## + err_quit("udp_client error for %s, %s: %s",## 11 ##src/lib/udp_client.c## + host, serv, gai_strerror(n));## 12 ##src/lib/udp_client.c## + ressave = res;## 13 ##src/lib/udp_client.c## + + do {## 14 ##src/lib/udp_client.c## + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);## 15 ##src/lib/udp_client.c## + if (sockfd >= 0)## 16 ##src/lib/udp_client.c## + break; /* success */## 17 ##src/lib/udp_client.c## + } while ((res = res->ai_next) != NULL);## 18 ##src/lib/udp_client.c## + + if (res == NULL) /* errno set from final socket() */## 19 ##src/lib/udp_client.c## + err_sys("udp_client error for %s, %s", host, serv);## 20 ##src/lib/udp_client.c## + + *saptr = Malloc(res->ai_addrlen);## 21 ##src/lib/udp_client.c## + memcpy(*saptr, res->ai_addr, res->ai_addrlen);## 22 ##src/lib/udp_client.c## + *lenp = res->ai_addrlen;## 23 ##src/lib/udp_client.c## + + freeaddrinfo(ressave);## 24 ##src/lib/udp_client.c## + + return (sockfd);## 25 ##src/lib/udp_client.c## +}## 26 ##src/lib/udp_client.c## +/* end udp_client */ + +int## 27 ##src/lib/udp_client.c## +Udp_client(const char *host, const char *serv, SA **saptr, socklen_t *lenptr)## 28 ##src/lib/udp_client.c## +{## 29 ##src/lib/udp_client.c## + return (udp_client(host, serv, saptr, lenptr));## 30 ##src/lib/udp_client.c## +}## 31 ##src/lib/udp_client.c## diff --git a/lib/udp_connect.c b/lib/udp_connect.c new file mode 100644 index 0000000..5b90357 --- /dev/null +++ b/lib/udp_connect.c @@ -0,0 +1,49 @@ +/* include udp_connect */ +#include "unp.h" + +int +udp_connect(const char *host, const char *serv) +{ + int sockfd, n; + struct addrinfo hints, *res, *ressave; + + bzero(&hints, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + + if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0) + err_quit("udp_connect error for %s, %s: %s", + host, serv, gai_strerror(n)); + ressave = res; + + do { + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (sockfd < 0) + continue; /* ignore this one */ + + if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0) + break; /* success */ + + Close(sockfd); /* ignore this one */ + } while ( (res = res->ai_next) != NULL); + + if (res == NULL) /* errno set from final connect() */ + err_sys("udp_connect error for %s, %s", host, serv); + + freeaddrinfo(ressave); + + return(sockfd); +} +/* end udp_connect */ + +int +Udp_connect(const char *host, const char *serv) +{ + int n; + + if ( (n = udp_connect(host, serv)) < 0) { + err_quit("udp_connect error for %s, %s: %s", + host, serv, gai_strerror(-n)); + } + return(n); +} diff --git a/lib/udp_connect.lc b/lib/udp_connect.lc new file mode 100644 index 0000000..96b98e8 --- /dev/null +++ b/lib/udp_connect.lc @@ -0,0 +1,49 @@ +/* include udp_connect */ +#include "unp.h"## 1 ##src/lib/udp_connect.c## + +int## 2 ##src/lib/udp_connect.c## +udp_connect(const char *host, const char *serv)## 3 ##src/lib/udp_connect.c## +{## 4 ##src/lib/udp_connect.c## + int sockfd, n;## 5 ##src/lib/udp_connect.c## + struct addrinfo hints, *res, *ressave;## 6 ##src/lib/udp_connect.c## + + bzero(&hints, sizeof(struct addrinfo));## 7 ##src/lib/udp_connect.c## + hints.ai_family = AF_UNSPEC;## 8 ##src/lib/udp_connect.c## + hints.ai_socktype = SOCK_DGRAM;## 9 ##src/lib/udp_connect.c## + + if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)## 10 ##src/lib/udp_connect.c## + err_quit("udp_connect error for %s, %s: %s",## 11 ##src/lib/udp_connect.c## + host, serv, gai_strerror(n));## 12 ##src/lib/udp_connect.c## + ressave = res;## 13 ##src/lib/udp_connect.c## + + do {## 14 ##src/lib/udp_connect.c## + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);## 15 ##src/lib/udp_connect.c## + if (sockfd < 0)## 16 ##src/lib/udp_connect.c## + continue; /* ignore this one */## 17 ##src/lib/udp_connect.c## + + if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)## 18 ##src/lib/udp_connect.c## + break; /* success */## 19 ##src/lib/udp_connect.c## + + Close(sockfd); /* ignore this one */## 20 ##src/lib/udp_connect.c## + } while ((res = res->ai_next) != NULL);## 21 ##src/lib/udp_connect.c## + + if (res == NULL) /* errno set from final connect() */## 22 ##src/lib/udp_connect.c## + err_sys("udp_connect error for %s, %s", host, serv);## 23 ##src/lib/udp_connect.c## + + freeaddrinfo(ressave);## 24 ##src/lib/udp_connect.c## + + return (sockfd);## 25 ##src/lib/udp_connect.c## +}## 26 ##src/lib/udp_connect.c## +/* end udp_connect */ + +int## 27 ##src/lib/udp_connect.c## +Udp_connect(const char *host, const char *serv)## 28 ##src/lib/udp_connect.c## +{## 29 ##src/lib/udp_connect.c## + int n;## 30 ##src/lib/udp_connect.c## + + if ((n = udp_connect(host, serv)) < 0) {## 31 ##src/lib/udp_connect.c## + err_quit("udp_connect error for %s, %s: %s",## 32 ##src/lib/udp_connect.c## + host, serv, gai_strerror(-n));## 33 ##src/lib/udp_connect.c## + }## 34 ##src/lib/udp_connect.c## + return (n);## 35 ##src/lib/udp_connect.c## +}## 36 ##src/lib/udp_connect.c## diff --git a/lib/udp_server.c b/lib/udp_server.c new file mode 100644 index 0000000..d9c2dcf --- /dev/null +++ b/lib/udp_server.c @@ -0,0 +1,47 @@ +/* include udp_server */ +#include "unp.h" + +int +udp_server(const char *host, const char *serv, socklen_t *addrlenp) +{ + int sockfd, n; + struct addrinfo hints, *res, *ressave; + + bzero(&hints, sizeof(struct addrinfo)); + hints.ai_flags = AI_PASSIVE; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + + if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0) + err_quit("udp_server error for %s, %s: %s", + host, serv, gai_strerror(n)); + ressave = res; + + do { + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (sockfd < 0) + continue; /* error - try next one */ + + if (bind(sockfd, res->ai_addr, res->ai_addrlen) == 0) + break; /* success */ + + Close(sockfd); /* bind error - close and try next one */ + } while ( (res = res->ai_next) != NULL); + + if (res == NULL) /* errno from final socket() or bind() */ + err_sys("udp_server error for %s, %s", host, serv); + + if (addrlenp) + *addrlenp = res->ai_addrlen; /* return size of protocol address */ + + freeaddrinfo(ressave); + + return(sockfd); +} +/* end udp_server */ + +int +Udp_server(const char *host, const char *serv, socklen_t *addrlenp) +{ + return(udp_server(host, serv, addrlenp)); +} diff --git a/lib/udp_server.lc b/lib/udp_server.lc new file mode 100644 index 0000000..3e9e6a7 --- /dev/null +++ b/lib/udp_server.lc @@ -0,0 +1,47 @@ +/* include udp_server */ +#include "unp.h"## 1 ##src/lib/udp_server.c## + +int## 2 ##src/lib/udp_server.c## +udp_server(const char *host, const char *serv, socklen_t *addrlenp)## 3 ##src/lib/udp_server.c## +{## 4 ##src/lib/udp_server.c## + int sockfd, n;## 5 ##src/lib/udp_server.c## + struct addrinfo hints, *res, *ressave;## 6 ##src/lib/udp_server.c## + + bzero(&hints, sizeof(struct addrinfo));## 7 ##src/lib/udp_server.c## + hints.ai_flags = AI_PASSIVE;## 8 ##src/lib/udp_server.c## + hints.ai_family = AF_UNSPEC;## 9 ##src/lib/udp_server.c## + hints.ai_socktype = SOCK_DGRAM;## 10 ##src/lib/udp_server.c## + + if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)## 11 ##src/lib/udp_server.c## + err_quit("udp_server error for %s, %s: %s",## 12 ##src/lib/udp_server.c## + host, serv, gai_strerror(n));## 13 ##src/lib/udp_server.c## + ressave = res;## 14 ##src/lib/udp_server.c## + + do {## 15 ##src/lib/udp_server.c## + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);## 16 ##src/lib/udp_server.c## + if (sockfd < 0)## 17 ##src/lib/udp_server.c## + continue; /* error, try next one */## 18 ##src/lib/udp_server.c## + + if (bind(sockfd, res->ai_addr, res->ai_addrlen) == 0)## 19 ##src/lib/udp_server.c## + break; /* success */## 20 ##src/lib/udp_server.c## + + Close(sockfd); /* bind error, close and try next one */## 21 ##src/lib/udp_server.c## + } while ((res = res->ai_next) != NULL);## 22 ##src/lib/udp_server.c## + + if (res == NULL) /* errno from final socket() or bind() */## 23 ##src/lib/udp_server.c## + err_sys("udp_server error for %s, %s", host, serv);## 24 ##src/lib/udp_server.c## + + if (addrlenp)## 25 ##src/lib/udp_server.c## + *addrlenp = res->ai_addrlen; /* return size of protocol address */## 26 ##src/lib/udp_server.c## + + freeaddrinfo(ressave);## 27 ##src/lib/udp_server.c## + + return (sockfd);## 28 ##src/lib/udp_server.c## +}## 29 ##src/lib/udp_server.c## +/* end udp_server */ + +int## 30 ##src/lib/udp_server.c## +Udp_server(const char *host, const char *serv, socklen_t *addrlenp)## 31 ##src/lib/udp_server.c## +{## 32 ##src/lib/udp_server.c## + return (udp_server(host, serv, addrlenp));## 33 ##src/lib/udp_server.c## +}## 34 ##src/lib/udp_server.c## diff --git a/lib/unp.h b/lib/unp.h new file mode 100644 index 0000000..5b8e2a2 --- /dev/null +++ b/lib/unp.h @@ -0,0 +1,517 @@ +/* include unph */ +/* Our own header. Tabs are set for 4 spaces, not 8 */ + +#ifndef __unp_h +#define __unp_h + +#include "../config.h" /* configuration options for current OS */ + /* "../config.h" is generated by configure */ + +/* If anything changes in the following list of #includes, must change + acsite.m4 also, for configure's tests. */ + +#include /* basic system data types */ +#include /* basic socket definitions */ +#if TIME_WITH_SYS_TIME +#include /* timeval{} for select() */ +#include /* timespec{} for pselect() */ +#else +#if HAVE_SYS_TIME_H +#include /* includes unsafely */ +#else +#include /* old system? */ +#endif +#endif +#include /* sockaddr_in{} and other Internet defns */ +#include /* inet(3) functions */ +#include +#include /* for nonblocking */ +#include +#include +#include +#include +#include +#include /* for S_xxx file mode constants */ +#include /* for iovec{} and readv/writev */ +#include +#include +#include /* for Unix domain sockets */ + +#ifdef HAVE_SYS_SELECT_H +# include /* for convenience */ +#endif + +#ifdef HAVE_SYS_SYSCTL_H +#ifdef HAVE_SYS_PARAM_H +# include /* OpenBSD prereq for sysctl.h */ +#endif +# include +#endif + +#ifdef HAVE_POLL_H +# include /* for convenience */ +#endif + +#ifdef HAVE_SYS_EVENT_H +# include /* for kqueue */ +#endif + +#ifdef HAVE_STRINGS_H +# include /* for convenience */ +#endif + +/* Three headers are normally needed for socket/file ioctl's: + * , , and . + */ +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_FILIO_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif + +#ifdef HAVE_PTHREAD_H +# include +#endif + +#ifdef HAVE_NET_IF_DL_H +# include +#endif + +#ifdef HAVE_NETINET_SCTP_H +#include +#endif + +/* OSF/1 actually disables recv() and send() in */ +#ifdef __osf__ +#undef recv +#undef send +#define recv(a,b,c,d) recvfrom(a,b,c,d,0,0) +#define send(a,b,c,d) sendto(a,b,c,d,0,0) +#endif + +#ifndef INADDR_NONE +/* $$.Ic INADDR_NONE$$ */ +#define INADDR_NONE 0xffffffff /* should have been in */ +#endif + +#ifndef SHUT_RD /* these three POSIX names are new */ +#define SHUT_RD 0 /* shutdown for reading */ +#define SHUT_WR 1 /* shutdown for writing */ +#define SHUT_RDWR 2 /* shutdown for reading and writing */ +/* $$.Ic SHUT_RD$$ */ +/* $$.Ic SHUT_WR$$ */ +/* $$.Ic SHUT_RDWR$$ */ +#endif + +/* *INDENT-OFF* */ +#ifndef INET_ADDRSTRLEN +/* $$.Ic INET_ADDRSTRLEN$$ */ +#define INET_ADDRSTRLEN 16 /* "ddd.ddd.ddd.ddd\0" + 1234567890123456 */ +#endif + +/* Define following even if IPv6 not supported, so we can always allocate + an adequately sized buffer without #ifdefs in the code. */ +#ifndef INET6_ADDRSTRLEN +/* $$.Ic INET6_ADDRSTRLEN$$ */ +#define INET6_ADDRSTRLEN 46 /* max size of IPv6 address string: + "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx" or + "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd\0" + 1234567890123456789012345678901234567890123456 */ +#endif +/* *INDENT-ON* */ + +/* Define bzero() as a macro if it's not in standard C library. */ +#ifndef HAVE_BZERO +#define bzero(ptr,n) memset(ptr, 0, n) +/* $$.If bzero$$ */ +/* $$.If memset$$ */ +#endif + +/* Older resolvers do not have gethostbyname2() */ +#ifndef HAVE_GETHOSTBYNAME2 +#define gethostbyname2(host,family) gethostbyname((host)) +#endif + +/* The structure returned by recvfrom_flags() */ +struct unp_in_pktinfo { + struct in_addr ipi_addr; /* dst IPv4 address */ + int ipi_ifindex;/* received interface index */ +}; +/* $$.It unp_in_pktinfo$$ */ +/* $$.Ib ipi_addr$$ */ +/* $$.Ib ipi_ifindex$$ */ + +/* We need the newer CMSG_LEN() and CMSG_SPACE() macros, but few + implementations support them today. These two macros really need + an ALIGN() macro, but each implementation does this differently. */ +#ifndef CMSG_LEN +/* $$.Im CMSG_LEN$$ */ +#define CMSG_LEN(size) (sizeof(struct cmsghdr) + (size)) +#endif +#ifndef CMSG_SPACE +/* $$.Im CMSG_SPACE$$ */ +#define CMSG_SPACE(size) (sizeof(struct cmsghdr) + (size)) +#endif + +/* POSIX requires the SUN_LEN() macro, but not all implementations DefinE + it (yet). Note that this 4.4BSD macro works regardless whether there is + a length field or not. */ +#ifndef SUN_LEN +/* $$.Im SUN_LEN$$ */ +# define SUN_LEN(su) \ + (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) +#endif + +/* POSIX renames "Unix domain" as "local IPC." + Not all systems DefinE AF_LOCAL and PF_LOCAL (yet). */ +#ifndef AF_LOCAL +#define AF_LOCAL AF_UNIX +#endif +#ifndef PF_LOCAL +#define PF_LOCAL PF_UNIX +#endif + +/* POSIX requires that an #include of DefinE INFTIM, but many + systems still DefinE it in . We don't want to include + all the STREAMS stuff if it's not needed, so we just DefinE INFTIM here. + This is the standard value, but there's no guarantee it is -1. */ +#ifndef INFTIM +#define INFTIM (-1) /* infinite poll timeout */ +/* $$.Ic INFTIM$$ */ +#ifdef HAVE_POLL_H +#define INFTIM_UNPH /* tell unpxti.h we defined it */ +#endif +#endif + +/* Following could be derived from SOMAXCONN in , but many + kernels still #define it as 5, while actually supporting many more */ +#define LISTENQ 1024 /* 2nd argument to listen() */ + +/* Miscellaneous constants */ +#define MAXLINE 4096 /* max text line length */ +#define BUFFSIZE 8192 /* buffer size for reads and writes */ + +/* Define some port number that can be used for our examples */ +#define SERV_PORT 9877 /* TCP and UDP */ +#define SERV_PORT_STR "9877" /* TCP and UDP */ +#define UNIXSTR_PATH "/tmp/unix.str" /* Unix domain stream */ +#define UNIXDG_PATH "/tmp/unix.dg" /* Unix domain datagram */ +/* $$.ix [LISTENQ]~constant,~definition~of$$ */ +/* $$.ix [MAXLINE]~constant,~definition~of$$ */ +/* $$.ix [BUFFSIZE]~constant,~definition~of$$ */ +/* $$.ix [SERV_PORT]~constant,~definition~of$$ */ +/* $$.ix [UNIXSTR_PATH]~constant,~definition~of$$ */ +/* $$.ix [UNIXDG_PATH]~constant,~definition~of$$ */ + +/* Following shortens all the typecasts of pointer arguments: */ +#define SA struct sockaddr + +#ifndef HAVE_STRUCT_SOCKADDR_STORAGE +/* + * RFC 3493: protocol-independent placeholder for socket addresses + */ +#define __SS_MAXSIZE 128 +#define __SS_ALIGNSIZE (sizeof(int64_t)) +#ifdef HAVE_SOCKADDR_SA_LEN +#define __SS_PAD1SIZE (__SS_ALIGNSIZE - sizeof(u_char) - sizeof(sa_family_t)) +#else +#define __SS_PAD1SIZE (__SS_ALIGNSIZE - sizeof(sa_family_t)) +#endif +#define __SS_PAD2SIZE (__SS_MAXSIZE - 2*__SS_ALIGNSIZE) + +struct sockaddr_storage { +#ifdef HAVE_SOCKADDR_SA_LEN + u_char ss_len; +#endif + sa_family_t ss_family; + char __ss_pad1[__SS_PAD1SIZE]; + int64_t __ss_align; + char __ss_pad2[__SS_PAD2SIZE]; +}; +#endif + +#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) + /* default file access permissions for new files */ +#define DIR_MODE (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH) + /* default permissions for new directories */ + +typedef void Sigfunc(int); /* for signal handlers */ + +#define min(a,b) ((a) < (b) ? (a) : (b)) +#define max(a,b) ((a) > (b) ? (a) : (b)) + +#ifndef HAVE_ADDRINFO_STRUCT +# include "../lib/addrinfo.h" +#endif + +#ifndef HAVE_IF_NAMEINDEX_STRUCT +struct if_nameindex { + unsigned int if_index; /* 1, 2, ... */ + char *if_name; /* null-terminated name: "le0", ... */ +}; +/* $$.It if_nameindex$$ */ +/* $$.Ib if_index$$ */ +/* $$.Ib if_name$$ */ +#endif + +#ifndef HAVE_TIMESPEC_STRUCT +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* and nanoseconds */ +}; +/* $$.It timespec$$ */ +/* $$.Ib tv_sec$$ */ +/* $$.Ib tv_nsec$$ */ +#endif +/* end unph */ + + /* prototypes for our own library functions */ +int connect_nonb(int, const SA *, socklen_t, int); +int connect_timeo(int, const SA *, socklen_t, int); +int daemon_init(const char *, int); +void daemon_inetd(const char *, int); +void dg_cli(FILE *, int, const SA *, socklen_t); +void dg_echo(int, SA *, socklen_t); +int family_to_level(int); +char *gf_time(void); +void heartbeat_cli(int, int, int); +void heartbeat_serv(int, int, int); +struct addrinfo *host_serv(const char *, const char *, int, int); +int inet_srcrt_add(char *); +u_char *inet_srcrt_init(int); +void inet_srcrt_print(u_char *, int); +void inet6_srcrt_print(void *); +char **my_addrs(int *); +int readable_timeo(int, int); +ssize_t readline(int, void *, size_t); +ssize_t readn(int, void *, size_t); +ssize_t read_fd(int, void *, size_t, int *); +ssize_t recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *, + struct unp_in_pktinfo *); +Sigfunc *signal_intr(int, Sigfunc *); +int sock_bind_wild(int, int); +int sock_cmp_addr(const SA *, const SA *, socklen_t); +int sock_cmp_port(const SA *, const SA *, socklen_t); +int sock_get_port(const SA *, socklen_t); +void sock_set_addr(SA *, socklen_t, const void *); +void sock_set_port(SA *, socklen_t, int); +void sock_set_wild(SA *, socklen_t); +char *sock_ntop(const SA *, socklen_t); +char *sock_ntop_host(const SA *, socklen_t); +int sockfd_to_family(int); +void str_echo(int); +void str_cli(FILE *, int); +int tcp_connect(const char *, const char *); +int tcp_listen(const char *, const char *, socklen_t *); +void tv_sub(struct timeval *, struct timeval *); +int udp_client(const char *, const char *, SA **, socklen_t *); +int udp_connect(const char *, const char *); +int udp_server(const char *, const char *, socklen_t *); +int writable_timeo(int, int); +ssize_t writen(int, const void *, size_t); +ssize_t write_fd(int, void *, size_t, int); + +#ifdef MCAST +int mcast_leave(int, const SA *, socklen_t); +int mcast_join(int, const SA *, socklen_t, const char *, u_int); +int mcast_leave_source_group(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen); +int mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen, + const char *ifname, u_int ifindex); +int mcast_block_source(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen); +int mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen); +int mcast_get_if(int); +int mcast_get_loop(int); +int mcast_get_ttl(int); +int mcast_set_if(int, const char *, u_int); +int mcast_set_loop(int, int); +int mcast_set_ttl(int, int); + +void Mcast_leave(int, const SA *, socklen_t); +void Mcast_join(int, const SA *, socklen_t, const char *, u_int); +void Mcast_leave_source_group(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen); +void Mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen, + const char *ifname, u_int ifindex); +void Mcast_block_source(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen); +void Mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen, + const SA *grp, socklen_t grplen); +int Mcast_get_if(int); +int Mcast_get_loop(int); +int Mcast_get_ttl(int); +void Mcast_set_if(int, const char *, u_int); +void Mcast_set_loop(int, int); +void Mcast_set_ttl(int, int); +#endif + +uint16_t in_cksum(uint16_t *, int); + +#ifndef HAVE_GETADDRINFO_PROTO +int getaddrinfo(const char *, const char *, const struct addrinfo *, + struct addrinfo **); +void freeaddrinfo(struct addrinfo *); +char *gai_strerror(int); +#endif + +#ifndef HAVE_GETNAMEINFO_PROTO +int getnameinfo(const SA *, socklen_t, char *, size_t, char *, size_t, int); +#endif + +#ifndef HAVE_GETHOSTNAME_PROTO +int gethostname(char *, int); +#endif + +#ifndef HAVE_HSTRERROR_PROTO +const char *hstrerror(int); +#endif + +#ifndef HAVE_IF_NAMETOINDEX_PROTO +unsigned int if_nametoindex(const char *); +char *if_indextoname(unsigned int, char *); +void if_freenameindex(struct if_nameindex *); +struct if_nameindex *if_nameindex(void); +#endif + +#ifndef HAVE_INET_PTON_PROTO +int inet_pton(int, const char *, void *); +const char *inet_ntop(int, const void *, char *, size_t); +#endif + +#ifndef HAVE_INET_ATON_PROTO +int inet_aton(const char *, struct in_addr *); +#endif + +#ifndef HAVE_PSELECT_PROTO +int pselect(int, fd_set *, fd_set *, fd_set *, + const struct timespec *, const sigset_t *); +#endif + +#ifndef HAVE_SOCKATMARK_PROTO +int sockatmark(int); +#endif + +#ifndef HAVE_SNPRINTF_PROTO +int snprintf(char *, size_t, const char *, ...); +#endif + + /* prototypes for our own library wrapper functions */ +void Connect_timeo(int, const SA *, socklen_t, int); +int Family_to_level(int); +struct addrinfo *Host_serv(const char *, const char *, int, int); +const char *Inet_ntop(int, const void *, char *, size_t); +void Inet_pton(int, const char *, void *); +char *If_indextoname(unsigned int, char *); +unsigned int If_nametoindex(const char *); +struct if_nameindex *If_nameindex(void); +char **My_addrs(int *); +ssize_t Read_fd(int, void *, size_t, int *); +int Readable_timeo(int, int); +ssize_t Recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *, + struct unp_in_pktinfo *); +Sigfunc *Signal(int, Sigfunc *); +Sigfunc *Signal_intr(int, Sigfunc *); +int Sock_bind_wild(int, int); +char *Sock_ntop(const SA *, socklen_t); +char *Sock_ntop_host(const SA *, socklen_t); +int Sockfd_to_family(int); +int Tcp_connect(const char *, const char *); +int Tcp_listen(const char *, const char *, socklen_t *); +int Udp_client(const char *, const char *, SA **, socklen_t *); +int Udp_connect(const char *, const char *); +int Udp_server(const char *, const char *, socklen_t *); +ssize_t Write_fd(int, void *, size_t, int); +int Writable_timeo(int, int); + + /* prototypes for our Unix wrapper functions: see {Sec errors} */ +void *Calloc(size_t, size_t); +void Close(int); +void Dup2(int, int); +int Fcntl(int, int, int); +void Gettimeofday(struct timeval *, void *); +int Ioctl(int, int, void *); +pid_t Fork(void); +void *Malloc(size_t); +int Mkstemp(char *); +void *Mmap(void *, size_t, int, int, int, off_t); +int Open(const char *, int, mode_t); +void Pipe(int *fds); +ssize_t Read(int, void *, size_t); +void Sigaddset(sigset_t *, int); +void Sigdelset(sigset_t *, int); +void Sigemptyset(sigset_t *); +void Sigfillset(sigset_t *); +int Sigismember(const sigset_t *, int); +void Sigpending(sigset_t *); +void Sigprocmask(int, const sigset_t *, sigset_t *); +char *Strdup(const char *); +long Sysconf(int); +void Sysctl(int *, u_int, void *, size_t *, void *, size_t); +void Unlink(const char *); +pid_t Wait(int *); +pid_t Waitpid(pid_t, int *, int); +void Write(int, void *, size_t); + + /* prototypes for our stdio wrapper functions: see {Sec errors} */ +void Fclose(FILE *); +FILE *Fdopen(int, const char *); +char *Fgets(char *, int, FILE *); +FILE *Fopen(const char *, const char *); +void Fputs(const char *, FILE *); + + /* prototypes for our socket wrapper functions: see {Sec errors} */ +int Accept(int, SA *, socklen_t *); +void Bind(int, const SA *, socklen_t); +void Connect(int, const SA *, socklen_t); +void Getpeername(int, SA *, socklen_t *); +void Getsockname(int, SA *, socklen_t *); +void Getsockopt(int, int, int, void *, socklen_t *); +#ifdef HAVE_INET6_RTH_INIT +int Inet6_rth_space(int, int); +void *Inet6_rth_init(void *, socklen_t, int, int); +void Inet6_rth_add(void *, const struct in6_addr *); +void Inet6_rth_reverse(const void *, void *); +int Inet6_rth_segments(const void *); +struct in6_addr *Inet6_rth_getaddr(const void *, int); +#endif +#ifdef HAVE_KQUEUE +int Kqueue(void); +int Kevent(int, const struct kevent *, int, + struct kevent *, int, const struct timespec *); +#endif +void Listen(int, int); +#ifdef HAVE_POLL +int Poll(struct pollfd *, unsigned long, int); +#endif +ssize_t Readline(int, void *, size_t); +ssize_t Readn(int, void *, size_t); +ssize_t Recv(int, void *, size_t, int); +ssize_t Recvfrom(int, void *, size_t, int, SA *, socklen_t *); +ssize_t Recvmsg(int, struct msghdr *, int); +int Select(int, fd_set *, fd_set *, fd_set *, struct timeval *); +void Send(int, const void *, size_t, int); +void Sendto(int, const void *, size_t, int, const SA *, socklen_t); +void Sendmsg(int, const struct msghdr *, int); +void Setsockopt(int, int, int, const void *, socklen_t); +void Shutdown(int, int); +int Sockatmark(int); +int Socket(int, int, int); +void Socketpair(int, int, int, int *); +void Writen(int, void *, size_t); + +void err_dump(const char *, ...); +void err_msg(const char *, ...); +void err_quit(const char *, ...); +void err_ret(const char *, ...); +void err_sys(const char *, ...); + +#endif /* __unp_h */ diff --git a/lib/unp.lh b/lib/unp.lh new file mode 100644 index 0000000..ce55419 --- /dev/null +++ b/lib/unp.lh @@ -0,0 +1,436 @@ +/* include unph */ +/* Our own header. Tabs are set for 4 spaces, not 8 */## 1 ##src/lib/unp.h## + +#ifndef __unp_h## 2 ##src/lib/unp.h## +#define __unp_h## 3 ##src/lib/unp.h## + +#include "../config.h" /* configuration options for current OS */## 4 ##src/lib/unp.h## + /* "../config.h" is generated by configure */## 5 ##src/lib/unp.h## + +/* If anything changes in the following list of #includes, must change## 6 ##src/lib/unp.h## + acsite.m4 also, for configure's tests. */## 7 ##src/lib/unp.h## + +#include /* basic system data types */## 8 ##src/lib/unp.h## +#include /* basic socket definitions */## 9 ##src/lib/unp.h## +#include /* timeval{} for select() */## 10 ##src/lib/unp.h## +#include /* timespec{} for pselect() */## 11 ##src/lib/unp.h## +#include /* sockaddr_in{} and other Internet defns */## 12 ##src/lib/unp.h## +#include /* inet(3) functions */## 13 ##src/lib/unp.h## +#include ## 14 ##src/lib/unp.h## +#include /* for nonblocking */## 15 ##src/lib/unp.h## +#include ## 16 ##src/lib/unp.h## +#include ## 17 ##src/lib/unp.h## +#include ## 18 ##src/lib/unp.h## +#include ## 19 ##src/lib/unp.h## +#include ## 20 ##src/lib/unp.h## +#include /* for S_xxx file mode constants */## 21 ##src/lib/unp.h## +#include /* for iovec{} and readv/writev */## 22 ##src/lib/unp.h## +#include ## 23 ##src/lib/unp.h## +#include ## 24 ##src/lib/unp.h## +#include /* for Unix domain sockets */## 25 ##src/lib/unp.h## + +#ifdef HAVE_SYS_SELECT_H## 26 ##src/lib/unp.h## +#include /* for convenience */## 27 ##src/lib/unp.h## +#endif## 28 ##src/lib/unp.h## + +#ifdef HAVE_POLL_H## 29 ##src/lib/unp.h## +#include /* for convenience */## 30 ##src/lib/unp.h## +#endif## 31 ##src/lib/unp.h## + +#ifdef HAVE_STRINGS_H## 32 ##src/lib/unp.h## +#include /* for convenience */## 33 ##src/lib/unp.h## +#endif## 34 ##src/lib/unp.h## + +/* Three headers are normally needed for socket/file ioctl's:## 35 ##src/lib/unp.h## + * , , and .## 36 ##src/lib/unp.h## + */## 37 ##src/lib/unp.h## +#ifdef HAVE_SYS_IOCTL_H## 38 ##src/lib/unp.h## +#include ## 39 ##src/lib/unp.h## +#endif## 40 ##src/lib/unp.h## +#ifdef HAVE_SYS_FILIO_H## 41 ##src/lib/unp.h## +#include ## 42 ##src/lib/unp.h## +#endif## 43 ##src/lib/unp.h## +#ifdef HAVE_SYS_SOCKIO_H## 44 ##src/lib/unp.h## +#include ## 45 ##src/lib/unp.h## +#endif## 46 ##src/lib/unp.h## + +#ifdef HAVE_PTHREAD_H## 47 ##src/lib/unp.h## +#include ## 48 ##src/lib/unp.h## +#endif## 49 ##src/lib/unp.h## + +/* OSF/1 actually disables recv() and send() in */## 50 ##src/lib/unp.h## +#ifdef __osf__## 51 ##src/lib/unp.h## +#undef recv## 52 ##src/lib/unp.h## +#undef send## 53 ##src/lib/unp.h## +#define recv(a,b,c,d) recvfrom(a,b,c,d,0,0)## 54 ##src/lib/unp.h## +#define send(a,b,c,d) sendto(a,b,c,d,0,0)## 55 ##src/lib/unp.h## +#endif## 56 ##src/lib/unp.h## + +#ifndef INADDR_NONE## 57 ##src/lib/unp.h## +/* $$.Ic INADDR_NONE$$ */ +#define INADDR_NONE 0xffffffff /* should have been in */## 58 ##src/lib/unp.h## +#endif## 59 ##src/lib/unp.h## + +#ifndef SHUT_RD /* these three Posix.1g names are quite new */## 60 ##src/lib/unp.h## +#define SHUT_RD 0 /* shutdown for reading */## 61 ##src/lib/unp.h## +#define SHUT_WR 1 /* shutdown for writing */## 62 ##src/lib/unp.h## +#define SHUT_RDWR 2 /* shutdown for reading and writing */## 63 ##src/lib/unp.h## +/* $$.Ic SHUT_RD$$ */ +/* $$.Ic SHUT_WR$$ */ +/* $$.Ic SHUT_RDWR$$ */ +#endif## 64 ##src/lib/unp.h## +#ifndef INET_ADDRSTRLEN## 65 ##src/lib/unp.h## +/* $$.Ic INET_ADDRSTRLEN$$ */ +#define INET_ADDRSTRLEN 16 /* "ddd.ddd.ddd.ddd\0"## 66 ##src/lib/unp.h## + 1234567890123456 */## 67 ##src/lib/unp.h## +#endif## 68 ##src/lib/unp.h## + +/* Define following even if IPv6 not supported, so we can always allocate## 69 ##src/lib/unp.h## + an adequately-sized buffer, without #ifdefs in the code. */## 70 ##src/lib/unp.h## +#ifndef INET6_ADDRSTRLEN## 71 ##src/lib/unp.h## +/* $$.Ic INET6_ADDRSTRLEN$$ */ +#define INET6_ADDRSTRLEN 46 /* max size of IPv6 address string:## 72 ##src/lib/unp.h## + "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx" or## 73 ##src/lib/unp.h## + "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd\0"## 74 ##src/lib/unp.h## + 1234567890123456789012345678901234567890123456 */## 75 ##src/lib/unp.h## +#endif## 76 ##src/lib/unp.h## + +/* Define bzero() as a macro if it's not in standard C library. */## 77 ##src/lib/unp.h## +#ifndef HAVE_BZERO## 78 ##src/lib/unp.h## +#define bzero(ptr,n) memset(ptr, 0, n)## 79 ##src/lib/unp.h## +/* $$.If bzero$$ */ +/* $$.If memset$$ */ +#endif## 80 ##src/lib/unp.h## + +/* Older resolvers do not have gethostbyname2() */## 81 ##src/lib/unp.h## +#ifndef HAVE_GETHOSTBYNAME2## 82 ##src/lib/unp.h## +#define gethostbyname2(host,family) gethostbyname((host))## 83 ##src/lib/unp.h## +#endif## 84 ##src/lib/unp.h## + +/* The structure returned by recvfrom_flags() */## 85 ##src/lib/unp.h## +struct in_pktinfo {## 86 ##src/lib/unp.h## + struct in_addr ipi_addr; /* dst IPv4 address */## 87 ##src/lib/unp.h## + int ipi_ifindex; /* received interface index */## 88 ##src/lib/unp.h## +};## 89 ##src/lib/unp.h## +/* $$.It in_pktinfo$$ */ +/* $$.Ib ipi_addr$$ */ +/* $$.Ib ipi_ifindex$$ */ + +/* We need the newer CMSG_LEN() and CMSG_SPACE() macros, but few## 90 ##src/lib/unp.h## + implementations support them today. These two macros really need## 91 ##src/lib/unp.h## + an ALIGN() macro, but each implementation does this differently. */## 92 ##src/lib/unp.h## +#ifndef CMSG_LEN## 93 ##src/lib/unp.h## +/* $$.Ic CMSG_LEN$$ */ +#define CMSG_LEN(size) (sizeof(struct cmsghdr) + (size))## 94 ##src/lib/unp.h## +#endif## 95 ##src/lib/unp.h## +#ifndef CMSG_SPACE## 96 ##src/lib/unp.h## +/* $$.Ic CMSG_SPACE$$ */ +#define CMSG_SPACE(size) (sizeof(struct cmsghdr) + (size))## 97 ##src/lib/unp.h## +#endif## 98 ##src/lib/unp.h## + +/* Posix.1g requires the SUN_LEN() macro but not all implementations define## 99 ##src/lib/unp.h## + it (yet). Note that this 4.4BSD macro works regardless whether there is##100 ##src/lib/unp.h## + a length field or not. */##101 ##src/lib/unp.h## +#ifndef SUN_LEN##102 ##src/lib/unp.h## +/* $$.Im SUN_LEN$$ */ +#define SUN_LEN(su) \##103 ##src/lib/unp.h## + (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))##104 ##src/lib/unp.h## +#endif##105 ##src/lib/unp.h## + +/* Posix.1g renames "Unix domain" as "local IPC".##106 ##src/lib/unp.h## + But not all systems define AF_LOCAL and PF_LOCAL (yet). */##107 ##src/lib/unp.h## +#ifndef AF_LOCAL##108 ##src/lib/unp.h## +#define AF_LOCAL AF_UNIX##109 ##src/lib/unp.h## +#endif##110 ##src/lib/unp.h## +#ifndef PF_LOCAL##111 ##src/lib/unp.h## +#define PF_LOCAL PF_UNIX##112 ##src/lib/unp.h## +#endif##113 ##src/lib/unp.h## + +/* Posix.1g requires that an #include of define INFTIM, but many##114 ##src/lib/unp.h## + systems still define it in . We don't want to include##115 ##src/lib/unp.h## + all the streams stuff if it's not needed, so we just define INFTIM here.##116 ##src/lib/unp.h## + This is the standard value, but there's no guarantee it is -1. */##117 ##src/lib/unp.h## +#ifndef INFTIM##118 ##src/lib/unp.h## +#define INFTIM (-1) /* infinite poll timeout */##119 ##src/lib/unp.h## +/* $$.Ic INFTIM$$ */ +#ifdef HAVE_POLL_H##120 ##src/lib/unp.h## +#define INFTIM_UNPH /* tell unpxti.h we defined it */##121 ##src/lib/unp.h## +#endif##122 ##src/lib/unp.h## +#endif##123 ##src/lib/unp.h## + +/* Following could be derived from SOMAXCONN in , but many##124 ##src/lib/unp.h## + kernels still #define it as 5, while actually supporting many more */##125 ##src/lib/unp.h## +#define LISTENQ 1024 /* 2nd argument to listen() */##126 ##src/lib/unp.h## + +/* Miscellaneous constants */##127 ##src/lib/unp.h## +#define MAXLINE 4096 /* max text line length */##128 ##src/lib/unp.h## +#define MAXSOCKADDR 128 /* max socket address structure size */##129 ##src/lib/unp.h## +#define BUFFSIZE 8192 /* buffer size for reads and writes */##130 ##src/lib/unp.h## + +/* Define some port number that can be used for client-servers */##131 ##src/lib/unp.h## +#define SERV_PORT 9877 /* TCP and UDP client-servers */##132 ##src/lib/unp.h## +#define SERV_PORT_STR "9877" /* TCP and UDP client-servers */##133 ##src/lib/unp.h## +#define UNIXSTR_PATH "/tmp/unix.str" /* Unix domain stream cli-serv */##134 ##src/lib/unp.h## +#define UNIXDG_PATH "/tmp/unix.dg" /* Unix domain datagram cli-serv */##135 ##src/lib/unp.h## +/* $$.ix [LISTENQ]~constant,~definition~of$$ */ +/* $$.ix [MAXLINE]~constant,~definition~of$$ */ +/* $$.ix [MAXSOCKADDR]~constant,~definition~of$$ */ +/* $$.ix [BUFFSIZE]~constant,~definition~of$$ */ +/* $$.ix [SERV_PORT]~constant,~definition~of$$ */ +/* $$.ix [UNIXSTR_PATH]~constant,~definition~of$$ */ +/* $$.ix [UNIXDG_PATH]~constant,~definition~of$$ */ + +/* Following shortens all the type casts of pointer arguments */##136 ##src/lib/unp.h## +#define SA struct sockaddr##137 ##src/lib/unp.h## + +#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)##138 ##src/lib/unp.h## + /* default file access permissions for new files */##139 ##src/lib/unp.h## +#define DIR_MODE (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)##140 ##src/lib/unp.h## + /* default permissions for new directories */##141 ##src/lib/unp.h## + +typedef void Sigfunc (int); /* for signal handlers */##142 ##src/lib/unp.h## + +#define min(a,b) ((a) < (b) ? (a) : (b))##143 ##src/lib/unp.h## +#define max(a,b) ((a) > (b) ? (a) : (b))##144 ##src/lib/unp.h## + +#ifndef HAVE_ADDRINFO_STRUCT##145 ##src/lib/unp.h## +#include "../lib/addrinfo.h"##146 ##src/lib/unp.h## +#endif##147 ##src/lib/unp.h## + +#ifndef HAVE_IF_NAMEINDEX_STRUCT##148 ##src/lib/unp.h## +struct if_nameindex {##149 ##src/lib/unp.h## + unsigned int if_index; /* 1, 2, ... */##150 ##src/lib/unp.h## + char *if_name; /* null terminated name: "le0", ... */##151 ##src/lib/unp.h## +};##152 ##src/lib/unp.h## +/* $$.It if_nameindex$$ */ +/* $$.Ib if_index$$ */ +/* $$.Ib if_name$$ */ +#endif##153 ##src/lib/unp.h## + +#ifndef HAVE_TIMESPEC_STRUCT##154 ##src/lib/unp.h## +struct timespec {##155 ##src/lib/unp.h## + time_t tv_sec; /* seconds */##156 ##src/lib/unp.h## + long tv_nsec; /* and nanoseconds */##157 ##src/lib/unp.h## +};##158 ##src/lib/unp.h## +/* $$.It timespec$$ */ +/* $$.Ib tv_sec$$ */ +/* $$.Ib tv_nsec$$ */ +#endif##159 ##src/lib/unp.h## +/* end unph */ + + /* prototypes for our own library functions */##160 ##src/lib/unp.h## +int connect_nonb(int, const SA *, socklen_t, int);##161 ##src/lib/unp.h## +int connect_timeo(int, const SA *, socklen_t, int);##162 ##src/lib/unp.h## +void daemon_init(const char *, int);##163 ##src/lib/unp.h## +void daemon_inetd(const char *, int);##164 ##src/lib/unp.h## +void dg_cli(FILE *, int, const SA *, socklen_t);##165 ##src/lib/unp.h## +void dg_echo(int, SA *, socklen_t);##166 ##src/lib/unp.h## +char *gf_time(void);##167 ##src/lib/unp.h## +void heartbeat_cli(int, int, int);##168 ##src/lib/unp.h## +void heartbeat_serv(int, int, int);##169 ##src/lib/unp.h## +struct addrinfo *host_serv(const char *, const char *, int, int);##170 ##src/lib/unp.h## +int inet_srcrt_add(char *, int);##171 ##src/lib/unp.h## +u_char *inet_srcrt_init(void);##172 ##src/lib/unp.h## +void inet_srcrt_print(u_char *, int);##173 ##src/lib/unp.h## +char **my_addrs(int *);##174 ##src/lib/unp.h## +int readable_timeo(int, int);##175 ##src/lib/unp.h## +ssize_t readline(int, void *, size_t);##176 ##src/lib/unp.h## +ssize_t readn(int, void *, size_t);##177 ##src/lib/unp.h## +ssize_t read_fd(int, void *, size_t, int *);##178 ##src/lib/unp.h## +ssize_t recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *,##179 ##src/lib/unp.h## + struct in_pktinfo *);##180 ##src/lib/unp.h## +Sigfunc *signal_intr(int, Sigfunc *);##181 ##src/lib/unp.h## +int sock_bind_wild(int, int);##182 ##src/lib/unp.h## +int sock_cmp_addr(const SA *, const SA *, socklen_t);##183 ##src/lib/unp.h## +int sock_cmp_port(const SA *, const SA *, socklen_t);##184 ##src/lib/unp.h## +int sock_get_port(const SA *, socklen_t);##185 ##src/lib/unp.h## +void sock_set_addr(SA *, socklen_t, const void *);##186 ##src/lib/unp.h## +void sock_set_port(SA *, socklen_t, int);##187 ##src/lib/unp.h## +void sock_set_wild(SA *, socklen_t);##188 ##src/lib/unp.h## +char *sock_ntop(const SA *, socklen_t);##189 ##src/lib/unp.h## +char *sock_ntop_host(const SA *, socklen_t);##190 ##src/lib/unp.h## +int sockfd_to_family(int);##191 ##src/lib/unp.h## +void str_echo(int);##192 ##src/lib/unp.h## +void str_cli(FILE *, int);##193 ##src/lib/unp.h## +int tcp_connect(const char *, const char *);##194 ##src/lib/unp.h## +int tcp_listen(const char *, const char *, socklen_t *);##195 ##src/lib/unp.h## +void tv_sub(struct timeval *, struct timeval *);##196 ##src/lib/unp.h## +int udp_client(const char *, const char *, void **, socklen_t *);##197 ##src/lib/unp.h## +int udp_connect(const char *, const char *);##198 ##src/lib/unp.h## +int udp_server(const char *, const char *, socklen_t *);##199 ##src/lib/unp.h## +int writable_timeo(int, int);##200 ##src/lib/unp.h## +ssize_t writen(int, const void *, size_t);##201 ##src/lib/unp.h## +ssize_t write_fd(int, void *, size_t, int);##202 ##src/lib/unp.h## + +#ifdef MCAST##203 ##src/lib/unp.h## +int mcast_leave(int, const SA *, socklen_t);##204 ##src/lib/unp.h## +int mcast_join(int, const SA *, socklen_t, const char *, u_int);##205 ##src/lib/unp.h## +int mcast_get_if(int);##206 ##src/lib/unp.h## +int mcast_get_loop(int);##207 ##src/lib/unp.h## +int mcast_get_ttl(int);##208 ##src/lib/unp.h## +int mcast_set_if(int, const char *, u_int);##209 ##src/lib/unp.h## +int mcast_set_loop(int, int);##210 ##src/lib/unp.h## +int mcast_set_ttl(int, int);##211 ##src/lib/unp.h## + +void Mcast_leave(int, const SA *, socklen_t);##212 ##src/lib/unp.h## +void Mcast_join(int, const SA *, socklen_t, const char *, u_int);##213 ##src/lib/unp.h## +int Mcast_get_if(int);##214 ##src/lib/unp.h## +int Mcast_get_loop(int);##215 ##src/lib/unp.h## +int Mcast_get_ttl(int);##216 ##src/lib/unp.h## +void Mcast_set_if(int, const char *, u_int);##217 ##src/lib/unp.h## +void Mcast_set_loop(int, int);##218 ##src/lib/unp.h## +void Mcast_set_ttl(int, int);##219 ##src/lib/unp.h## +#endif##220 ##src/lib/unp.h## + +unsigned short in_cksum(unsigned short *, int);##221 ##src/lib/unp.h## + +#ifndef HAVE_GETADDRINFO_PROTO##222 ##src/lib/unp.h## +int getaddrinfo(const char *, const char *, const struct addrinfo *,##223 ##src/lib/unp.h## + struct addrinfo **);##224 ##src/lib/unp.h## +void freeaddrinfo(struct addrinfo *);##225 ##src/lib/unp.h## +char *gai_strerror(int);##226 ##src/lib/unp.h## +#endif##227 ##src/lib/unp.h## + +#ifndef HAVE_GETNAMEINFO_PROTO##228 ##src/lib/unp.h## +int getnameinfo(const SA *, socklen_t, char *, size_t, char *, size_t, int);##229 ##src/lib/unp.h## +#endif##230 ##src/lib/unp.h## + +#ifndef HAVE_GETHOSTNAME_PROTO##231 ##src/lib/unp.h## +int gethostname(char *, int);##232 ##src/lib/unp.h## +#endif##233 ##src/lib/unp.h## + +#ifndef HAVE_HSTRERROR_PROTO##234 ##src/lib/unp.h## +const char *hstrerror(int);##235 ##src/lib/unp.h## +#endif##236 ##src/lib/unp.h## + +#ifndef HAVE_IF_NAMETOINDEX_PROTO##237 ##src/lib/unp.h## +unsigned int if_nametoindex(const char *);##238 ##src/lib/unp.h## +char *if_indextoname(unsigned int, char *);##239 ##src/lib/unp.h## +void if_freenameindex(struct if_nameindex *);##240 ##src/lib/unp.h## +struct if_nameindex *if_nameindex(void);##241 ##src/lib/unp.h## +#endif##242 ##src/lib/unp.h## + +#ifndef HAVE_INET_PTON_PROTO##243 ##src/lib/unp.h## +int inet_pton(int, const char *, void *);##244 ##src/lib/unp.h## +const char *inet_ntop(int, const void *, char *, size_t);##245 ##src/lib/unp.h## +#endif##246 ##src/lib/unp.h## + +#ifndef HAVE_INET_ATON_PROTO##247 ##src/lib/unp.h## +int inet_aton(const char *, struct in_addr *);##248 ##src/lib/unp.h## +#endif##249 ##src/lib/unp.h## + +#ifndef HAVE_ISFDTYPE_PROTO##250 ##src/lib/unp.h## +int isfdtype(int, int);##251 ##src/lib/unp.h## +#endif##252 ##src/lib/unp.h## + +#ifndef HAVE_PSELECT_PROTO##253 ##src/lib/unp.h## +int pselect(int, fd_set *, fd_set *, fd_set *,##254 ##src/lib/unp.h## + const struct timespec *, const sigset_t *);##255 ##src/lib/unp.h## +#endif##256 ##src/lib/unp.h## + +#ifndef HAVE_SOCKATMARK_PROTO##257 ##src/lib/unp.h## +int sockatmark(int);##258 ##src/lib/unp.h## +#endif##259 ##src/lib/unp.h## + +#ifndef HAVE_SNPRINTF_PROTO##260 ##src/lib/unp.h## +int snprintf(char *, size_t, const char *,...);##261 ##src/lib/unp.h## +#endif##262 ##src/lib/unp.h## + + /* prototypes for our own library wrapper functions */##263 ##src/lib/unp.h## +void Connect_timeo(int, const SA *, socklen_t, int);##264 ##src/lib/unp.h## +struct addrinfo *Host_serv(const char *, const char *, int, int);##265 ##src/lib/unp.h## +const char *Inet_ntop(int, const void *, char *, size_t);##266 ##src/lib/unp.h## +void Inet_pton(int, const char *, void *);##267 ##src/lib/unp.h## +char *If_indextoname(unsigned int, char *);##268 ##src/lib/unp.h## +unsigned int If_nametoindex(const char *);##269 ##src/lib/unp.h## +struct if_nameindex *If_nameindex(void);##270 ##src/lib/unp.h## +char **My_addrs(int *);##271 ##src/lib/unp.h## +ssize_t Read_fd(int, void *, size_t, int *);##272 ##src/lib/unp.h## +int Readable_timeo(int, int);##273 ##src/lib/unp.h## +ssize_t Recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *,##274 ##src/lib/unp.h## + struct in_pktinfo *);##275 ##src/lib/unp.h## +Sigfunc *Signal(int, Sigfunc *);##276 ##src/lib/unp.h## +Sigfunc *Signal_intr(int, Sigfunc *);##277 ##src/lib/unp.h## +int Sock_bind_wild(int, int);##278 ##src/lib/unp.h## +char *Sock_ntop(const SA *, socklen_t);##279 ##src/lib/unp.h## +char *Sock_ntop_host(const SA *, socklen_t);##280 ##src/lib/unp.h## +int Sockfd_to_family(int);##281 ##src/lib/unp.h## +int Tcp_connect(const char *, const char *);##282 ##src/lib/unp.h## +int Tcp_listen(const char *, const char *, socklen_t *);##283 ##src/lib/unp.h## +int Udp_client(const char *, const char *, void **, socklen_t *);##284 ##src/lib/unp.h## +int Udp_connect(const char *, const char *);##285 ##src/lib/unp.h## +int Udp_server(const char *, const char *, socklen_t *);##286 ##src/lib/unp.h## +ssize_t Write_fd(int, void *, size_t, int);##287 ##src/lib/unp.h## +int Writable_timeo(int, int);##288 ##src/lib/unp.h## + + /* prototypes for our Unix wrapper functions: see {Sec errors} */##289 ##src/lib/unp.h## +void *Calloc(size_t, size_t);##290 ##src/lib/unp.h## +void Close(int);##291 ##src/lib/unp.h## +void Dup2(int, int);##292 ##src/lib/unp.h## +int Fcntl(int, int, int);##293 ##src/lib/unp.h## +void Gettimeofday(struct timeval *, void *);##294 ##src/lib/unp.h## +int Ioctl(int, int, void *);##295 ##src/lib/unp.h## +pid_t Fork(void);##296 ##src/lib/unp.h## +void *Malloc(size_t);##297 ##src/lib/unp.h## +void Mktemp(char *);##298 ##src/lib/unp.h## +void *Mmap(void *, size_t, int, int, int, off_t);##299 ##src/lib/unp.h## +int Open(const char *, int, mode_t);##300 ##src/lib/unp.h## +void Pipe(int *fds);##301 ##src/lib/unp.h## +ssize_t Read(int, void *, size_t);##302 ##src/lib/unp.h## +void Sigaddset(sigset_t *, int);##303 ##src/lib/unp.h## +void Sigdelset(sigset_t *, int);##304 ##src/lib/unp.h## +void Sigemptyset(sigset_t *);##305 ##src/lib/unp.h## +void Sigfillset(sigset_t *);##306 ##src/lib/unp.h## +int Sigismember(const sigset_t *, int);##307 ##src/lib/unp.h## +void Sigpending(sigset_t *);##308 ##src/lib/unp.h## +void Sigprocmask(int, const sigset_t *, sigset_t *);##309 ##src/lib/unp.h## +char *Strdup(const char *);##310 ##src/lib/unp.h## +long Sysconf(int);##311 ##src/lib/unp.h## +void Sysctl(int *, u_int, void *, size_t *, void *, size_t);##312 ##src/lib/unp.h## +void Unlink(const char *);##313 ##src/lib/unp.h## +pid_t Wait(int *);##314 ##src/lib/unp.h## +pid_t Waitpid(pid_t, int *, int);##315 ##src/lib/unp.h## +void Write(int, void *, size_t);##316 ##src/lib/unp.h## + + /* prototypes for our stdio wrapper functions: see {Sec errors} */##317 ##src/lib/unp.h## +void Fclose(FILE *);##318 ##src/lib/unp.h## +FILE *Fdopen(int, const char *);##319 ##src/lib/unp.h## +char *Fgets(char *, int, FILE *);##320 ##src/lib/unp.h## +FILE *Fopen(const char *, const char *);##321 ##src/lib/unp.h## +void Fputs(const char *, FILE *);##322 ##src/lib/unp.h## + + /* prototypes for our socket wrapper functions: see {Sec errors} */##323 ##src/lib/unp.h## +int Accept(int, SA *, socklen_t *);##324 ##src/lib/unp.h## +void Bind(int, const SA *, socklen_t);##325 ##src/lib/unp.h## +void Connect(int, const SA *, socklen_t);##326 ##src/lib/unp.h## +void Getpeername(int, SA *, socklen_t *);##327 ##src/lib/unp.h## +void Getsockname(int, SA *, socklen_t *);##328 ##src/lib/unp.h## +void Getsockopt(int, int, int, void *, socklen_t *);##329 ##src/lib/unp.h## +int Isfdtype(int, int);##330 ##src/lib/unp.h## +void Listen(int, int);##331 ##src/lib/unp.h## +#ifdef HAVE_POLL##332 ##src/lib/unp.h## +int Poll(struct pollfd *, unsigned long, int);##333 ##src/lib/unp.h## +#endif##334 ##src/lib/unp.h## +ssize_t Readline(int, void *, size_t);##335 ##src/lib/unp.h## +ssize_t Readn(int, void *, size_t);##336 ##src/lib/unp.h## +ssize_t Recv(int, void *, size_t, int);##337 ##src/lib/unp.h## +ssize_t Recvfrom(int, void *, size_t, int, SA *, socklen_t *);##338 ##src/lib/unp.h## +ssize_t Recvmsg(int, struct msghdr *, int);##339 ##src/lib/unp.h## +int Select(int, fd_set *, fd_set *, fd_set *, struct timeval *);##340 ##src/lib/unp.h## +void Send(int, const void *, size_t, int);##341 ##src/lib/unp.h## +void Sendto(int, const void *, size_t, int, const SA *, socklen_t);##342 ##src/lib/unp.h## +void Sendmsg(int, const struct msghdr *, int);##343 ##src/lib/unp.h## +void Setsockopt(int, int, int, const void *, socklen_t);##344 ##src/lib/unp.h## +void Shutdown(int, int);##345 ##src/lib/unp.h## +int Sockatmark(int);##346 ##src/lib/unp.h## +int Socket(int, int, int);##347 ##src/lib/unp.h## +void Socketpair(int, int, int, int *);##348 ##src/lib/unp.h## +void Writen(int, void *, size_t);##349 ##src/lib/unp.h## + +void err_dump(const char *,...);##350 ##src/lib/unp.h## +void err_msg(const char *,...);##351 ##src/lib/unp.h## +void err_quit(const char *,...);##352 ##src/lib/unp.h## +void err_ret(const char *,...);##353 ##src/lib/unp.h## +void err_sys(const char *,...);##354 ##src/lib/unp.h## + +#endif /* __unp_h */##355 ##src/lib/unp.h## diff --git a/lib/unpifi.h b/lib/unpifi.h new file mode 100644 index 0000000..ca10965 --- /dev/null +++ b/lib/unpifi.h @@ -0,0 +1,34 @@ +/* Our own header for the programs that need interface configuration info. + Include this file, instead of "unp.h". */ + +#ifndef __unp_ifi_h +#define __unp_ifi_h + +#include "unp.h" +#include + +#define IFI_NAME 16 /* same as IFNAMSIZ in */ +#define IFI_HADDR 8 /* allow for 64-bit EUI-64 in future */ + +struct ifi_info { + char ifi_name[IFI_NAME]; /* interface name, null-terminated */ + short ifi_index; /* interface index */ + short ifi_mtu; /* interface MTU */ + u_char ifi_haddr[IFI_HADDR]; /* hardware address */ + u_short ifi_hlen; /* # bytes in hardware address: 0, 6, 8 */ + short ifi_flags; /* IFF_xxx constants from */ + short ifi_myflags; /* our own IFI_xxx flags */ + struct sockaddr *ifi_addr; /* primary address */ + struct sockaddr *ifi_brdaddr;/* broadcast address */ + struct sockaddr *ifi_dstaddr;/* destination address */ + struct ifi_info *ifi_next; /* next of these structures */ +}; + +#define IFI_ALIAS 1 /* ifi_addr is an alias */ + + /* function prototypes */ +struct ifi_info *get_ifi_info(int, int); +struct ifi_info *Get_ifi_info(int, int); +void free_ifi_info(struct ifi_info *); + +#endif /* __unp_ifi_h */ diff --git a/lib/unprtt.h b/lib/unprtt.h new file mode 100644 index 0000000..a96b94f --- /dev/null +++ b/lib/unprtt.h @@ -0,0 +1,30 @@ +#ifndef __unp_rtt_h +#define __unp_rtt_h + +#include "unp.h" + +struct rtt_info { + float rtt_rtt; /* most recent measured RTT, in seconds */ + float rtt_srtt; /* smoothed RTT estimator, in seconds */ + float rtt_rttvar; /* smoothed mean deviation, in seconds */ + float rtt_rto; /* current RTO to use, in seconds */ + int rtt_nrexmt; /* # times retransmitted: 0, 1, 2, ... */ + uint32_t rtt_base; /* # sec since 1/1/1970 at start */ +}; + +#define RTT_RXTMIN 2 /* min retransmit timeout value, in seconds */ +#define RTT_RXTMAX 60 /* max retransmit timeout value, in seconds */ +#define RTT_MAXNREXMT 3 /* max # times to retransmit */ + + /* function prototypes */ +void rtt_debug(struct rtt_info *); +void rtt_init(struct rtt_info *); +void rtt_newpack(struct rtt_info *); +int rtt_start(struct rtt_info *); +void rtt_stop(struct rtt_info *, uint32_t); +int rtt_timeout(struct rtt_info *); +uint32_t rtt_ts(struct rtt_info *); + +extern int rtt_d_flag; /* can be set to nonzero for addl info */ + +#endif /* __unp_rtt_h */ diff --git a/lib/unprtt.lh b/lib/unprtt.lh new file mode 100644 index 0000000..47d5c74 --- /dev/null +++ b/lib/unprtt.lh @@ -0,0 +1,30 @@ +#ifndef __unp_rtt_h## 1 ##src/lib/unprtt.h## +#define __unp_rtt_h## 2 ##src/lib/unprtt.h## + +#include "unp.h"## 3 ##src/lib/unprtt.h## + +struct rtt_info {## 4 ##src/lib/unprtt.h## + float rtt_rtt; /* most recent measured RTT, seconds */## 5 ##src/lib/unprtt.h## + float rtt_srtt; /* smoothed RTT estimator, seconds */## 6 ##src/lib/unprtt.h## + float rtt_rttvar; /* smoothed mean deviation, seconds */## 7 ##src/lib/unprtt.h## + float rtt_rto; /* current RTO to use, seconds */## 8 ##src/lib/unprtt.h## + int rtt_nrexmt; /* #times retransmitted: 0, 1, 2, ... */## 9 ##src/lib/unprtt.h## + uint32_t rtt_base; /* #sec since 1/1/1970 at start */## 10 ##src/lib/unprtt.h## +};## 11 ##src/lib/unprtt.h## + +#define RTT_RXTMIN 2 /* min retransmit timeout value, seconds */## 12 ##src/lib/unprtt.h## +#define RTT_RXTMAX 60 /* max retransmit timeout value, seconds */## 13 ##src/lib/unprtt.h## +#define RTT_MAXNREXMT 3 /* max #times to retransmit */## 14 ##src/lib/unprtt.h## + + /* function prototypes */## 15 ##src/lib/unprtt.h## +void rtt_debug(struct rtt_info *);## 16 ##src/lib/unprtt.h## +void rtt_init(struct rtt_info *);## 17 ##src/lib/unprtt.h## +void rtt_newpack(struct rtt_info *);## 18 ##src/lib/unprtt.h## +int rtt_start(struct rtt_info *);## 19 ##src/lib/unprtt.h## +void rtt_stop(struct rtt_info *, uint32_t);## 20 ##src/lib/unprtt.h## +int rtt_timeout(struct rtt_info *);## 21 ##src/lib/unprtt.h## +uint32_t rtt_ts(struct rtt_info *);## 22 ##src/lib/unprtt.h## + +extern int rtt_d_flag; /* can be set nonzero for addl info */## 23 ##src/lib/unprtt.h## + +#endif /* __unp_rtt_h */## 24 ##src/lib/unprtt.h## diff --git a/lib/unpthread.h b/lib/unpthread.h new file mode 100644 index 0000000..e79b779 --- /dev/null +++ b/lib/unpthread.h @@ -0,0 +1,31 @@ +/* Our own header for the programs that use threads. + Include this file, instead of "unp.h". */ + +#ifndef __unp_pthread_h +#define __unp_pthread_h + +#include "unp.h" + +void Pthread_create(pthread_t *, const pthread_attr_t *, + void * (*)(void *), void *); +void Pthread_join(pthread_t, void **); +void Pthread_detach(pthread_t); +void Pthread_kill(pthread_t, int); + +void Pthread_mutexattr_init(pthread_mutexattr_t *); +void Pthread_mutexattr_setpshared(pthread_mutexattr_t *, int); +void Pthread_mutex_init(pthread_mutex_t *, pthread_mutexattr_t *); +void Pthread_mutex_lock(pthread_mutex_t *); +void Pthread_mutex_unlock(pthread_mutex_t *); + +void Pthread_cond_broadcast(pthread_cond_t *); +void Pthread_cond_signal(pthread_cond_t *); +void Pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); +void Pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *, + const struct timespec *); + +void Pthread_key_create(pthread_key_t *, void (*)(void *)); +void Pthread_setspecific(pthread_key_t, const void *); +void Pthread_once(pthread_once_t *, void (*)(void)); + +#endif /* __unp_pthread_h */ diff --git a/lib/wraplib.c b/lib/wraplib.c new file mode 100644 index 0000000..c73cbb8 --- /dev/null +++ b/lib/wraplib.c @@ -0,0 +1,31 @@ +/* + * Wrapper functions for our own library functions. + * Most are included in the source file for the function itself. + */ + +#include "unp.h" + +const char * +Inet_ntop(int family, const void *addrptr, char *strptr, size_t len) +{ + const char *ptr; + + if (strptr == NULL) /* check for old code */ + err_quit("NULL 3rd argument to inet_ntop"); + if ( (ptr = inet_ntop(family, addrptr, strptr, len)) == NULL) + err_sys("inet_ntop error"); /* sets errno */ + return(ptr); +} + +void +Inet_pton(int family, const char *strptr, void *addrptr) +{ + int n; + + if ( (n = inet_pton(family, strptr, addrptr)) < 0) + err_sys("inet_pton error for %s", strptr); /* errno set */ + else if (n == 0) + err_quit("inet_pton error for %s", strptr); /* errno not set */ + + /* nothing to return */ +} diff --git a/lib/wrappthread.c b/lib/wrappthread.c new file mode 100644 index 0000000..c307cf3 --- /dev/null +++ b/lib/wrappthread.c @@ -0,0 +1,188 @@ +/* + * pthreads wrapper functions. + */ + +#include "unp.h" +#include "unpthread.h" + +void +Pthread_create(pthread_t *tid, const pthread_attr_t *attr, + void * (*func)(void *), void *arg) +{ + int n; + + if ( (n = pthread_create(tid, attr, func, arg)) == 0) + return; + errno = n; + err_sys("pthread_create error"); +} + +void +Pthread_join(pthread_t tid, void **status) +{ + int n; + + if ( (n = pthread_join(tid, status)) == 0) + return; + errno = n; + err_sys("pthread_join error"); +} + +void +Pthread_detach(pthread_t tid) +{ + int n; + + if ( (n = pthread_detach(tid)) == 0) + return; + errno = n; + err_sys("pthread_detach error"); +} + +void +Pthread_kill(pthread_t tid, int signo) +{ + int n; + + if ( (n = pthread_kill(tid, signo)) == 0) + return; + errno = n; + err_sys("pthread_kill error"); +} + +void +Pthread_mutexattr_init(pthread_mutexattr_t *attr) +{ + int n; + + if ( (n = pthread_mutexattr_init(attr)) == 0) + return; + errno = n; + err_sys("pthread_mutexattr_init error"); +} + +#ifdef _POSIX_THREAD_PROCESS_SHARED +void +Pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int flag) +{ + int n; + + if ( (n = pthread_mutexattr_setpshared(attr, flag)) == 0) + return; + errno = n; + err_sys("pthread_mutexattr_setpshared error"); +} +#endif + +void +Pthread_mutex_init(pthread_mutex_t *mptr, pthread_mutexattr_t *attr) +{ + int n; + + if ( (n = pthread_mutex_init(mptr, attr)) == 0) + return; + errno = n; + err_sys("pthread_mutex_init error"); +} + +/* include Pthread_mutex_lock */ +void +Pthread_mutex_lock(pthread_mutex_t *mptr) +{ + int n; + + if ( (n = pthread_mutex_lock(mptr)) == 0) + return; + errno = n; + err_sys("pthread_mutex_lock error"); +} +/* end Pthread_mutex_lock */ + +void +Pthread_mutex_unlock(pthread_mutex_t *mptr) +{ + int n; + + if ( (n = pthread_mutex_unlock(mptr)) == 0) + return; + errno = n; + err_sys("pthread_mutex_unlock error"); +} + +void +Pthread_cond_broadcast(pthread_cond_t *cptr) +{ + int n; + + if ( (n = pthread_cond_broadcast(cptr)) == 0) + return; + errno = n; + err_sys("pthread_cond_broadcast error"); +} + +void +Pthread_cond_signal(pthread_cond_t *cptr) +{ + int n; + + if ( (n = pthread_cond_signal(cptr)) == 0) + return; + errno = n; + err_sys("pthread_cond_signal error"); +} + +void +Pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr) +{ + int n; + + if ( (n = pthread_cond_wait(cptr, mptr)) == 0) + return; + errno = n; + err_sys("pthread_cond_wait error"); +} + +void +Pthread_cond_timedwait(pthread_cond_t *cptr, pthread_mutex_t *mptr, + const struct timespec *tsptr) +{ + int n; + + if ( (n = pthread_cond_timedwait(cptr, mptr, tsptr)) == 0) + return; + errno = n; + err_sys("pthread_cond_timedwait error"); +} + +void +Pthread_once(pthread_once_t *ptr, void (*func)(void)) +{ + int n; + + if ( (n = pthread_once(ptr, func)) == 0) + return; + errno = n; + err_sys("pthread_once error"); +} + +void +Pthread_key_create(pthread_key_t *key, void (*func)(void *)) +{ + int n; + + if ( (n = pthread_key_create(key, func)) == 0) + return; + errno = n; + err_sys("pthread_key_create error"); +} + +void +Pthread_setspecific(pthread_key_t key, const void *value) +{ + int n; + + if ( (n = pthread_setspecific(key, value)) == 0) + return; + errno = n; + err_sys("pthread_setspecific error"); +} diff --git a/lib/wrappthread.lc b/lib/wrappthread.lc new file mode 100644 index 0000000..16a6f8a --- /dev/null +++ b/lib/wrappthread.lc @@ -0,0 +1,188 @@ +/*## 1 ##src/lib/wrappthread.c## + * pthreads wrapper functions.## 2 ##src/lib/wrappthread.c## + */## 3 ##src/lib/wrappthread.c## + +#include "unp.h"## 4 ##src/lib/wrappthread.c## +#include "unpthread.h"## 5 ##src/lib/wrappthread.c## + +void## 6 ##src/lib/wrappthread.c## +Pthread_create(pthread_t * tid, const pthread_attr_t * attr,## 7 ##src/lib/wrappthread.c## + void *(*func) (void *), void *arg)## 8 ##src/lib/wrappthread.c## +{## 9 ##src/lib/wrappthread.c## + int n;## 10 ##src/lib/wrappthread.c## + + if ((n = pthread_create(tid, attr, func, arg)) == 0)## 11 ##src/lib/wrappthread.c## + return;## 12 ##src/lib/wrappthread.c## + errno = n;## 13 ##src/lib/wrappthread.c## + err_sys("pthread_create error");## 14 ##src/lib/wrappthread.c## +}## 15 ##src/lib/wrappthread.c## + +void## 16 ##src/lib/wrappthread.c## +Pthread_join(pthread_t tid, void **status)## 17 ##src/lib/wrappthread.c## +{## 18 ##src/lib/wrappthread.c## + int n;## 19 ##src/lib/wrappthread.c## + + if ((n = pthread_join(tid, status)) == 0)## 20 ##src/lib/wrappthread.c## + return;## 21 ##src/lib/wrappthread.c## + errno = n;## 22 ##src/lib/wrappthread.c## + err_sys("pthread_join error");## 23 ##src/lib/wrappthread.c## +}## 24 ##src/lib/wrappthread.c## + +void## 25 ##src/lib/wrappthread.c## +Pthread_detach(pthread_t tid)## 26 ##src/lib/wrappthread.c## +{## 27 ##src/lib/wrappthread.c## + int n;## 28 ##src/lib/wrappthread.c## + + if ((n = pthread_detach(tid)) == 0)## 29 ##src/lib/wrappthread.c## + return;## 30 ##src/lib/wrappthread.c## + errno = n;## 31 ##src/lib/wrappthread.c## + err_sys("pthread_detach error");## 32 ##src/lib/wrappthread.c## +}## 33 ##src/lib/wrappthread.c## + +void## 34 ##src/lib/wrappthread.c## +Pthread_kill(pthread_t tid, int signo)## 35 ##src/lib/wrappthread.c## +{## 36 ##src/lib/wrappthread.c## + int n;## 37 ##src/lib/wrappthread.c## + + if ((n = pthread_kill(tid, signo)) == 0)## 38 ##src/lib/wrappthread.c## + return;## 39 ##src/lib/wrappthread.c## + errno = n;## 40 ##src/lib/wrappthread.c## + err_sys("pthread_kill error");## 41 ##src/lib/wrappthread.c## +}## 42 ##src/lib/wrappthread.c## + +void## 43 ##src/lib/wrappthread.c## +Pthread_mutexattr_init(pthread_mutexattr_t * attr)## 44 ##src/lib/wrappthread.c## +{## 45 ##src/lib/wrappthread.c## + int n;## 46 ##src/lib/wrappthread.c## + + if ((n = pthread_mutexattr_init(attr)) == 0)## 47 ##src/lib/wrappthread.c## + return;## 48 ##src/lib/wrappthread.c## + errno = n;## 49 ##src/lib/wrappthread.c## + err_sys("pthread_mutexattr_init error");## 50 ##src/lib/wrappthread.c## +}## 51 ##src/lib/wrappthread.c## + +#ifdef _POSIX_THREAD_PROCESS_SHARED## 52 ##src/lib/wrappthread.c## +void## 53 ##src/lib/wrappthread.c## +Pthread_mutexattr_setpshared(pthread_mutexattr_t * attr, int flag)## 54 ##src/lib/wrappthread.c## +{## 55 ##src/lib/wrappthread.c## + int n;## 56 ##src/lib/wrappthread.c## + + if ((n = pthread_mutexattr_setpshared(attr, flag)) == 0)## 57 ##src/lib/wrappthread.c## + return;## 58 ##src/lib/wrappthread.c## + errno = n;## 59 ##src/lib/wrappthread.c## + err_sys("pthread_mutexattr_setpshared error");## 60 ##src/lib/wrappthread.c## +}## 61 ##src/lib/wrappthread.c## +#endif## 62 ##src/lib/wrappthread.c## + +void## 63 ##src/lib/wrappthread.c## +Pthread_mutex_init(pthread_mutex_t *mptr, pthread_mutexattr_t * attr)## 64 ##src/lib/wrappthread.c## +{## 65 ##src/lib/wrappthread.c## + int n;## 66 ##src/lib/wrappthread.c## + + if ((n = pthread_mutex_init(mptr, attr)) == 0)## 67 ##src/lib/wrappthread.c## + return;## 68 ##src/lib/wrappthread.c## + errno = n;## 69 ##src/lib/wrappthread.c## + err_sys("pthread_mutex_init error");## 70 ##src/lib/wrappthread.c## +}## 71 ##src/lib/wrappthread.c## + +/* include Pthread_mutex_lock */ +void## 72 ##src/lib/wrappthread.c## +Pthread_mutex_lock(pthread_mutex_t *mptr)## 73 ##src/lib/wrappthread.c## +{## 74 ##src/lib/wrappthread.c## + int n;## 75 ##src/lib/wrappthread.c## + + if ((n = pthread_mutex_lock(mptr)) == 0)## 76 ##src/lib/wrappthread.c## + return;## 77 ##src/lib/wrappthread.c## + errno = n;## 78 ##src/lib/wrappthread.c## + err_sys("pthread_mutex_lock error");## 79 ##src/lib/wrappthread.c## +}## 80 ##src/lib/wrappthread.c## +/* end Pthread_mutex_lock */ + +void## 81 ##src/lib/wrappthread.c## +Pthread_mutex_unlock(pthread_mutex_t *mptr)## 82 ##src/lib/wrappthread.c## +{## 83 ##src/lib/wrappthread.c## + int n;## 84 ##src/lib/wrappthread.c## + + if ((n = pthread_mutex_unlock(mptr)) == 0)## 85 ##src/lib/wrappthread.c## + return;## 86 ##src/lib/wrappthread.c## + errno = n;## 87 ##src/lib/wrappthread.c## + err_sys("pthread_mutex_unlock error");## 88 ##src/lib/wrappthread.c## +}## 89 ##src/lib/wrappthread.c## + +void## 90 ##src/lib/wrappthread.c## +Pthread_cond_broadcast(pthread_cond_t *cptr)## 91 ##src/lib/wrappthread.c## +{## 92 ##src/lib/wrappthread.c## + int n;## 93 ##src/lib/wrappthread.c## + + if ((n = pthread_cond_broadcast(cptr)) == 0)## 94 ##src/lib/wrappthread.c## + return;## 95 ##src/lib/wrappthread.c## + errno = n;## 96 ##src/lib/wrappthread.c## + err_sys("pthread_cond_broadcast error");## 97 ##src/lib/wrappthread.c## +}## 98 ##src/lib/wrappthread.c## + +void## 99 ##src/lib/wrappthread.c## +Pthread_cond_signal(pthread_cond_t *cptr)##100 ##src/lib/wrappthread.c## +{##101 ##src/lib/wrappthread.c## + int n;##102 ##src/lib/wrappthread.c## + + if ((n = pthread_cond_signal(cptr)) == 0)##103 ##src/lib/wrappthread.c## + return;##104 ##src/lib/wrappthread.c## + errno = n;##105 ##src/lib/wrappthread.c## + err_sys("pthread_cond_signal error");##106 ##src/lib/wrappthread.c## +}##107 ##src/lib/wrappthread.c## + +void##108 ##src/lib/wrappthread.c## +Pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr)##109 ##src/lib/wrappthread.c## +{##110 ##src/lib/wrappthread.c## + int n;##111 ##src/lib/wrappthread.c## + + if ((n = pthread_cond_wait(cptr, mptr)) == 0)##112 ##src/lib/wrappthread.c## + return;##113 ##src/lib/wrappthread.c## + errno = n;##114 ##src/lib/wrappthread.c## + err_sys("pthread_cond_wait error");##115 ##src/lib/wrappthread.c## +}##116 ##src/lib/wrappthread.c## + +void##117 ##src/lib/wrappthread.c## +Pthread_cond_timedwait(pthread_cond_t *cptr, pthread_mutex_t *mptr,##118 ##src/lib/wrappthread.c## + const struct timespec *tsptr)##119 ##src/lib/wrappthread.c## +{##120 ##src/lib/wrappthread.c## + int n;##121 ##src/lib/wrappthread.c## + + if ((n = pthread_cond_timedwait(cptr, mptr, tsptr)) == 0)##122 ##src/lib/wrappthread.c## + return;##123 ##src/lib/wrappthread.c## + errno = n;##124 ##src/lib/wrappthread.c## + err_sys("pthread_cond_timedwait error");##125 ##src/lib/wrappthread.c## +}##126 ##src/lib/wrappthread.c## + +void##127 ##src/lib/wrappthread.c## +Pthread_once(pthread_once_t * ptr, void (*func) (void))##128 ##src/lib/wrappthread.c## +{##129 ##src/lib/wrappthread.c## + int n;##130 ##src/lib/wrappthread.c## + + if ((n = pthread_once(ptr, func)) == 0)##131 ##src/lib/wrappthread.c## + return;##132 ##src/lib/wrappthread.c## + errno = n;##133 ##src/lib/wrappthread.c## + err_sys("pthread_once error");##134 ##src/lib/wrappthread.c## +}##135 ##src/lib/wrappthread.c## + +void##136 ##src/lib/wrappthread.c## +Pthread_key_create(pthread_key_t * key, void (*func) (void *))##137 ##src/lib/wrappthread.c## +{##138 ##src/lib/wrappthread.c## + int n;##139 ##src/lib/wrappthread.c## + + if ((n = pthread_key_create(key, func)) == 0)##140 ##src/lib/wrappthread.c## + return;##141 ##src/lib/wrappthread.c## + errno = n;##142 ##src/lib/wrappthread.c## + err_sys("pthread_key_create error");##143 ##src/lib/wrappthread.c## +}##144 ##src/lib/wrappthread.c## + +void##145 ##src/lib/wrappthread.c## +Pthread_setspecific(pthread_key_t key, const void *value)##146 ##src/lib/wrappthread.c## +{##147 ##src/lib/wrappthread.c## + int n;##148 ##src/lib/wrappthread.c## + + if ((n = pthread_setspecific(key, value)) == 0)##149 ##src/lib/wrappthread.c## + return;##150 ##src/lib/wrappthread.c## + errno = n;##151 ##src/lib/wrappthread.c## + err_sys("pthread_setspecific error");##152 ##src/lib/wrappthread.c## +}##153 ##src/lib/wrappthread.c## diff --git a/lib/wrapsock.c b/lib/wrapsock.c new file mode 100644 index 0000000..4ae03c9 --- /dev/null +++ b/lib/wrapsock.c @@ -0,0 +1,306 @@ +/* + * Socket wrapper functions. + * These could all go into separate files, so only the ones needed cause + * the corresponding function to be added to the executable. If sockets + * are a library (SVR4) this might make a difference (?), but if sockets + * are in the kernel (BSD) it doesn't matter. + * + * These wrapper functions also use the same prototypes as POSIX.1g, + * which might differ from many implementations (i.e., POSIX.1g specifies + * the fourth argument to getsockopt() as "void *", not "char *"). + * + * If your system's headers are not correct [i.e., the Solaris 2.5 + * omits the "const" from the second argument to both + * bind() and connect()], you'll get warnings of the form: + *warning: passing arg 2 of `bind' discards `const' from pointer target type + *warning: passing arg 2 of `connect' discards `const' from pointer target type + */ + +#include "unp.h" + +int +Accept(int fd, struct sockaddr *sa, socklen_t *salenptr) +{ + int n; + +again: + if ( (n = accept(fd, sa, salenptr)) < 0) { +#ifdef EPROTO + if (errno == EPROTO || errno == ECONNABORTED) +#else + if (errno == ECONNABORTED) +#endif + goto again; + else + err_sys("accept error"); + } + return(n); +} + +void +Bind(int fd, const struct sockaddr *sa, socklen_t salen) +{ + if (bind(fd, sa, salen) < 0) + err_sys("bind error"); +} + +void +Connect(int fd, const struct sockaddr *sa, socklen_t salen) +{ + if (connect(fd, sa, salen) < 0) + err_sys("connect error"); +} + +void +Getpeername(int fd, struct sockaddr *sa, socklen_t *salenptr) +{ + if (getpeername(fd, sa, salenptr) < 0) + err_sys("getpeername error"); +} + +void +Getsockname(int fd, struct sockaddr *sa, socklen_t *salenptr) +{ + if (getsockname(fd, sa, salenptr) < 0) + err_sys("getsockname error"); +} + +void +Getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlenptr) +{ + if (getsockopt(fd, level, optname, optval, optlenptr) < 0) + err_sys("getsockopt error"); +} + +#ifdef HAVE_INET6_RTH_INIT +int +Inet6_rth_space(int type, int segments) +{ + int ret; + + ret = inet6_rth_space(type, segments); + if (ret < 0) + err_quit("inet6_rth_space error"); + + return ret; +} + +void * +Inet6_rth_init(void *rthbuf, socklen_t rthlen, int type, int segments) +{ + void *ret; + + ret = inet6_rth_init(rthbuf, rthlen, type, segments); + if (ret == NULL) + err_quit("inet6_rth_init error"); + + return ret; +} + +void +Inet6_rth_add(void *rthbuf, const struct in6_addr *addr) +{ + if (inet6_rth_add(rthbuf, addr) < 0) + err_quit("inet6_rth_add error"); +} + +void +Inet6_rth_reverse(const void *in, void *out) +{ + if (inet6_rth_reverse(in, out) < 0) + err_quit("inet6_rth_reverse error"); +} + +int +Inet6_rth_segments(const void *rthbuf) +{ + int ret; + + ret = inet6_rth_segments(rthbuf); + if (ret < 0) + err_quit("inet6_rth_segments error"); + + return ret; +} + +struct in6_addr * +Inet6_rth_getaddr(const void *rthbuf, int idx) +{ + struct in6_addr *ret; + + ret = inet6_rth_getaddr(rthbuf, idx); + if (ret == NULL) + err_quit("inet6_rth_getaddr error"); + + return ret; +} +#endif + +#ifdef HAVE_KQUEUE +int +Kqueue(void) +{ + int ret; + + if ((ret = kqueue()) < 0) + err_sys("kqueue error"); + return ret; +} + +int +Kevent(int kq, const struct kevent *changelist, int nchanges, + struct kevent *eventlist, int nevents, const struct timespec *timeout) +{ + int ret; + + if ((ret = kevent(kq, changelist, nchanges, + eventlist, nevents, timeout)) < 0) + err_sys("kevent error"); + return ret; +} +#endif + + +/* include Listen */ +void +Listen(int fd, int backlog) +{ + char *ptr; + + /*4can override 2nd argument with environment variable */ + if ( (ptr = getenv("LISTENQ")) != NULL) + backlog = atoi(ptr); + + if (listen(fd, backlog) < 0) + err_sys("listen error"); +} +/* end Listen */ + +#ifdef HAVE_POLL +int +Poll(struct pollfd *fdarray, unsigned long nfds, int timeout) +{ + int n; + + if ( (n = poll(fdarray, nfds, timeout)) < 0) + err_sys("poll error"); + + return(n); +} +#endif + +ssize_t +Recv(int fd, void *ptr, size_t nbytes, int flags) +{ + ssize_t n; + + if ( (n = recv(fd, ptr, nbytes, flags)) < 0) + err_sys("recv error"); + return(n); +} + +ssize_t +Recvfrom(int fd, void *ptr, size_t nbytes, int flags, + struct sockaddr *sa, socklen_t *salenptr) +{ + ssize_t n; + + if ( (n = recvfrom(fd, ptr, nbytes, flags, sa, salenptr)) < 0) + err_sys("recvfrom error"); + return(n); +} + +ssize_t +Recvmsg(int fd, struct msghdr *msg, int flags) +{ + ssize_t n; + + if ( (n = recvmsg(fd, msg, flags)) < 0) + err_sys("recvmsg error"); + return(n); +} + +int +Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *timeout) +{ + int n; + + if ( (n = select(nfds, readfds, writefds, exceptfds, timeout)) < 0) + err_sys("select error"); + return(n); /* can return 0 on timeout */ +} + +void +Send(int fd, const void *ptr, size_t nbytes, int flags) +{ + if (send(fd, ptr, nbytes, flags) != (ssize_t)nbytes) + err_sys("send error"); +} + +void +Sendto(int fd, const void *ptr, size_t nbytes, int flags, + const struct sockaddr *sa, socklen_t salen) +{ + if (sendto(fd, ptr, nbytes, flags, sa, salen) != (ssize_t)nbytes) + err_sys("sendto error"); +} + +void +Sendmsg(int fd, const struct msghdr *msg, int flags) +{ + unsigned int i; + ssize_t nbytes; + + nbytes = 0; /* must first figure out what return value should be */ + for (i = 0; i < msg->msg_iovlen; i++) + nbytes += msg->msg_iov[i].iov_len; + + if (sendmsg(fd, msg, flags) != nbytes) + err_sys("sendmsg error"); +} + +void +Setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen) +{ + if (setsockopt(fd, level, optname, optval, optlen) < 0) + err_sys("setsockopt error"); +} + +void +Shutdown(int fd, int how) +{ + if (shutdown(fd, how) < 0) + err_sys("shutdown error"); +} + +int +Sockatmark(int fd) +{ + int n; + + if ( (n = sockatmark(fd)) < 0) + err_sys("sockatmark error"); + return(n); +} + +/* include Socket */ +int +Socket(int family, int type, int protocol) +{ + int n; + + if ( (n = socket(family, type, protocol)) < 0) + err_sys("socket error"); + return(n); +} +/* end Socket */ + +void +Socketpair(int family, int type, int protocol, int *fd) +{ + int n; + + if ( (n = socketpair(family, type, protocol, fd)) < 0) + err_sys("socketpair error"); +} diff --git a/lib/wrapsock.lc b/lib/wrapsock.lc new file mode 100644 index 0000000..963b3f8 --- /dev/null +++ b/lib/wrapsock.lc @@ -0,0 +1,219 @@ +/*## 1 ##src/lib/wrapsock.c## + * Socket wrapper functions.## 2 ##src/lib/wrapsock.c## + * These could all go into separate files, so only the ones needed cause## 3 ##src/lib/wrapsock.c## + * the corresponding function to be added to the executable. If sockets## 4 ##src/lib/wrapsock.c## + * are a library (SVR4) this might make a difference (?), but if sockets## 5 ##src/lib/wrapsock.c## + * are in the kernel (BSD) it doesn't matter.## 6 ##src/lib/wrapsock.c## + *## 7 ##src/lib/wrapsock.c## + * These wrapper functions also use the same prototypes as POSIX.1g,## 8 ##src/lib/wrapsock.c## + * which might differ from many implementations (i.e., POSIX.1g specifies## 9 ##src/lib/wrapsock.c## + * the fourth argument to getsockopt() as "void *", not "char *").## 10 ##src/lib/wrapsock.c## + *## 11 ##src/lib/wrapsock.c## + * If your system's headers are not correct [i.e., the Solaris 2.5## 12 ##src/lib/wrapsock.c## + * omits the "const" from the second argument to both## 13 ##src/lib/wrapsock.c## + * bind() and connect()], you'll get warnings of the form:## 14 ##src/lib/wrapsock.c## + *warning: passing arg 2 of bind discards const from pointer target type## 15 ##src/lib/wrapsock.c## + *warning: passing arg 2 of connect discards const from pointer target type## 16 ##src/lib/wrapsock.c## + */## 17 ##src/lib/wrapsock.c## + +#include "unp.h"## 18 ##src/lib/wrapsock.c## + +int## 19 ##src/lib/wrapsock.c## +Accept(int fd, struct sockaddr *sa, socklen_t *salenptr)## 20 ##src/lib/wrapsock.c## +{## 21 ##src/lib/wrapsock.c## + int n;## 22 ##src/lib/wrapsock.c## + + again:## 23 ##src/lib/wrapsock.c## + if ((n = accept(fd, sa, salenptr)) < 0) {## 24 ##src/lib/wrapsock.c## +#ifdef EPROTO## 25 ##src/lib/wrapsock.c## + if (errno == EPROTO || errno == ECONNABORTED)## 26 ##src/lib/wrapsock.c## +#else## 27 ##src/lib/wrapsock.c## + if (errno == ECONNABORTED)## 28 ##src/lib/wrapsock.c## +#endif## 29 ##src/lib/wrapsock.c## + goto again;## 30 ##src/lib/wrapsock.c## + else## 31 ##src/lib/wrapsock.c## + err_sys("accept error");## 32 ##src/lib/wrapsock.c## + }## 33 ##src/lib/wrapsock.c## + return (n);## 34 ##src/lib/wrapsock.c## +}## 35 ##src/lib/wrapsock.c## + +void## 36 ##src/lib/wrapsock.c## +Bind(int fd, const struct sockaddr *sa, socklen_t salen)## 37 ##src/lib/wrapsock.c## +{## 38 ##src/lib/wrapsock.c## + if (bind(fd, sa, salen) < 0)## 39 ##src/lib/wrapsock.c## + err_sys("bind error");## 40 ##src/lib/wrapsock.c## +}## 41 ##src/lib/wrapsock.c## + +void## 42 ##src/lib/wrapsock.c## +Connect(int fd, const struct sockaddr *sa, socklen_t salen)## 43 ##src/lib/wrapsock.c## +{## 44 ##src/lib/wrapsock.c## + if (connect(fd, sa, salen) < 0)## 45 ##src/lib/wrapsock.c## + err_sys("connect error");## 46 ##src/lib/wrapsock.c## +}## 47 ##src/lib/wrapsock.c## + +void## 48 ##src/lib/wrapsock.c## +Getpeername(int fd, struct sockaddr *sa, socklen_t *salenptr)## 49 ##src/lib/wrapsock.c## +{## 50 ##src/lib/wrapsock.c## + if (getpeername(fd, sa, salenptr) < 0)## 51 ##src/lib/wrapsock.c## + err_sys("getpeername error");## 52 ##src/lib/wrapsock.c## +}## 53 ##src/lib/wrapsock.c## + +void## 54 ##src/lib/wrapsock.c## +Getsockname(int fd, struct sockaddr *sa, socklen_t *salenptr)## 55 ##src/lib/wrapsock.c## +{## 56 ##src/lib/wrapsock.c## + if (getsockname(fd, sa, salenptr) < 0)## 57 ##src/lib/wrapsock.c## + err_sys("getsockname error");## 58 ##src/lib/wrapsock.c## +}## 59 ##src/lib/wrapsock.c## + +void## 60 ##src/lib/wrapsock.c## +Getsockopt(int fd, int level, int optname, void *optval,## 61 ##src/lib/wrapsock.c## + socklen_t *optlenptr)## 62 ##src/lib/wrapsock.c## +{## 63 ##src/lib/wrapsock.c## + if (getsockopt(fd, level, optname, optval, optlenptr) < 0)## 64 ##src/lib/wrapsock.c## + err_sys("getsockopt error");## 65 ##src/lib/wrapsock.c## +}## 66 ##src/lib/wrapsock.c## + +/* include Listen */ +void## 67 ##src/lib/wrapsock.c## +Listen(int fd, int backlog)## 68 ##src/lib/wrapsock.c## +{## 69 ##src/lib/wrapsock.c## + char *ptr;## 70 ##src/lib/wrapsock.c## + + /* 4can override 2nd argument with environment variable */## 71 ##src/lib/wrapsock.c## + if ((ptr = getenv("LISTENQ")) != NULL)## 72 ##src/lib/wrapsock.c## + backlog = atoi(ptr);## 73 ##src/lib/wrapsock.c## + + if (listen(fd, backlog) < 0)## 74 ##src/lib/wrapsock.c## + err_sys("listen error");## 75 ##src/lib/wrapsock.c## +}## 76 ##src/lib/wrapsock.c## +/* end Listen */ + +#ifdef HAVE_POLL## 77 ##src/lib/wrapsock.c## +int## 78 ##src/lib/wrapsock.c## +Poll(struct pollfd *fdarray, unsigned long nfds, int timeout)## 79 ##src/lib/wrapsock.c## +{## 80 ##src/lib/wrapsock.c## + int n;## 81 ##src/lib/wrapsock.c## + + if ((n = poll(fdarray, nfds, timeout)) < 0)## 82 ##src/lib/wrapsock.c## + err_sys("poll error");## 83 ##src/lib/wrapsock.c## + + return (n);## 84 ##src/lib/wrapsock.c## +}## 85 ##src/lib/wrapsock.c## +#endif## 86 ##src/lib/wrapsock.c## + +ssize_t## 87 ##src/lib/wrapsock.c## +Recv(int fd, void *ptr, size_t nbytes, int flags)## 88 ##src/lib/wrapsock.c## +{## 89 ##src/lib/wrapsock.c## + ssize_t n;## 90 ##src/lib/wrapsock.c## + + if ((n = recv(fd, ptr, nbytes, flags)) < 0)## 91 ##src/lib/wrapsock.c## + err_sys("recv error");## 92 ##src/lib/wrapsock.c## + return (n);## 93 ##src/lib/wrapsock.c## +}## 94 ##src/lib/wrapsock.c## + +ssize_t## 95 ##src/lib/wrapsock.c## +Recvfrom(int fd, void *ptr, size_t nbytes, int flags,## 96 ##src/lib/wrapsock.c## + struct sockaddr *sa, socklen_t *salenptr)## 97 ##src/lib/wrapsock.c## +{## 98 ##src/lib/wrapsock.c## + ssize_t n;## 99 ##src/lib/wrapsock.c## + + if ((n = recvfrom(fd, ptr, nbytes, flags, sa, salenptr)) < 0)##100 ##src/lib/wrapsock.c## + err_sys("recvfrom error");##101 ##src/lib/wrapsock.c## + return (n);##102 ##src/lib/wrapsock.c## +}##103 ##src/lib/wrapsock.c## + +ssize_t##104 ##src/lib/wrapsock.c## +Recvmsg(int fd, struct msghdr *msg, int flags)##105 ##src/lib/wrapsock.c## +{##106 ##src/lib/wrapsock.c## + ssize_t n;##107 ##src/lib/wrapsock.c## + + if ((n = recvmsg(fd, msg, flags)) < 0)##108 ##src/lib/wrapsock.c## + err_sys("recvmsg error");##109 ##src/lib/wrapsock.c## + return (n);##110 ##src/lib/wrapsock.c## +}##111 ##src/lib/wrapsock.c## + +int##112 ##src/lib/wrapsock.c## +Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,##113 ##src/lib/wrapsock.c## + struct timeval *timeout)##114 ##src/lib/wrapsock.c## +{##115 ##src/lib/wrapsock.c## + int n;##116 ##src/lib/wrapsock.c## + + if ((n = select(nfds, readfds, writefds, exceptfds, timeout)) < 0)##117 ##src/lib/wrapsock.c## + err_sys("select error");##118 ##src/lib/wrapsock.c## + return (n); /* can return 0 on timeout */##119 ##src/lib/wrapsock.c## +}##120 ##src/lib/wrapsock.c## + +void##121 ##src/lib/wrapsock.c## +Send(int fd, const void *ptr, size_t nbytes, int flags)##122 ##src/lib/wrapsock.c## +{##123 ##src/lib/wrapsock.c## + if (send(fd, ptr, nbytes, flags) != (ssize_t) nbytes)##124 ##src/lib/wrapsock.c## + err_sys("send error");##125 ##src/lib/wrapsock.c## +}##126 ##src/lib/wrapsock.c## + +void##127 ##src/lib/wrapsock.c## +Sendto(int fd, const void *ptr, size_t nbytes, int flags,##128 ##src/lib/wrapsock.c## + const struct sockaddr *sa, socklen_t salen)##129 ##src/lib/wrapsock.c## +{##130 ##src/lib/wrapsock.c## + if (sendto(fd, ptr, nbytes, flags, sa, salen) != (ssize_t) nbytes)##131 ##src/lib/wrapsock.c## + err_sys("sendto error");##132 ##src/lib/wrapsock.c## +}##133 ##src/lib/wrapsock.c## + +void##134 ##src/lib/wrapsock.c## +Sendmsg(int fd, const struct msghdr *msg, int flags)##135 ##src/lib/wrapsock.c## +{##136 ##src/lib/wrapsock.c## + unsigned int i;##137 ##src/lib/wrapsock.c## + ssize_t nbytes;##138 ##src/lib/wrapsock.c## + + nbytes = 0; /* must first figure out what return value should be */##139 ##src/lib/wrapsock.c## + for (i = 0; i < msg->msg_iovlen; i++)##140 ##src/lib/wrapsock.c## + nbytes += msg->msg_iov[i].iov_len;##141 ##src/lib/wrapsock.c## + + if (sendmsg(fd, msg, flags) != nbytes)##142 ##src/lib/wrapsock.c## + err_sys("sendmsg error");##143 ##src/lib/wrapsock.c## +}##144 ##src/lib/wrapsock.c## + +void##145 ##src/lib/wrapsock.c## +Setsockopt(int fd, int level, int optname, const void *optval,##146 ##src/lib/wrapsock.c## + socklen_t optlen)##147 ##src/lib/wrapsock.c## +{##148 ##src/lib/wrapsock.c## + if (setsockopt(fd, level, optname, optval, optlen) < 0)##149 ##src/lib/wrapsock.c## + err_sys("setsockopt error");##150 ##src/lib/wrapsock.c## +}##151 ##src/lib/wrapsock.c## + +void##152 ##src/lib/wrapsock.c## +Shutdown(int fd, int how)##153 ##src/lib/wrapsock.c## +{##154 ##src/lib/wrapsock.c## + if (shutdown(fd, how) < 0)##155 ##src/lib/wrapsock.c## + err_sys("shutdown error");##156 ##src/lib/wrapsock.c## +}##157 ##src/lib/wrapsock.c## + +int##158 ##src/lib/wrapsock.c## +Sockatmark(int fd)##159 ##src/lib/wrapsock.c## +{##160 ##src/lib/wrapsock.c## + int n;##161 ##src/lib/wrapsock.c## + + if ((n = sockatmark(fd)) < 0)##162 ##src/lib/wrapsock.c## + err_sys("sockatmark error");##163 ##src/lib/wrapsock.c## + return (n);##164 ##src/lib/wrapsock.c## +}##165 ##src/lib/wrapsock.c## + +/* include Socket */ +int##166 ##src/lib/wrapsock.c## +Socket(int family, int type, int protocol)##167 ##src/lib/wrapsock.c## +{##168 ##src/lib/wrapsock.c## + int n;##169 ##src/lib/wrapsock.c## + + if ((n = socket(family, type, protocol)) < 0)##170 ##src/lib/wrapsock.c## + err_sys("socket error");##171 ##src/lib/wrapsock.c## + return (n);##172 ##src/lib/wrapsock.c## +}##173 ##src/lib/wrapsock.c## +/* end Socket */ + +void##174 ##src/lib/wrapsock.c## +Socketpair(int family, int type, int protocol, int *fd)##175 ##src/lib/wrapsock.c## +{##176 ##src/lib/wrapsock.c## + int n;##177 ##src/lib/wrapsock.c## + + if ((n = socketpair(family, type, protocol, fd)) < 0)##178 ##src/lib/wrapsock.c## + err_sys("socketpair error");##179 ##src/lib/wrapsock.c## +}##180 ##src/lib/wrapsock.c## diff --git a/lib/wrapstdio.c b/lib/wrapstdio.c new file mode 100644 index 0000000..a156c45 --- /dev/null +++ b/lib/wrapstdio.c @@ -0,0 +1,52 @@ +/* + * Standard I/O wrapper functions. + */ + +#include "unp.h" + +void +Fclose(FILE *fp) +{ + if (fclose(fp) != 0) + err_sys("fclose error"); +} + +FILE * +Fdopen(int fd, const char *type) +{ + FILE *fp; + + if ( (fp = fdopen(fd, type)) == NULL) + err_sys("fdopen error"); + + return(fp); +} + +char * +Fgets(char *ptr, int n, FILE *stream) +{ + char *rptr; + + if ( (rptr = fgets(ptr, n, stream)) == NULL && ferror(stream)) + err_sys("fgets error"); + + return (rptr); +} + +FILE * +Fopen(const char *filename, const char *mode) +{ + FILE *fp; + + if ( (fp = fopen(filename, mode)) == NULL) + err_sys("fopen error"); + + return(fp); +} + +void +Fputs(const char *ptr, FILE *stream) +{ + if (fputs(ptr, stream) == EOF) + err_sys("fputs error"); +} diff --git a/lib/wrapunix.c b/lib/wrapunix.c new file mode 100644 index 0000000..d6a23ce --- /dev/null +++ b/lib/wrapunix.c @@ -0,0 +1,264 @@ +/* + * Socket wrapper functions. + * These could all go into separate files, so only the ones needed cause + * the corresponding function to be added to the executable. If sockets + * are a library (SVR4) this might make a difference (?), but if sockets + * are in the kernel (BSD) it doesn't matter. + * + * These wrapper functions also use the same prototypes as POSIX.1g, + * which might differ from many implementations (i.e., POSIX.1g specifies + * the fourth argument to getsockopt() as "void *", not "char *"). + * + * If your system's headers are not correct [i.e., the Solaris 2.5 + * omits the "const" from the second argument to both + * bind() and connect()], you'll get warnings of the form: + *warning: passing arg 2 of `bind' discards `const' from pointer target type + *warning: passing arg 2 of `connect' discards `const' from pointer target type + */ + +#include "unp.h" + +void * +Calloc(size_t n, size_t size) +{ + void *ptr; + + if ( (ptr = calloc(n, size)) == NULL) + err_sys("calloc error"); + return(ptr); +} + +void +Close(int fd) +{ + if (close(fd) == -1) + err_sys("close error"); +} + +void +Dup2(int fd1, int fd2) +{ + if (dup2(fd1, fd2) == -1) + err_sys("dup2 error"); +} + +int +Fcntl(int fd, int cmd, int arg) +{ + int n; + + if ( (n = fcntl(fd, cmd, arg)) == -1) + err_sys("fcntl error"); + return(n); +} + +void +Gettimeofday(struct timeval *tv, void *foo) +{ + if (gettimeofday(tv, foo) == -1) + err_sys("gettimeofday error"); + return; +} + +int +Ioctl(int fd, int request, void *arg) +{ + int n; + + if ( (n = ioctl(fd, request, arg)) == -1) + err_sys("ioctl error"); + return(n); /* streamio of I_LIST returns value */ +} + +pid_t +Fork(void) +{ + pid_t pid; + + if ( (pid = fork()) == -1) + err_sys("fork error"); + return(pid); +} + +void * +Malloc(size_t size) +{ + void *ptr; + + if ( (ptr = malloc(size)) == NULL) + err_sys("malloc error"); + return(ptr); +} + +int +Mkstemp(char *template) +{ + int i; + +#ifdef HAVE_MKSTEMP + if ((i = mkstemp(template)) < 0) + err_quit("mkstemp error"); +#else + if (mktemp(template) == NULL || template[0] == 0) + err_quit("mktemp error"); + i = Open(template, O_CREAT | O_WRONLY, FILE_MODE); +#endif + + return i; +} + +#include + +void * +Mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) +{ + void *ptr; + + if ( (ptr = mmap(addr, len, prot, flags, fd, offset)) == ((void *) -1)) + err_sys("mmap error"); + return(ptr); +} + +int +Open(const char *pathname, int oflag, mode_t mode) +{ + int fd; + + if ( (fd = open(pathname, oflag, mode)) == -1) + err_sys("open error for %s", pathname); + return(fd); +} + +void +Pipe(int *fds) +{ + if (pipe(fds) < 0) + err_sys("pipe error"); +} + +ssize_t +Read(int fd, void *ptr, size_t nbytes) +{ + ssize_t n; + + if ( (n = read(fd, ptr, nbytes)) == -1) + err_sys("read error"); + return(n); +} + +void +Sigaddset(sigset_t *set, int signo) +{ + if (sigaddset(set, signo) == -1) + err_sys("sigaddset error"); +} + +void +Sigdelset(sigset_t *set, int signo) +{ + if (sigdelset(set, signo) == -1) + err_sys("sigdelset error"); +} + +void +Sigemptyset(sigset_t *set) +{ + if (sigemptyset(set) == -1) + err_sys("sigemptyset error"); +} + +void +Sigfillset(sigset_t *set) +{ + if (sigfillset(set) == -1) + err_sys("sigfillset error"); +} + +int +Sigismember(const sigset_t *set, int signo) +{ + int n; + + if ( (n = sigismember(set, signo)) == -1) + err_sys("sigismember error"); + return(n); +} + +void +Sigpending(sigset_t *set) +{ + if (sigpending(set) == -1) + err_sys("sigpending error"); +} + +void +Sigprocmask(int how, const sigset_t *set, sigset_t *oset) +{ + if (sigprocmask(how, set, oset) == -1) + err_sys("sigprocmask error"); +} + +char * +Strdup(const char *str) +{ + char *ptr; + + if ( (ptr = strdup(str)) == NULL) + err_sys("strdup error"); + return(ptr); +} + +long +Sysconf(int name) +{ + long val; + + errno = 0; /* in case sysconf() does not change this */ + if ( (val = sysconf(name)) == -1) + err_sys("sysconf error"); + return(val); +} + +#ifdef HAVE_SYS_SYSCTL_H +void +Sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + if (sysctl(name, namelen, oldp, oldlenp, newp, newlen) == -1) + err_sys("sysctl error"); +} +#endif + +void +Unlink(const char *pathname) +{ + if (unlink(pathname) == -1) + err_sys("unlink error for %s", pathname); +} + +pid_t +Wait(int *iptr) +{ + pid_t pid; + + if ( (pid = wait(iptr)) == -1) + err_sys("wait error"); + return(pid); +} + +pid_t +Waitpid(pid_t pid, int *iptr, int options) +{ + pid_t retpid; + + if ( (retpid = waitpid(pid, iptr, options)) == -1) + err_sys("waitpid error"); + return(retpid); +} + +void +Write(int fd, void *ptr, size_t nbytes) +{ + if (write(fd, ptr, nbytes) != nbytes) + err_sys("write error"); +} diff --git a/lib/writable_timeo.c b/lib/writable_timeo.c new file mode 100644 index 0000000..b0c35e2 --- /dev/null +++ b/lib/writable_timeo.c @@ -0,0 +1,29 @@ +/* include writable_timeo */ +#include "unp.h" + +int +writable_timeo(int fd, int sec) +{ + fd_set wset; + struct timeval tv; + + FD_ZERO(&wset); + FD_SET(fd, &wset); + + tv.tv_sec = sec; + tv.tv_usec = 0; + + return(select(fd+1, NULL, &wset, NULL, &tv)); + /* > 0 if descriptor is writable */ +} +/* end writable_timeo */ + +int +Writable_timeo(int fd, int sec) +{ + int n; + + if ( (n = writable_timeo(fd, sec)) < 0) + err_sys("writable_timeo error"); + return(n); +} diff --git a/lib/write_fd.c b/lib/write_fd.c new file mode 100644 index 0000000..789136a --- /dev/null +++ b/lib/write_fd.c @@ -0,0 +1,51 @@ +/* include write_fd */ +#include "unp.h" + +ssize_t +write_fd(int fd, void *ptr, size_t nbytes, int sendfd) +{ + struct msghdr msg; + struct iovec iov[1]; + +#ifdef HAVE_MSGHDR_MSG_CONTROL + union { + struct cmsghdr cm; + char control[CMSG_SPACE(sizeof(int))]; + } control_un; + struct cmsghdr *cmptr; + + msg.msg_control = control_un.control; + msg.msg_controllen = sizeof(control_un.control); + + cmptr = CMSG_FIRSTHDR(&msg); + cmptr->cmsg_len = CMSG_LEN(sizeof(int)); + cmptr->cmsg_level = SOL_SOCKET; + cmptr->cmsg_type = SCM_RIGHTS; + *((int *) CMSG_DATA(cmptr)) = sendfd; +#else + msg.msg_accrights = (caddr_t) &sendfd; + msg.msg_accrightslen = sizeof(int); +#endif + + msg.msg_name = NULL; + msg.msg_namelen = 0; + + iov[0].iov_base = ptr; + iov[0].iov_len = nbytes; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + return(sendmsg(fd, &msg, 0)); +} +/* end write_fd */ + +ssize_t +Write_fd(int fd, void *ptr, size_t nbytes, int sendfd) +{ + ssize_t n; + + if ( (n = write_fd(fd, ptr, nbytes, sendfd)) < 0) + err_sys("write_fd error"); + + return(n); +} diff --git a/lib/write_fd.lc b/lib/write_fd.lc new file mode 100644 index 0000000..672e2b9 --- /dev/null +++ b/lib/write_fd.lc @@ -0,0 +1,51 @@ +/* include write_fd */ +#include "unp.h"## 1 ##src/lib/write_fd.c## + +ssize_t## 2 ##src/lib/write_fd.c## +write_fd(int fd, void *ptr, size_t nbytes, int sendfd)## 3 ##src/lib/write_fd.c## +{## 4 ##src/lib/write_fd.c## + struct msghdr msg;## 5 ##src/lib/write_fd.c## + struct iovec iov[1];## 6 ##src/lib/write_fd.c## + +#ifdef HAVE_MSGHDR_MSG_CONTROL## 7 ##src/lib/write_fd.c## + union {## 8 ##src/lib/write_fd.c## + struct cmsghdr cm;## 9 ##src/lib/write_fd.c## + char control[CMSG_SPACE(sizeof(int))];## 10 ##src/lib/write_fd.c## + } control_un;## 11 ##src/lib/write_fd.c## + struct cmsghdr *cmptr;## 12 ##src/lib/write_fd.c## + + msg.msg_control = control_un.control;## 13 ##src/lib/write_fd.c## + msg.msg_controllen = sizeof(control_un.control);## 14 ##src/lib/write_fd.c## + + cmptr = CMSG_FIRSTHDR(&msg);## 15 ##src/lib/write_fd.c## + cmptr->cmsg_len = CMSG_LEN(sizeof(int));## 16 ##src/lib/write_fd.c## + cmptr->cmsg_level = SOL_SOCKET;## 17 ##src/lib/write_fd.c## + cmptr->cmsg_type = SCM_RIGHTS;## 18 ##src/lib/write_fd.c## + *((int *) CMSG_DATA(cmptr)) = sendfd;## 19 ##src/lib/write_fd.c## +#else## 20 ##src/lib/write_fd.c## + msg.msg_accrights = (caddr_t) & sendfd;## 21 ##src/lib/write_fd.c## + msg.msg_accrightslen = sizeof(int);## 22 ##src/lib/write_fd.c## +#endif## 23 ##src/lib/write_fd.c## + + msg.msg_name = NULL;## 24 ##src/lib/write_fd.c## + msg.msg_namelen = 0;## 25 ##src/lib/write_fd.c## + + iov[0].iov_base = ptr;## 26 ##src/lib/write_fd.c## + iov[0].iov_len = nbytes;## 27 ##src/lib/write_fd.c## + msg.msg_iov = iov;## 28 ##src/lib/write_fd.c## + msg.msg_iovlen = 1;## 29 ##src/lib/write_fd.c## + + return (sendmsg(fd, &msg, 0));## 30 ##src/lib/write_fd.c## +}## 31 ##src/lib/write_fd.c## +/* end write_fd */ + +ssize_t## 32 ##src/lib/write_fd.c## +Write_fd(int fd, void *ptr, size_t nbytes, int sendfd)## 33 ##src/lib/write_fd.c## +{## 34 ##src/lib/write_fd.c## + ssize_t n;## 35 ##src/lib/write_fd.c## + + if ((n = write_fd(fd, ptr, nbytes, sendfd)) < 0)## 36 ##src/lib/write_fd.c## + err_sys("write_fd error");## 37 ##src/lib/write_fd.c## + + return (n);## 38 ##src/lib/write_fd.c## +}## 39 ##src/lib/write_fd.c## diff --git a/lib/writen.c b/lib/writen.c new file mode 100644 index 0000000..0bf8eb7 --- /dev/null +++ b/lib/writen.c @@ -0,0 +1,33 @@ +/* include writen */ +#include "unp.h" + +ssize_t /* Write "n" bytes to a descriptor. */ +writen(int fd, const void *vptr, size_t n) +{ + size_t nleft; + ssize_t nwritten; + const char *ptr; + + ptr = vptr; + nleft = n; + while (nleft > 0) { + if ( (nwritten = write(fd, ptr, nleft)) <= 0) { + if (nwritten < 0 && errno == EINTR) + nwritten = 0; /* and call write() again */ + else + return(-1); /* error */ + } + + nleft -= nwritten; + ptr += nwritten; + } + return(n); +} +/* end writen */ + +void +Writen(int fd, void *ptr, size_t nbytes) +{ + if (writen(fd, ptr, nbytes) != nbytes) + err_sys("writen error"); +} diff --git a/lib/writen.lc b/lib/writen.lc new file mode 100644 index 0000000..0fe387d --- /dev/null +++ b/lib/writen.lc @@ -0,0 +1,33 @@ +/* include writen */ +#include "unp.h"## 1 ##src/lib/writen.c## + +ssize_t /* Write "n" bytes to a descriptor. */## 2 ##src/lib/writen.c## +writen(int fd, const void *vptr, size_t n)## 3 ##src/lib/writen.c## +{## 4 ##src/lib/writen.c## + size_t nleft;## 5 ##src/lib/writen.c## + ssize_t nwritten;## 6 ##src/lib/writen.c## + const char *ptr;## 7 ##src/lib/writen.c## + + ptr = vptr;## 8 ##src/lib/writen.c## + nleft = n;## 9 ##src/lib/writen.c## + while (nleft > 0) {## 10 ##src/lib/writen.c## + if ((nwritten = write(fd, ptr, nleft)) <= 0) {## 11 ##src/lib/writen.c## + if (nwritten < 0 && errno == EINTR)## 12 ##src/lib/writen.c## + nwritten = 0; /* and call write() again */## 13 ##src/lib/writen.c## + else## 14 ##src/lib/writen.c## + return (-1); /* error */## 15 ##src/lib/writen.c## + }## 16 ##src/lib/writen.c## + + nleft -= nwritten;## 17 ##src/lib/writen.c## + ptr += nwritten;## 18 ##src/lib/writen.c## + }## 19 ##src/lib/writen.c## + return (n);## 20 ##src/lib/writen.c## +}## 21 ##src/lib/writen.c## +/* end writen */ + +void## 22 ##src/lib/writen.c## +Writen(int fd, void *ptr, size_t nbytes)## 23 ##src/lib/writen.c## +{## 24 ##src/lib/writen.c## + if (writen(fd, ptr, nbytes) != nbytes)## 25 ##src/lib/writen.c## + err_sys("writen error");## 26 ##src/lib/writen.c## +}## 27 ##src/lib/writen.c## diff --git a/libfree/Make.tar b/libfree/Make.tar new file mode 100755 index 0000000..770dd04 --- /dev/null +++ b/libfree/Make.tar @@ -0,0 +1,6 @@ +#!/bin/sh + +tar -cvf addrinfo.tar README.getaddrinfo addrinfo.h getaddrinfo.c \ + getnameinfo.c test_addrinfo.c inet_ntop.c inet_pton.c + +compress addrinfo.tar diff --git a/libfree/Makefile b/libfree/Makefile new file mode 100644 index 0000000..8578107 --- /dev/null +++ b/libfree/Makefile @@ -0,0 +1,11 @@ +include ../Make.defines + +all: ${LIBFREE_OBJS} + ar rv ${LIBUNP_NAME} $? + ${RANLIB} ${LIBUNP_NAME} + +test_inet_pton: test_inet_pton.o + ${CC} ${CFLAGS} -o $@ test_inet_pton.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/libfree/README b/libfree/README new file mode 100644 index 0000000..cd4d816 --- /dev/null +++ b/libfree/README @@ -0,0 +1,3 @@ +This directory contains the library files that do *not* #include unp.h. +The intent is that these functions can stand alone, without the rest +of the code from the book. diff --git a/libfree/README.getaddrinfo b/libfree/README.getaddrinfo new file mode 100644 index 0000000..5c0e0ff --- /dev/null +++ b/libfree/README.getaddrinfo @@ -0,0 +1,19 @@ +09Sep96 + +Please read the comments at the begiinning of getaddrinfo.c. + +Supplied with this function are the two files inet_pton.c and +inet_ntop.c from the BIND-4.9.4 release. The arguments of +these two functions differ from the current (but old) Internet +Draft "ipngwg-bsd-api-05.txt", but the next revision of this +draft will document these functions as they exist in BIND-4.9.4. + +Beware that most IPv6 releases are "alpha" at this time. The +use of the RES_USE_INET6 option in getaddrinfo() is again from +the BIND-4.9.4 release, as this is what will become the standard. +But few implementations, if any, support this unless you install +BIND-4.9.4 (or later) yourself. + +Buf fixes, suggestions, etc. are welcome. + + Rich Stevens (rstevens@kohala.com) diff --git a/libfree/addrinfo.h b/libfree/addrinfo.h new file mode 100644 index 0000000..7cef135 --- /dev/null +++ b/libfree/addrinfo.h @@ -0,0 +1,48 @@ +#ifndef __addrinfo_h +#define __addrinfo_h + +/* + * Everything here really belongs in . + * These defines are separate for now, to avoid having to modify the + * system's header. + */ + +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for host */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; + + /* following for getaddrinfo() */ +#define AI_PASSIVE 1 /* socket is intended for bind() + listen() */ +#define AI_CANONNAME 2 /* return canonical name */ + + /* following for getnameinfo() */ +#define NI_MAXHOST 1025 /* max hostname returned */ +#define NI_MAXSERV 32 /* max service name returned */ + +#define NI_NOFQDN 1 /* do not return FQDN */ +#define NI_NUMERICHOST 2 /* return numeric form of hostname */ +#define NI_NAMEREQD 4 /* return error if hostname not found */ +#define NI_NUMERICSERV 8 /* return numeric form of service name */ +#define NI_DGRAM 16 /* datagram service for getservbyname() */ + + /* error returns */ +#define EAI_ADDRFAMILY 1 /* address family for host not supported */ +#define EAI_AGAIN 2 /* temporary failure in name resolution */ +#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ +#define EAI_FAIL 4 /* non-recoverable failure in name resolution */ +#define EAI_FAMILY 5 /* ai_family not supported */ +#define EAI_MEMORY 6 /* memory allocation failure */ +#define EAI_NODATA 7 /* no address associated with host */ +#define EAI_NONAME 8 /* host nor service provided, or not known */ +#define EAI_SERVICE 9 /* service not supported for ai_socktype */ +#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ +#define EAI_SYSTEM 11 /* system error returned in errno */ + +#endif /* __addrinfo_h */ diff --git a/libfree/getaddrinfo.c b/libfree/getaddrinfo.c new file mode 100644 index 0000000..6b221e1 --- /dev/null +++ b/libfree/getaddrinfo.c @@ -0,0 +1,769 @@ +/* + * Copyright (c) 1996 W. Richard Stevens. All rights reserved. + * + * Permission to use or modify this software for educational or + * for commercial purposes, and without fee, is hereby granted, + * provided that the above copyright notice appears in connection + * with any and all uses, with clear indication as to any + * modifications made. The author RESERVES the sole rights of + * reproduction, publication and distribution and hence permission + * to print this source code in any book, reference manual, + * magazine, or other type of publication, including any digital + * medium, must be granted in writing by W. Richard Stevens. + * + * The author makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +/* tabs set for 4 spaces, not 8 */ + +#ifdef __osf__ +#define _SOCKADDR_LEN /* required for this implementation */ +#define INET6 /* required for this implementation */ +#endif + +#include +#include +#include +#include /* isdigit() */ +#include /* hostent{}, servent{}, etc. */ +#include /* inet_pton() */ +#include +#include /* DNS resolver */ +#include /* malloc() and calloc() */ +#include /* strdup() and strncpy() */ +#include /* unlink() */ +#include /* for Unix domain socket stuff */ + +#ifndef __osf__ +#include "addrinfo.h" /* defines in here really belong in */ +#endif + +/* NOTE: this code assumes you have the inet_pton() function as defined + * in the BIND-4.9.4 release or later (ftp://ftp.vix.com/pub/bind). + * If you don't have this in your resolver library, in this tar file is + * a copy of it, along with inet_ntop(). */ + +/* We need a way to determine if the compiling host supports IPv4/IPv6. + * Cannot test for AF_INET6, as some vendors #define it, even though + * they don't support it. */ + +#ifdef AF_INET +#define IPV4 /* this is tested throughout the code that follows */ +#endif + + /* no one constant that all implementations define, sigh */ +#if defined(IPV6ADDR_ANY_INIT) +#define IPV6 /* this is tested throughout the code that follows */ +#elif defined(IPV6_FLOWINFO_FLOWLABEL) +#define IPV6 /* this is tested throughout the code that follows */ +#endif + +/* There is no requirement that getaddrinfo() support Unix domain sockets, + * but what the heck, it doesn't take too much code, and it's a real good + * test whether an application is *really* protocol-independent. */ + +#ifdef AF_UNIX +#define LOCAL /* this is tested throughout the code that follows */ + +#ifndef AF_LOCAL +#define AF_LOCAL AF_UNIX /* the Posix.1g correct term */ +#endif +#ifndef PF_LOCAL +#define PF_LOCAL PF_UNIX /* the Posix.1g correct term */ +#endif + +#endif /* AF_UNIX */ + +/* Define REENTRANT if the reentrant versions of get{host|serv}byname + * are to be used. + * Note that getaddrinfo{} *must* be reentrant if the underlying + * get{host|serv}byname_r functions are provided. + * This program has only been tested with the Solaris 2.x functions. + * (I have no idea if other vendors have the same functions or not.) + * + * Long diatribe: Don't define REENTRANT. At least not until you know + * what your vendor's gethostbyname_r() function does with regard to + * IPv4/IPv6 addresses. If you really need a reentrant version of this + * function, because you call it from different threads, then use a + * mutex lock to protect the calls. + * The problem at the time of this writing is the handling of IPv4/IPv6 + * addresses. BIND-4.9.4 does it the "right" way :-), but this won't + * be documented until a later revision of the IPv6 BSD API spec. Also + * BIND-4.9.4 doesn't provide the reentrant _r() functions, and I have + * no idea what the vendors like Sun have done with these functions. + * The code far below that calls gethostbyname() sets the resolver + * RES_USE_INET6 option if the caller specifies an ai_family of AF_INET6. + * This causes 16-byte addresses to be returned, regardless, either + * "true" IPv6 address from AAAA records, or IPv4-mapped IPv6 addresses + * from A records. If the caller specifies an ai_family of AF_INET6, + * then we should return 16-byte addresses. + * With BIND-4.9.4 the caller can also force the return of 16-byte addresses + * by setting the environment variable RES_OPTIONS, as in + * % RES_OPTIONS=inet6 ./a.out arguments... + * This way the caller need not pollute the code with code like + * ai_family = AF_INET6, making the code protocol-dependent. + */ + +/* #define REENTRANT */ + +/* Define following function prototype if your headers don't define it */ + +int inet_pton(int, const char *, void *); + +#define HENTBUFSIZ 8*1024 +#define HENTMAXADDR 32 /* max binary address: 16 for IPv4, 24 for IPv6 */ + + /* following internal flags cannot overlap with other AI_xxx flags */ +#define AI_CLONE 4 /* clone this entry for other socket types */ + + /* function prototypes for our own internal functions */ +static int getaddrinfo_host(const char *, struct hostent *, + struct hostent **, char *, int, int); +static int getaddrinfo_serv(struct addrinfo *, + const struct addrinfo *, const char *, + struct servent *, char *, int); +static int getaddrinfo_port(struct addrinfo *, int , int); +static int addrinfo_local(const char *, struct addrinfo *, + struct addrinfo **); +static struct addrinfo *getaddrinfo_clone(struct addrinfo *); + + /* globals for all functions in this file; these *must* be + read-only if this function is to be reentrant */ +static struct addrinfo hints_default; + +int +getaddrinfo(const char *host, const char *serv, + const struct addrinfo *hintsptr, struct addrinfo **result) +{ + int rc, error; + struct hostent *hptr, hent; + struct servent sent; + char hentbuf[HENTBUFSIZ], hent_addr[HENTMAXADDR]; + char *hent_aliases[1], *hent_addr_list[2]; + char **ap; + struct addrinfo hints, *ai, *aihead, **aipnext; + +#ifdef IPV4 + struct sockaddr_in *sinptr; +#endif + +#ifdef IPV6 + struct sockaddr_in6 *sin6ptr; +#endif + +/* If we encounter an error we want to free() any dynamic memory + that we've allocated. This is our hack to simplify the code. */ +#define error(e) { error = (e); goto bad; } + + /* + * We must make a copy of the caller's hints structure, so we can + * modify ai_family. If the caller doesn't provide a hints structure, + * use a default one. This simplifies all the following code. + * In the default one, ai_flags, ai_socktype, and ai_protocol are all 0, + * but we have to set ai_family to AF_UNSPEC, which isn't guaranteed to + * be 0. + */ + if (hintsptr == NULL) { + hints_default.ai_family = AF_UNSPEC; + hints = hints_default; /* struct copy */ + } else + hints = *hintsptr; /* struct copy */ + + /* + * First some error checking. + */ + if (hints.ai_flags & ~(AI_PASSIVE | AI_CANONNAME)) + error(EAI_BADFLAGS); /* unknown flag bits */ + + /* + * Check that the family is valid, and if a socket type is also + * specified, check that it's valid for the family. + */ + if (hints.ai_family != 0) { + switch(hints.ai_family) { + case AF_UNSPEC: break; + /* Actually, AF_UNSPEC is normally defined as 0, + but Posix.1g does not require this. */ +#ifdef IPV4 + case AF_INET: + if (hints.ai_socktype != 0 && + (hints.ai_socktype != SOCK_STREAM && + hints.ai_socktype != SOCK_DGRAM && + hints.ai_socktype != SOCK_RAW)) + error(EAI_SOCKTYPE); /* invalid socket type */ + break; +#endif +#ifdef IPV6 + case AF_INET6: + if (hints.ai_socktype != 0 && + (hints.ai_socktype != SOCK_STREAM && + hints.ai_socktype != SOCK_DGRAM && + hints.ai_socktype != SOCK_RAW)) + error(EAI_SOCKTYPE); /* invalid socket type */ + break; +#endif +#ifdef LOCAL + case AF_LOCAL: + if (hints.ai_socktype != 0 && + (hints.ai_socktype != SOCK_STREAM && + hints.ai_socktype != SOCK_DGRAM)) + error(EAI_SOCKTYPE); /* invalid socket type */ + break; +#endif + default: + error(EAI_FAMILY); /* unknown protocol family */ + } + } + + if (host == NULL || host[0] == '\0') { + if (serv == NULL || serv[0] == '\0') + error(EAI_NONAME); /* either host or serv must be specified */ + + if (hints.ai_flags & AI_PASSIVE) { + /* + * No "host" and AI_PASSIVE: the returned address must be + * ready for bind(): 0.0.0.0 for IPv4 or 0::0 for IPv6. + */ + switch (hints.ai_family) { +#ifdef IPV4 + case AF_INET: host = "0.0.0.0"; break; +#endif +#ifdef IPV6 + case AF_INET6: host = "0::0"; break; +#endif +#ifdef LOCAL + case AF_LOCAL: + if (serv[0] != '/') /* allow service to specify path */ + error(EAI_ADDRFAMILY); + break; +#endif + case 0: error(EAI_ADDRFAMILY); + /* How can we initialize a socket address structure + for a passive open if we don't even know the family? */ + } + } else { + /* + * No host and not AI_PASSIVE: caller implies connect() to + * local host. + */ + + host = "localhost"; + } + } else if (hints.ai_family == 0) { + /* + * Caller specifies a host but no address family. + * If the host string is really a valid IPv4 dotted-decimal address, + * set family to IPv4. Similarly for IPv6 strings. + * This allows server applications to be protocol independent + * (not having to hard code a protocol family), allowing the + * user who starts the program to specify either 0.0.0.0 or 0::0. + * + * Assumed below is that inet_pton() allows only "valid" strings, + * which Paul Vixie put into the BIND-4.9.4 version of this function. + */ + + char temp[16]; + +#ifdef IPV4 + if (inet_pton(AF_INET, host, temp) == 1) + hints.ai_family = AF_INET; +#endif +#ifdef IPV6 + if (inet_pton(AF_INET6, host, temp) == 1) + hints.ai_family = AF_INET6; +#endif + /* + * Note that we could bypass some of the testing done in + * getaddrinfo_host(), but it doesn't seem worth complicating + * this (already long) function. + */ + } + +#ifdef LOCAL + /* + * For a Unix domain socket only one string can be provided and we + * require it to be an absolute pathname. (Using relative pathnames + * is asking for trouble.) We allow this string to be specified as + * either the hostname or the service name, in which case we ignore + * the other string. Notice that a slash is not allowed in a DNS + * hostname (see RFC 1912) and a slash does not appear in any of the + * service names in /etc/services either. Hence no conflict. + * For example, often a protocol-independent server will allow an + * argument to specify the service (e.g., port number) and let the + * hostname be wildcarded. Similarly, a protocol-independent client + * often allows only the hostname as a command-line argument, hardcoding + * a service name in the program (which we ignore). + */ + + if ((host != NULL && host[0] == '/')) + return(addrinfo_local(host, &hints, result)); + + if ((serv != NULL && serv[0] == '/')) + return(addrinfo_local(serv, &hints, result)); +#endif + + /* + * Look up the host. The code above guarantees that "host" + * is a nonnull pointer to a nonull string. + * + * We first initialize "hent" assuming "host" is an IPv4/IPv6 address + * (instead of a name). This saves passing lots of additional + * arguments to getaddrinfo_host(). + */ + + hent.h_name = hentbuf; /* char string specifying address goes here */ + hent.h_aliases = hent_aliases; + hent_aliases[0] = NULL; /* no aliases */ + hent.h_addr_list = hent_addr_list; + hent_addr_list[0] = hent_addr; /* one binary address in [0] */ + hent_addr_list[1] = NULL; + hptr = &hent; + + if ( (rc = getaddrinfo_host(host, &hent, &hptr, hentbuf, HENTBUFSIZ, + hints.ai_family)) != 0) + error(rc); + + /* + * "hptr" now points to a filled in hostent{}. + * If "host" was an IPv4/IPv6 address, instead of a name, then + * "hptr" points to our own "hent" structure. + * If gethostbyname_r() was called, then "hptr" points to our own + * "hent" structure, which was passed as as an argument to the + * reentrant function. + * If gethostbyname() was called, then "hptr" points to the static + * hostent{} that it returned. + * + * Check for address family mismatch if the caller specified one. + * Note that Posix.1g assumes that AF_foo == PF_foo. + */ + if (hints.ai_family != AF_UNSPEC && hints.ai_family != hptr->h_addrtype) + error(EAI_ADDRFAMILY); + + /* + * Go through the list of returned addresses and create one + * addrinfo{} for each one, linking all the structures together. + * We still have not looked at the service--that comes after this. + */ + + aihead = NULL; + aipnext = &aihead; + for (ap = hptr->h_addr_list; *ap != NULL; ap++) { + if ( (ai = calloc(1, sizeof(struct addrinfo))) == NULL) + error(EAI_MEMORY); + *aipnext = ai; /* prev points to this new one */ + aipnext = &ai->ai_next; /* pointer to next one goes here */ + + /* initialize from hints; could be 0 */ + if ( (ai->ai_socktype = hints.ai_socktype) == 0) + ai->ai_flags |= AI_CLONE; + ai->ai_protocol = hints.ai_protocol; + + ai->ai_family = hptr->h_addrtype; + switch (ai->ai_family) { + /* + * Allocate a socket address structure and fill it in. + * The port number will be filled in later, when the service + * is processed. + */ +#ifdef IPV4 + case AF_INET: + if ( (sinptr = calloc(1, sizeof(struct sockaddr_in))) == NULL) + error(EAI_MEMORY); +#ifdef SIN_LEN + sinptr->sin_len = sizeof(struct sockaddr_in); +#endif + sinptr->sin_family = AF_INET; + memcpy(&sinptr->sin_addr, *ap, sizeof(struct in_addr)); + ai->ai_addr = (struct sockaddr *) sinptr; + ai->ai_addrlen = sizeof(struct sockaddr_in); + break; +#endif /* IPV4 */ + +#ifdef IPV6 + case AF_INET6: + if ( (sin6ptr = calloc(1, sizeof(struct sockaddr_in6))) == NULL) + error(EAI_MEMORY); +#ifdef SIN6_LEN + sin6ptr->sin6_len = sizeof(struct sockaddr_in6); +#endif + sin6ptr->sin6_family = AF_INET6; + memcpy(&sin6ptr->sin6_addr, *ap, sizeof(struct in6_addr)); + ai->ai_addr = (struct sockaddr *) sin6ptr; + ai->ai_addrlen = sizeof(struct sockaddr_in6); + break; +#endif /* IPV6 */ + } + } + /* "aihead" points to the first structure in the linked list */ + + if (hints.ai_flags & AI_CANONNAME) { + /* + * Posix.1g doesn't say what to do if this flag is set and + * multiple addrinfo structures are returned. + * We return the canonical name only in the first addrinfo{}. + */ + if (hptr->h_name != NULL) { + if ( (aihead->ai_canonname = strdup(hptr->h_name)) == NULL) + error(EAI_MEMORY); + } else { + /* + * Posix.1g says we can just set ai_canonname to point to the + * "host" argument, but that makes freeaddrinfo() harder. + * We dynamically allocate room for a copy of "host". + */ + if ( (aihead->ai_canonname = strdup(host)) == NULL) + error(EAI_MEMORY); + } + } + + /* + * Now look up the service, if specified. + */ + if (serv != NULL && serv[0] != '\0') { + if ( (rc = getaddrinfo_serv(aihead, &hints, serv, &sent, + hentbuf, HENTBUFSIZ)) != 0) + error(rc); + } + + *result = aihead; /* pointer to first structure in linked list */ + return(0); + +bad: + freeaddrinfo(aihead); /* free any alloc'ed memory */ + return(error); +} + +/* + * This function handles the host string. + */ + +static int +getaddrinfo_host(const char *host, + struct hostent *hptr, struct hostent **hptrptr, + char *buf, int bufsiz, int family) +{ + +#ifdef REENTRANT + int h_errno; +#endif /* REENTRANT */ + +#ifdef IPV4 + /* + * We explicitly check for an IPv4 dotted-decimal string. + * Recent versions of gethostbyname(), starting around BIND 4.9.2 + * do this too, but we have the check here so we don't depend on + * this newer feature. (You wouldn't believe the ancient versions + * of BIND that some vendors ship.) + */ + if (isdigit(host[0])) { + if (inet_pton(AF_INET, host, hptr->h_addr_list[0]) == 1) { + /* Success. Finish making up the hostent{} as though + we had called gethostbyname(). */ + strncpy(hptr->h_name, host, bufsiz-1); + buf[bufsiz-1] = '\0'; + hptr->h_addrtype = AF_INET; + hptr->h_length = sizeof(struct in_addr); + return(0); + } + } +#endif /* IPV4 */ + +#ifdef IPV6 + /* + * Check for an IPv6 hex string. + */ + if (isxdigit(host[0]) || host[0] == ':') { + if (inet_pton(AF_INET6, host, hptr->h_addr_list[0]) == 1) { + /* Success. Finish making up a hostent{} as though + we had called gethostbyname(). */ + strncpy(buf, host, bufsiz-1); + buf[bufsiz-1] = '\0'; + hptr->h_addrtype = AF_INET6; + hptr->h_length = sizeof(struct in6_addr); + return(0); + } + } +#endif /* IPV6 */ + + /* + * Not an address, must be a hostname, try the DNS. + * Initialize the resolver, if not already initialized. + */ + + if ((_res.options & RES_INIT) == 0) + res_init(); /* need this to set _res.options below */ + +#ifdef IPV6 + /* + * Notice that the following might be considered optional, and + * could be #ifdef'ed out if your does not define + * RES_USE_INET6. But I am assuming you have BIND-4.9.4 installed + * and want the IPv4/IPv6 semantics that it defines for gethostbyname(). + */ + +#ifndef RES_USE_INET6 + /* This is a gross hack; following line from BIND-4.9.4 release ... */ + /* (if you're using 4.9.4, but have not installed the include files) */ +#define RES_USE_INET6 0x00002000 /* use/map IPv6 in gethostbyname() */ +#endif + if (family == AF_INET6) + _res.options |= RES_USE_INET6; +#endif /* IPV6 */ + +#ifdef REENTRANT + hptr = gethostbyname_r(host, hptr, buf, bufsiz, &h_errno); +#else + hptr = gethostbyname(host); +#endif /* REENTRANT */ + if (hptr == NULL) { + switch (h_errno) { + case HOST_NOT_FOUND: return(EAI_NONAME); + case TRY_AGAIN: return(EAI_AGAIN); + case NO_RECOVERY: return(EAI_FAIL); + case NO_DATA: return(EAI_NODATA); + default: return(EAI_NONAME); + } + } + *hptrptr = hptr; + return(0); +} + +/* + * This function handles the service string. + */ + +static int +getaddrinfo_serv(struct addrinfo *aihead, + const struct addrinfo *hintsptr, const char *serv, + struct servent *sptrarg, char *buf, int bufsiz) +{ + int port, rc; + int nfound = 0; + struct servent *sptr; + + /* + * We allow the service to be a numeric string, which we + * interpret as a decimal port number. Posix.1g doesn't + * explicitly say to do this, but it just makes sense. + * But to do this the caller must specify a socket type, + * else there's no way to return values for socket(). + */ + + if (isdigit(serv[0]) && hintsptr->ai_socktype != 0) { + port = htons(atoi(serv)); + if ( (rc = getaddrinfo_port(aihead, port, hintsptr->ai_socktype)) == 0) + return(EAI_NONAME); + else if (rc < 0) + return(EAI_MEMORY); + else + return(0); + } + + /* + * Not a special case, try the "/etc/services" file (or whatever). + * We first try TCP, if applicable. + */ + + if (hintsptr->ai_socktype == 0 || hintsptr->ai_socktype == SOCK_STREAM) { +#ifdef REENTRANT + sptr = getservbyname_r(serv, "tcp", sptrarg, buf, bufsiz); +#else + sptr = getservbyname(serv, "tcp"); +#endif /* REENTRANT */ + if (sptr != NULL) { + rc = getaddrinfo_port(aihead, sptr->s_port, SOCK_STREAM); + if (rc < 0) + return(EAI_MEMORY); + nfound += rc; + } + } + + /* + * Now try UDP, if applicable. + */ + if (hintsptr->ai_socktype == 0 || hintsptr->ai_socktype == SOCK_DGRAM) { +#ifdef REENTRANT + sptr = getservbyname_r(serv, "udp", sptrarg, buf, bufsiz); +#else + sptr = getservbyname(serv, "udp"); +#endif /* REENTRANT */ + if (sptr != NULL) { + rc = getaddrinfo_port(aihead, sptr->s_port, SOCK_DGRAM); + if (rc < 0) + return(EAI_MEMORY); + nfound += rc; + } + } + + if (nfound == 0) { + /* You could call getservbyname() one more time, with no + protocol specified, but "tcp" and "udp" are all that + are supported today. */ + + if (hintsptr->ai_socktype == 0) + return(EAI_NONAME); /* all calls to getservbyname() failed */ + else + return(EAI_SERVICE);/* service not supported for socket type */ + } + return(0); +} + +/* + * Go through all the addrinfo structures, checking for a match of the + * socket type and filling in the socket type, and then the port number + * in the corresponding socket address structures. + * + * The AI_CLONE flag works as follows. Consider a multihomed host with + * two IP addresses and no socket type specified by the caller. After + * the "host" search there are two addrinfo structures, one per IP address. + * Assuming a service supported by both TCP and UDP (say the daytime + * service) we need to return *four* addrinfo structures: + * IP#1, SOCK_STREAM, TCP port, + * IP#1, SOCK_DGRAM, UDP port, + * IP#2, SOCK_STREAM, TCP port, + * IP#2, SOCK_DGRAM, UDP port. + * To do this, when the "host" loop creates an addrinfo structure, if the + * caller has not specified a socket type (hints->ai_socktype == 0), the + * AI_CLONE flag is set. When the following function finds an entry like + * this it is handled as follows: If the entry's ai_socktype is still 0, + * this is the first use of the structure, and the ai_socktype field is set. + * But, if the entry's ai_socktype is nonzero, then we clone a new addrinfo + * structure and set it's ai_socktype to the new value. Although we only + * need two socket types today (SOCK_STREAM and SOCK_DGRAM) this algorithm + * will handle any number. Also notice that Posix.1g requires all socket + * types to be nonzero. + */ + +static int +getaddrinfo_port(struct addrinfo *aihead, int port, int socktype) + /* port must be in network byte order */ +{ + int nfound = 0; + struct addrinfo *ai; + + for (ai = aihead; ai != NULL; ai = ai->ai_next) { + /* + * We set the socket type but not the protocol, because if a + * port number is specified, the protocol must be TCP or UDP, + * and a protocol of 0 for socket() is fine for TCP and UDP. + * The only time a nonzero protocol argument is required by + * socket() is for a raw socket, in which case a service will + * not be specified to getaddrinfo(). + */ + + if (ai->ai_flags & AI_CLONE) { + if (ai->ai_socktype != 0) { + if ( (ai = getaddrinfo_clone(ai)) == NULL) + return(-1); /* tell caller it's a memory allocation error */ + /* ai points to newly cloned entry, which is what we want */ + } + } else if (ai->ai_socktype != socktype) + continue; /* ignore if mismatch on socket type */ + + ai->ai_socktype = socktype; + + switch (ai->ai_family) { +#ifdef IPV4 + case AF_INET: + ((struct sockaddr_in *) ai->ai_addr)->sin_port = port; + nfound++; + break; +#endif +#ifdef IPV6 + case AF_INET6: + ((struct sockaddr_in6 *) ai->ai_addr)->sin6_port = port; + nfound++; + break; +#endif + } + } + return(nfound); +} + +/* + * Clone a new addrinfo structure from an existing one. + */ + +static struct addrinfo * +getaddrinfo_clone(struct addrinfo *ai) +{ + struct addrinfo *new; + + if ( (new = calloc(1, sizeof(struct addrinfo))) == NULL) + return(NULL); + + new->ai_next = ai->ai_next; + ai->ai_next = new; + + new->ai_flags = 0; /* make sure AI_CLONE is off */ + new->ai_family = ai->ai_family; + new->ai_socktype = ai->ai_socktype; + new->ai_protocol = ai->ai_protocol; + new->ai_canonname = NULL; + new->ai_addrlen = ai->ai_addrlen; + if ( (new->ai_addr = malloc(ai->ai_addrlen)) == NULL) + return(NULL); + memcpy(new->ai_addr, ai->ai_addr, ai->ai_addrlen); + + return(new); +} + +#ifdef LOCAL +/* + * Do everything for a Unix domain socket. + * Only one addrinfo{} is returned. + */ + +static int +addrinfo_local(const char *path, struct addrinfo *hints, + struct addrinfo **result) +{ + struct addrinfo *ai; + struct sockaddr_un *unp; + + if (hints->ai_socktype == 0) + return(EAI_SOCKTYPE); /* we cannot tell socket type from service */ + + if ( (ai = calloc(1, sizeof(struct addrinfo))) == NULL) + return(NULL); + + ai->ai_flags = 0; + ai->ai_family = AF_LOCAL; + ai->ai_socktype = hints->ai_socktype; + ai->ai_protocol = 0; + + /* allocate and fill in a socket address structure */ + ai->ai_addrlen = sizeof(struct sockaddr_un); + if ( (ai->ai_addr = malloc(ai->ai_addrlen)) == NULL) + return(EAI_MEMORY); + unp = (struct sockaddr_un *) ai->ai_addr; + unp->sun_family = AF_UNIX; + strncpy(unp->sun_path, path, sizeof(unp->sun_path)); + + ai->ai_canonname = NULL; /* maybe return the i-node number :-) */ + ai->ai_next = NULL; + *result = ai; + + if (hints->ai_flags & AI_PASSIVE) + unlink(path); /* OK if this fails */ + + return(0); /* success */ +} +#endif /* LOCAL */ + +void +freeaddrinfo(struct addrinfo *aihead) +{ + struct addrinfo *ai, *ainext; + + for (ai = aihead; ai != NULL; ai = ainext) { + if (ai->ai_addr != NULL) + free(ai->ai_addr); /* the socket address structure */ + if (ai->ai_canonname != NULL) + free(ai->ai_canonname); /* the canonical name */ + ainext = ai->ai_next; /* can't fetch ai_next after free() */ + free(ai); /* the addrinfo{} itself */ + } +} diff --git a/libfree/getnameinfo.c b/libfree/getnameinfo.c new file mode 100644 index 0000000..90c0bef --- /dev/null +++ b/libfree/getnameinfo.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 1996 W. Richard Stevens. All rights reserved. + * + * Permission to use or modify this software for educational or + * for commercial purposes, and without fee, is hereby granted, + * provided that the above copyright notice appears in connection + * with any and all uses, with clear indication as to any + * modifications made. The author RESERVES the sole rights of + * reproduction, publication and distribution and hence permission + * to print this source code in any book, reference manual, + * magazine, or other type of publication, including any digital + * medium, must be granted in writing by W. Richard Stevens. + * + * The author makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +/* tabs set for 4 spaces, not 8 */ +#include +#include +#include +#include /* hostent{}, servent{}, etc. */ +#include /* strncpy() */ + +/* We need a way to determine if the compiling host supports IPv4/IPv6. + Cannot test for AF_INET6, as some vendors #define it, even though + they don't support it. */ +#ifdef AF_INET +#define IPV4 /* this is tested throughout the code that follows */ +#endif +#ifdef IPV6ADDR_ANY_INIT +#define IPV6 /* this is tested throughout the code that follows */ +#endif + +/* Define following if the reentrant versions of get{host|serv}byaddr + are to be used. + Note that getaddrinfo{} must be reentrant if the underlying + get{host|serv}byaddr_r functions are provided. */ +/* #define REENTRANT */ + +#define HENTBUFSIZ 8*1024 + + /* function prototypes for our own internal functions */ +static int do_ipv46(char *, size_t, char *, size_t, + void *, size_t, int, int); + +int +getnameinfo(const struct sockaddr *sa, size_t salen, + char *host, size_t hostlen, char *serv, size_t servlen) +{ + + switch (sa->sa_family) { +#ifdef IPV4 + case AF_INET: { + struct sockaddr_in *sain = (struct sockaddr_in *) sa; + + return(do_ipv46(host, hostlen, serv, servlen, + &sain->sin_addr, sizeof(struct in_addr), AF_INET, + sain->sin_port)); + } +#endif /* IPV4 */ + +#ifdef IPV6 + case AF_INET6: { + struct sockaddr_in6 *sain = (struct sockaddr_in6 *) sa; + + return(do_ipv46(host, hostlen, serv, servlen, + &sain->sin6_addr, sizeof(struct in6_addr), AF_INET6, + sain->sin6_port)); + } +#endif /* IPV6 */ + + default: + return(1); + } +} + +/* + * Handle either an IPv4 or an IPv6 address and port. + */ + +static int +do_ipv46(char *host, size_t hostlen, char *serv, size_t servlen, + void *aptr, size_t alen, int family, int port) +{ + struct hostent *hptr, hent; + struct servent *sptr, sent; + char hentbuf[HENTBUFSIZ]; + + if (hostlen > 0) { +#ifdef REENTRANT + hptr = gethostbyaddr_r(aptr, alen, family, + &hent, hentbuf, HENTBUFSIZ, &h_errno); +#else + hptr = gethostbyaddr(aptr, alen, family); +#endif + if (hptr != NULL && hptr->h_name != NULL) + strncpy(host, hptr->h_name, hostlen); + else + return(1); + } + + if (servlen > 0) { + /* + * Notice that we do not have enough information to pass a + * "protocol" argument to getservbyport(), so the assumption + * is that the protocol (TCP or UDP) does not matter. + */ +#ifdef REENTRANT + sptr = getservbyport_r(port, NULL, + &sent, hentbuf, HENTBUFSIZ); +#else + sptr = getservbyport(port, NULL); +#endif + if (sptr != NULL && sptr->s_name != NULL) + strncpy(serv, sptr->s_name, servlen); + else + return(1); + } + return(0); +} diff --git a/libfree/in_cksum.c b/libfree/in_cksum.c new file mode 100644 index 0000000..1e42638 --- /dev/null +++ b/libfree/in_cksum.c @@ -0,0 +1,32 @@ +#include "unp.h" + +uint16_t +in_cksum(uint16_t *addr, int len) +{ + int nleft = len; + uint32_t sum = 0; + uint16_t *w = addr; + uint16_t answer = 0; + + /* + * Our algorithm is simple, using a 32 bit accumulator (sum), we add + * sequential 16 bit words to it, and at the end, fold back all the + * carry bits from the top 16 bits into the lower 16 bits. + */ + while (nleft > 1) { + sum += *w++; + nleft -= 2; + } + + /* 4mop up an odd byte, if necessary */ + if (nleft == 1) { + *(unsigned char *)(&answer) = *(unsigned char *)w ; + sum += answer; + } + + /* 4add back carry outs from top 16 bits to low 16 bits */ + sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ + sum += (sum >> 16); /* add carry */ + answer = ~sum; /* truncate to 16 bits */ + return(answer); +} diff --git a/libfree/inet_aton.c b/libfree/inet_aton.c new file mode 100644 index 0000000..abe19c1 --- /dev/null +++ b/libfree/inet_aton.c @@ -0,0 +1,128 @@ +/* + * inet_aton.c,v 1.3 1993/05/19 03:39:32 jch Exp + */ + +/* Gated Release 3.5 */ +/* Copyright (c) 1990,1991,1992,1993,1994,1995 by Cornell University. All */ +/* rights reserved. Refer to Particulars and other Copyright notices at */ +/* the end of this file. */ +/* */ + +#include +#include + +/* + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + */ + +int +inet_aton(const char *cp, struct in_addr *ap) +{ + int dots = 0; + register u_long acc = 0, addr = 0; + + do { + register char cc = *cp; + + switch (cc) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + acc = acc * 10 + (cc - '0'); + break; + + case '.': + if (++dots > 3) { + return 0; + } + /* Fall through */ + + case '\0': + if (acc > 255) { + return 0; + } + addr = addr << 8 | acc; + acc = 0; + break; + + default: + return 0; + } + } while (*cp++) ; + + /* Normalize the address */ + if (dots < 3) { + addr <<= 8 * (3 - dots) ; + } + + /* Store it if requested */ + if (ap) { + ap->s_addr = htonl(addr); + } + + return 1; +} + +/* + * ------------------------------------------------------------------------ + * + * GateD, Release 3.5 + * + * Copyright (c) 1990,1991,1992,1993,1994,1995 by Cornell University. + * All rights reserved. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Royalty-free licenses to redistribute GateD Release + * 3 in whole or in part may be obtained by writing to: + * + * GateDaemon Project + * Information Technologies/Network Resources + * 200 CCC + * Cornell University + * Ithaca, NY 14853-2601 USA + * + * GateD is based on Kirton's EGP, UC Berkeley's routing + * daemon (routed), and DCN's HELLO routing Protocol. + * Development of GateD has been supported in part by the + * National Science Foundation. + * + * Please forward bug fixes, enhancements and questions to the + * gated mailing list: gated-people@gated.cornell.edu. + * + * ------------------------------------------------------------------------ + * + * Portions of this software may fall under the following + * copyrights: + * + * Copyright (c) 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are + * permitted provided that the above copyright notice and + * this paragraph are duplicated in all such forms and that + * any documentation, advertising materials, and other + * materials related to such distribution and use + * acknowledge that the software was developed by the + * University of California, Berkeley. The name of the + * University may not be used to endorse or promote + * products derived from this software without specific + * prior written permission. THIS SOFTWARE IS PROVIDED + * ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ diff --git a/libfree/inet_ntop.c b/libfree/inet_ntop.c new file mode 100644 index 0000000..192cdbd --- /dev/null +++ b/libfree/inet_ntop.c @@ -0,0 +1,198 @@ +/* This is from the BIND 4.9.4 release, modified to compile by itself */ + +/* Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$Id: inet_ntop.c,v 1.1.1.1 2002/11/14 03:33:35 fenner Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define IN6ADDRSZ 16 +#define INT16SZ 2 + +#ifndef AF_INET6 +#define AF_INET6 AF_MAX+1 /* just to let this compile */ +#endif + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static const char *inet_ntop4(const u_char *src, char *dst, size_t size); +static const char *inet_ntop6(const u_char *src, char *dst, size_t size); + +/* char * + * inet_ntop(af, src, dst, size) + * convert a network format address to presentation format. + * return: + * pointer to presentation format address (`dst'), or NULL (see errno). + * author: + * Paul Vixie, 1996. + */ +const char * +inet_ntop(af, src, dst, size) + int af; + const void *src; + char *dst; + size_t size; +{ + switch (af) { + case AF_INET: + return (inet_ntop4(src, dst, size)); + case AF_INET6: + return (inet_ntop6(src, dst, size)); + default: + errno = EAFNOSUPPORT; + return (NULL); + } + /* NOTREACHED */ +} + +/* const char * + * inet_ntop4(src, dst, size) + * format an IPv4 address, more or less like inet_ntoa() + * return: + * `dst' (as a const) + * notes: + * (1) uses no statics + * (2) takes a u_char* not an in_addr as input + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop4(src, dst, size) + const u_char *src; + char *dst; + size_t size; +{ + static const char fmt[] = "%u.%u.%u.%u"; + char tmp[sizeof "255.255.255.255"]; + + sprintf(tmp, fmt, src[0], src[1], src[2], src[3]); + if (strlen(tmp) > size) { + errno = ENOSPC; + return (NULL); + } + strcpy(dst, tmp); + return (dst); +} + +/* const char * + * inet_ntop6(src, dst, size) + * convert IPv6 binary address into presentation (printable) format + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop6(src, dst, size) + const u_char *src; + char *dst; + size_t size; +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; + struct { int base, len; } best, cur; + u_int words[IN6ADDRSZ / INT16SZ]; + int i; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, 0, sizeof words); + for (i = 0; i < IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + cur.base = -1; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) + *tp++ = ':'; + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) + *tp++ = ':'; + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) + return (NULL); + tp += strlen(tp); + break; + } + sprintf(tp, "%x", words[i]); + tp += strlen(tp); + } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ((tp - tmp) > size) { + errno = ENOSPC; + return (NULL); + } + strcpy(dst, tmp); + return (dst); +} diff --git a/libfree/inet_ntop_ipv4.c b/libfree/inet_ntop_ipv4.c new file mode 100644 index 0000000..6aaae4d --- /dev/null +++ b/libfree/inet_ntop_ipv4.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include + +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif + +/* include inet_ntop */ +const char * +inet_ntop(int family, const void *addrptr, char *strptr, size_t len) +{ + const u_char *p = (const u_char *) addrptr; + + if (family == AF_INET) { + char temp[INET_ADDRSTRLEN]; + + snprintf(temp, sizeof(temp), "%d.%d.%d.%d", + p[0], p[1], p[2], p[3]); + if (strlen(temp) >= len) { + errno = ENOSPC; + return (NULL); + } + strcpy(strptr, temp); + return (strptr); + } + errno = EAFNOSUPPORT; + return (NULL); +} +/* end inet_ntop */ diff --git a/libfree/inet_ntop_ipv4.lc b/libfree/inet_ntop_ipv4.lc new file mode 100644 index 0000000..d150b39 --- /dev/null +++ b/libfree/inet_ntop_ipv4.lc @@ -0,0 +1,30 @@ +#include ## 1 ##src/libfree/inet_ntop_ipv4.c## +#include ## 2 ##src/libfree/inet_ntop_ipv4.c## +#include ## 3 ##src/libfree/inet_ntop_ipv4.c## +#include ## 4 ##src/libfree/inet_ntop_ipv4.c## + +#ifndef INET_ADDRSTRLEN## 5 ##src/libfree/inet_ntop_ipv4.c## +#define INET_ADDRSTRLEN 16## 6 ##src/libfree/inet_ntop_ipv4.c## +#endif## 7 ##src/libfree/inet_ntop_ipv4.c## + +/* include inet_ntop */ +const char *## 8 ##src/libfree/inet_ntop_ipv4.c## +inet_ntop(int family, const void *addrptr, char *strptr, size_t len)## 9 ##src/libfree/inet_ntop_ipv4.c## +{## 10 ##src/libfree/inet_ntop_ipv4.c## + const u_char *p = (const u_char *) addrptr;## 11 ##src/libfree/inet_ntop_ipv4.c## + + if (family == AF_INET) {## 12 ##src/libfree/inet_ntop_ipv4.c## + char temp[INET_ADDRSTRLEN];## 13 ##src/libfree/inet_ntop_ipv4.c## + + snprintf(temp, sizeof(temp), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);## 14 ##src/libfree/inet_ntop_ipv4.c## + if (strlen(temp) >= len) {## 15 ##src/libfree/inet_ntop_ipv4.c## + errno = ENOSPC;## 16 ##src/libfree/inet_ntop_ipv4.c## + return (NULL);## 17 ##src/libfree/inet_ntop_ipv4.c## + }## 18 ##src/libfree/inet_ntop_ipv4.c## + strcpy(strptr, temp);## 19 ##src/libfree/inet_ntop_ipv4.c## + return (strptr);## 20 ##src/libfree/inet_ntop_ipv4.c## + }## 21 ##src/libfree/inet_ntop_ipv4.c## + errno = EAFNOSUPPORT;## 22 ##src/libfree/inet_ntop_ipv4.c## + return (NULL);## 23 ##src/libfree/inet_ntop_ipv4.c## +}## 24 ##src/libfree/inet_ntop_ipv4.c## +/* end inet_ntop */ diff --git a/libfree/inet_pton.c b/libfree/inet_pton.c new file mode 100644 index 0000000..7f37018 --- /dev/null +++ b/libfree/inet_pton.c @@ -0,0 +1,224 @@ +/* This is from the BIND 4.9.4 release, modified to compile by itself */ + +/* Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$Id: inet_pton.c,v 1.1.1.1 2002/11/14 03:33:35 fenner Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include + +#define IN6ADDRSZ 16 +#define INADDRSZ 4 +#define INT16SZ 2 + +#ifndef AF_INET6 +#define AF_INET6 AF_MAX+1 /* just to let this compile */ +#endif + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static int inet_pton4(const char *src, u_char *dst); +static int inet_pton6(const char *src, u_char *dst); + +/* int + * inet_pton(af, src, dst) + * convert from presentation format (which usually means ASCII printable) + * to network format (which is usually some kind of binary format). + * return: + * 1 if the address was valid for the specified address family + * 0 if the address wasn't valid (`dst' is untouched in this case) + * -1 if some other error occurred (`dst' is untouched in this case, too) + * author: + * Paul Vixie, 1996. + */ +int +inet_pton(af, src, dst) + int af; + const char *src; + void *dst; +{ + switch (af) { + case AF_INET: + return (inet_pton4(src, dst)); + case AF_INET6: + return (inet_pton6(src, dst)); + default: + errno = EAFNOSUPPORT; + return (-1); + } + /* NOTREACHED */ +} + +/* int + * inet_pton4(src, dst) + * like inet_aton() but without all the hexadecimal and shorthand. + * return: + * 1 if `src' is a valid dotted quad, else 0. + * notice: + * does not touch `dst' unless it's returning 1. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton4(src, dst) + const char *src; + u_char *dst; +{ + static const char digits[] = "0123456789"; + int saw_digit, octets, ch; + u_char tmp[INADDRSZ], *tp; + + saw_digit = 0; + octets = 0; + *(tp = tmp) = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr(digits, ch)) != NULL) { + u_int new = *tp * 10 + (pch - digits); + + if (new > 255) + return (0); + *tp = new; + if (! saw_digit) { + if (++octets > 4) + return (0); + saw_digit = 1; + } + } else if (ch == '.' && saw_digit) { + if (octets == 4) + return (0); + *++tp = 0; + saw_digit = 0; + } else + return (0); + } + if (octets < 4) + return (0); + /* bcopy(tmp, dst, INADDRSZ); */ + memcpy(dst, tmp, INADDRSZ); + return (1); +} + +/* int + * inet_pton6(src, dst) + * convert presentation level address to network order binary form. + * return: + * 1 if `src' is a valid [RFC1884 2.2] address, else 0. + * notice: + * (1) does not touch `dst' unless it's returning 1. + * (2) :: in a full address is silently ignored. + * credit: + * inspired by Mark Andrews. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton6(src, dst) + const char *src; + u_char *dst; +{ + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, saw_xdigit; + u_int val; + + memset((tp = tmp), 0, IN6ADDRSZ); + endp = tp + IN6ADDRSZ; + colonp = NULL; + /* Leading :: requires some special handling. */ + if (*src == ':') + if (*++src != ':') + return (0); + curtok = src; + saw_xdigit = 0; + val = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + val <<= 4; + val |= (pch - xdigits); + if (val > 0xffff) + return (0); + saw_xdigit = 1; + continue; + } + if (ch == ':') { + curtok = src; + if (!saw_xdigit) { + if (colonp) + return (0); + colonp = tp; + continue; + } + if (tp + INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + saw_xdigit = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + INADDRSZ) <= endp) && + inet_pton4(curtok, tp) > 0) { + tp += INADDRSZ; + saw_xdigit = 0; + break; /* '\0' was seen by inet_pton4(). */ + } + return (0); + } + if (saw_xdigit) { + if (tp + INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + } + if (colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const int n = tp - colonp; + int i; + + for (i = 1; i <= n; i++) { + endp[- i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + if (tp != endp) + return (0); + /* bcopy(tmp, dst, IN6ADDRSZ); */ + memcpy(dst, tmp, IN6ADDRSZ); + return (1); +} diff --git a/libfree/inet_pton_ipv4.c b/libfree/inet_pton_ipv4.c new file mode 100644 index 0000000..09a7c1e --- /dev/null +++ b/libfree/inet_pton_ipv4.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include +#include +#include + +/* Delete following line if your system's headers already DefinE this + function prototype */ +int inet_aton(const char *, struct in_addr *); + +/* include inet_pton */ +int +inet_pton(int family, const char *strptr, void *addrptr) +{ + if (family == AF_INET) { + struct in_addr in_val; + + if (inet_aton(strptr, &in_val)) { + memcpy(addrptr, &in_val, sizeof(struct in_addr)); + return (1); + } + return(0); + } + errno = EAFNOSUPPORT; + return (-1); +} +/* end inet_pton */ diff --git a/libfree/inet_pton_ipv4.lc b/libfree/inet_pton_ipv4.lc new file mode 100644 index 0000000..93fe100 --- /dev/null +++ b/libfree/inet_pton_ipv4.lc @@ -0,0 +1,28 @@ +#include ## 1 ##src/libfree/inet_pton_ipv4.c## +#include ## 2 ##src/libfree/inet_pton_ipv4.c## +#include ## 3 ##src/libfree/inet_pton_ipv4.c## +#include ## 4 ##src/libfree/inet_pton_ipv4.c## +#include ## 5 ##src/libfree/inet_pton_ipv4.c## +#include ## 6 ##src/libfree/inet_pton_ipv4.c## + +/* Delete following line if your system's headers already define this## 7 ##src/libfree/inet_pton_ipv4.c## + function prototype */## 8 ##src/libfree/inet_pton_ipv4.c## +int inet_aton(const char *, struct in_addr *);## 9 ##src/libfree/inet_pton_ipv4.c## + +/* include inet_pton */ +int## 10 ##src/libfree/inet_pton_ipv4.c## +inet_pton(int family, const char *strptr, void *addrptr)## 11 ##src/libfree/inet_pton_ipv4.c## +{## 12 ##src/libfree/inet_pton_ipv4.c## + if (family == AF_INET) {## 13 ##src/libfree/inet_pton_ipv4.c## + struct in_addr in_val;## 14 ##src/libfree/inet_pton_ipv4.c## + + if (inet_aton(strptr, &in_val)) {## 15 ##src/libfree/inet_pton_ipv4.c## + memcpy(addrptr, &in_val, sizeof(struct in_addr));## 16 ##src/libfree/inet_pton_ipv4.c## + return (1);## 17 ##src/libfree/inet_pton_ipv4.c## + }## 18 ##src/libfree/inet_pton_ipv4.c## + return (0);## 19 ##src/libfree/inet_pton_ipv4.c## + }## 20 ##src/libfree/inet_pton_ipv4.c## + errno = EAFNOSUPPORT;## 21 ##src/libfree/inet_pton_ipv4.c## + return (-1);## 22 ##src/libfree/inet_pton_ipv4.c## +}## 23 ##src/libfree/inet_pton_ipv4.c## +/* end inet_pton */ diff --git a/libfree/test_ascii2addr.c b/libfree/test_ascii2addr.c new file mode 100644 index 0000000..331aef4 --- /dev/null +++ b/libfree/test_ascii2addr.c @@ -0,0 +1,15 @@ +#include +#include +#include +#include +#include + +main() +{ + struct in6_addr foo; + + printf("ascii2addr returned %d\n", + ascii2addr(AF_INET6, "::140.252.13.36", &foo)); + + exit(0); +} diff --git a/libfree/test_getservbyname_r.c b/libfree/test_getservbyname_r.c new file mode 100644 index 0000000..5f0483b --- /dev/null +++ b/libfree/test_getservbyname_r.c @@ -0,0 +1,21 @@ +#include + +main() +{ + char buf[8192]; + struct servent sent, *sptr; + + sptr = getservbyname_r("tftp", "tcp", &sent, buf, sizeof(buf)); + printf("TCP, sptr = %p\n", sptr); + + sptr = getservbyname_r("tftp", "udp", &sent, buf, sizeof(buf)); + printf("UDP, sptr = %p\n", sptr); + + sptr = getservbyname_r("tftp", "tcp", &sent, buf, sizeof(buf)); + printf("TCP, sptr = %p\n", sptr); + + sptr = getservbyname_r("tftp", "udp", &sent, buf, sizeof(buf)); + printf("UDP, sptr = %p\n", sptr); + + exit(0); +} diff --git a/libfree/test_inet_pton.c b/libfree/test_inet_pton.c new file mode 100644 index 0000000..1b22adf --- /dev/null +++ b/libfree/test_inet_pton.c @@ -0,0 +1,42 @@ +#include "../lib/unp.h" + +#ifndef AF_INET6 +#define AF_INET6 AF_MAX+1 /* just to let this compile */ +#endif + +int inet_pton(int, const char *, void *); + +int +main(int argc, char **argv) +{ + int i; + char buff[100]; + + /* + * Make certain that we can test the difference between 0.0.0.0 + * being acceptable for AF_INET (but not acceptable for AF_INET6) + * and 0::0 being OK for AF_INET6 (but not OK for AF_INET). + * This way a server can be coded as protocol independent (IPv4 or + * IPv6) but let the user specify the local IP address as either + * 0.0.0.0 or 0::0 as an indirect way of telling the server when + * it starts, which protocol to use (but still allowing the server + * to bind the wildcard address). + */ + + if ( (i = inet_pton(AF_INET, "0.0.0.0", buff)) != 1) /* should be OK */ + printf("AF_INET, 0.0.0.0 returned: %d\n", i); + if ( (i = inet_pton(AF_INET6, "0.0.0.0", buff)) != 0) + printf("AF_INET6, 0.0.0.0 returned: %d\n", i); + + if ( (i = inet_pton(AF_INET6, "0::0", buff)) != 1) /* should be OK */ + printf("AF_INET6, 0::0 returned: %d\n", i); + if ( (i = inet_pton(AF_INET, "0::0", buff)) != 0) + printf("AF_INET, 0::0 returned: %d\n", i); + + printf("inet_pton(AF_INET6, \"1.2.3.4\", buff) returns %d\n", + inet_pton(AF_INET6, "1.2.3.4", buff)); + printf("inet_pton(AF_INET6, \"::1.2.3.4\", buff) returns %d\n", + inet_pton(AF_INET6, "::1.2.3.4", buff)); + + exit(0); +} diff --git a/libgai/Makefile b/libgai/Makefile new file mode 100644 index 0000000..e6362f1 --- /dev/null +++ b/libgai/Makefile @@ -0,0 +1,22 @@ +include ../Make.defines + +# Note: In the source code in this directory I #ifdef the constants +# IPv4, IPv6 (both lowercase "v"), and UNIXdomain. This is instead of +# the all-uppercase constants so that these #ifdef/#endif lines do not +# appear in the book (too much clutter, given the amount of conditional +# testing for all the code in this directory). + +all: ${LIBGAI_OBJS} + ar rv ${LIBUNP_NAME} $? + ${RANLIB} ${LIBUNP_NAME} + +PROGS = testga test1 + +testga: testga.o + ${CC} ${CFLAGS} -o $@ testga.o ${LIBS} + +test1: test1.o + ${CC} ${CFLAGS} -o $@ test1.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/libgai/addrinfo.h b/libgai/addrinfo.h new file mode 100644 index 0000000..7cef135 --- /dev/null +++ b/libgai/addrinfo.h @@ -0,0 +1,48 @@ +#ifndef __addrinfo_h +#define __addrinfo_h + +/* + * Everything here really belongs in . + * These defines are separate for now, to avoid having to modify the + * system's header. + */ + +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for host */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; + + /* following for getaddrinfo() */ +#define AI_PASSIVE 1 /* socket is intended for bind() + listen() */ +#define AI_CANONNAME 2 /* return canonical name */ + + /* following for getnameinfo() */ +#define NI_MAXHOST 1025 /* max hostname returned */ +#define NI_MAXSERV 32 /* max service name returned */ + +#define NI_NOFQDN 1 /* do not return FQDN */ +#define NI_NUMERICHOST 2 /* return numeric form of hostname */ +#define NI_NAMEREQD 4 /* return error if hostname not found */ +#define NI_NUMERICSERV 8 /* return numeric form of service name */ +#define NI_DGRAM 16 /* datagram service for getservbyname() */ + + /* error returns */ +#define EAI_ADDRFAMILY 1 /* address family for host not supported */ +#define EAI_AGAIN 2 /* temporary failure in name resolution */ +#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ +#define EAI_FAIL 4 /* non-recoverable failure in name resolution */ +#define EAI_FAMILY 5 /* ai_family not supported */ +#define EAI_MEMORY 6 /* memory allocation failure */ +#define EAI_NODATA 7 /* no address associated with host */ +#define EAI_NONAME 8 /* host nor service provided, or not known */ +#define EAI_SERVICE 9 /* service not supported for ai_socktype */ +#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ +#define EAI_SYSTEM 11 /* system error returned in errno */ + +#endif /* __addrinfo_h */ diff --git a/libgai/freeaddrinfo.c b/libgai/freeaddrinfo.c new file mode 100644 index 0000000..c8d4c8b --- /dev/null +++ b/libgai/freeaddrinfo.c @@ -0,0 +1,20 @@ +#include "gai_hdr.h" + +/* include freeaddrinfo */ +void +freeaddrinfo(struct addrinfo *aihead) +{ + struct addrinfo *ai, *ainext; + + for (ai = aihead; ai != NULL; ai = ainext) { + if (ai->ai_addr != NULL) + free(ai->ai_addr); /* socket address structure */ + + if (ai->ai_canonname != NULL) + free(ai->ai_canonname); + + ainext = ai->ai_next; /* can't fetch ai_next after free() */ + free(ai); /* the addrinfo{} itself */ + } +} +/* end freeaddrinfo */ diff --git a/libgai/ga_aistruct.c b/libgai/ga_aistruct.c new file mode 100644 index 0000000..8abc06a --- /dev/null +++ b/libgai/ga_aistruct.c @@ -0,0 +1,89 @@ +#include "gai_hdr.h" + +/* + * Create and fill in an addrinfo{}. + */ + +/* include ga_aistruct1 */ +int +ga_aistruct(struct addrinfo ***paipnext, const struct addrinfo *hintsp, + const void *addr, int family) +{ + struct addrinfo *ai; + + if ( (ai = calloc(1, sizeof(struct addrinfo))) == NULL) + return(EAI_MEMORY); + ai->ai_next = NULL; + ai->ai_canonname = NULL; + **paipnext = ai; + *paipnext = &ai->ai_next; + + if ( (ai->ai_socktype = hintsp->ai_socktype) == 0) + ai->ai_flags |= AI_CLONE; + + ai->ai_protocol = hintsp->ai_protocol; +/* end ga_aistruct1 */ + +/* include ga_aistruct2 */ + switch ((ai->ai_family = family)) { +#ifdef IPv4 + case AF_INET: { + struct sockaddr_in *sinptr; + + /* 4allocate sockaddr_in{} and fill in all but port */ + if ( (sinptr = calloc(1, sizeof(struct sockaddr_in))) == NULL) + return(EAI_MEMORY); +#ifdef HAVE_SOCKADDR_SA_LEN + sinptr->sin_len = sizeof(struct sockaddr_in); +#endif + sinptr->sin_family = AF_INET; + memcpy(&sinptr->sin_addr, addr, sizeof(struct in_addr)); + ai->ai_addr = (struct sockaddr *) sinptr; + ai->ai_addrlen = sizeof(struct sockaddr_in); + break; + } +#endif /* IPV4 */ +#ifdef IPv6 + case AF_INET6: { + struct sockaddr_in6 *sin6ptr; + + /* 4allocate sockaddr_in6{} and fill in all but port */ + if ( (sin6ptr = calloc(1, sizeof(struct sockaddr_in6))) == NULL) + return(EAI_MEMORY); +#ifdef HAVE_SOCKADDR_SA_LEN + sin6ptr->sin6_len = sizeof(struct sockaddr_in6); +#endif + sin6ptr->sin6_family = AF_INET6; + memcpy(&sin6ptr->sin6_addr, addr, sizeof(struct in6_addr)); + ai->ai_addr = (struct sockaddr *) sin6ptr; + ai->ai_addrlen = sizeof(struct sockaddr_in6); + break; + } +#endif /* IPV6 */ +#ifdef UNIXdomain + case AF_LOCAL: { + struct sockaddr_un *unp; + + /* 4allocate sockaddr_un{} and fill in */ +/* *INDENT-OFF* */ + if (strlen(addr) >= sizeof(unp->sun_path)) + return(EAI_SERVICE); + if ( (unp = calloc(1, sizeof(struct sockaddr_un))) == NULL) + return(EAI_MEMORY); +/* *INDENT-ON* */ + unp->sun_family = AF_LOCAL; + strcpy(unp->sun_path, addr); +#ifdef HAVE_SOCKADDR_SA_LEN + unp->sun_len = SUN_LEN(unp); +#endif + ai->ai_addr = (struct sockaddr *) unp; + ai->ai_addrlen = sizeof(struct sockaddr_un); + if (hintsp->ai_flags & AI_PASSIVE) + unlink(unp->sun_path); /* OK if this fails */ + break; + } +#endif /* UNIXDOMAIN */ + } + return(0); +} +/* end ga_aistruct2 */ diff --git a/libgai/ga_aistruct.lc b/libgai/ga_aistruct.lc new file mode 100644 index 0000000..4de057e --- /dev/null +++ b/libgai/ga_aistruct.lc @@ -0,0 +1,81 @@ +#include "gai_hdr.h"## 1 ##src/libgai/ga_aistruct.c## + +/*## 2 ##src/libgai/ga_aistruct.c## + * Create and fill in an addrinfo{}.## 3 ##src/libgai/ga_aistruct.c## + */## 4 ##src/libgai/ga_aistruct.c## + +/* include ga_aistruct1 */ +int## 5 ##src/libgai/ga_aistruct.c## +ga_aistruct(struct addrinfo ***paipnext, const struct addrinfo *hintsp,## 6 ##src/libgai/ga_aistruct.c## + const void *addr, int family)## 7 ##src/libgai/ga_aistruct.c## +{## 8 ##src/libgai/ga_aistruct.c## + struct addrinfo *ai;## 9 ##src/libgai/ga_aistruct.c## + + if ((ai = calloc(1, sizeof(struct addrinfo))) == NULL)## 10 ##src/libgai/ga_aistruct.c## + return (EAI_MEMORY);## 11 ##src/libgai/ga_aistruct.c## + ai->ai_next = NULL;## 12 ##src/libgai/ga_aistruct.c## + ai->ai_canonname = NULL;## 13 ##src/libgai/ga_aistruct.c## + **paipnext = ai;## 14 ##src/libgai/ga_aistruct.c## + *paipnext = &ai->ai_next;## 15 ##src/libgai/ga_aistruct.c## + + if ((ai->ai_socktype = hintsp->ai_socktype) == 0)## 16 ##src/libgai/ga_aistruct.c## + ai->ai_flags |= AI_CLONE;## 17 ##src/libgai/ga_aistruct.c## + + ai->ai_protocol = hintsp->ai_protocol;## 18 ##src/libgai/ga_aistruct.c## +/* end ga_aistruct1 */ + +/* include ga_aistruct2 */ + switch ((ai->ai_family = family)) {## 19 ##src/libgai/ga_aistruct.c## + case AF_INET:{## 20 ##src/libgai/ga_aistruct.c## + struct sockaddr_in *sinptr;## 21 ##src/libgai/ga_aistruct.c## + + /* 4allocate sockaddr_in{} and fill in all but port */## 22 ##src/libgai/ga_aistruct.c## + if ((sinptr = calloc(1, sizeof(struct sockaddr_in))) == NULL)## 23 ##src/libgai/ga_aistruct.c## + return (EAI_MEMORY);## 24 ##src/libgai/ga_aistruct.c## +#ifdef HAVE_SOCKADDR_SA_LEN## 25 ##src/libgai/ga_aistruct.c## + sinptr->sin_len = sizeof(struct sockaddr_in);## 26 ##src/libgai/ga_aistruct.c## +#endif## 27 ##src/libgai/ga_aistruct.c## + sinptr->sin_family = AF_INET;## 28 ##src/libgai/ga_aistruct.c## + memcpy(&sinptr->sin_addr, addr, sizeof(struct in_addr));## 29 ##src/libgai/ga_aistruct.c## + ai->ai_addr = (struct sockaddr *) sinptr;## 30 ##src/libgai/ga_aistruct.c## + ai->ai_addrlen = sizeof(struct sockaddr_in);## 31 ##src/libgai/ga_aistruct.c## + break;## 32 ##src/libgai/ga_aistruct.c## + }## 33 ##src/libgai/ga_aistruct.c## + case AF_INET6:{## 34 ##src/libgai/ga_aistruct.c## + struct sockaddr_in6 *sin6ptr;## 35 ##src/libgai/ga_aistruct.c## + + /* 4allocate sockaddr_in6{} and fill in all but port */## 36 ##src/libgai/ga_aistruct.c## + if ((sin6ptr = calloc(1, sizeof(struct sockaddr_in6))) == NULL)## 37 ##src/libgai/ga_aistruct.c## + return (EAI_MEMORY);## 38 ##src/libgai/ga_aistruct.c## +#ifdef HAVE_SOCKADDR_SA_LEN## 39 ##src/libgai/ga_aistruct.c## + sin6ptr->sin6_len = sizeof(struct sockaddr_in6);## 40 ##src/libgai/ga_aistruct.c## +#endif## 41 ##src/libgai/ga_aistruct.c## + sin6ptr->sin6_family = AF_INET6;## 42 ##src/libgai/ga_aistruct.c## + memcpy(&sin6ptr->sin6_addr, addr, sizeof(struct in6_addr));## 43 ##src/libgai/ga_aistruct.c## + ai->ai_addr = (struct sockaddr *) sin6ptr;## 44 ##src/libgai/ga_aistruct.c## + ai->ai_addrlen = sizeof(struct sockaddr_in6);## 45 ##src/libgai/ga_aistruct.c## + break;## 46 ##src/libgai/ga_aistruct.c## + }## 47 ##src/libgai/ga_aistruct.c## + case AF_LOCAL:{## 48 ##src/libgai/ga_aistruct.c## + struct sockaddr_un *unp;## 49 ##src/libgai/ga_aistruct.c## + + /* 4allocate sockaddr_un{} and fill in */## 50 ##src/libgai/ga_aistruct.c## + if (strlen(addr) >= sizeof(unp->sun_path))## 51 ##src/libgai/ga_aistruct.c## + return(EAI_SERVICE);## 52 ##src/libgai/ga_aistruct.c## + if ( (unp = calloc(1, sizeof(struct sockaddr_un))) == NULL)## 53 ##src/libgai/ga_aistruct.c## + return(EAI_MEMORY);## 54 ##src/libgai/ga_aistruct.c## + unp->sun_family = AF_LOCAL;## 55 ##src/libgai/ga_aistruct.c## + strcpy(unp->sun_path, addr);## 56 ##src/libgai/ga_aistruct.c## +#ifdef HAVE_SOCKADDR_SA_LEN## 57 ##src/libgai/ga_aistruct.c## + unp->sun_len = SUN_LEN(unp);## 58 ##src/libgai/ga_aistruct.c## +#endif## 59 ##src/libgai/ga_aistruct.c## + ai->ai_addr = (struct sockaddr *) unp;## 60 ##src/libgai/ga_aistruct.c## + ai->ai_addrlen = sizeof(struct sockaddr_un);## 61 ##src/libgai/ga_aistruct.c## + if (hintsp->ai_flags & AI_PASSIVE)## 62 ##src/libgai/ga_aistruct.c## + unlink(unp->sun_path); /* OK if this fails */## 63 ##src/libgai/ga_aistruct.c## + break;## 64 ##src/libgai/ga_aistruct.c## + }## 65 ##src/libgai/ga_aistruct.c## + }## 66 ##src/libgai/ga_aistruct.c## + return (0);## 67 ##src/libgai/ga_aistruct.c## +}## 68 ##src/libgai/ga_aistruct.c## +/* end ga_aistruct2 */ diff --git a/libgai/ga_clone.c b/libgai/ga_clone.c new file mode 100644 index 0000000..b764497 --- /dev/null +++ b/libgai/ga_clone.c @@ -0,0 +1,31 @@ +#include "gai_hdr.h" + +/* + * Clone a new addrinfo structure from an existing one. + */ + +/* include ga_clone */ +struct addrinfo * +ga_clone(struct addrinfo *ai) +{ + struct addrinfo *new; + + if ( (new = calloc(1, sizeof(struct addrinfo))) == NULL) + return(NULL); + + new->ai_next = ai->ai_next; + ai->ai_next = new; + + new->ai_flags = 0; /* make sure AI_CLONE is off */ + new->ai_family = ai->ai_family; + new->ai_socktype = ai->ai_socktype; + new->ai_protocol = ai->ai_protocol; + new->ai_canonname = NULL; + new->ai_addrlen = ai->ai_addrlen; + if ( (new->ai_addr = malloc(ai->ai_addrlen)) == NULL) + return(NULL); + memcpy(new->ai_addr, ai->ai_addr, ai->ai_addrlen); + + return(new); +} +/* end ga_clone */ diff --git a/libgai/ga_clone.lc b/libgai/ga_clone.lc new file mode 100644 index 0000000..9a302c5 --- /dev/null +++ b/libgai/ga_clone.lc @@ -0,0 +1,31 @@ +#include "gai_hdr.h"## 1 ##src/libgai/ga_clone.c## + +/*## 2 ##src/libgai/ga_clone.c## + * Clone a new addrinfo structure from an existing one.## 3 ##src/libgai/ga_clone.c## + */## 4 ##src/libgai/ga_clone.c## + +/* include ga_clone */ +struct addrinfo *## 5 ##src/libgai/ga_clone.c## +ga_clone(struct addrinfo *ai)## 6 ##src/libgai/ga_clone.c## +{## 7 ##src/libgai/ga_clone.c## + struct addrinfo *new;## 8 ##src/libgai/ga_clone.c## + + if ((new = calloc(1, sizeof(struct addrinfo))) == NULL)## 9 ##src/libgai/ga_clone.c## + return (NULL);## 10 ##src/libgai/ga_clone.c## + + new->ai_next = ai->ai_next;## 11 ##src/libgai/ga_clone.c## + ai->ai_next = new;## 12 ##src/libgai/ga_clone.c## + + new->ai_flags = 0; /* make sure AI_CLONE is off */## 13 ##src/libgai/ga_clone.c## + new->ai_family = ai->ai_family;## 14 ##src/libgai/ga_clone.c## + new->ai_socktype = ai->ai_socktype;## 15 ##src/libgai/ga_clone.c## + new->ai_protocol = ai->ai_protocol;## 16 ##src/libgai/ga_clone.c## + new->ai_canonname = NULL;## 17 ##src/libgai/ga_clone.c## + new->ai_addrlen = ai->ai_addrlen;## 18 ##src/libgai/ga_clone.c## + if ((new->ai_addr = malloc(ai->ai_addrlen)) == NULL)## 19 ##src/libgai/ga_clone.c## + return (NULL);## 20 ##src/libgai/ga_clone.c## + memcpy(new->ai_addr, ai->ai_addr, ai->ai_addrlen);## 21 ##src/libgai/ga_clone.c## + + return (new);## 22 ##src/libgai/ga_clone.c## +}## 23 ##src/libgai/ga_clone.c## +/* end ga_clone */ diff --git a/libgai/ga_echeck.c b/libgai/ga_echeck.c new file mode 100644 index 0000000..56060c7 --- /dev/null +++ b/libgai/ga_echeck.c @@ -0,0 +1,54 @@ +#include "gai_hdr.h" + +/* + * Basic error checking of flags, family, socket type, and protocol. + */ + +/* include ga_echeck */ +int +ga_echeck(const char *hostname, const char *servname, + int flags, int family, int socktype, int protocol) +{ + if (flags & ~(AI_PASSIVE | AI_CANONNAME)) + return(EAI_BADFLAGS); /* unknown flag bits */ + + if (hostname == NULL || hostname[0] == '\0') { + if (servname == NULL || servname[0] == '\0') + return(EAI_NONAME); /* host or service must be specified */ + } + + switch(family) { + case AF_UNSPEC: + break; +#ifdef IPv4 + case AF_INET: + if (socktype != 0 && + (socktype != SOCK_STREAM && + socktype != SOCK_DGRAM && + socktype != SOCK_RAW)) + return(EAI_SOCKTYPE); /* invalid socket type */ + break; +#endif +#ifdef IPv6 + case AF_INET6: + if (socktype != 0 && + (socktype != SOCK_STREAM && + socktype != SOCK_DGRAM && + socktype != SOCK_RAW)) + return(EAI_SOCKTYPE); /* invalid socket type */ + break; +#endif +#ifdef UNIXdomain + case AF_LOCAL: + if (socktype != 0 && + (socktype != SOCK_STREAM && + socktype != SOCK_DGRAM)) + return(EAI_SOCKTYPE); /* invalid socket type */ + break; +#endif + default: + return(EAI_FAMILY); /* unknown protocol family */ + } + return(0); +} +/* end ga_echeck */ diff --git a/libgai/ga_echeck.lc b/libgai/ga_echeck.lc new file mode 100644 index 0000000..73aebc9 --- /dev/null +++ b/libgai/ga_echeck.lc @@ -0,0 +1,45 @@ +#include "gai_hdr.h"## 1 ##src/libgai/ga_echeck.c## + +/*## 2 ##src/libgai/ga_echeck.c## + * Basic error checking of flags, family, socket type, and protocol.## 3 ##src/libgai/ga_echeck.c## + */## 4 ##src/libgai/ga_echeck.c## + +/* include ga_echeck */ +int## 5 ##src/libgai/ga_echeck.c## +ga_echeck(const char *hostname, const char *servname,## 6 ##src/libgai/ga_echeck.c## + int flags, int family, int socktype, int protocol)## 7 ##src/libgai/ga_echeck.c## +{## 8 ##src/libgai/ga_echeck.c## + if (flags & ~(AI_PASSIVE | AI_CANONNAME))## 9 ##src/libgai/ga_echeck.c## + return (EAI_BADFLAGS); /* unknown flag bits */## 10 ##src/libgai/ga_echeck.c## + + if (hostname == NULL || hostname[0] == '\0') {## 11 ##src/libgai/ga_echeck.c## + if (servname == NULL || servname[0] == '\0')## 12 ##src/libgai/ga_echeck.c## + return (EAI_NONAME); /* host or service must be specified */## 13 ##src/libgai/ga_echeck.c## + }## 14 ##src/libgai/ga_echeck.c## + + switch (family) {## 15 ##src/libgai/ga_echeck.c## + case AF_UNSPEC:## 16 ##src/libgai/ga_echeck.c## + break;## 17 ##src/libgai/ga_echeck.c## + case AF_INET:## 18 ##src/libgai/ga_echeck.c## + if (socktype != 0 &&## 19 ##src/libgai/ga_echeck.c## + (socktype != SOCK_STREAM &&## 20 ##src/libgai/ga_echeck.c## + socktype != SOCK_DGRAM && socktype != SOCK_RAW))## 21 ##src/libgai/ga_echeck.c## + return (EAI_SOCKTYPE); /* invalid socket type */## 22 ##src/libgai/ga_echeck.c## + break;## 23 ##src/libgai/ga_echeck.c## + case AF_INET6:## 24 ##src/libgai/ga_echeck.c## + if (socktype != 0 &&## 25 ##src/libgai/ga_echeck.c## + (socktype != SOCK_STREAM &&## 26 ##src/libgai/ga_echeck.c## + socktype != SOCK_DGRAM && socktype != SOCK_RAW))## 27 ##src/libgai/ga_echeck.c## + return (EAI_SOCKTYPE); /* invalid socket type */## 28 ##src/libgai/ga_echeck.c## + break;## 29 ##src/libgai/ga_echeck.c## + case AF_LOCAL:## 30 ##src/libgai/ga_echeck.c## + if (socktype != 0 &&## 31 ##src/libgai/ga_echeck.c## + (socktype != SOCK_STREAM && socktype != SOCK_DGRAM))## 32 ##src/libgai/ga_echeck.c## + return (EAI_SOCKTYPE); /* invalid socket type */## 33 ##src/libgai/ga_echeck.c## + break;## 34 ##src/libgai/ga_echeck.c## + default:## 35 ##src/libgai/ga_echeck.c## + return (EAI_FAMILY); /* unknown protocol family */## 36 ##src/libgai/ga_echeck.c## + }## 37 ##src/libgai/ga_echeck.c## + return (0);## 38 ##src/libgai/ga_echeck.c## +}## 39 ##src/libgai/ga_echeck.c## +/* end ga_echeck */ diff --git a/libgai/ga_nsearch.c b/libgai/ga_nsearch.c new file mode 100644 index 0000000..8abc433 --- /dev/null +++ b/libgai/ga_nsearch.c @@ -0,0 +1,115 @@ +#include "gai_hdr.h" + +/* + * Set up the search[] array with the hostnames and address families + * that we are to look up. + */ + +/* include ga_nsearch1 */ +int +ga_nsearch(const char *hostname, const struct addrinfo *hintsp, + struct search *search) +{ + int nsearch = 0; + + if (hostname == NULL || hostname[0] == '\0') { + if (hintsp->ai_flags & AI_PASSIVE) { + /* 4no hostname and AI_PASSIVE: implies wildcard bind */ + switch (hintsp->ai_family) { +#ifdef IPv4 + case AF_INET: + search[nsearch].host = "0.0.0.0"; + search[nsearch].family = AF_INET; + nsearch++; + break; +#endif +#ifdef IPv6 + case AF_INET6: + search[nsearch].host = "0::0"; + search[nsearch].family = AF_INET6; + nsearch++; + break; +#endif + case AF_UNSPEC: +#ifdef IPv6 + search[nsearch].host = "0::0"; /* IPv6 first, then IPv4 */ + search[nsearch].family = AF_INET6; + nsearch++; +#endif +#ifdef IPv4 + search[nsearch].host = "0.0.0.0"; + search[nsearch].family = AF_INET; + nsearch++; +#endif + break; + } +/* end ga_nsearch1 */ +/* include ga_nsearch2 */ + } else { + /* 4no host and not AI_PASSIVE: connect to local host */ + switch (hintsp->ai_family) { +#ifdef IPv4 + case AF_INET: + search[nsearch].host = "localhost"; /* 127.0.0.1 */ + search[nsearch].family = AF_INET; + nsearch++; + break; +#endif +#ifdef IPv6 + case AF_INET6: + search[nsearch].host = "0::1"; + search[nsearch].family = AF_INET6; + nsearch++; + break; +#endif + case AF_UNSPEC: +#ifdef IPv6 + search[nsearch].host = "0::1"; /* IPv6 first, then IPv4 */ + search[nsearch].family = AF_INET6; + nsearch++; +#endif +#ifdef IPv4 + search[nsearch].host = "localhost"; + search[nsearch].family = AF_INET; + nsearch++; +#endif + break; + } + } +/* end ga_nsearch2 */ +/* include ga_nsearch3 */ + } else { /* host is specified */ + switch (hintsp->ai_family) { +#ifdef IPv4 + case AF_INET: + search[nsearch].host = hostname; + search[nsearch].family = AF_INET; + nsearch++; + break; +#endif +#ifdef IPv6 + case AF_INET6: + search[nsearch].host = hostname; + search[nsearch].family = AF_INET6; + nsearch++; + break; +#endif + case AF_UNSPEC: +#ifdef IPv6 + search[nsearch].host = hostname; + search[nsearch].family = AF_INET6; /* IPv6 first */ + nsearch++; +#endif +#ifdef IPv4 + search[nsearch].host = hostname; + search[nsearch].family = AF_INET; /* then IPv4 */ + nsearch++; +#endif + break; + } + } + if (nsearch < 1 || nsearch > 2) + err_quit("nsearch = %d", nsearch); + return(nsearch); +} +/* end ga_nsearch3 */ diff --git a/libgai/ga_nsearch.lc b/libgai/ga_nsearch.lc new file mode 100644 index 0000000..d37341c --- /dev/null +++ b/libgai/ga_nsearch.lc @@ -0,0 +1,91 @@ +#include "gai_hdr.h"## 1 ##src/libgai/ga_nsearch.c## + +/*## 2 ##src/libgai/ga_nsearch.c## + * Set up the search[] array with the hostnames and address families## 3 ##src/libgai/ga_nsearch.c## + * that we are to look up.## 4 ##src/libgai/ga_nsearch.c## + */## 5 ##src/libgai/ga_nsearch.c## + +/* include ga_nsearch1 */ +int## 6 ##src/libgai/ga_nsearch.c## +ga_nsearch(const char *hostname, const struct addrinfo *hintsp,## 7 ##src/libgai/ga_nsearch.c## + struct search *search)## 8 ##src/libgai/ga_nsearch.c## +{## 9 ##src/libgai/ga_nsearch.c## + int nsearch = 0;## 10 ##src/libgai/ga_nsearch.c## + + if (hostname == NULL || hostname[0] == '\0') {## 11 ##src/libgai/ga_nsearch.c## + if (hintsp->ai_flags & AI_PASSIVE) {## 12 ##src/libgai/ga_nsearch.c## + /* 4no hostname and AI_PASSIVE: implies wildcard bind */## 13 ##src/libgai/ga_nsearch.c## + switch (hintsp->ai_family) {## 14 ##src/libgai/ga_nsearch.c## + case AF_INET:## 15 ##src/libgai/ga_nsearch.c## + search[nsearch].host = "0.0.0.0";## 16 ##src/libgai/ga_nsearch.c## + search[nsearch].family = AF_INET;## 17 ##src/libgai/ga_nsearch.c## + nsearch++;## 18 ##src/libgai/ga_nsearch.c## + break;## 19 ##src/libgai/ga_nsearch.c## + case AF_INET6:## 20 ##src/libgai/ga_nsearch.c## + search[nsearch].host = "0::0";## 21 ##src/libgai/ga_nsearch.c## + search[nsearch].family = AF_INET6;## 22 ##src/libgai/ga_nsearch.c## + nsearch++;## 23 ##src/libgai/ga_nsearch.c## + break;## 24 ##src/libgai/ga_nsearch.c## + case AF_UNSPEC:## 25 ##src/libgai/ga_nsearch.c## + search[nsearch].host = "0::0"; /* IPv6 first, then IPv4 */## 26 ##src/libgai/ga_nsearch.c## + search[nsearch].family = AF_INET6;## 27 ##src/libgai/ga_nsearch.c## + nsearch++;## 28 ##src/libgai/ga_nsearch.c## + search[nsearch].host = "0.0.0.0";## 29 ##src/libgai/ga_nsearch.c## + search[nsearch].family = AF_INET;## 30 ##src/libgai/ga_nsearch.c## + nsearch++;## 31 ##src/libgai/ga_nsearch.c## + break;## 32 ##src/libgai/ga_nsearch.c## + }## 33 ##src/libgai/ga_nsearch.c## +/* end ga_nsearch1 */ +/* include ga_nsearch2 */ + } else {## 34 ##src/libgai/ga_nsearch.c## + /* 4no host and not AI_PASSIVE: connect to local host */## 35 ##src/libgai/ga_nsearch.c## + switch (hintsp->ai_family) {## 36 ##src/libgai/ga_nsearch.c## + case AF_INET:## 37 ##src/libgai/ga_nsearch.c## + search[nsearch].host = "localhost"; /* 127.0.0.1 */## 38 ##src/libgai/ga_nsearch.c## + search[nsearch].family = AF_INET;## 39 ##src/libgai/ga_nsearch.c## + nsearch++;## 40 ##src/libgai/ga_nsearch.c## + break;## 41 ##src/libgai/ga_nsearch.c## + case AF_INET6:## 42 ##src/libgai/ga_nsearch.c## + search[nsearch].host = "0::1";## 43 ##src/libgai/ga_nsearch.c## + search[nsearch].family = AF_INET6;## 44 ##src/libgai/ga_nsearch.c## + nsearch++;## 45 ##src/libgai/ga_nsearch.c## + break;## 46 ##src/libgai/ga_nsearch.c## + case AF_UNSPEC:## 47 ##src/libgai/ga_nsearch.c## + search[nsearch].host = "0::1"; /* IPv6 first, then IPv4 */## 48 ##src/libgai/ga_nsearch.c## + search[nsearch].family = AF_INET6;## 49 ##src/libgai/ga_nsearch.c## + nsearch++;## 50 ##src/libgai/ga_nsearch.c## + search[nsearch].host = "localhost";## 51 ##src/libgai/ga_nsearch.c## + search[nsearch].family = AF_INET;## 52 ##src/libgai/ga_nsearch.c## + nsearch++;## 53 ##src/libgai/ga_nsearch.c## + break;## 54 ##src/libgai/ga_nsearch.c## + }## 55 ##src/libgai/ga_nsearch.c## + }## 56 ##src/libgai/ga_nsearch.c## +/* end ga_nsearch2 */ +/* include ga_nsearch3 */ + } else { /* host is specified */## 57 ##src/libgai/ga_nsearch.c## + switch (hintsp->ai_family) {## 58 ##src/libgai/ga_nsearch.c## + case AF_INET:## 59 ##src/libgai/ga_nsearch.c## + search[nsearch].host = hostname;## 60 ##src/libgai/ga_nsearch.c## + search[nsearch].family = AF_INET;## 61 ##src/libgai/ga_nsearch.c## + nsearch++;## 62 ##src/libgai/ga_nsearch.c## + break;## 63 ##src/libgai/ga_nsearch.c## + case AF_INET6:## 64 ##src/libgai/ga_nsearch.c## + search[nsearch].host = hostname;## 65 ##src/libgai/ga_nsearch.c## + search[nsearch].family = AF_INET6;## 66 ##src/libgai/ga_nsearch.c## + nsearch++;## 67 ##src/libgai/ga_nsearch.c## + break;## 68 ##src/libgai/ga_nsearch.c## + case AF_UNSPEC:## 69 ##src/libgai/ga_nsearch.c## + search[nsearch].host = hostname;## 70 ##src/libgai/ga_nsearch.c## + search[nsearch].family = AF_INET6; /* IPv6 first */## 71 ##src/libgai/ga_nsearch.c## + nsearch++;## 72 ##src/libgai/ga_nsearch.c## + search[nsearch].host = hostname;## 73 ##src/libgai/ga_nsearch.c## + search[nsearch].family = AF_INET; /* then IPv4 */## 74 ##src/libgai/ga_nsearch.c## + nsearch++;## 75 ##src/libgai/ga_nsearch.c## + break;## 76 ##src/libgai/ga_nsearch.c## + }## 77 ##src/libgai/ga_nsearch.c## + }## 78 ##src/libgai/ga_nsearch.c## + if (nsearch < 1 || nsearch > 2)## 79 ##src/libgai/ga_nsearch.c## + err_quit("nsearch = %d", nsearch);## 80 ##src/libgai/ga_nsearch.c## + return (nsearch);## 81 ##src/libgai/ga_nsearch.c## +}## 82 ##src/libgai/ga_nsearch.c## +/* end ga_nsearch3 */ diff --git a/libgai/ga_port.c b/libgai/ga_port.c new file mode 100644 index 0000000..655bcdf --- /dev/null +++ b/libgai/ga_port.c @@ -0,0 +1,66 @@ +#include "gai_hdr.h" + +/* + * Go through all the addrinfo structures, checking for a match of the + * socket type and filling in the socket type, and then the port number + * in the corresponding socket address structures. + * + * The AI_CLONE flag works as follows. Consider a multihomed host with + * two IP addresses and no socket type specified by the caller. After + * the "host" search there are two addrinfo structures, one per IP address. + * Assuming a service supported by both TCP and UDP (say the daytime + * service) we need to return *four* addrinfo structures: + * IP#1, SOCK_STREAM, TCP port, + * IP#1, SOCK_DGRAM, UDP port, + * IP#2, SOCK_STREAM, TCP port, + * IP#2, SOCK_DGRAM, UDP port. + * To do this, when the "host" loop creates an addrinfo structure, if the + * caller has not specified a socket type (hintsp->ai_socktype == 0), the + * AI_CLONE flag is set. When the following function finds an entry like + * this it is handled as follows: If the entry's ai_socktype is still 0, + * this is the first use of the structure, and the ai_socktype field is set. + * But, if the entry's ai_socktype is nonzero, then we clone a new addrinfo + * structure and set it's ai_socktype to the new value. Although we only + * need two socket types today (SOCK_STREAM and SOCK_DGRAM) this algorithm + * will handle any number. Also notice that Posix.1g requires all socket + * types to be nonzero. + */ + +/* include ga_port */ +int +ga_port(struct addrinfo *aihead, int port, int socktype) + /* port must be in network byte order */ +{ + int nfound = 0; + struct addrinfo *ai; + + for (ai = aihead; ai != NULL; ai = ai->ai_next) { + if (ai->ai_flags & AI_CLONE) { + if (ai->ai_socktype != 0) { + if ( (ai = ga_clone(ai)) == NULL) + return(-1); /* memory allocation error */ + /* ai points to newly cloned entry, which is what we want */ + } + } else if (ai->ai_socktype != socktype) + continue; /* ignore if mismatch on socket type */ + + ai->ai_socktype = socktype; + + switch (ai->ai_family) { +#ifdef IPv4 + case AF_INET: + ((struct sockaddr_in *) ai->ai_addr)->sin_port = port; + nfound++; + break; +#endif +#ifdef IPv6 + case AF_INET6: + ((struct sockaddr_in6 *) ai->ai_addr)->sin6_port = port; + nfound++; + break; +#endif + } + } + return(nfound); +} +/* end ga_port */ diff --git a/libgai/ga_port.lc b/libgai/ga_port.lc new file mode 100644 index 0000000..04171ea --- /dev/null +++ b/libgai/ga_port.lc @@ -0,0 +1,62 @@ +#include "gai_hdr.h"## 1 ##src/libgai/ga_port.c## + +/*## 2 ##src/libgai/ga_port.c## + * Go through all the addrinfo structures, checking for a match of the## 3 ##src/libgai/ga_port.c## + * socket type and filling in the socket type, and then the port number## 4 ##src/libgai/ga_port.c## + * in the corresponding socket address structures.## 5 ##src/libgai/ga_port.c## + *## 6 ##src/libgai/ga_port.c## + * The AI_CLONE flag works as follows. Consider a multihomed host with## 7 ##src/libgai/ga_port.c## + * two IP addresses and no socket type specified by the caller. After## 8 ##src/libgai/ga_port.c## + * the "host" search there are two addrinfo structures, one per IP address.## 9 ##src/libgai/ga_port.c## + * Assuming a service supported by both TCP and UDP (say the daytime## 10 ##src/libgai/ga_port.c## + * service) we need to return *four* addrinfo structures:## 11 ##src/libgai/ga_port.c## + * IP#1, SOCK_STREAM, TCP port,## 12 ##src/libgai/ga_port.c## + * IP#1, SOCK_DGRAM, UDP port,## 13 ##src/libgai/ga_port.c## + * IP#2, SOCK_STREAM, TCP port,## 14 ##src/libgai/ga_port.c## + * IP#2, SOCK_DGRAM, UDP port.## 15 ##src/libgai/ga_port.c## + * To do this, when the "host" loop creates an addrinfo structure, if the## 16 ##src/libgai/ga_port.c## + * caller has not specified a socket type (hintsp->ai_socktype == 0), the## 17 ##src/libgai/ga_port.c## + * AI_CLONE flag is set. When the following function finds an entry like## 18 ##src/libgai/ga_port.c## + * this it is handled as follows: If the entry's ai_socktype is still 0,## 19 ##src/libgai/ga_port.c## + * this is the first use of the structure, and the ai_socktype field is set.## 20 ##src/libgai/ga_port.c## + * But, if the entry's ai_socktype is nonzero, then we clone a new addrinfo## 21 ##src/libgai/ga_port.c## + * structure and set it's ai_socktype to the new value. Although we only## 22 ##src/libgai/ga_port.c## + * need two socket types today (SOCK_STREAM and SOCK_DGRAM) this algorithm## 23 ##src/libgai/ga_port.c## + * will handle any number. Also notice that Posix.1g requires all socket## 24 ##src/libgai/ga_port.c## + * types to be nonzero.## 25 ##src/libgai/ga_port.c## + */## 26 ##src/libgai/ga_port.c## + +/* include ga_port */ +int## 27 ##src/libgai/ga_port.c## +ga_port(struct addrinfo *aihead, int port, int socktype)## 28 ##src/libgai/ga_port.c## + /* port must be in network byte order */## 29 ##src/libgai/ga_port.c## +{## 30 ##src/libgai/ga_port.c## + int nfound = 0;## 31 ##src/libgai/ga_port.c## + struct addrinfo *ai;## 32 ##src/libgai/ga_port.c## + + for (ai = aihead; ai != NULL; ai = ai->ai_next) {## 33 ##src/libgai/ga_port.c## + if (ai->ai_flags & AI_CLONE) {## 34 ##src/libgai/ga_port.c## + if (ai->ai_socktype != 0) {## 35 ##src/libgai/ga_port.c## + if ((ai = ga_clone(ai)) == NULL)## 36 ##src/libgai/ga_port.c## + return (-1); /* memory allocation error */## 37 ##src/libgai/ga_port.c## + /* ai points to newly cloned entry, which is what we want */## 38 ##src/libgai/ga_port.c## + }## 39 ##src/libgai/ga_port.c## + } else if (ai->ai_socktype != socktype)## 40 ##src/libgai/ga_port.c## + continue; /* ignore if mismatch on socket type */## 41 ##src/libgai/ga_port.c## + + ai->ai_socktype = socktype;## 42 ##src/libgai/ga_port.c## + + switch (ai->ai_family) {## 43 ##src/libgai/ga_port.c## + case AF_INET:## 44 ##src/libgai/ga_port.c## + ((struct sockaddr_in *) ai->ai_addr)->sin_port = port;## 45 ##src/libgai/ga_port.c## + nfound++;## 46 ##src/libgai/ga_port.c## + break;## 47 ##src/libgai/ga_port.c## + case AF_INET6:## 48 ##src/libgai/ga_port.c## + ((struct sockaddr_in6 *) ai->ai_addr)->sin6_port = port;## 49 ##src/libgai/ga_port.c## + nfound++;## 50 ##src/libgai/ga_port.c## + break;## 51 ##src/libgai/ga_port.c## + }## 52 ##src/libgai/ga_port.c## + }## 53 ##src/libgai/ga_port.c## + return (nfound);## 54 ##src/libgai/ga_port.c## +}## 55 ##src/libgai/ga_port.c## +/* end ga_port */ diff --git a/libgai/ga_serv.c b/libgai/ga_serv.c new file mode 100644 index 0000000..53cd395 --- /dev/null +++ b/libgai/ga_serv.c @@ -0,0 +1,58 @@ +#include "gai_hdr.h" + +/* + * This function handles the service string. + */ + +/* include ga_serv */ +int +ga_serv(struct addrinfo *aihead, const struct addrinfo *hintsp, + const char *serv) +{ + int port, rc, nfound; + struct servent *sptr; + + nfound = 0; + if (isdigit(serv[0])) { /* check for port number string first */ + port = htons(atoi(serv)); + if (hintsp->ai_socktype) { + /* 4caller specifies socket type */ + if ( (rc = ga_port(aihead, port, hintsp->ai_socktype)) < 0) + return(EAI_MEMORY); + nfound += rc; + } else { + /* 4caller does not specify socket type */ + if ( (rc = ga_port(aihead, port, SOCK_STREAM)) < 0) + return(EAI_MEMORY); + nfound += rc; + if ( (rc = ga_port(aihead, port, SOCK_DGRAM)) < 0) + return(EAI_MEMORY); + nfound += rc; + } + } else { + /* 4try service name, TCP then UDP */ + if (hintsp->ai_socktype == 0 || hintsp->ai_socktype == SOCK_STREAM) { + if ( (sptr = getservbyname(serv, "tcp")) != NULL) { + if ( (rc = ga_port(aihead, sptr->s_port, SOCK_STREAM)) < 0) + return(EAI_MEMORY); + nfound += rc; + } + } + if (hintsp->ai_socktype == 0 || hintsp->ai_socktype == SOCK_DGRAM) { + if ( (sptr = getservbyname(serv, "udp")) != NULL) { + if ( (rc = ga_port(aihead, sptr->s_port, SOCK_DGRAM)) < 0) + return(EAI_MEMORY); + nfound += rc; + } + } + } + + if (nfound == 0) { + if (hintsp->ai_socktype == 0) + return(EAI_NONAME); /* all calls to getservbyname() failed */ + else + return(EAI_SERVICE);/* service not supported for socket type */ + } + return(0); +} +/* end ga_serv */ diff --git a/libgai/ga_serv.lc b/libgai/ga_serv.lc new file mode 100644 index 0000000..f8ee780 --- /dev/null +++ b/libgai/ga_serv.lc @@ -0,0 +1,58 @@ +#include "gai_hdr.h"## 1 ##src/libgai/ga_serv.c## + +/*## 2 ##src/libgai/ga_serv.c## + * This function handles the service string.## 3 ##src/libgai/ga_serv.c## + */## 4 ##src/libgai/ga_serv.c## + +/* include ga_serv */ +int## 5 ##src/libgai/ga_serv.c## +ga_serv(struct addrinfo *aihead, const struct addrinfo *hintsp,## 6 ##src/libgai/ga_serv.c## + const char *serv)## 7 ##src/libgai/ga_serv.c## +{## 8 ##src/libgai/ga_serv.c## + int port, rc, nfound;## 9 ##src/libgai/ga_serv.c## + struct servent *sptr;## 10 ##src/libgai/ga_serv.c## + + nfound = 0;## 11 ##src/libgai/ga_serv.c## + if (isdigit(serv[0])) { /* check for port number string first */## 12 ##src/libgai/ga_serv.c## + port = htons(atoi(serv));## 13 ##src/libgai/ga_serv.c## + if (hintsp->ai_socktype) {## 14 ##src/libgai/ga_serv.c## + /* 4caller specifies socket type */## 15 ##src/libgai/ga_serv.c## + if ((rc = ga_port(aihead, port, hintsp->ai_socktype)) < 0)## 16 ##src/libgai/ga_serv.c## + return (EAI_MEMORY);## 17 ##src/libgai/ga_serv.c## + nfound += rc;## 18 ##src/libgai/ga_serv.c## + } else {## 19 ##src/libgai/ga_serv.c## + /* 4caller does not specify socket type */## 20 ##src/libgai/ga_serv.c## + if ((rc = ga_port(aihead, port, SOCK_STREAM)) < 0)## 21 ##src/libgai/ga_serv.c## + return (EAI_MEMORY);## 22 ##src/libgai/ga_serv.c## + nfound += rc;## 23 ##src/libgai/ga_serv.c## + if ((rc = ga_port(aihead, port, SOCK_DGRAM)) < 0)## 24 ##src/libgai/ga_serv.c## + return (EAI_MEMORY);## 25 ##src/libgai/ga_serv.c## + nfound += rc;## 26 ##src/libgai/ga_serv.c## + }## 27 ##src/libgai/ga_serv.c## + } else {## 28 ##src/libgai/ga_serv.c## + /* 4try service name, TCP then UDP */## 29 ##src/libgai/ga_serv.c## + if (hintsp->ai_socktype == 0 || hintsp->ai_socktype == SOCK_STREAM) {## 30 ##src/libgai/ga_serv.c## + if ((sptr = getservbyname(serv, "tcp")) != NULL) {## 31 ##src/libgai/ga_serv.c## + if ((rc = ga_port(aihead, sptr->s_port, SOCK_STREAM)) < 0)## 32 ##src/libgai/ga_serv.c## + return (EAI_MEMORY);## 33 ##src/libgai/ga_serv.c## + nfound += rc;## 34 ##src/libgai/ga_serv.c## + }## 35 ##src/libgai/ga_serv.c## + }## 36 ##src/libgai/ga_serv.c## + if (hintsp->ai_socktype == 0 || hintsp->ai_socktype == SOCK_DGRAM) {## 37 ##src/libgai/ga_serv.c## + if ((sptr = getservbyname(serv, "udp")) != NULL) {## 38 ##src/libgai/ga_serv.c## + if ((rc = ga_port(aihead, sptr->s_port, SOCK_DGRAM)) < 0)## 39 ##src/libgai/ga_serv.c## + return (EAI_MEMORY);## 40 ##src/libgai/ga_serv.c## + nfound += rc;## 41 ##src/libgai/ga_serv.c## + }## 42 ##src/libgai/ga_serv.c## + }## 43 ##src/libgai/ga_serv.c## + }## 44 ##src/libgai/ga_serv.c## + + if (nfound == 0) {## 45 ##src/libgai/ga_serv.c## + if (hintsp->ai_socktype == 0)## 46 ##src/libgai/ga_serv.c## + return (EAI_NONAME); /* all calls to getservbyname() failed */## 47 ##src/libgai/ga_serv.c## + else## 48 ##src/libgai/ga_serv.c## + return (EAI_SERVICE); /* service not supported for socket type */## 49 ##src/libgai/ga_serv.c## + }## 50 ##src/libgai/ga_serv.c## + return (0);## 51 ##src/libgai/ga_serv.c## +}## 52 ##src/libgai/ga_serv.c## +/* end ga_serv */ diff --git a/libgai/ga_unix.c b/libgai/ga_unix.c new file mode 100644 index 0000000..74decbf --- /dev/null +++ b/libgai/ga_unix.c @@ -0,0 +1,42 @@ +#include "gai_hdr.h" +#include + +#ifdef UNIXdomain +/* include ga_unix */ +int +ga_unix(const char *path, struct addrinfo *hintsp, struct addrinfo **result) +{ + int rc; + struct addrinfo *aihead, **aipnext; + + aihead = NULL; + aipnext = &aihead; + + if (hintsp->ai_family != AF_UNSPEC && hintsp->ai_family != AF_LOCAL) + return(EAI_ADDRFAMILY); + + if (hintsp->ai_socktype == 0) { + /* 4no socket type specified: return stream then dgram */ + hintsp->ai_socktype = SOCK_STREAM; + if ( (rc = ga_aistruct(&aipnext, hintsp, path, AF_LOCAL)) != 0) + return(rc); + hintsp->ai_socktype = SOCK_DGRAM; + } + + if ( (rc = ga_aistruct(&aipnext, hintsp, path, AF_LOCAL)) != 0) + return(rc); + + if (hintsp->ai_flags & AI_CANONNAME) { + struct utsname myname; + + if (uname(&myname) < 0) + return(EAI_SYSTEM); + if ( (aihead->ai_canonname = strdup(myname.nodename)) == NULL) + return(EAI_MEMORY); + } + + *result = aihead; /* pointer to first structure in linked list */ + return(0); +} +/* end ga_unix */ +#endif /* UNIXdomain */ diff --git a/libgai/ga_unix.lc b/libgai/ga_unix.lc new file mode 100644 index 0000000..fd761a0 --- /dev/null +++ b/libgai/ga_unix.lc @@ -0,0 +1,40 @@ +#include "gai_hdr.h"## 1 ##src/libgai/ga_unix.c## +#include ## 2 ##src/libgai/ga_unix.c## + +/* include ga_unix */ +int## 3 ##src/libgai/ga_unix.c## +ga_unix(const char *path, struct addrinfo *hintsp, struct addrinfo **result)## 4 ##src/libgai/ga_unix.c## +{## 5 ##src/libgai/ga_unix.c## + int rc;## 6 ##src/libgai/ga_unix.c## + struct addrinfo *aihead, **aipnext;## 7 ##src/libgai/ga_unix.c## + + aihead = NULL;## 8 ##src/libgai/ga_unix.c## + aipnext = &aihead;## 9 ##src/libgai/ga_unix.c## + + if (hintsp->ai_family != AF_UNSPEC && hintsp->ai_family != AF_LOCAL)## 10 ##src/libgai/ga_unix.c## + return (EAI_ADDRFAMILY);## 11 ##src/libgai/ga_unix.c## + + if (hintsp->ai_socktype == 0) {## 12 ##src/libgai/ga_unix.c## + /* 4no socket type specified: return stream then dgram */## 13 ##src/libgai/ga_unix.c## + hintsp->ai_socktype = SOCK_STREAM;## 14 ##src/libgai/ga_unix.c## + if ((rc = ga_aistruct(&aipnext, hintsp, path, AF_LOCAL)) != 0)## 15 ##src/libgai/ga_unix.c## + return (rc);## 16 ##src/libgai/ga_unix.c## + hintsp->ai_socktype = SOCK_DGRAM;## 17 ##src/libgai/ga_unix.c## + }## 18 ##src/libgai/ga_unix.c## + + if ((rc = ga_aistruct(&aipnext, hintsp, path, AF_LOCAL)) != 0)## 19 ##src/libgai/ga_unix.c## + return (rc);## 20 ##src/libgai/ga_unix.c## + + if (hintsp->ai_flags & AI_CANONNAME) {## 21 ##src/libgai/ga_unix.c## + struct utsname myname;## 22 ##src/libgai/ga_unix.c## + + if (uname(&myname) < 0)## 23 ##src/libgai/ga_unix.c## + return (EAI_SYSTEM);## 24 ##src/libgai/ga_unix.c## + if ((aihead->ai_canonname = strdup(myname.nodename)) == NULL)## 25 ##src/libgai/ga_unix.c## + return (EAI_MEMORY);## 26 ##src/libgai/ga_unix.c## + }## 27 ##src/libgai/ga_unix.c## + + *result = aihead; /* pointer to first structure in linked list */## 28 ##src/libgai/ga_unix.c## + return (0);## 29 ##src/libgai/ga_unix.c## +}## 30 ##src/libgai/ga_unix.c## +/* end ga_unix */ diff --git a/libgai/gai_hdr.h b/libgai/gai_hdr.h new file mode 100644 index 0000000..a25860a --- /dev/null +++ b/libgai/gai_hdr.h @@ -0,0 +1,23 @@ +#include "unp.h" +#include /* isxdigit(), etc. */ + + /* following internal flag cannot overlap with other AI_xxx flags */ +#define AI_CLONE 4 /* clone this entry for other socket types */ + +struct search { + const char *host; /* hostname or address string */ + int family; /* AF_xxx */ +}; + + /* 4function prototypes for our own internal functions */ +int ga_aistruct(struct addrinfo ***, const struct addrinfo *, + const void *, int); +struct addrinfo *ga_clone(struct addrinfo *); +int ga_echeck(const char *, const char *, int, int, int, int); +int ga_nsearch(const char *, const struct addrinfo *, struct search *); +int ga_port(struct addrinfo *, int , int); +int ga_serv(struct addrinfo *, const struct addrinfo *, const char *); +int ga_unix(const char *, struct addrinfo *, struct addrinfo **); + +int gn_ipv46(char *, size_t, char *, size_t, void *, size_t, + int, int, int); diff --git a/libgai/gai_hdr.lh b/libgai/gai_hdr.lh new file mode 100644 index 0000000..4e7ac2e --- /dev/null +++ b/libgai/gai_hdr.lh @@ -0,0 +1,23 @@ +#include "unp.h"## 1 ##src/libgai/gai_hdr.h## +#include /* isxdigit(), etc. */## 2 ##src/libgai/gai_hdr.h## + + /* following internal flag cannot overlap with other AI_xxx flags */## 3 ##src/libgai/gai_hdr.h## +#define AI_CLONE 4 /* clone this entry for other socket types */## 4 ##src/libgai/gai_hdr.h## + +struct search {## 5 ##src/libgai/gai_hdr.h## + const char *host; /* hostname or address string */## 6 ##src/libgai/gai_hdr.h## + int family; /* AF_xxx */## 7 ##src/libgai/gai_hdr.h## +};## 8 ##src/libgai/gai_hdr.h## + + /* 4function prototypes for our own internal functions */## 9 ##src/libgai/gai_hdr.h## +int ga_aistruct(struct addrinfo ***, const struct addrinfo *,## 10 ##src/libgai/gai_hdr.h## + const void *, int);## 11 ##src/libgai/gai_hdr.h## +struct addrinfo *ga_clone(struct addrinfo *);## 12 ##src/libgai/gai_hdr.h## +int ga_echeck(const char *, const char *, int, int, int, int);## 13 ##src/libgai/gai_hdr.h## +int ga_nsearch(const char *, const struct addrinfo *, struct search *);## 14 ##src/libgai/gai_hdr.h## +int ga_port(struct addrinfo *, int, int);## 15 ##src/libgai/gai_hdr.h## +int ga_serv(struct addrinfo *, const struct addrinfo *, const char *);## 16 ##src/libgai/gai_hdr.h## +int ga_unix(const char *, struct addrinfo *, struct addrinfo **);## 17 ##src/libgai/gai_hdr.h## + +int gn_ipv46(char *, size_t, char *, size_t, void *, size_t,## 18 ##src/libgai/gai_hdr.h## + int, int, int);## 19 ##src/libgai/gai_hdr.h## diff --git a/libgai/gai_strerror.c b/libgai/gai_strerror.c new file mode 100644 index 0000000..c0495ab --- /dev/null +++ b/libgai/gai_strerror.c @@ -0,0 +1,26 @@ +/* + * Return a string containing some additional information after an + * error from getaddrinfo(). + */ + +#include +#include "addrinfo.h" /* XXX should be */ + +char * +gai_strerror(int err) +{ + switch (err) { + case EAI_ADDRFAMILY:return("address family for host not supported"); + case EAI_AGAIN: return("temporary failure in name resolution"); + case EAI_BADFLAGS: return("invalid flags value"); + case EAI_FAIL: return("non-recoverable failure in name resolution"); + case EAI_FAMILY: return("address family not supported"); + case EAI_MEMORY: return("memory allocation failure"); + case EAI_NODATA: return("no address associated with host"); + case EAI_NONAME: return("host nor service provided, or not known"); + case EAI_SERVICE: return("service not supported for socket type"); + case EAI_SOCKTYPE: return("socket type not supported"); + case EAI_SYSTEM: return("system error"); + default: return("unknown getaddrinfo() error"); + } +} diff --git a/libgai/getaddrinfo.c b/libgai/getaddrinfo.c new file mode 100644 index 0000000..e4ec036 --- /dev/null +++ b/libgai/getaddrinfo.c @@ -0,0 +1,168 @@ +/* include ga1 */ +#include "gai_hdr.h" +#include /* needed for */ +#include /* res_init, _res */ + +int +getaddrinfo(const char *hostname, const char *servname, + const struct addrinfo *hintsp, struct addrinfo **result) +{ + int rc, error, nsearch; + char **ap, *canon; + struct hostent *hptr; + struct search search[3], *sptr; + struct addrinfo hints, *aihead, **aipnext; + + /* + * If we encounter an error we want to free() any dynamic memory + * that we've allocated. This is our hack to simplify the code. + */ +#define error(e) { error = (e); goto bad; } + + aihead = NULL; /* initialize automatic variables */ + aipnext = &aihead; + canon = NULL; + + if (hintsp == NULL) { + bzero(&hints, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + } else + hints = *hintsp; /* struct copy */ + + /* 4first some basic error checking */ + if ( (rc = ga_echeck(hostname, servname, hints.ai_flags, hints.ai_family, + hints.ai_socktype, hints.ai_protocol)) != 0) + error(rc); + +#ifdef UNIXdomain + /* 4special case Unix domain first */ + if (hostname != NULL && + (strcmp(hostname, "/local") == 0 || strcmp(hostname, "/unix") == 0) && + (servname != NULL && servname[0] == '/')) + return(ga_unix(servname, &hints, result)); +#endif +/* end ga1 */ + +/* include ga3 */ + /* 4remainder of function for IPv4/IPv6 */ + nsearch = ga_nsearch(hostname, &hints, &search[0]); + for (sptr = &search[0]; sptr < &search[nsearch]; sptr++) { +#ifdef IPv4 + /* 4check for an IPv4 dotted-decimal string */ + if (isdigit(sptr->host[0])) { + struct in_addr inaddr; + + if (inet_pton(AF_INET, sptr->host, &inaddr) == 1) { + if (hints.ai_family != AF_UNSPEC && + hints.ai_family != AF_INET) + error(EAI_ADDRFAMILY); + if (sptr->family != AF_INET) + continue; /* ignore */ + rc = ga_aistruct(&aipnext, &hints, &inaddr, AF_INET); + if (rc != 0) + error(rc); + continue; + } + } +#endif + +#ifdef IPv6 + /* 4check for an IPv6 hex string */ + if ((isxdigit(sptr->host[0]) || sptr->host[0] == ':') && + (strchr(sptr->host, ':') != NULL)) { + struct in6_addr in6addr; + + if (inet_pton(AF_INET6, sptr->host, &in6addr) == 1) { + if (hints.ai_family != AF_UNSPEC && + hints.ai_family != AF_INET6) + error(EAI_ADDRFAMILY); + if (sptr->family != AF_INET6) + continue; /* ignore */ + rc = ga_aistruct(&aipnext, &hints, &in6addr, AF_INET6); + if (rc != 0) + error(rc); + continue; + } + } +#endif +/* end ga3 */ +/* include ga4 */ + /* 4remainder of for() to look up hostname */ + if ((_res.options & RES_INIT) == 0) + res_init(); /* need this to set _res.options */ + + if (nsearch == 2) { +#ifdef IPv6 + _res.options &= ~RES_USE_INET6; +#endif + hptr = gethostbyname2(sptr->host, sptr->family); + } else { +#ifdef IPv6 + if (sptr->family == AF_INET6) + _res.options |= RES_USE_INET6; + else + _res.options &= ~RES_USE_INET6; +#endif + hptr = gethostbyname(sptr->host); + } + if (hptr == NULL) { + if (nsearch == 2) + continue; /* failure OK if multiple searches */ + + switch (h_errno) { + case HOST_NOT_FOUND: error(EAI_NONAME); + case TRY_AGAIN: error(EAI_AGAIN); + case NO_RECOVERY: error(EAI_FAIL); + case NO_DATA: error(EAI_NODATA); + default: error(EAI_NONAME); + } + } + + /* 4check for address family mismatch if one specified */ + if (hints.ai_family != AF_UNSPEC && hints.ai_family != hptr->h_addrtype) + error(EAI_ADDRFAMILY); + + /* 4save canonical name first time */ + if (hostname != NULL && hostname[0] != '\0' && + (hints.ai_flags & AI_CANONNAME) && canon == NULL) { + if ( (canon = strdup(hptr->h_name)) == NULL) + error(EAI_MEMORY); + } + + /* 4create one addrinfo{} for each returned address */ + for (ap = hptr->h_addr_list; *ap != NULL; ap++) { + rc = ga_aistruct(&aipnext, &hints, *ap, hptr->h_addrtype); + if (rc != 0) + error(rc); + } + } + if (aihead == NULL) + error(EAI_NONAME); /* nothing found */ +/* end ga4 */ + +/* include ga5 */ + /* 4return canonical name */ + if (hostname != NULL && hostname[0] != '\0' && + hints.ai_flags & AI_CANONNAME) { + if (canon != NULL) + aihead->ai_canonname = canon; /* strdup'ed earlier */ + else { + if ( (aihead->ai_canonname = strdup(search[0].host)) == NULL) + error(EAI_MEMORY); + } + } + + /* 4now process the service name */ + if (servname != NULL && servname[0] != '\0') { + if ( (rc = ga_serv(aihead, &hints, servname)) != 0) + error(rc); + } + + *result = aihead; /* pointer to first structure in linked list */ + return(0); + +bad: + freeaddrinfo(aihead); /* free any alloc'ed memory */ + return(error); +} +/* end ga5 */ diff --git a/libgai/getaddrinfo.lc b/libgai/getaddrinfo.lc new file mode 100644 index 0000000..f745002 --- /dev/null +++ b/libgai/getaddrinfo.lc @@ -0,0 +1,164 @@ +/* include ga1 */ +#include "gai_hdr.h"## 1 ##src/libgai/getaddrinfo.c## +#include /* needed for */## 2 ##src/libgai/getaddrinfo.c## +#include /* res_init, _res */## 3 ##src/libgai/getaddrinfo.c## + +int## 4 ##src/libgai/getaddrinfo.c## +getaddrinfo(const char *hostname, const char *servname,## 5 ##src/libgai/getaddrinfo.c## + const struct addrinfo *hintsp, struct addrinfo **result)## 6 ##src/libgai/getaddrinfo.c## +{## 7 ##src/libgai/getaddrinfo.c## + int rc, error, nsearch;## 8 ##src/libgai/getaddrinfo.c## + char **ap, *canon;## 9 ##src/libgai/getaddrinfo.c## + struct hostent *hptr;## 10 ##src/libgai/getaddrinfo.c## + struct search search[3], *sptr;## 11 ##src/libgai/getaddrinfo.c## + struct addrinfo hints, *aihead, **aipnext;## 12 ##src/libgai/getaddrinfo.c## + + /* ## 13 ##src/libgai/getaddrinfo.c## + * If we encounter an error we want to free() any dynamic memory## 14 ##src/libgai/getaddrinfo.c## + * that we've allocated. This is our hack to simplify the code.## 15 ##src/libgai/getaddrinfo.c## + */## 16 ##src/libgai/getaddrinfo.c## +#define error(e) { error = (e); goto bad; }## 17 ##src/libgai/getaddrinfo.c## + + aihead = NULL; /* initialize automatic variables */## 18 ##src/libgai/getaddrinfo.c## + aipnext = &aihead;## 19 ##src/libgai/getaddrinfo.c## + canon = NULL;## 20 ##src/libgai/getaddrinfo.c## + + if (hintsp == NULL) {## 21 ##src/libgai/getaddrinfo.c## + bzero(&hints, sizeof(hints));## 22 ##src/libgai/getaddrinfo.c## + hints.ai_family = AF_UNSPEC;## 23 ##src/libgai/getaddrinfo.c## + } else## 24 ##src/libgai/getaddrinfo.c## + hints = *hintsp; /* struct copy */## 25 ##src/libgai/getaddrinfo.c## + + /* 4first some basic error checking */## 26 ##src/libgai/getaddrinfo.c## + if ((rc = ga_echeck(hostname, servname, hints.ai_flags, hints.ai_family,## 27 ##src/libgai/getaddrinfo.c## + hints.ai_socktype, hints.ai_protocol)) != 0)## 28 ##src/libgai/getaddrinfo.c## + error(rc);## 29 ##src/libgai/getaddrinfo.c## + + /* 4special case Unix domain first */## 30 ##src/libgai/getaddrinfo.c## + if (hostname != NULL &&## 31 ##src/libgai/getaddrinfo.c## + (strcmp(hostname, "/local") == 0 || strcmp(hostname, "/unix") == 0)## 32 ##src/libgai/getaddrinfo.c## + && (servname != NULL && servname[0] == '/'))## 33 ##src/libgai/getaddrinfo.c## + return (ga_unix(servname, &hints, result));## 34 ##src/libgai/getaddrinfo.c## +/* end ga1 */ + +/* include ga3 */ + /* 4remainder of function for IPv4/IPv6 */## 35 ##src/libgai/getaddrinfo.c## + nsearch = ga_nsearch(hostname, &hints, &search[0]);## 36 ##src/libgai/getaddrinfo.c## + for (sptr = &search[0]; sptr < &search[nsearch]; sptr++) {## 37 ##src/libgai/getaddrinfo.c## + /* 4check for an IPv4 dotted-decimal string */## 38 ##src/libgai/getaddrinfo.c## + if (isdigit(sptr->host[0])) {## 39 ##src/libgai/getaddrinfo.c## + struct in_addr inaddr;## 40 ##src/libgai/getaddrinfo.c## + + if (inet_pton(AF_INET, sptr->host, &inaddr) == 1) {## 41 ##src/libgai/getaddrinfo.c## + if (hints.ai_family != AF_UNSPEC &&## 42 ##src/libgai/getaddrinfo.c## + hints.ai_family != AF_INET)## 43 ##src/libgai/getaddrinfo.c## + error(EAI_ADDRFAMILY);## 44 ##src/libgai/getaddrinfo.c## + if (sptr->family != AF_INET)## 45 ##src/libgai/getaddrinfo.c## + continue; /* ignore */## 46 ##src/libgai/getaddrinfo.c## + rc = ga_aistruct(&aipnext, &hints, &inaddr, AF_INET);## 47 ##src/libgai/getaddrinfo.c## + if (rc != 0)## 48 ##src/libgai/getaddrinfo.c## + error(rc);## 49 ##src/libgai/getaddrinfo.c## + continue;## 50 ##src/libgai/getaddrinfo.c## + }## 51 ##src/libgai/getaddrinfo.c## + }## 52 ##src/libgai/getaddrinfo.c## + + /* 4check for an IPv6 hex string */## 53 ##src/libgai/getaddrinfo.c## + if ((isxdigit(sptr->host[0]) || sptr->host[0] == ':') &&## 54 ##src/libgai/getaddrinfo.c## + (strchr(sptr->host, ':') != NULL)) {## 55 ##src/libgai/getaddrinfo.c## + struct in6_addr in6addr;## 56 ##src/libgai/getaddrinfo.c## + + if (inet_pton(AF_INET6, sptr->host, &in6addr) == 1) {## 57 ##src/libgai/getaddrinfo.c## + if (hints.ai_family != AF_UNSPEC &&## 58 ##src/libgai/getaddrinfo.c## + hints.ai_family != AF_INET6)## 59 ##src/libgai/getaddrinfo.c## + error(EAI_ADDRFAMILY);## 60 ##src/libgai/getaddrinfo.c## + if (sptr->family != AF_INET6)## 61 ##src/libgai/getaddrinfo.c## + continue; /* ignore */## 62 ##src/libgai/getaddrinfo.c## + rc = ga_aistruct(&aipnext, &hints, &in6addr, AF_INET6);## 63 ##src/libgai/getaddrinfo.c## + if (rc != 0)## 64 ##src/libgai/getaddrinfo.c## + error(rc);## 65 ##src/libgai/getaddrinfo.c## + continue;## 66 ##src/libgai/getaddrinfo.c## + }## 67 ##src/libgai/getaddrinfo.c## + }## 68 ##src/libgai/getaddrinfo.c## +/* end ga3 */ +/* include ga4 */ + /* 4remainder of for() to look up hostname */## 69 ##src/libgai/getaddrinfo.c## + if ((_res.options & RES_INIT) == 0)## 70 ##src/libgai/getaddrinfo.c## + res_init(); /* need this to set _res.options */## 71 ##src/libgai/getaddrinfo.c## + + if (nsearch == 2) {## 72 ##src/libgai/getaddrinfo.c## + _res.options &= ~RES_USE_INET6;## 73 ##src/libgai/getaddrinfo.c## + hptr = gethostbyname2(sptr->host, sptr->family);## 74 ##src/libgai/getaddrinfo.c## + } else {## 75 ##src/libgai/getaddrinfo.c## + if (sptr->family == AF_INET6)## 76 ##src/libgai/getaddrinfo.c## + _res.options |= RES_USE_INET6;## 77 ##src/libgai/getaddrinfo.c## + else## 78 ##src/libgai/getaddrinfo.c## + _res.options &= ~RES_USE_INET6;## 79 ##src/libgai/getaddrinfo.c## + hptr = gethostbyname(sptr->host);## 80 ##src/libgai/getaddrinfo.c## + }## 81 ##src/libgai/getaddrinfo.c## + if (hptr == NULL) {## 82 ##src/libgai/getaddrinfo.c## + if (nsearch == 2)## 83 ##src/libgai/getaddrinfo.c## + continue; /* failure OK if multiple searches */## 84 ##src/libgai/getaddrinfo.c## + + switch (h_errno) {## 85 ##src/libgai/getaddrinfo.c## + case HOST_NOT_FOUND:## 86 ##src/libgai/getaddrinfo.c## + error(EAI_NONAME);## 87 ##src/libgai/getaddrinfo.c## + case TRY_AGAIN:## 88 ##src/libgai/getaddrinfo.c## + error(EAI_AGAIN);## 89 ##src/libgai/getaddrinfo.c## + case NO_RECOVERY:## 90 ##src/libgai/getaddrinfo.c## + error(EAI_FAIL);## 91 ##src/libgai/getaddrinfo.c## + case NO_DATA:## 92 ##src/libgai/getaddrinfo.c## + error(EAI_NODATA);## 93 ##src/libgai/getaddrinfo.c## + default:## 94 ##src/libgai/getaddrinfo.c## + error(EAI_NONAME);## 95 ##src/libgai/getaddrinfo.c## + }## 96 ##src/libgai/getaddrinfo.c## + }## 97 ##src/libgai/getaddrinfo.c## + + /* 4check for address family mismatch if one specified */## 98 ##src/libgai/getaddrinfo.c## + if (hints.ai_family != AF_UNSPEC## 99 ##src/libgai/getaddrinfo.c## + && hints.ai_family != hptr->h_addrtype)##100 ##src/libgai/getaddrinfo.c## + error(EAI_ADDRFAMILY);##101 ##src/libgai/getaddrinfo.c## + + /* 4save canonical name first time */##102 ##src/libgai/getaddrinfo.c## + if (hostname != NULL && hostname[0] != '\0' &&##103 ##src/libgai/getaddrinfo.c## + (hints.ai_flags & AI_CANONNAME) && canon == NULL) {##104 ##src/libgai/getaddrinfo.c## + if ((canon = strdup(hptr->h_name)) == NULL)##105 ##src/libgai/getaddrinfo.c## + error(EAI_MEMORY);##106 ##src/libgai/getaddrinfo.c## + }##107 ##src/libgai/getaddrinfo.c## + + /* 4create one addrinfo{} for each returned address */##108 ##src/libgai/getaddrinfo.c## + for (ap = hptr->h_addr_list; *ap != NULL; ap++) {##109 ##src/libgai/getaddrinfo.c## + rc = ga_aistruct(&aipnext, &hints, *ap, hptr->h_addrtype);##110 ##src/libgai/getaddrinfo.c## + if (rc != 0)##111 ##src/libgai/getaddrinfo.c## + error(rc);##112 ##src/libgai/getaddrinfo.c## + }##113 ##src/libgai/getaddrinfo.c## + }##114 ##src/libgai/getaddrinfo.c## + if (aihead == NULL)##115 ##src/libgai/getaddrinfo.c## + error(EAI_NONAME); /* nothing found */##116 ##src/libgai/getaddrinfo.c## +/* end ga4 */ + +/* include ga5 */ + /* 4return canonical name */##117 ##src/libgai/getaddrinfo.c## + if (hostname != NULL && hostname[0] != '\0' &&##118 ##src/libgai/getaddrinfo.c## + hints.ai_flags & AI_CANONNAME) {##119 ##src/libgai/getaddrinfo.c## + if (canon != NULL)##120 ##src/libgai/getaddrinfo.c## + aihead->ai_canonname = canon; /* strdup'ed earlier */##121 ##src/libgai/getaddrinfo.c## + else {##122 ##src/libgai/getaddrinfo.c## + if ((aihead->ai_canonname = strdup(search[0].host)) == NULL)##123 ##src/libgai/getaddrinfo.c## + error(EAI_MEMORY);##124 ##src/libgai/getaddrinfo.c## + }##125 ##src/libgai/getaddrinfo.c## + }##126 ##src/libgai/getaddrinfo.c## + + /* 4now process the service name */##127 ##src/libgai/getaddrinfo.c## + if (servname != NULL && servname[0] != '\0') {##128 ##src/libgai/getaddrinfo.c## + if ((rc = ga_serv(aihead, &hints, servname)) != 0)##129 ##src/libgai/getaddrinfo.c## + error(rc);##130 ##src/libgai/getaddrinfo.c## + }##131 ##src/libgai/getaddrinfo.c## + + *result = aihead; /* pointer to first structure in linked list */##132 ##src/libgai/getaddrinfo.c## + return (0);##133 ##src/libgai/getaddrinfo.c## + + bad:##134 ##src/libgai/getaddrinfo.c## + freeaddrinfo(aihead); /* free any alloc'ed memory */##135 ##src/libgai/getaddrinfo.c## + return (error);##136 ##src/libgai/getaddrinfo.c## +}##137 ##src/libgai/getaddrinfo.c## +/* end ga5 */ diff --git a/libgai/getnameinfo.c b/libgai/getnameinfo.c new file mode 100644 index 0000000..95480a5 --- /dev/null +++ b/libgai/getnameinfo.c @@ -0,0 +1,47 @@ +#include "gai_hdr.h" + +/* include getnameinfo */ +int +getnameinfo(const struct sockaddr *sa, socklen_t salen, + char *host, size_t hostlen, + char *serv, size_t servlen, int flags) +{ + + switch (sa->sa_family) { +#ifdef IPv4 + case AF_INET: { + struct sockaddr_in *sain = (struct sockaddr_in *) sa; + + return(gn_ipv46(host, hostlen, serv, servlen, + &sain->sin_addr, sizeof(struct in_addr), + AF_INET, sain->sin_port, flags)); + } +#endif + +#ifdef IPv6 + case AF_INET6: { + struct sockaddr_in6 *sain = (struct sockaddr_in6 *) sa; + + return(gn_ipv46(host, hostlen, serv, servlen, + &sain->sin6_addr, sizeof(struct in6_addr), + AF_INET6, sain->sin6_port, flags)); + } +#endif + +#ifdef UNIXdomain + case AF_LOCAL: { + struct sockaddr_un *un = (struct sockaddr_un *) sa; + + if (hostlen > 0) + snprintf(host, hostlen, "%s", "/local"); + if (servlen > 0) + snprintf(serv, servlen, "%s", un->sun_path); + return(0); + } +#endif + + default: + return(1); + } +} +/* end getnameinfo */ diff --git a/libgai/getnameinfo.lc b/libgai/getnameinfo.lc new file mode 100644 index 0000000..2318309 --- /dev/null +++ b/libgai/getnameinfo.lc @@ -0,0 +1,41 @@ +#include "gai_hdr.h"## 1 ##src/libgai/getnameinfo.c## + +/* include getnameinfo */ +int## 2 ##src/libgai/getnameinfo.c## +getnameinfo(const struct sockaddr *sa, socklen_t salen,## 3 ##src/libgai/getnameinfo.c## + char *host, size_t hostlen,## 4 ##src/libgai/getnameinfo.c## + char *serv, size_t servlen, int flags)## 5 ##src/libgai/getnameinfo.c## +{## 6 ##src/libgai/getnameinfo.c## + + switch (sa->sa_family) {## 7 ##src/libgai/getnameinfo.c## + case AF_INET:{## 8 ##src/libgai/getnameinfo.c## + struct sockaddr_in *sain = (struct sockaddr_in *) sa;## 9 ##src/libgai/getnameinfo.c## + + return (gn_ipv46(host, hostlen, serv, servlen,## 10 ##src/libgai/getnameinfo.c## + &sain->sin_addr, sizeof(struct in_addr),## 11 ##src/libgai/getnameinfo.c## + AF_INET, sain->sin_port, flags));## 12 ##src/libgai/getnameinfo.c## + }## 13 ##src/libgai/getnameinfo.c## + + case AF_INET6:{## 14 ##src/libgai/getnameinfo.c## + struct sockaddr_in6 *sain = (struct sockaddr_in6 *) sa;## 15 ##src/libgai/getnameinfo.c## + + return (gn_ipv46(host, hostlen, serv, servlen,## 16 ##src/libgai/getnameinfo.c## + &sain->sin6_addr, sizeof(struct in6_addr),## 17 ##src/libgai/getnameinfo.c## + AF_INET6, sain->sin6_port, flags));## 18 ##src/libgai/getnameinfo.c## + }## 19 ##src/libgai/getnameinfo.c## + + case AF_LOCAL:{## 20 ##src/libgai/getnameinfo.c## + struct sockaddr_un *un = (struct sockaddr_un *) sa;## 21 ##src/libgai/getnameinfo.c## + + if (hostlen > 0)## 22 ##src/libgai/getnameinfo.c## + snprintf(host, hostlen, "%s", "/local");## 23 ##src/libgai/getnameinfo.c## + if (servlen > 0)## 24 ##src/libgai/getnameinfo.c## + snprintf(serv, servlen, "%s", un->sun_path);## 25 ##src/libgai/getnameinfo.c## + return (0);## 26 ##src/libgai/getnameinfo.c## + }## 27 ##src/libgai/getnameinfo.c## + + default:## 28 ##src/libgai/getnameinfo.c## + return (1);## 29 ##src/libgai/getnameinfo.c## + }## 30 ##src/libgai/getnameinfo.c## +}## 31 ##src/libgai/getnameinfo.c## +/* end getnameinfo */ diff --git a/libgai/gn_ipv46.c b/libgai/gn_ipv46.c new file mode 100644 index 0000000..512f50d --- /dev/null +++ b/libgai/gn_ipv46.c @@ -0,0 +1,50 @@ +#include "gai_hdr.h" + +/* + * Handle either an IPv4 or an IPv6 address and port. + */ + +/* include gn_ipv46 */ +int +gn_ipv46(char *host, size_t hostlen, char *serv, size_t servlen, + void *aptr, size_t alen, int family, int port, int flags) +{ + char *ptr; + struct hostent *hptr; + struct servent *sptr; + + if (hostlen > 0) { + if (flags & NI_NUMERICHOST) { + if (inet_ntop(family, aptr, host, hostlen) == NULL) + return(1); + } else { + hptr = gethostbyaddr(aptr, alen, family); + if (hptr != NULL && hptr->h_name != NULL) { + if (flags & NI_NOFQDN) { + if ( (ptr = strchr(hptr->h_name, '.')) != NULL) + *ptr = 0; /* overwrite first dot */ + } + snprintf(host, hostlen, "%s", hptr->h_name); + } else { + if (flags & NI_NAMEREQD) + return(1); + if (inet_ntop(family, aptr, host, hostlen) == NULL) + return(1); + } + } + } + + if (servlen > 0) { + if (flags & NI_NUMERICSERV) { + snprintf(serv, servlen, "%d", ntohs(port)); + } else { + sptr = getservbyport(port, (flags & NI_DGRAM) ? "udp" : NULL); + if (sptr != NULL && sptr->s_name != NULL) + snprintf(serv, servlen, "%s", sptr->s_name); + else + snprintf(serv, servlen, "%d", ntohs(port)); + } + } + return(0); +} +/* end gn_ipv46 */ diff --git a/libgai/gn_ipv46.lc b/libgai/gn_ipv46.lc new file mode 100644 index 0000000..c438878 --- /dev/null +++ b/libgai/gn_ipv46.lc @@ -0,0 +1,50 @@ +#include "gai_hdr.h"## 1 ##src/libgai/gn_ipv46.c## + +/*## 2 ##src/libgai/gn_ipv46.c## + * Handle either an IPv4 or an IPv6 address and port.## 3 ##src/libgai/gn_ipv46.c## + */## 4 ##src/libgai/gn_ipv46.c## + +/* include gn_ipv46 */ +int## 5 ##src/libgai/gn_ipv46.c## +gn_ipv46(char *host, size_t hostlen, char *serv, size_t servlen,## 6 ##src/libgai/gn_ipv46.c## + void *aptr, size_t alen, int family, int port, int flags)## 7 ##src/libgai/gn_ipv46.c## +{## 8 ##src/libgai/gn_ipv46.c## + char *ptr;## 9 ##src/libgai/gn_ipv46.c## + struct hostent *hptr;## 10 ##src/libgai/gn_ipv46.c## + struct servent *sptr;## 11 ##src/libgai/gn_ipv46.c## + + if (hostlen > 0) {## 12 ##src/libgai/gn_ipv46.c## + if (flags & NI_NUMERICHOST) {## 13 ##src/libgai/gn_ipv46.c## + if (inet_ntop(family, aptr, host, hostlen) == NULL)## 14 ##src/libgai/gn_ipv46.c## + return (1);## 15 ##src/libgai/gn_ipv46.c## + } else {## 16 ##src/libgai/gn_ipv46.c## + hptr = gethostbyaddr(aptr, alen, family);## 17 ##src/libgai/gn_ipv46.c## + if (hptr != NULL && hptr->h_name != NULL) {## 18 ##src/libgai/gn_ipv46.c## + if (flags & NI_NOFQDN) {## 19 ##src/libgai/gn_ipv46.c## + if ((ptr = strchr(hptr->h_name, '.')) != NULL)## 20 ##src/libgai/gn_ipv46.c## + *ptr = 0; /* overwrite first dot */## 21 ##src/libgai/gn_ipv46.c## + }## 22 ##src/libgai/gn_ipv46.c## + snprintf(host, hostlen, "%s", hptr->h_name);## 23 ##src/libgai/gn_ipv46.c## + } else {## 24 ##src/libgai/gn_ipv46.c## + if (flags & NI_NAMEREQD)## 25 ##src/libgai/gn_ipv46.c## + return (1);## 26 ##src/libgai/gn_ipv46.c## + if (inet_ntop(family, aptr, host, hostlen) == NULL)## 27 ##src/libgai/gn_ipv46.c## + return (1);## 28 ##src/libgai/gn_ipv46.c## + }## 29 ##src/libgai/gn_ipv46.c## + }## 30 ##src/libgai/gn_ipv46.c## + }## 31 ##src/libgai/gn_ipv46.c## + + if (servlen > 0) {## 32 ##src/libgai/gn_ipv46.c## + if (flags & NI_NUMERICSERV) {## 33 ##src/libgai/gn_ipv46.c## + snprintf(serv, servlen, "%d", ntohs(port));## 34 ##src/libgai/gn_ipv46.c## + } else {## 35 ##src/libgai/gn_ipv46.c## + sptr = getservbyport(port, (flags & NI_DGRAM) ? "udp" : NULL);## 36 ##src/libgai/gn_ipv46.c## + if (sptr != NULL && sptr->s_name != NULL)## 37 ##src/libgai/gn_ipv46.c## + snprintf(serv, servlen, "%s", sptr->s_name);## 38 ##src/libgai/gn_ipv46.c## + else## 39 ##src/libgai/gn_ipv46.c## + snprintf(serv, servlen, "%d", ntohs(port));## 40 ##src/libgai/gn_ipv46.c## + }## 41 ##src/libgai/gn_ipv46.c## + }## 42 ##src/libgai/gn_ipv46.c## + return (0);## 43 ##src/libgai/gn_ipv46.c## +}## 44 ##src/libgai/gn_ipv46.c## +/* end gn_ipv46 */ diff --git a/libgai/old/ga_unixstruct.c b/libgai/old/ga_unixstruct.c new file mode 100644 index 0000000..7b06c9d --- /dev/null +++ b/libgai/old/ga_unixstruct.c @@ -0,0 +1,36 @@ +#include "gai_hdr.h" + +#ifdef UNIXDOMAIN +int +ga_unixstruct(const char *path, struct addrinfo *hintsp, + struct addrinfo **result, int socktype) +{ + struct addrinfo *ai; + struct sockaddr_un *unp; + + if ( (ai = calloc(1, sizeof(struct addrinfo))) == NULL) + return(EAI_MEMORY); + + ai->ai_flags = 0; + ai->ai_family = AF_LOCAL; + ai->ai_socktype = socktype; + ai->ai_protocol = 0; + + /* allocate and fill in a socket address structure */ + ai->ai_addrlen = sizeof(struct sockaddr_un); + if ( (ai->ai_addr = malloc(ai->ai_addrlen)) == NULL) + return(EAI_MEMORY); + unp = (struct sockaddr_un *) ai->ai_addr; + unp->sun_family = AF_UNIX; + strncpy(unp->sun_path, path, sizeof(unp->sun_path)); + + ai->ai_canonname = NULL; + ai->ai_next = NULL; + *result = ai; + + if (hintsp->ai_flags & AI_PASSIVE) + unlink(path); /* OK if this fails */ + + return(0); /* success */ +} +#endif /* UNIXDOMAIN */ diff --git a/libgai/old/savecopy.c b/libgai/old/savecopy.c new file mode 100644 index 0000000..13c9e5d --- /dev/null +++ b/libgai/old/savecopy.c @@ -0,0 +1,582 @@ +#include "unp.h" +#include /* isxdigit(), etc. */ +#include +#include /* res_init, _res */ + + /* following internal flag cannot overlap with other AI_xxx flags */ +#define AI_CLONE 4 /* clone this entry for other socket types */ + +struct search { + const char *host; /* hostname of address string */ + int family; /* AF_xxx */ +}; + + /* function prototypes for our own internal functions */ +static int ga_echeck(const char *, const char *, const struct addrinfo *); +static int ga_nsearch(const char *, const struct addrinfo *, + struct search *); +static int ga_aistruct(struct addrinfo ***, const struct addrinfo *, + void *, int); +static int ga_serv(struct addrinfo *, const struct addrinfo *, const char *); +static int ga_port(struct addrinfo *, int , int); +static int ga_unix(const char *, struct addrinfo *, struct addrinfo **); +static struct addrinfo *ga_clone(struct addrinfo *); + + /* globals for all functions in this file; these *must* be + read-only if this function is to be reentrant */ +static struct addrinfo hints_default; + +int +getaddrinfo(const char *hostname, const char *servname, + const struct addrinfo *hintsp, struct addrinfo **result) +{ + int rc, error, nsearch; + char **ap; + struct hostent *hptr; + struct search search[3], *sptr; + struct addrinfo hints, *ai, *aihead, **aipnext; + + /* + * If we encounter an error we want to free() any dynamic memory + * that we've allocated. This is our hack to simplify the code. + */ +#define error(e) { error = (e); goto bad; } + + if (hintsp == NULL) { + hints = hints_default; /* struct copy */ + hints.ai_family = AF_UNSPEC; + } else + hints = *hintsp; /* struct copy */ + + /* 4first some basic error checking */ + if ( (rc = ga_echeck(hostname, servname, &hints)) != 0) + error(rc); + +#ifdef UNIXDOMAIN + /* + * Special case Unix domain first; + * remainder of function for IPv4/IPv6. + */ + if (hostname != NULL && hostname[0] == '/' && + (servname == NULL || servname[0] == '\0')) + return(ga_unix(hostname, &hints, result)); + + if (servname != NULL && servname[0] == '/' && + (hostname == NULL || hostname[0] == '\0')) + return(ga_unix(servname, &hints, result)); +#endif + + nsearch = ga_nsearch(hostname, &hints, &search[0]); + + aihead = NULL; + aipnext = &aihead; + for (sptr = &search[0]; sptr < &search[nsearch]; sptr++) { +#ifdef IPV4 + /* 4check for an IPv4 dotted-decimal string */ + if (isdigit(sptr->host[0])) { + struct in_addr inaddr; + + if (inet_pton(AF_INET, sptr->host, &inaddr) == 1) { + rc = ga_aistruct(&aipnext, &hints, &inaddr, AF_INET); + if (rc != 0) + error(rc); + continue; + } + } +#endif + +#ifdef IPV6 + /* 4check for an IPv6 hex string */ + if (isxdigit(sptr->host[0]) || sptr->host[0] == ':') { + struct in6_addr in6addr; + + if (inet_pton(AF_INET6, sptr->host, &in6addr) == 1) { + rc = ga_aistruct(&aipnext, &hints, &in6addr, AF_INET6); + if (rc != 0) + error(rc); + continue; + } + } +#endif + /* 4look up hostname */ + if ((_res.options & RES_INIT) == 0) + res_init(); /* need this to set _res.options */ + + if (nsearch == 2) + hptr = gethostbyname2(sptr->host, sptr->family); + else { +#ifdef IPV6 + if (sptr->family == AF_INET6) + _res.options |= RES_USE_INET6; + else + _res.options &= ~RES_USE_INET6; +#endif + hptr = gethostbyname(sptr->host); + } + if (hptr == NULL) { + switch (h_errno) { + case HOST_NOT_FOUND: error(EAI_NONAME); + case TRY_AGAIN: error(EAI_AGAIN); + case NO_RECOVERY: error(EAI_FAIL); + case NO_DATA: error(EAI_NODATA); + default: error(EAI_NONAME); + } + } + + /* 4check for address family mismatch if one specified */ + if (hints.ai_family != AF_UNSPEC && hints.ai_family != hptr->h_addrtype) + error(EAI_ADDRFAMILY); + + /* 4create one addrinfo{} for each returned address */ + for (ap = hptr->h_addr_list; *ap != NULL; ap++) { + if ( (ai = calloc(1, sizeof(struct addrinfo))) == NULL) + error(EAI_MEMORY); + *aipnext = ai; + aipnext = &ai->ai_next; + rc = ga_aistruct(&aipnext, &hints, *ap, hptr->h_addrtype); + if (rc != 0) + error(rc); + } + } + /* "aihead" points to the first structure in the linked list */ + + if (hostname != NULL && hostname[0] != '\0' && + hints.ai_flags & AI_CANONNAME) { + aihead->ai_canonname = strdup(hptr->h_name != NULL ? + hptr->h_name : search[0].host); + if (aihead->ai_canonname == NULL) + error(EAI_MEMORY); + } + + /* 4now process the service name */ + if (servname != NULL && servname[0] != '\0') { + if ( (rc = ga_serv(aihead, &hints, servname)) != 0) + error(rc); + } + + *result = aihead; /* pointer to first structure in linked list */ + return(0); + +bad: + freeaddrinfo(aihead); /* free any alloc'ed memory */ + return(error); +} + +/* + * Basic error checking at the beginning. + */ + +static int +ga_echeck(const char *hostname, const char *servname, + const struct addrinfo *hintsp) +{ + if (hintsp->ai_flags & ~(AI_PASSIVE | AI_CANONNAME)) + return(EAI_BADFLAGS); /* unknown flag bits */ + + if (hostname == NULL || hostname[0] == '\0') { + if (servname == NULL || servname[0] == '\0') + return(EAI_NONAME); /* host or service must be specified */ + } + + switch(hintsp->ai_family) { + case AF_UNSPEC: + break; +#ifdef IPV4 + case AF_INET: + if (hintsp->ai_socktype != 0 && + (hintsp->ai_socktype != SOCK_STREAM && + hintsp->ai_socktype != SOCK_DGRAM && + hintsp->ai_socktype != SOCK_RAW)) + return(EAI_SOCKTYPE); /* invalid socket type */ + break; +#endif +#ifdef IPV6 + case AF_INET6: + if (hintsp->ai_socktype != 0 && + (hintsp->ai_socktype != SOCK_STREAM && + hintsp->ai_socktype != SOCK_DGRAM && + hintsp->ai_socktype != SOCK_RAW)) + return(EAI_SOCKTYPE); /* invalid socket type */ + break; +#endif +#ifdef UNIXDOMAIN + case AF_LOCAL: + if (hintsp->ai_socktype != 0 && + (hintsp->ai_socktype != SOCK_STREAM && + hintsp->ai_socktype != SOCK_DGRAM)) + return(EAI_SOCKTYPE); /* invalid socket type */ + break; +#endif + default: + return(EAI_FAMILY); /* unknown protocol family */ + } + return(0); +} + +/* + * Set up the search[] array with the hostnames and address families + * that we are to look up. + */ + +static int +ga_nsearch(const char *hostname, const struct addrinfo *hintsp, + struct search *search) +{ + int nsearch = 0; + + if (hostname == NULL || hostname[0] == '\0') { + if (hintsp->ai_flags & AI_PASSIVE) { + /* 4no hostname and AI_PASSIVE: implies wildcard bind */ + switch (hintsp->ai_family) { +#ifdef IPV4 + case AF_INET: + search[nsearch].host = "0.0.0.0"; + search[nsearch].family = AF_INET; + nsearch++; + break; +#endif +#ifdef IPV6 + case AF_INET6: + search[nsearch].host = "0::0"; + search[nsearch].family = AF_INET6; + nsearch++; + break; +#endif + case AF_UNSPEC: +#ifdef IPV6 + search[nsearch].host = "0::0"; /* IPv6 first, then IPv4 */ + search[nsearch].family = AF_INET6; + nsearch++; +#endif +#ifdef IPV4 + search[nsearch].host = "0.0.0.0"; + search[nsearch].family = AF_INET; + nsearch++; +#endif + break; + } + } else { + /* 4no host and not AI_PASSIVE: connect to local host */ + switch (hintsp->ai_family) { +#ifdef IPV4 + case AF_INET: + search[nsearch].host = "localhost"; /* 127.0.0.1 */ + search[nsearch].family = AF_INET; + nsearch++; + break; +#endif +#ifdef IPV6 + case AF_INET6: + search[nsearch].host = "0::1"; + search[nsearch].family = AF_INET6; + nsearch++; + break; +#endif + case AF_UNSPEC: +#ifdef IPV6 + search[nsearch].host = "0::1"; /* IPv6 first, then IPv4 */ + search[nsearch].family = AF_INET6; + nsearch++; +#endif +#ifdef IPV4 + search[nsearch].host = "localhost"; + search[nsearch].family = AF_INET; + nsearch++; +#endif + break; + } + } + } else { /* host is specified */ + switch (hintsp->ai_family) { +#ifdef IPV4 + case AF_INET: + search[nsearch].host = hostname; + search[nsearch].family = AF_INET; + nsearch++; + break; +#endif +#ifdef IPV6 + case AF_INET6: + search[nsearch].host = hostname; + search[nsearch].family = AF_INET6; + nsearch++; + break; +#endif + case AF_UNSPEC: +#ifdef IPV6 + search[nsearch].host = hostname; + search[nsearch].family = AF_INET6; /* IPv6 first */ + nsearch++; +#endif +#ifdef IPV4 + search[nsearch].host = hostname; + search[nsearch].family = AF_INET; /* then IPv4 */ + nsearch++; +#endif + break; + } + } + if (nsearch < 1 || nsearch > 2) + err_quit("nsearch = %d", nsearch); + return(nsearch); +} + +/* + * Create and fill in a addrinfo{}. + */ + +static int +ga_aistruct(struct addrinfo ***paipnext, const struct addrinfo *hintsp, + void *addr, int family) +{ + struct addrinfo *ai; + + if ( (ai = calloc(1, sizeof(struct addrinfo))) == NULL) + return(EAI_MEMORY); + ai->ai_next = NULL; + ai->ai_canonname = NULL; + **paipnext = ai; + *paipnext = &ai->ai_next; + + if ( (ai->ai_socktype = hintsp->ai_socktype) == 0) + ai->ai_flags |= AI_CLONE; + + ai->ai_protocol = hintsp->ai_protocol; + + switch ((ai->ai_family = family)) { +#ifdef IPV4 + case AF_INET: { + struct sockaddr_in *sinptr; + + /* 4allocate sockaddr_in{} and fill in all but port */ + if ( (sinptr = calloc(1, sizeof(struct sockaddr_in))) == NULL) + return(EAI_MEMORY); +#ifdef HAVE_SOCKADDR_SA_LEN + sinptr->sin_len = sizeof(struct sockaddr_in); +#endif + sinptr->sin_family = AF_INET; + memcpy(&sinptr->sin_addr, addr, sizeof(struct in_addr)); + ai->ai_addr = (struct sockaddr *) sinptr; + ai->ai_addrlen = sizeof(struct sockaddr_in); + break; + } +#endif /* IPV4 */ + +#ifdef IPV6 + /* 4allocate sockaddr_in6{} and fill in all but port */ + case AF_INET6: { + struct sockaddr_in6 *sin6ptr; + + if ( (sin6ptr = calloc(1, sizeof(struct sockaddr_in6))) == NULL) + return(EAI_MEMORY); +#ifdef HAVE_SOCKADDR_SA_LEN + sin6ptr->sin6_len = sizeof(struct sockaddr_in6); +#endif + sin6ptr->sin6_family = AF_INET6; + memcpy(&sin6ptr->sin6_addr, addr, sizeof(struct in6_addr)); + ai->ai_addr = (struct sockaddr *) sin6ptr; + ai->ai_addrlen = sizeof(struct sockaddr_in6); + break; + } +#endif /* IPV6 */ + } + return(0); +} + +/* + * This function handles the service string. + */ + +static int +ga_serv(struct addrinfo *aihead, const struct addrinfo *hintsp, + const char *serv) +{ + int port, rc, nfound; + struct servent *sptr; + + /* 4check for port number first */ + if (isdigit(serv[0]) && hintsp->ai_socktype != 0) { + port = htons(atoi(serv)); + if ( (rc = ga_port(aihead, port, hintsp->ai_socktype)) == 0) + return(EAI_NONAME); + else if (rc < 0) + return(EAI_MEMORY); + else + return(0); + } + + /* 4try TCP first */ + nfound = 0; + if (hintsp->ai_socktype == 0 || hintsp->ai_socktype == SOCK_STREAM) { + if ( (sptr = getservbyname(serv, "tcp")) != NULL) { + if ( (rc = ga_port(aihead, sptr->s_port, SOCK_STREAM)) < 0) + return(EAI_MEMORY); + nfound += rc; + } + } + + /* 4try UDP */ + if (hintsp->ai_socktype == 0 || hintsp->ai_socktype == SOCK_DGRAM) { + if ( (sptr = getservbyname(serv, "udp")) != NULL) { + if ( (rc = ga_port(aihead, sptr->s_port, SOCK_DGRAM)) < 0) + return(EAI_MEMORY); + nfound += rc; + } + } + + if (nfound == 0) { + if (hintsp->ai_socktype == 0) + return(EAI_NONAME); /* all calls to getservbyname() failed */ + else + return(EAI_SERVICE);/* service not supported for socket type */ + } + return(0); +} + +/* + * Go through all the addrinfo structures, checking for a match of the + * socket type and filling in the socket type, and then the port number + * in the corresponding socket address structures. + * + * The AI_CLONE flag works as follows. Consider a multihomed host with + * two IP addresses and no socket type specified by the caller. After + * the "host" search there are two addrinfo structures, one per IP address. + * Assuming a service supported by both TCP and UDP (say the daytime + * service) we need to return *four* addrinfo structures: + * IP#1, SOCK_STREAM, TCP port, + * IP#1, SOCK_DGRAM, UDP port, + * IP#2, SOCK_STREAM, TCP port, + * IP#2, SOCK_DGRAM, UDP port. + * To do this, when the "host" loop creates an addrinfo structure, if the + * caller has not specified a socket type (hintsp->ai_socktype == 0), the + * AI_CLONE flag is set. When the following function finds an entry like + * this it is handled as follows: If the entry's ai_socktype is still 0, + * this is the first use of the structure, and the ai_socktype field is set. + * But, if the entry's ai_socktype is nonzero, then we clone a new addrinfo + * structure and set it's ai_socktype to the new value. Although we only + * need two socket types today (SOCK_STREAM and SOCK_DGRAM) this algorithm + * will handle any number. Also notice that Posix.1g requires all socket + * types to be nonzero. + */ + +static int +ga_port(struct addrinfo *aihead, int port, int socktype) + /* port must be in network byte order */ +{ + int nfound = 0; + struct addrinfo *ai; + + for (ai = aihead; ai != NULL; ai = ai->ai_next) { + if (ai->ai_flags & AI_CLONE) { + if (ai->ai_socktype != 0) { + if ( (ai = ga_clone(ai)) == NULL) + return(-1); /* memory allocation error */ + /* ai points to newly cloned entry, which is what we want */ + } + } else if (ai->ai_socktype != socktype) + continue; /* ignore if mismatch on socket type */ + + ai->ai_socktype = socktype; + + switch (ai->ai_family) { +#ifdef IPV4 + case AF_INET: + ((struct sockaddr_in *) ai->ai_addr)->sin_port = port; + nfound++; + break; +#endif +#ifdef IPV6 + case AF_INET6: + ((struct sockaddr_in6 *) ai->ai_addr)->sin6_port = port; + nfound++; + break; +#endif + } + } + return(nfound); +} + +/* + * Clone a new addrinfo structure from an existing one. + */ + +static struct addrinfo * +ga_clone(struct addrinfo *ai) +{ + struct addrinfo *new; + + if ( (new = calloc(1, sizeof(struct addrinfo))) == NULL) + return(NULL); + + new->ai_next = ai->ai_next; + ai->ai_next = new; + + new->ai_flags = 0; /* make sure AI_CLONE is off */ + new->ai_family = ai->ai_family; + new->ai_socktype = ai->ai_socktype; + new->ai_protocol = ai->ai_protocol; + new->ai_canonname = NULL; + new->ai_addrlen = ai->ai_addrlen; + if ( (new->ai_addr = malloc(ai->ai_addrlen)) == NULL) + return(NULL); + memcpy(new->ai_addr, ai->ai_addr, ai->ai_addrlen); + + return(new); +} + +#ifdef UNIXDOMAIN +/* + * Do everything for a Unix domain socket. + * Only one addrinfo{} is returned. + */ + +static int +ga_unix(const char *path, struct addrinfo *hintsp, struct addrinfo **result) +{ + struct addrinfo *ai; + struct sockaddr_un *unp; + + if (hintsp->ai_socktype == 0) + return(EAI_SOCKTYPE); /* we cannot tell socket type from service */ + + if ( (ai = calloc(1, sizeof(struct addrinfo))) == NULL) + return(NULL); + + ai->ai_flags = 0; + ai->ai_family = AF_LOCAL; + ai->ai_socktype = hintsp->ai_socktype; + ai->ai_protocol = 0; + + /* allocate and fill in a socket address structure */ + ai->ai_addrlen = sizeof(struct sockaddr_un); + if ( (ai->ai_addr = malloc(ai->ai_addrlen)) == NULL) + return(EAI_MEMORY); + unp = (struct sockaddr_un *) ai->ai_addr; + unp->sun_family = AF_UNIX; + strncpy(unp->sun_path, path, sizeof(unp->sun_path)); + + ai->ai_canonname = NULL; /* maybe return the i-node number :-) */ + ai->ai_next = NULL; + *result = ai; + + if (hintsp->ai_flags & AI_PASSIVE) + unlink(path); /* OK if this fails */ + + return(0); /* success */ +} +#endif /* UNIXDOMAIN */ + +void +freeaddrinfo(struct addrinfo *aihead) +{ + struct addrinfo *ai, *ainext; + + for (ai = aihead; ai != NULL; ai = ainext) { + if (ai->ai_addr != NULL) + free(ai->ai_addr); /* the socket address structure */ + if (ai->ai_canonname != NULL) + free(ai->ai_canonname); /* the canonical name */ + ainext = ai->ai_next; /* can't fetch ai_next after free() */ + free(ai); /* the addrinfo{} itself */ + } +} diff --git a/libgai/test1.c b/libgai/test1.c new file mode 100644 index 0000000..8d35c55 --- /dev/null +++ b/libgai/test1.c @@ -0,0 +1,28 @@ +#include "unp.h" + +/* + * See that gethostbyname2() with an address string as the first argument + * is broken in BIND-8.1-REL. + * gethostbyname2("127.0.0.1", AF_INET6) -> OK! + */ + +int +main(int argc, char **argv) +{ + struct hostent *hptr; + + if (argc != 2) + err_quit("usage: test2 "); + + printf("gethostbyname2(%s, AF_INET): ", argv[1]); + hptr = gethostbyname2(argv[1], AF_INET); + printf("%s\n", (hptr == NULL) ? "failed" : "OK"); + +#ifdef IPv6 + printf("gethostbyname2(%s, AF_INET6): ", argv[1]); + hptr = gethostbyname2(argv[1], AF_INET6); + printf("%s\n", (hptr == NULL) ? "failed" : "OK"); +#endif + + exit(0); +} diff --git a/libgai/testga.c b/libgai/testga.c new file mode 100644 index 0000000..b363f67 --- /dev/null +++ b/libgai/testga.c @@ -0,0 +1,357 @@ +#include "unp.h" + +/* + * Test program for getaddrinfo() and getnameinfo(). + */ + + /* function prototypes for internal functions */ +static void do_errtest(void); +static void do_funccall(const char *, const char *, int, int, int, int, int); +static int do_onetest(char *, char *, struct addrinfo *, int); +static const char *str_fam(int); +static const char *str_sock(int); +static void usage(const char *); + + /* globals */ +int vflag; + +int +main(int argc, char **argv) +{ + int doerrtest = 0; + int loopcount = 1; + int c, i; + char *host = NULL; + char hostbuf[NI_MAXHOST]; + char *serv = NULL; + char servbuf[NI_MAXSERV]; + struct protoent *proto; + struct addrinfo hints; /* set by command-line options */ + + if (argc < 2) + usage(""); + + memset(&hints, 0, sizeof(struct addrinfo)); + + opterr = 0; /* don't want getopt() writing to stderr */ + while ( (c = getopt(argc, argv, "cef:h:l:pr:s:t:v")) != -1) { + switch (c) { + case 'c': + hints.ai_flags |= AI_CANONNAME; + break; + + case 'e': + doerrtest = 1; + break; + + case 'f': /* address family */ +#ifdef IPv4 + if (strcmp(optarg, "inet") == 0) { + hints.ai_family = AF_INET; + break; + } +#endif +#ifdef IPv6 + if (strcmp(optarg, "inet6") == 0) { + hints.ai_family = AF_INET6; + break; + } +#endif +#ifdef UNIXdomain + if (strcmp(optarg, "unix") == 0) { + hints.ai_family = AF_LOCAL; + break; + } +#endif + usage("invalid -f option"); + + case 'h': /* host */ + strncpy(hostbuf, optarg, NI_MAXHOST-1); + host = hostbuf; + break; + + case 'l': /* loop count */ + loopcount = atoi(optarg); + break; + + case 'p': + hints.ai_flags |= AI_PASSIVE; + break; + + case 'r': /* protocol */ + if ((proto = getprotobyname(optarg)) == NULL) { + hints.ai_protocol = atoi(optarg); + } else { + hints.ai_protocol = proto->p_proto; + } + break; + + case 's': + strncpy(servbuf, optarg, NI_MAXSERV-1); + serv = servbuf; + break; + + case 't': /* socket type */ + if (strcmp(optarg, "stream") == 0) { + hints.ai_socktype = SOCK_STREAM; + break; + } + + if (strcmp(optarg, "dgram") == 0) { + hints.ai_socktype = SOCK_DGRAM; + break; + } + + if (strcmp(optarg, "raw") == 0) { + hints.ai_socktype = SOCK_RAW; + break; + } + +#ifdef SOCK_RDM + if (strcmp(optarg, "rdm") == 0) { + hints.ai_socktype = SOCK_RDM; + break; + } +#endif + +#ifdef SOCK_SEQPACKET + if (strcmp(optarg, "seqpacket") == 0) { + hints.ai_socktype = SOCK_SEQPACKET; + break; + } +#endif + usage("invalid -t option"); + + case 'v': + vflag = 1; + break; + + case '?': + usage("unrecognized option"); + } + } + if (optind < argc) { + usage("extra args"); + } + + if (doerrtest) { + do_errtest(); + exit(0); + } + + for (i = 1; i <= loopcount; i++) { + if (do_onetest(host, serv, &hints, i) > 0) + exit(1); + + if (i % 1000 == 0) { + printf(" %d", i); + fflush(stdout); + } + } + + exit(0); +} + +/* + * Check that the right error codes are returned for invalid input. + * Test all the errors that are easy to test for. + */ + +static void +do_errtest(void) +{ + /* passive open with no hostname and no address family */ + do_funccall(NULL, "ftp", AI_PASSIVE, 0, 0, 0, 0); + + /* kind of hard to automatically test EAI_AGAIN ??? */ + + /* invalid flags */ + do_funccall("localhost", NULL, 999999, 0, 0, 0, EAI_BADFLAGS); + + /* how to test EAI_FAIL ??? */ + + /* invalid address family */ + do_funccall("localhost", NULL, 0, AF_SNA, 0, 0, EAI_FAMILY); + + /* hard to test for EAI_MEMORY: would have to malloc() until + failure, then give some back, then call getaddrinfo and + hope that its memory requests would not be satisfied. */ + + /* to test for EAI_NODATA: would have to know of a host with + no A record in the DNS */ + +#ifdef notdef /* following depends on resolver, sigh */ + /* believe it or not, there is a registered domain "bar.com", + so the following should generate NO_DATA from the DNS */ + do_funccall("foo.bar.foo.bar.foo.bar.com", NULL, 0, 0, 0, 0, EAI_NODATA); +#endif + + /* no hostname, no service name */ + do_funccall(NULL, NULL, 0, 0, 0, 0, EAI_NONAME); + + /* invalid hostname (should be interpreted in local default domain) */ + do_funccall("lkjjkhjhghgfgfd", NULL, 0, 0, 0, 0, EAI_NONAME); + + /* invalid service name */ + do_funccall(NULL, "nosuchservice", 0, 0, 0, 0, EAI_NONAME); + + /* service valid but not supported for socket type */ + do_funccall("localhost", "telnet", 0, 0, SOCK_DGRAM, 0, EAI_SERVICE); + + /* service valid but not supported for socket type */ + do_funccall("localhost", "tftp", 0, 0, SOCK_STREAM, 0, EAI_SERVICE); + + /* invalid socket type */ + do_funccall("localhost", NULL, 0, AF_INET, SOCK_SEQPACKET, 0, EAI_SOCKTYPE); + + /* EAI_SYSTEM not generated by my implementation */ +} + +static void +do_funccall(const char *host, const char *serv, + int flags, int family, int socktype, int protocol, int exprc) +{ + int rc; + struct addrinfo hints, *res; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_flags = flags; + hints.ai_family = family; + hints.ai_socktype = socktype; + hints.ai_protocol = protocol; + + rc = getaddrinfo(host, serv, &hints, &res); + if (rc != exprc) { + printf("expected return = %d (%s),\nactual return = %d (%s)\n", + exprc, gai_strerror(exprc), rc, gai_strerror(rc)); + if (host != NULL) + printf(" host = %s\n", host); + if (serv != NULL) + printf(" serv = %s\n", serv); + printf(" flags = %d, family = %s, socktype = %s, protocol = %d\n", + flags, str_fam(family), str_sock(socktype), protocol); + exit(2); + } +} + +static int +do_onetest(char *host, char *serv, struct addrinfo *hints, int iteration) +{ + int rc, fd, verbose; + struct addrinfo *res, *rescopy; + char rhost[NI_MAXHOST], rserv[NI_MAXSERV]; + + verbose = vflag && (iteration == 1); /* only first time */ + + if (host != NULL && verbose) + printf("host = %s\n", host); + if (serv != NULL && verbose) + printf("serv = %s\n", serv); + + rc = getaddrinfo(host, serv, hints, &res); + if (rc != 0) { + printf("getaddrinfo return code = %d (%s)\n", rc, gai_strerror(rc)); + return(1); + } + + rescopy = res; + do { + if (iteration == 1) { /* always print results first time */ + printf("\nsocket(%s, %s, %d)", str_fam(res->ai_family), + str_sock(res->ai_socktype), res->ai_protocol); + + /* canonname should be set only in first addrinfo{} */ + if (hints->ai_flags & AI_CANONNAME) { + if (res->ai_canonname) + printf(", ai_canonname = %s", res->ai_canonname); + } + printf("\n"); + + printf("\taddress: %s\n", + Sock_ntop(res->ai_addr, res->ai_addrlen)); + } + + /* Call socket() to make sure return values are valid */ + fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (fd < 0) + printf("call to socket() failed!\n"); + else + close(fd); + + /* + * Call getnameinfo() to check the reverse mapping. + */ + + rc = getnameinfo(res->ai_addr, res->ai_addrlen, + rhost, NI_MAXHOST, rserv, NI_MAXSERV, + (res->ai_socktype == SOCK_DGRAM) ? NI_DGRAM: 0); + if (rc == 0) { + if (verbose) + printf("\tgetnameinfo: host = %s, serv = %s\n", + rhost, rserv); + } else + printf("getnameinfo returned %d (%s)\n", rc, gai_strerror(rc)); + + } while ( (res = res->ai_next) != NULL); + + freeaddrinfo(rescopy); + return(0); +} + +static void +usage(const char *msg) +{ + printf( +"usage: testaddrinfo [ options ]\n" +"options: -h (can be hostname or address string)\n" +" -s (can be service name or decimal port number)\n" +" -c AI_CANONICAL flag\n" +" -p AI_PASSIVE flag\n" +" -l N loop N times (check for memory leaks with ps)\n" +" -f X address family, X = inet, inet6, unix\n" +" -r X protocol, X = tcp, udp, ... or number e.g. 6, 17, ...\n" +" -t X socket type, X = stream, dgram, raw, rdm, seqpacket\n" +" -v verbose\n" +" -e only do test of error returns (no options required)\n" +" without -e, one or both of and must be specified.\n" +); + + if (msg[0] != 0) + printf("%s\n", msg); + exit(1); +} + +static const char * +str_fam(int family) +{ +#ifdef IPv4 + if (family == AF_INET) + return("AF_INET"); +#endif +#ifdef IPv6 + if (family == AF_INET6) + return("AF_INET6"); +#endif +#ifdef UNIXdomain + if (family == AF_LOCAL) + return("AF_LOCAL"); +#endif + return(""); +} + +static const char * +str_sock(int socktype) +{ + switch(socktype) { + case SOCK_STREAM: return "SOCK_STREAM"; + case SOCK_DGRAM: return "SOCK_DGRAM"; + case SOCK_RAW: return "SOCK_RAW"; +#ifdef SOCK_RDM + case SOCK_RDM: return "SOCK_RDM"; +#endif +#ifdef SOCK_SEQPACKET + case SOCK_SEQPACKET:return "SOCK_SEQPACKET"; +#endif + default: return ""; + } +} diff --git a/libroute/Makefile b/libroute/Makefile new file mode 100644 index 0000000..d5b5220 --- /dev/null +++ b/libroute/Makefile @@ -0,0 +1,8 @@ +include ../Make.defines + +all: ${LIBROUTE_OBJS} + ar rv ${LIBUNP_NAME} $? + ${RANLIB} ${LIBUNP_NAME} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/libroute/get_rtaddrs.c b/libroute/get_rtaddrs.c new file mode 100644 index 0000000..203fefe --- /dev/null +++ b/libroute/get_rtaddrs.c @@ -0,0 +1,28 @@ +#include "unproute.h" + +/* + * Round up 'a' to next multiple of 'size', which must be a power of 2 + */ +#define ROUNDUP(a, size) (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a)) + +/* + * Step to next socket address structure; + * if sa_len is 0, assume it is sizeof(u_long). + */ +#define NEXT_SA(ap) ap = (SA *) \ + ((caddr_t) ap + (ap->sa_len ? ROUNDUP(ap->sa_len, sizeof (u_long)) : \ + sizeof(u_long))) + +void +get_rtaddrs(int addrs, SA *sa, SA **rti_info) +{ + int i; + + for (i = 0; i < RTAX_MAX; i++) { + if (addrs & (1 << i)) { + rti_info[i] = sa; + NEXT_SA(sa); + } else + rti_info[i] = NULL; + } +} diff --git a/libroute/get_rtaddrs.lc b/libroute/get_rtaddrs.lc new file mode 100644 index 0000000..54e5d87 --- /dev/null +++ b/libroute/get_rtaddrs.lc @@ -0,0 +1,28 @@ +#include "unproute.h"## 1 ##src/libroute/get_rtaddrs.c## + +/*## 2 ##src/libroute/get_rtaddrs.c## + * Round up 'a' to next multiple of 'size'## 3 ##src/libroute/get_rtaddrs.c## + */## 4 ##src/libroute/get_rtaddrs.c## +#define ROUNDUP(a, size) (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))## 5 ##src/libroute/get_rtaddrs.c## + +/*## 6 ##src/libroute/get_rtaddrs.c## + * Step to next socket address structure;## 7 ##src/libroute/get_rtaddrs.c## + * if sa_len is 0, assume it is sizeof(u_long).## 8 ##src/libroute/get_rtaddrs.c## + */## 9 ##src/libroute/get_rtaddrs.c## +#define NEXT_SA(ap) ap = (SA *) \## 10 ##src/libroute/get_rtaddrs.c## + ((caddr_t) ap + (ap->sa_len ? ROUNDUP(ap->sa_len, sizeof (u_long)) : \## 11 ##src/libroute/get_rtaddrs.c## + sizeof(u_long)))## 12 ##src/libroute/get_rtaddrs.c## + +void## 13 ##src/libroute/get_rtaddrs.c## +get_rtaddrs(int addrs, SA *sa, SA **rti_info)## 14 ##src/libroute/get_rtaddrs.c## +{## 15 ##src/libroute/get_rtaddrs.c## + int i;## 16 ##src/libroute/get_rtaddrs.c## + + for (i = 0; i < RTAX_MAX; i++) {## 17 ##src/libroute/get_rtaddrs.c## + if (addrs & (1 << i)) {## 18 ##src/libroute/get_rtaddrs.c## + rti_info[i] = sa;## 19 ##src/libroute/get_rtaddrs.c## + NEXT_SA(sa);## 20 ##src/libroute/get_rtaddrs.c## + } else## 21 ##src/libroute/get_rtaddrs.c## + rti_info[i] = NULL;## 22 ##src/libroute/get_rtaddrs.c## + }## 23 ##src/libroute/get_rtaddrs.c## +}## 24 ##src/libroute/get_rtaddrs.c## diff --git a/libroute/if_indextoname.c b/libroute/if_indextoname.c new file mode 100644 index 0000000..357c11b --- /dev/null +++ b/libroute/if_indextoname.c @@ -0,0 +1,51 @@ +/* include if_indextoname */ +#include "unpifi.h" +#include "unproute.h" + +char * +if_indextoname(unsigned int idx, char *name) +{ + char *buf, *next, *lim; + size_t len; + struct if_msghdr *ifm; + struct sockaddr *sa, *rti_info[RTAX_MAX]; + struct sockaddr_dl *sdl; + + if ( (buf = net_rt_iflist(0, idx, &len)) == NULL) + return(NULL); + + lim = buf + len; + for (next = buf; next < lim; next += ifm->ifm_msglen) { + ifm = (struct if_msghdr *) next; + if (ifm->ifm_type == RTM_IFINFO) { + sa = (struct sockaddr *) (ifm + 1); + get_rtaddrs(ifm->ifm_addrs, sa, rti_info); + if ( (sa = rti_info[RTAX_IFP]) != NULL) { + if (sa->sa_family == AF_LINK) { + sdl = (struct sockaddr_dl *) sa; + if (sdl->sdl_index == idx) { + int slen = min(IFNAMSIZ - 1, sdl->sdl_nlen); + strncpy(name, sdl->sdl_data, slen); + name[slen] = 0; /* null terminate */ + free(buf); + return(name); + } + } + } + + } + } + free(buf); + return(NULL); /* no match for index */ +} +/* end if_indextoname */ + +char * +If_indextoname(unsigned int idx, char *name) +{ + char *ptr; + + if ( (ptr = if_indextoname(idx, name)) == NULL) + err_quit("if_indextoname error for %d", idx); + return(ptr); +} diff --git a/libroute/if_indextoname.lc b/libroute/if_indextoname.lc new file mode 100644 index 0000000..1023b26 --- /dev/null +++ b/libroute/if_indextoname.lc @@ -0,0 +1,50 @@ +/* include if_indextoname */ +#include "unpifi.h"## 1 ##src/libroute/if_indextoname.c## +#include "unproute.h"## 2 ##src/libroute/if_indextoname.c## + +char *## 3 ##src/libroute/if_indextoname.c## +if_indextoname(unsigned int index, char *name)## 4 ##src/libroute/if_indextoname.c## +{## 5 ##src/libroute/if_indextoname.c## + char *buf, *next, *lim;## 6 ##src/libroute/if_indextoname.c## + size_t len;## 7 ##src/libroute/if_indextoname.c## + struct if_msghdr *ifm;## 8 ##src/libroute/if_indextoname.c## + struct sockaddr *sa, *rti_info[RTAX_MAX];## 9 ##src/libroute/if_indextoname.c## + struct sockaddr_dl *sdl;## 10 ##src/libroute/if_indextoname.c## + + if ((buf = net_rt_iflist(0, index, &len)) == NULL)## 11 ##src/libroute/if_indextoname.c## + return (NULL);## 12 ##src/libroute/if_indextoname.c## + + lim = buf + len;## 13 ##src/libroute/if_indextoname.c## + for (next = buf; next < lim; next += ifm->ifm_msglen) {## 14 ##src/libroute/if_indextoname.c## + ifm = (struct if_msghdr *) next;## 15 ##src/libroute/if_indextoname.c## + if (ifm->ifm_type == RTM_IFINFO) {## 16 ##src/libroute/if_indextoname.c## + sa = (struct sockaddr *) (ifm + 1);## 17 ##src/libroute/if_indextoname.c## + get_rtaddrs(ifm->ifm_addrs, sa, rti_info);## 18 ##src/libroute/if_indextoname.c## + if ((sa = rti_info[RTAX_IFP]) != NULL) {## 19 ##src/libroute/if_indextoname.c## + if (sa->sa_family == AF_LINK) {## 20 ##src/libroute/if_indextoname.c## + sdl = (struct sockaddr_dl *) sa;## 21 ##src/libroute/if_indextoname.c## + if (sdl->sdl_index == index) {## 22 ##src/libroute/if_indextoname.c## + strncpy(name, sdl->sdl_data, sdl->sdl_nlen);## 23 ##src/libroute/if_indextoname.c## + name[sdl->sdl_nlen] = 0; /* null terminate */## 24 ##src/libroute/if_indextoname.c## + free(buf);## 25 ##src/libroute/if_indextoname.c## + return (name);## 26 ##src/libroute/if_indextoname.c## + }## 27 ##src/libroute/if_indextoname.c## + }## 28 ##src/libroute/if_indextoname.c## + }## 29 ##src/libroute/if_indextoname.c## + + }## 30 ##src/libroute/if_indextoname.c## + }## 31 ##src/libroute/if_indextoname.c## + free(buf);## 32 ##src/libroute/if_indextoname.c## + return (NULL); /* no match for index */## 33 ##src/libroute/if_indextoname.c## +}## 34 ##src/libroute/if_indextoname.c## +/* end if_indextoname */ + +char *## 35 ##src/libroute/if_indextoname.c## +If_indextoname(unsigned int index, char *name)## 36 ##src/libroute/if_indextoname.c## +{## 37 ##src/libroute/if_indextoname.c## + char *ptr;## 38 ##src/libroute/if_indextoname.c## + + if ((ptr = if_indextoname(index, name)) == NULL)## 39 ##src/libroute/if_indextoname.c## + err_quit("if_indextoname error for %d", index);## 40 ##src/libroute/if_indextoname.c## + return (ptr);## 41 ##src/libroute/if_indextoname.c## +}## 42 ##src/libroute/if_indextoname.c## diff --git a/libroute/if_nameindex.c b/libroute/if_nameindex.c new file mode 100644 index 0000000..cf97c96 --- /dev/null +++ b/libroute/if_nameindex.c @@ -0,0 +1,67 @@ +/* include if_nameindex */ +#include "unpifi.h" +#include "unproute.h" + +struct if_nameindex * +if_nameindex(void) +{ + char *buf, *next, *lim; + size_t len; + struct if_msghdr *ifm; + struct sockaddr *sa, *rti_info[RTAX_MAX]; + struct sockaddr_dl *sdl; + struct if_nameindex *result, *ifptr; + char *namptr; + + if ( (buf = net_rt_iflist(0, 0, &len)) == NULL) + return(NULL); + + if ( (result = malloc(len)) == NULL) /* overestimate */ + return(NULL); + ifptr = result; + namptr = (char *) result + len; /* names start at end of buffer */ + + lim = buf + len; + for (next = buf; next < lim; next += ifm->ifm_msglen) { + ifm = (struct if_msghdr *) next; + if (ifm->ifm_type == RTM_IFINFO) { + sa = (struct sockaddr *) (ifm + 1); + get_rtaddrs(ifm->ifm_addrs, sa, rti_info); + if ( (sa = rti_info[RTAX_IFP]) != NULL) { + if (sa->sa_family == AF_LINK) { + sdl = (struct sockaddr_dl *) sa; + namptr -= sdl->sdl_nlen + 1; + strncpy(namptr, &sdl->sdl_data[0], sdl->sdl_nlen); + namptr[sdl->sdl_nlen] = 0; /* null terminate */ + ifptr->if_name = namptr; + ifptr->if_index = sdl->sdl_index; + ifptr++; + } + } + + } + } + ifptr->if_name = NULL; /* mark end of array of structs */ + ifptr->if_index = 0; + free(buf); + return(result); /* caller must free() this when done */ +} +/* end if_nameindex */ + +/* include if_freenameindex */ +void +if_freenameindex(struct if_nameindex *ptr) +{ + free(ptr); +} +/* end if_freenameindex */ + +struct if_nameindex * +If_nameindex(void) +{ + struct if_nameindex *ifptr; + + if ( (ifptr = if_nameindex()) == NULL) + err_quit("if_nameindex error"); + return(ifptr); +} diff --git a/libroute/if_nameindex.lc b/libroute/if_nameindex.lc new file mode 100644 index 0000000..cc1b684 --- /dev/null +++ b/libroute/if_nameindex.lc @@ -0,0 +1,67 @@ +/* include if_nameindex */ +#include "unpifi.h"## 1 ##src/libroute/if_nameindex.c## +#include "unproute.h"## 2 ##src/libroute/if_nameindex.c## + +struct if_nameindex *## 3 ##src/libroute/if_nameindex.c## +if_nameindex(void)## 4 ##src/libroute/if_nameindex.c## +{## 5 ##src/libroute/if_nameindex.c## + char *buf, *next, *lim;## 6 ##src/libroute/if_nameindex.c## + size_t len;## 7 ##src/libroute/if_nameindex.c## + struct if_msghdr *ifm;## 8 ##src/libroute/if_nameindex.c## + struct sockaddr *sa, *rti_info[RTAX_MAX];## 9 ##src/libroute/if_nameindex.c## + struct sockaddr_dl *sdl;## 10 ##src/libroute/if_nameindex.c## + struct if_nameindex *result, *ifptr;## 11 ##src/libroute/if_nameindex.c## + char *namptr;## 12 ##src/libroute/if_nameindex.c## + + if ((buf = net_rt_iflist(0, 0, &len)) == NULL)## 13 ##src/libroute/if_nameindex.c## + return (NULL);## 14 ##src/libroute/if_nameindex.c## + + if ((result = malloc(len)) == NULL) /* overestimate */## 15 ##src/libroute/if_nameindex.c## + return (NULL);## 16 ##src/libroute/if_nameindex.c## + ifptr = result;## 17 ##src/libroute/if_nameindex.c## + namptr = (char *) result + len; /* names start at end of buffer */## 18 ##src/libroute/if_nameindex.c## + + lim = buf + len;## 19 ##src/libroute/if_nameindex.c## + for (next = buf; next < lim; next += ifm->ifm_msglen) {## 20 ##src/libroute/if_nameindex.c## + ifm = (struct if_msghdr *) next;## 21 ##src/libroute/if_nameindex.c## + if (ifm->ifm_type == RTM_IFINFO) {## 22 ##src/libroute/if_nameindex.c## + sa = (struct sockaddr *) (ifm + 1);## 23 ##src/libroute/if_nameindex.c## + get_rtaddrs(ifm->ifm_addrs, sa, rti_info);## 24 ##src/libroute/if_nameindex.c## + if ((sa = rti_info[RTAX_IFP]) != NULL) {## 25 ##src/libroute/if_nameindex.c## + if (sa->sa_family == AF_LINK) {## 26 ##src/libroute/if_nameindex.c## + sdl = (struct sockaddr_dl *) sa;## 27 ##src/libroute/if_nameindex.c## + namptr -= sdl->sdl_nlen + 1;## 28 ##src/libroute/if_nameindex.c## + strncpy(namptr, &sdl->sdl_data[0], sdl->sdl_nlen);## 29 ##src/libroute/if_nameindex.c## + namptr[sdl->sdl_nlen] = 0; /* null terminate */## 30 ##src/libroute/if_nameindex.c## + ifptr->if_name = namptr;## 31 ##src/libroute/if_nameindex.c## + ifptr->if_index = sdl->sdl_index;## 32 ##src/libroute/if_nameindex.c## + ifptr++;## 33 ##src/libroute/if_nameindex.c## + }## 34 ##src/libroute/if_nameindex.c## + }## 35 ##src/libroute/if_nameindex.c## + + }## 36 ##src/libroute/if_nameindex.c## + }## 37 ##src/libroute/if_nameindex.c## + ifptr->if_name = NULL; /* mark end of array of structs */## 38 ##src/libroute/if_nameindex.c## + ifptr->if_index = 0;## 39 ##src/libroute/if_nameindex.c## + free(buf);## 40 ##src/libroute/if_nameindex.c## + return (result); /* caller must free() this when done */## 41 ##src/libroute/if_nameindex.c## +}## 42 ##src/libroute/if_nameindex.c## +/* end if_nameindex */ + +/* include if_freenameindex */ +void## 43 ##src/libroute/if_nameindex.c## +if_freenameindex(struct if_nameindex *ptr)## 44 ##src/libroute/if_nameindex.c## +{## 45 ##src/libroute/if_nameindex.c## + free(ptr);## 46 ##src/libroute/if_nameindex.c## +}## 47 ##src/libroute/if_nameindex.c## +/* end if_freenameindex */ + +struct if_nameindex *## 48 ##src/libroute/if_nameindex.c## +If_nameindex(void)## 49 ##src/libroute/if_nameindex.c## +{## 50 ##src/libroute/if_nameindex.c## + struct if_nameindex *ifptr;## 51 ##src/libroute/if_nameindex.c## + + if ((ifptr = if_nameindex()) == NULL)## 52 ##src/libroute/if_nameindex.c## + err_quit("if_nameindex error");## 53 ##src/libroute/if_nameindex.c## + return (ifptr);## 54 ##src/libroute/if_nameindex.c## +}## 55 ##src/libroute/if_nameindex.c## diff --git a/libroute/if_nametoindex.c b/libroute/if_nametoindex.c new file mode 100644 index 0000000..fb13e52 --- /dev/null +++ b/libroute/if_nametoindex.c @@ -0,0 +1,51 @@ +/* include if_nametoindex */ +#include "unpifi.h" +#include "unproute.h" + +unsigned int +if_nametoindex(const char *name) +{ + unsigned int idx, namelen; + char *buf, *next, *lim; + size_t len; + struct if_msghdr *ifm; + struct sockaddr *sa, *rti_info[RTAX_MAX]; + struct sockaddr_dl *sdl; + + if ( (buf = net_rt_iflist(0, 0, &len)) == NULL) + return(0); + + namelen = strlen(name); + lim = buf + len; + for (next = buf; next < lim; next += ifm->ifm_msglen) { + ifm = (struct if_msghdr *) next; + if (ifm->ifm_type == RTM_IFINFO) { + sa = (struct sockaddr *) (ifm + 1); + get_rtaddrs(ifm->ifm_addrs, sa, rti_info); + if ( (sa = rti_info[RTAX_IFP]) != NULL) { + if (sa->sa_family == AF_LINK) { + sdl = (struct sockaddr_dl *) sa; + if (sdl->sdl_nlen == namelen && strncmp(&sdl->sdl_data[0], name, sdl->sdl_nlen) == 0) { + idx = sdl->sdl_index; /* save before free() */ + free(buf); + return(idx); + } + } + } + + } + } + free(buf); + return(0); /* no match for name */ +} +/* end if_nametoindex */ + +unsigned int +If_nametoindex(const char *name) +{ + int idx; + + if ( (idx = if_nametoindex(name)) == 0) + err_quit("if_nametoindex error for %s", name); + return(idx); +} diff --git a/libroute/if_nametoindex.lc b/libroute/if_nametoindex.lc new file mode 100644 index 0000000..eae5d8f --- /dev/null +++ b/libroute/if_nametoindex.lc @@ -0,0 +1,50 @@ +/* include if_nametoindex */ +#include "unpifi.h"## 1 ##src/libroute/if_nametoindex.c## +#include "unproute.h"## 2 ##src/libroute/if_nametoindex.c## + +unsigned int## 3 ##src/libroute/if_nametoindex.c## +if_nametoindex(const char *name)## 4 ##src/libroute/if_nametoindex.c## +{## 5 ##src/libroute/if_nametoindex.c## + unsigned int index;## 6 ##src/libroute/if_nametoindex.c## + char *buf, *next, *lim;## 7 ##src/libroute/if_nametoindex.c## + size_t len;## 8 ##src/libroute/if_nametoindex.c## + struct if_msghdr *ifm;## 9 ##src/libroute/if_nametoindex.c## + struct sockaddr *sa, *rti_info[RTAX_MAX];## 10 ##src/libroute/if_nametoindex.c## + struct sockaddr_dl *sdl;## 11 ##src/libroute/if_nametoindex.c## + + if ((buf = net_rt_iflist(0, 0, &len)) == NULL)## 12 ##src/libroute/if_nametoindex.c## + return (0);## 13 ##src/libroute/if_nametoindex.c## + + lim = buf + len;## 14 ##src/libroute/if_nametoindex.c## + for (next = buf; next < lim; next += ifm->ifm_msglen) {## 15 ##src/libroute/if_nametoindex.c## + ifm = (struct if_msghdr *) next;## 16 ##src/libroute/if_nametoindex.c## + if (ifm->ifm_type == RTM_IFINFO) {## 17 ##src/libroute/if_nametoindex.c## + sa = (struct sockaddr *) (ifm + 1);## 18 ##src/libroute/if_nametoindex.c## + get_rtaddrs(ifm->ifm_addrs, sa, rti_info);## 19 ##src/libroute/if_nametoindex.c## + if ((sa = rti_info[RTAX_IFP]) != NULL) {## 20 ##src/libroute/if_nametoindex.c## + if (sa->sa_family == AF_LINK) {## 21 ##src/libroute/if_nametoindex.c## + sdl = (struct sockaddr_dl *) sa;## 22 ##src/libroute/if_nametoindex.c## + if (strncmp(&sdl->sdl_data[0], name, sdl->sdl_nlen) == 0) {## 23 ##src/libroute/if_nametoindex.c## + index = sdl->sdl_index; /* save before free() */## 24 ##src/libroute/if_nametoindex.c## + free(buf);## 25 ##src/libroute/if_nametoindex.c## + return (index);## 26 ##src/libroute/if_nametoindex.c## + }## 27 ##src/libroute/if_nametoindex.c## + }## 28 ##src/libroute/if_nametoindex.c## + }## 29 ##src/libroute/if_nametoindex.c## + + }## 30 ##src/libroute/if_nametoindex.c## + }## 31 ##src/libroute/if_nametoindex.c## + free(buf);## 32 ##src/libroute/if_nametoindex.c## + return (0); /* no match for name */## 33 ##src/libroute/if_nametoindex.c## +}## 34 ##src/libroute/if_nametoindex.c## +/* end if_nametoindex */ + +unsigned int## 35 ##src/libroute/if_nametoindex.c## +If_nametoindex(const char *name)## 36 ##src/libroute/if_nametoindex.c## +{## 37 ##src/libroute/if_nametoindex.c## + int index;## 38 ##src/libroute/if_nametoindex.c## + + if ((index = if_nametoindex(name)) == 0)## 39 ##src/libroute/if_nametoindex.c## + err_quit("if_nametoindex error for %s", name);## 40 ##src/libroute/if_nametoindex.c## + return (index);## 41 ##src/libroute/if_nametoindex.c## +}## 42 ##src/libroute/if_nametoindex.c## diff --git a/libroute/net_rt_dump.c b/libroute/net_rt_dump.c new file mode 100644 index 0000000..2200131 --- /dev/null +++ b/libroute/net_rt_dump.c @@ -0,0 +1,36 @@ +/* include net_rt_dump */ +#include "unproute.h" + +char * +net_rt_dump(int family, int flags, size_t *lenp) +{ + int mib[6]; + char *buf; + + mib[0] = CTL_NET; + mib[1] = AF_ROUTE; + mib[2] = 0; + mib[3] = family; /* only addresses of this family */ + mib[4] = NET_RT_DUMP; + mib[5] = flags; /* not looked at with NET_RT_DUMP */ + if (sysctl(mib, 6, NULL, lenp, NULL, 0) < 0) + return(NULL); + + if ( (buf = malloc(*lenp)) == NULL) + return(NULL); + if (sysctl(mib, 6, buf, lenp, NULL, 0) < 0) + return(NULL); + + return(buf); +} +/* end net_rt_dump */ + +char * +Net_rt_dump(int family, int flags, size_t *lenp) +{ + char *ptr; + + if ( (ptr = net_rt_dump(family, flags, lenp)) == NULL) + err_sys("net_rt_dump error"); + return(ptr); +} diff --git a/libroute/net_rt_iflist.c b/libroute/net_rt_iflist.c new file mode 100644 index 0000000..c9c1967 --- /dev/null +++ b/libroute/net_rt_iflist.c @@ -0,0 +1,38 @@ +/* include net_rt_iflist */ +#include "unproute.h" + +char * +net_rt_iflist(int family, int flags, size_t *lenp) +{ + int mib[6]; + char *buf; + + mib[0] = CTL_NET; + mib[1] = AF_ROUTE; + mib[2] = 0; + mib[3] = family; /* only addresses of this family */ + mib[4] = NET_RT_IFLIST; + mib[5] = flags; /* interface index or 0 */ + if (sysctl(mib, 6, NULL, lenp, NULL, 0) < 0) + return(NULL); + + if ( (buf = malloc(*lenp)) == NULL) + return(NULL); + if (sysctl(mib, 6, buf, lenp, NULL, 0) < 0) { + free(buf); + return(NULL); + } + + return(buf); +} +/* end net_rt_iflist */ + +char * +Net_rt_iflist(int family, int flags, size_t *lenp) +{ + char *ptr; + + if ( (ptr = net_rt_iflist(family, flags, lenp)) == NULL) + err_sys("net_rt_iflist error"); + return(ptr); +} diff --git a/libroute/net_rt_iflist.lc b/libroute/net_rt_iflist.lc new file mode 100644 index 0000000..b75cd89 --- /dev/null +++ b/libroute/net_rt_iflist.lc @@ -0,0 +1,38 @@ +/* include net_rt_iflist */ +#include "unproute.h"## 1 ##src/libroute/net_rt_iflist.c## + +char *## 2 ##src/libroute/net_rt_iflist.c## +net_rt_iflist(int family, int flags, size_t *lenp)## 3 ##src/libroute/net_rt_iflist.c## +{## 4 ##src/libroute/net_rt_iflist.c## + int mib[6];## 5 ##src/libroute/net_rt_iflist.c## + char *buf;## 6 ##src/libroute/net_rt_iflist.c## + + mib[0] = CTL_NET;## 7 ##src/libroute/net_rt_iflist.c## + mib[1] = AF_ROUTE;## 8 ##src/libroute/net_rt_iflist.c## + mib[2] = 0;## 9 ##src/libroute/net_rt_iflist.c## + mib[3] = family; /* only addresses of this family */## 10 ##src/libroute/net_rt_iflist.c## + mib[4] = NET_RT_IFLIST;## 11 ##src/libroute/net_rt_iflist.c## + mib[5] = flags; /* interface index, or 0 */## 12 ##src/libroute/net_rt_iflist.c## + if (sysctl(mib, 6, NULL, lenp, NULL, 0) < 0)## 13 ##src/libroute/net_rt_iflist.c## + return (NULL);## 14 ##src/libroute/net_rt_iflist.c## + + if ((buf = malloc(*lenp)) == NULL)## 15 ##src/libroute/net_rt_iflist.c## + return (NULL);## 16 ##src/libroute/net_rt_iflist.c## + if (sysctl(mib, 6, buf, lenp, NULL, 0) < 0) {## 17 ##src/libroute/net_rt_iflist.c## + free(buf);## 18 ##src/libroute/net_rt_iflist.c## + return (NULL);## 19 ##src/libroute/net_rt_iflist.c## + }## 20 ##src/libroute/net_rt_iflist.c## + + return (buf);## 21 ##src/libroute/net_rt_iflist.c## +}## 22 ##src/libroute/net_rt_iflist.c## +/* end net_rt_iflist */ + +char *## 23 ##src/libroute/net_rt_iflist.c## +Net_rt_iflist(int family, int flags, size_t *lenp)## 24 ##src/libroute/net_rt_iflist.c## +{## 25 ##src/libroute/net_rt_iflist.c## + char *ptr;## 26 ##src/libroute/net_rt_iflist.c## + + if ((ptr = net_rt_iflist(family, flags, lenp)) == NULL)## 27 ##src/libroute/net_rt_iflist.c## + err_sys("net_rt_iflist error");## 28 ##src/libroute/net_rt_iflist.c## + return (ptr);## 29 ##src/libroute/net_rt_iflist.c## +}## 30 ##src/libroute/net_rt_iflist.c## diff --git a/libroute/sock_masktop.c b/libroute/sock_masktop.c new file mode 100644 index 0000000..3e1c70d --- /dev/null +++ b/libroute/sock_masktop.c @@ -0,0 +1,24 @@ +#include "unproute.h" + +const char * +sock_masktop(SA *sa, socklen_t salen) +{ + static char str[INET6_ADDRSTRLEN]; + unsigned char *ptr = &sa->sa_data[2]; + + if (sa->sa_len == 0) + return("0.0.0.0"); + else if (sa->sa_len == 5) + snprintf(str, sizeof(str), "%d.0.0.0", *ptr); + else if (sa->sa_len == 6) + snprintf(str, sizeof(str), "%d.%d.0.0", *ptr, *(ptr+1)); + else if (sa->sa_len == 7) + snprintf(str, sizeof(str), "%d.%d.%d.0", *ptr, *(ptr+1), *(ptr+2)); + else if (sa->sa_len == 8) + snprintf(str, sizeof(str), "%d.%d.%d.%d", + *ptr, *(ptr+1), *(ptr+2), *(ptr+3)); + else + snprintf(str, sizeof(str), "(unknown mask, len = %d, family = %d)", + sa->sa_len, sa->sa_family); + return(str); +} diff --git a/libroute/unproute.h b/libroute/unproute.h new file mode 100644 index 0000000..a9ee61d --- /dev/null +++ b/libroute/unproute.h @@ -0,0 +1,20 @@ +#include "unp.h" +#include /* if_msghdr{} */ +#include /* sockaddr_sdl{} */ +#include /* RTA_xxx constants */ +#include + +#ifdef HAVE_SYS_SYSCTL_H +#include /* sysctl() */ +#endif + + /* function prototypes */ +void get_rtaddrs(int, struct sockaddr *, struct sockaddr **); +char *net_rt_iflist(int, int, size_t *); +char *net_rt_dump(int, int, size_t *); +const char *sock_masktop(struct sockaddr *, socklen_t); + + /* wrapper functions */ +char *Net_rt_iflist(int, int, size_t *); +char *Net_rt_dump(int, int, size_t *); +#define Sock_masktop(a,b) sock_masktop((a), (b)) diff --git a/mcast/Makefile b/mcast/Makefile new file mode 100644 index 0000000..273bc5e --- /dev/null +++ b/mcast/Makefile @@ -0,0 +1,26 @@ +include ../Make.defines + +PROGS = sendrecv udpcli05 udpcli06 udpserv01 + +all: ${PROGS} + +sendrecv: main.o send.o recv.o + ${CC} ${CFLAGS} -o $@ main.o send.o recv.o ${LIBS} + +# Version in book. +udpcli01: udpcli01.o dgclibcast1.o + ${CC} ${CFLAGS} -o $@ udpcli01.o dgclibcast1.o ${LIBS} + +# Correct version using sigsetjmp()/siglongjmp(). +udpcli05: udpcli05.o dgclimcast5.o + ${CC} ${CFLAGS} -o $@ udpcli05.o dgclimcast5.o ${LIBS} + +# Try to bind multicast address and send. +udpcli06: udpcli06.o dgclimcast6.o + ${CC} ${CFLAGS} -o $@ udpcli06.o dgclimcast6.o ${LIBS} + +udpserv01: udpserv01.o + ${CC} ${CFLAGS} -o $@ udpserv01.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/mcast/dgclibcast1.c b/mcast/dgclibcast1.c new file mode 100644 index 0000000..feff0e3 --- /dev/null +++ b/mcast/dgclibcast1.c @@ -0,0 +1,43 @@ +#include "unp.h" + +static void recvfrom_alarm(int); + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + socklen_t len; + struct sockaddr *preply_addr; + + preply_addr = Malloc(servlen); + + Signal(SIGALRM, recvfrom_alarm); + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + alarm(5); + for ( ; ; ) { + len = servlen; + n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len); + if (n == -1) { + if (errno == EINTR) + break; /* waited long enough for replies */ + else + err_sys("recvfrom error"); + } else { + recvline[n] = 0; /* null terminate */ + printf("from %s: %s", + Sock_ntop_host(preply_addr, servlen), recvline); + } + } + } +} + +static void +recvfrom_alarm(int signo) +{ + return; /* just interrupt the recvfrom() */ +} diff --git a/mcast/dgclimcast5.c b/mcast/dgclimcast5.c new file mode 100644 index 0000000..54c3f71 --- /dev/null +++ b/mcast/dgclimcast5.c @@ -0,0 +1,40 @@ +#include "unp.h" +#include + +static void recvfrom_alarm(int); +static sigjmp_buf jmpbuf; + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + socklen_t len; + struct sockaddr *preply_addr; + + preply_addr = Malloc(servlen); + + Signal(SIGALRM, recvfrom_alarm); + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + alarm(5); + for ( ; ; ) { + if (sigsetjmp(jmpbuf, 1) != 0) + break; + len = servlen; + n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len); + recvline[n] = 0; /* null terminate */ + printf("from %s: %s", + Sock_ntop_host(preply_addr, servlen), recvline); + } + } +} + +static void +recvfrom_alarm(int signo) +{ + siglongjmp(jmpbuf, 1); +} diff --git a/mcast/dgclimcast6.c b/mcast/dgclimcast6.c new file mode 100644 index 0000000..54c3f71 --- /dev/null +++ b/mcast/dgclimcast6.c @@ -0,0 +1,40 @@ +#include "unp.h" +#include + +static void recvfrom_alarm(int); +static sigjmp_buf jmpbuf; + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + socklen_t len; + struct sockaddr *preply_addr; + + preply_addr = Malloc(servlen); + + Signal(SIGALRM, recvfrom_alarm); + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + alarm(5); + for ( ; ; ) { + if (sigsetjmp(jmpbuf, 1) != 0) + break; + len = servlen; + n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len); + recvline[n] = 0; /* null terminate */ + printf("from %s: %s", + Sock_ntop_host(preply_addr, servlen), recvline); + } + } +} + +static void +recvfrom_alarm(int signo) +{ + siglongjmp(jmpbuf, 1); +} diff --git a/mcast/main.c b/mcast/main.c new file mode 100644 index 0000000..129fd0a --- /dev/null +++ b/mcast/main.c @@ -0,0 +1,34 @@ +#include "unp.h" + +void recv_all(int, socklen_t); +void send_all(int, SA *, socklen_t); + +int +main(int argc, char **argv) +{ + int sendfd, recvfd; + const int on = 1; + socklen_t salen; + struct sockaddr *sasend, *sarecv; + + if (argc != 3) + err_quit("usage: sendrecv "); + + sendfd = Udp_client(argv[1], argv[2], (void **) &sasend, &salen); + + recvfd = Socket(sasend->sa_family, SOCK_DGRAM, 0); + + Setsockopt(recvfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + + sarecv = Malloc(salen); + memcpy(sarecv, sasend, salen); + Bind(recvfd, sarecv, salen); + + Mcast_join(recvfd, sasend, salen, NULL, 0); + Mcast_set_loop(sendfd, 0); + + if (Fork() == 0) + recv_all(recvfd, salen); /* child -> receives */ + + send_all(sendfd, sasend, salen); /* parent -> sends */ +} diff --git a/mcast/recv.c b/mcast/recv.c new file mode 100644 index 0000000..b9933c4 --- /dev/null +++ b/mcast/recv.c @@ -0,0 +1,20 @@ +#include "unp.h" + +void +recv_all(int recvfd, socklen_t salen) +{ + int n; + char line[MAXLINE+1]; + socklen_t len; + struct sockaddr *safrom; + + safrom = Malloc(salen); + + for ( ; ; ) { + len = salen; + n = Recvfrom(recvfd, line, MAXLINE, 0, safrom, &len); + + line[n] = 0; /* null terminate */ + printf("from %s: %s", Sock_ntop(safrom, len), line); + } +} diff --git a/mcast/send.c b/mcast/send.c new file mode 100644 index 0000000..6b1a796 --- /dev/null +++ b/mcast/send.c @@ -0,0 +1,21 @@ +#include "unp.h" +#include + +#define SENDRATE 5 /* send one datagram every five seconds */ + +void +send_all(int sendfd, SA *sadest, socklen_t salen) +{ + char line[MAXLINE]; /* hostname and process ID */ + struct utsname myname; + + if (uname(&myname) < 0) + err_sys("uname error");; + snprintf(line, sizeof(line), "%s, %d\n", myname.nodename, getpid()); + + for ( ; ; ) { + Sendto(sendfd, line, strlen(line), 0, sadest, salen); + + sleep(SENDRATE); + } +} diff --git a/mcast/udpcli01.c b/mcast/udpcli01.c new file mode 100644 index 0000000..24ce753 --- /dev/null +++ b/mcast/udpcli01.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli01 "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/mcast/udpcli05.c b/mcast/udpcli05.c new file mode 100644 index 0000000..dd0cad3 --- /dev/null +++ b/mcast/udpcli05.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli05 "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(13); /* standard daytime server */ + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/mcast/udpcli06.c b/mcast/udpcli06.c new file mode 100644 index 0000000..e77401c --- /dev/null +++ b/mcast/udpcli06.c @@ -0,0 +1,23 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + socklen_t salen; + struct sockaddr *cli, *serv; + + if (argc != 2) + err_quit("usage: udpcli06 "); + + sockfd = Udp_client(argv[1], "daytime", (void **) &serv, &salen); + + cli = Malloc(salen); + memcpy(cli, serv, salen); /* copy socket address struct */ + sock_set_port(cli, salen, 0); /* and set port to 0 */ + Bind(sockfd, cli, salen); + + dg_cli(stdin, sockfd, serv, salen); + + exit(0); +} diff --git a/mcast/udpserv01.c b/mcast/udpserv01.c new file mode 100644 index 0000000..817ae6c --- /dev/null +++ b/mcast/udpserv01.c @@ -0,0 +1,25 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr, grpaddr, cliaddr; + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + bzero(&grpaddr, sizeof(servaddr)); + grpaddr.sin_family = AF_INET; + grpaddr.sin_addr.s_addr = inet_addr("224.0.0.1"); + + mcast_join(sockfd, &grpaddr, sizeof(grpaddr), NULL, 0); + + dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr)); +} diff --git a/mysdr/Makefile b/mysdr/Makefile new file mode 100644 index 0000000..b09a494 --- /dev/null +++ b/mysdr/Makefile @@ -0,0 +1,11 @@ +include ../Make.defines + +PROGS = mysdr + +all: ${PROGS} + +mysdr: main.o loop.o + ${CC} ${CFLAGS} -o $@ main.o loop.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/mysdr/loop.c b/mysdr/loop.c new file mode 100644 index 0000000..b68f7fc --- /dev/null +++ b/mysdr/loop.c @@ -0,0 +1,44 @@ +#include "mysdr.h" + +void +loop(int sockfd, socklen_t salen) +{ + socklen_t len; + ssize_t n; + char *p; + struct sockaddr *sa; + struct sap_packet { + uint32_t sap_header; + uint32_t sap_src; + char sap_data[BUFFSIZE]; + } buf; + + sa = Malloc(salen); + + for ( ; ; ) { + len = salen; + n = Recvfrom(sockfd, &buf, sizeof(buf) - 1, 0, sa, &len); + ((char *)&buf)[n] = 0; /* null terminate */ + buf.sap_header = ntohl(buf.sap_header); + + printf("From %s hash 0x%04x\n", Sock_ntop(sa, len), + buf.sap_header & SAP_HASH_MASK); + if (((buf.sap_header & SAP_VERSION_MASK) >> SAP_VERSION_SHIFT) > 1) { + err_msg("... version field not 1 (0x%08x)", buf.sap_header); + continue; + } + if (buf.sap_header & SAP_IPV6) { + err_msg("... IPv6"); + continue; + } + if (buf.sap_header & (SAP_DELETE|SAP_ENCRYPTED|SAP_COMPRESSED)) { + err_msg("... can't parse this packet type (0x%08x)", buf.sap_header); + continue; + } + p = buf.sap_data + ((buf.sap_header & SAP_AUTHLEN_MASK) + >> SAP_AUTHLEN_SHIFT); + if (strcmp(p, "application/sdp") == 0) + p += 16; + printf("%s\n", p); + } +} diff --git a/mysdr/loop.lc b/mysdr/loop.lc new file mode 100644 index 0000000..05d8262 --- /dev/null +++ b/mysdr/loop.lc @@ -0,0 +1,28 @@ +#include "unp.h"## 1 ##src/mysdr/loop.c## + +void## 2 ##src/mysdr/loop.c## +loop(int sockfd, socklen_t salen)## 3 ##src/mysdr/loop.c## +{## 4 ##src/mysdr/loop.c## + char buf[MAXLINE + 1];## 5 ##src/mysdr/loop.c## + socklen_t len;## 6 ##src/mysdr/loop.c## + ssize_t n;## 7 ##src/mysdr/loop.c## + struct sockaddr *sa;## 8 ##src/mysdr/loop.c## + struct sap_packet {## 9 ##src/mysdr/loop.c## + uint32_t sap_header;## 10 ##src/mysdr/loop.c## + uint32_t sap_src;## 11 ##src/mysdr/loop.c## + char sap_data[1];## 12 ##src/mysdr/loop.c## + } *sapptr;## 13 ##src/mysdr/loop.c## + + sa = Malloc(salen);## 14 ##src/mysdr/loop.c## + + for (;;) {## 15 ##src/mysdr/loop.c## + len = salen;## 16 ##src/mysdr/loop.c## + n = Recvfrom(sockfd, buf, MAXLINE, 0, sa, &len);## 17 ##src/mysdr/loop.c## + buf[n] = 0; /* null terminate */## 18 ##src/mysdr/loop.c## + + sapptr = (struct sap_packet *) buf;## 19 ##src/mysdr/loop.c## + if ((n -= 2 * sizeof(uint32_t)) <= 0)## 20 ##src/mysdr/loop.c## + err_quit("n = %d", n);## 21 ##src/mysdr/loop.c## + printf("From %s\n%s\n", Sock_ntop(sa, len), sapptr->sap_data);## 22 ##src/mysdr/loop.c## + }## 23 ##src/mysdr/loop.c## +}## 24 ##src/mysdr/loop.c## diff --git a/mysdr/main.c b/mysdr/main.c new file mode 100644 index 0000000..adfc34b --- /dev/null +++ b/mysdr/main.c @@ -0,0 +1,31 @@ +#include "unp.h" + +#define SAP_NAME "sap.mcast.net" /* default group name and port */ +#define SAP_PORT "9875" + +void loop(int, socklen_t); + +int +main(int argc, char **argv) +{ + int sockfd; + const int on = 1; + socklen_t salen; + struct sockaddr *sa; + + if (argc == 1) + sockfd = Udp_client(SAP_NAME, SAP_PORT, (void **) &sa, &salen); + else if (argc == 4) + sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen); + else + err_quit("usage: mysdr "); + + Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + Bind(sockfd, sa, salen); + + Mcast_join(sockfd, sa, salen, (argc == 4) ? argv[3] : NULL, 0); + + loop(sockfd, salen); /* receive and print */ + + exit(0); +} diff --git a/mysdr/main.lc b/mysdr/main.lc new file mode 100644 index 0000000..8f725cb --- /dev/null +++ b/mysdr/main.lc @@ -0,0 +1,31 @@ +#include "unp.h"## 1 ##src/mysdr/main.c## + +#define SAP_NAME "sap.mcast.net" /* default group name and port */## 2 ##src/mysdr/main.c## +#define SAP_PORT "9875"## 3 ##src/mysdr/main.c## + +void loop(int, socklen_t);## 4 ##src/mysdr/main.c## + +int## 5 ##src/mysdr/main.c## +main(int argc, char **argv)## 6 ##src/mysdr/main.c## +{## 7 ##src/mysdr/main.c## + int sockfd;## 8 ##src/mysdr/main.c## + const int on = 1;## 9 ##src/mysdr/main.c## + socklen_t salen;## 10 ##src/mysdr/main.c## + struct sockaddr *sa;## 11 ##src/mysdr/main.c## + + if (argc == 1)## 12 ##src/mysdr/main.c## + sockfd = Udp_client(SAP_NAME, SAP_PORT, (void **) &sa, &salen);## 13 ##src/mysdr/main.c## + else if (argc == 4)## 14 ##src/mysdr/main.c## + sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen);## 15 ##src/mysdr/main.c## + else## 16 ##src/mysdr/main.c## + err_quit("usage: mysdr ");## 17 ##src/mysdr/main.c## + + Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 18 ##src/mysdr/main.c## + Bind(sockfd, sa, salen);## 19 ##src/mysdr/main.c## + + Mcast_join(sockfd, sa, salen, (argc == 4) ? argv[3] : NULL, 0);## 20 ##src/mysdr/main.c## + + loop(sockfd, salen); /* receive and print */## 21 ##src/mysdr/main.c## + + exit(0);## 22 ##src/mysdr/main.c## +}## 23 ##src/mysdr/main.c## diff --git a/mysdr/mysdr.h b/mysdr/mysdr.h new file mode 100644 index 0000000..dcb1d3b --- /dev/null +++ b/mysdr/mysdr.h @@ -0,0 +1,12 @@ +#include "unp.h" + +#define SAP_VERSION 1 +#define SAP_VERSION_MASK 0xe0000000 +#define SAP_VERSION_SHIFT 29 +#define SAP_IPV6 0x10000000 +#define SAP_DELETE 0x04000000 +#define SAP_ENCRYPTED 0x02000000 +#define SAP_COMPRESSED 0x01000000 +#define SAP_AUTHLEN_MASK 0x00ff0000 +#define SAP_AUTHLEN_SHIFT 16 +#define SAP_HASH_MASK 0x0000ffff diff --git a/mysdr/script.1 b/mysdr/script.1 new file mode 100644 index 0000000..87cceea --- /dev/null +++ b/mysdr/script.1 @@ -0,0 +1,45 @@ +kohala % ./sdr +From 128.102.84.134/2840 +v=0 +o=shuttle 3050400397 3051818822 IN IP4 128.102.84.134 +s=NASA - Shuttle STS-79 Mission Coverage +i=Pre-launch and mission coverage of Shuttle Mission STS-79. Launch expected 9/16/96 with a mission duration anticipated of 9-10 days. STS-79 is the 4th in a series of joint docking missions between the Shuttle and the MIR Space Station. This session is being offered by NASA - Ames Research Center as a public service to the MBone community. +u=http://www-pao.ksc.nasa.gov/kscpao/kscpao.htm +p=NASA ARC Digital Video Lab (415) 604-6145 +e=NASA ARC Digital Video Lab +c=IN IP4 224.2.86.28/127 +t=3051608400 3052472400 +m=audio 19432 RTP/AVP 0 +m=video 61192 RTP/AVP 31 + +From 143.106.13.10/1119 +v=0 +o=vazquez 3051812968 3051813242 IN IP4 143.106.13.10 +s=Test IQ/Unicamp +i=Video Test/IQ Unic +p=Pedro A M Vazquez +55 019 239 7253 +e=Pedro A M Vazquez +t=3051811800 3052416600 +m=video 58960 rtp nv +c=IN IP4 224.2.60.105/127 +m=whiteboard 43591 udp wb +c=IN IP4 224.2.29.88/127 + +From 131.202.70.81/47880 +v=0 +o=spencer 3050069099 3050069347 IN IP4 131.202.70.81 +s=UNB / CSpace +i=This is a low rate video transmission sent from the University of New Brunswick, in Fredericton, New Brunswick, from CSpace, offices for the Community Access Program. Video is sent at ~20kbps, and audio is (usually) monitored as well. This feed is coming through from the host breakers.educ.unb.ca. If this is interferring with a scheduled broadcast, please let me know, and I will stop the transmission. dwight (spencer@unb.ca) +u=http://cspace.unb.ca/~spencer/ +e=Dwight E. Spencer +p=Dwight E. Spencer +1 (506) 447 3153 +c=IN IP4 224.2.246.116/127 +t=3050019000 3052524600 +r=86400 86400 0 +m=audio 22378 RTP/AVP 5 +c=IN IP4 224.2.246.116/127 +m=video 61338 RTP/AVP 31 +c=IN IP4 224.2.210.189/127 +m=text 61044 udp nt +c=IN IP4 224.2.147.133/127 + diff --git a/mysdr/script.2 b/mysdr/script.2 new file mode 100644 index 0000000..44ae715 --- /dev/null +++ b/mysdr/script.2 @@ -0,0 +1,1679 @@ +Script started on Sat Jul 12 15:51:28 1997 +kohala % ./mysdr +From 140.247.157.193.1047 +v=0 +o=karp 3077576976 3077577964 IN IP4 140.247.157.193 +s=Harvard's Aiken Computation Lab DEMOLITION +i=Live broadcast of the demolition of Harvard University's Aiken Computation Lab, to make way for the new Computer Science building, Maxwell-Dworkin. Broadcast will include commentary on the event by Harvard faculty, administrators, and students. Filmed in Destruct-O-Vision, from an unmanned camera INSIDE Aiken. +u=http://www.eecs.harvard.edu/aiken-go-boom +e=Brad Karp +p=Brad Karp +1 617-661-4979 +c=IN IP4 224.2.156.29/127 +t=3078820800 3080030400 +a=tool:sdr v2.4a6 +a=type:broadcast +m=audio 21226 RTP/AVP 5 +c=IN IP4 224.2.156.29/127 +a=ptime:40 +m=video 49998 RTP/AVP 31 +c=IN IP4 224.2.237.48/127 + +From 140.247.157.193.1047 +v=0 +o=karp 3077576976 3077577964 IN IP4 140.247.157.193 +s=Harvard's Aiken Computation Lab DEMOLITION +i=Live broadcast of the demolition of Harvard University's Aiken Computation Lab, to make way for the new Computer Science building, Maxwell-Dworkin. Broadcast will include commentary on the event by Harvard faculty, administrators, and students. Filmed in Destruct-O-Vision, from an unmanned camera INSIDE Aiken. +u=http://www.eecs.harvard.edu/aiken-go-boom +e=Brad Karp +p=Brad Karp +1 617-661-4979 +c=IN IP4 224.2.156.29/127 +t=3078820800 3080030400 +a=tool:sdr v2.4a6 +a=type:broadcast +m=audio 21226 RTP/AVP 5 +c=IN IP4 224.2.156.29/127 +a=ptime:40 +m=video 49998 RTP/AVP 31 +c=IN IP4 224.2.237.48/127 + +From 128.223.32.151.40710 +v=0 +o=llynch 3073936480 3075057183 IN IP4 128.223.32.151 +s=UO Presents KWVA Campus Radio +i=University of Oregon alternative radio +u=http://gladstone.uoregon.edu/~kwva/ +e=Lucy Lynch (University of Oregon) +p=Lucy Lynch (University of Oregon) (541) 346-1774 +c=IN IP4 224.2.240.123/127 +t=0 0 +a=tool:sdr v2.3a1 +a=type:test +m=audio 24676 RTP/AVP 0 +c=IN IP4 224.2.240.123/127 +a=ptime:40 + +From 130.240.64.67.32877 +v=0 +o=demo 3066564173 3066564269 IN IP4 130.240.64.67 +s=Places all over the world +i=Low bandwidth video (10 kb/s) with views from all over the world. It is probably wise to limit the overall bandwidth to 100 kb/s (that is, a maximum of ten 10 kb/s streams). Audio is primarily for feedback for the senders of video. +e=Hakan Lennestal +c=IN IP4 224.2.172.238/127 +t=0 0 +a=tool:CDT mAnnouncer 1.1.1 +a=type:broadcast +m=video 51482 RTP/AVP 31 +c=IN IP4 224.2.172.238/127 +m=audio 20154 RTP/AVP 121 +c=IN IP4 224.2.213.113/127 +a=rtpred1:5 +a=ptime:40 +a=rtpred2:5 +a=rtpmap:121 red/8000 + +From 130.240.64.67.32877 +v=0 +o=demo 3066564173 3066564269 IN IP4 130.240.64.67 +s=Places all over the world +i=Low bandwidth video (10 kb/s) with views from all over the world. It is probably wise to limit the overall bandwidth to 100 kb/s (that is, a maximum of ten 10 kb/s streams). Audio is primarily for feedback for the senders of video. +e=Hakan Lennestal +c=IN IP4 224.2.172.238/127 +t=0 0 +a=tool:CDT mAnnouncer 1.1.1 +a=type:broadcast +m=video 51482 RTP/AVP 31 +c=IN IP4 224.2.172.238/127 +m=audio 20154 RTP/AVP 121 +c=IN IP4 224.2.213.113/127 +a=rtpred1:5 +a=ptime:40 +a=rtpred2:5 +a=rtpmap:121 red/8000 + +From 141.213.8.193.32800 +v=0 +o=sugih 3066072073 3066072112 IN IP4 141.213.8.193 +s=UMich IRL (private) +i=UMich private use +u=http://irl.eecs.umich.edu/jamin/ +e=UMich IRL +p=UMich IRL +1 313 763 1583 +c=IN IP4 224.2.143.56/127 +t=0 0 +a=tool:sdr v2.3a1 +a=type:test +m=audio 21690 RTP/AVP 0 +c=IN IP4 224.2.143.56/127 +a=ptime:40 +m=video 51990 RTP/AVP 31 +c=IN IP4 224.2.200.96/127 +m=whiteboard 47284 udp wb +c=IN IP4 224.2.239.141/127 +m=text 54906 udp nt +c=IN IP4 224.2.242.3/127 + +From 141.213.8.193.32800 +v=0 +o=sugih 3066072073 3066072112 IN IP4 141.213.8.193 +s=UMich IRL (private) +i=UMich private use +u=http://irl.eecs.umich.edu/jamin/ +e=UMich IRL +p=UMich IRL +1 313 763 1583 +c=IN IP4 224.2.143.56/127 +t=0 0 +a=tool:sdr v2.3a1 +a=type:test +m=audio 21690 RTP/AVP 0 +c=IN IP4 224.2.143.56/127 +a=ptime:40 +m=video 51990 RTP/AVP 31 +c=IN IP4 224.2.200.96/127 +m=whiteboard 47284 udp wb +c=IN IP4 224.2.239.141/127 +m=text 54906 udp nt +c=IN IP4 224.2.242.3/127 + +From 146.246.238.52.33095 +v=0 +o=dgomes 3076197571 3076936543 IN IP4 146.246.238.52 +s=Diesel Combustion Collaboratory +i=This is a research MBone session initiated from the Sandia National Laboratory, California site. This session will facilitate collaboration among the participants in a distributed research project, specifically the Heavy Duty Diesel Combustion CRADA using standard MBone A/V tools. For more information, http://www-collab.ca.sandia.gov/ +u=www-collab.ca.sandia.gov/ +e=Diesel Combustion Collaboratory +p=Diesel Combustion Collaboratory 510-294-1479 +c=IN IP4 239.32.1.200/127 +t=3076142400 3078648000 +r=86400 86400 0 +a=tool:sdr v2.3a1 +a=type:meeting +m=audio 23164 RTP/AVP 0 +c=IN IP4 239.32.1.200/127 +a=ptime:40 +m=video 53626 RTP/AVP 31 +c=IN IP4 239.32.1.200/127 +m=whiteboard 33870 udp wb +c=IN IP4 239.32.1.200/127 +a=orient:portrait + +From 209.1.118.230.9875 +v=0 +o=Administrator 868490998 868548530 IN IP4 209.1.118.230 +s=Ginacarlo's TV +i=Giancarlo's TV Feed from ICAST in Los Gatos +u=http://www.icast.com/ +e=sales@icast.com +p=+01 408 8740700 +t=3080337120 3080689920 +r=79200 7200 0 +a=recvonly +a=tool:ICAST TCC Server V1.0/Build 1-1010 +m=audio 4640 RTP/AVP 0 +c=IN IP4 224.2.100.120/127 +m=video 4920 RTP/AVP 31 +c=IN IP4 224.2.100.120/127 +b=AS:123 +a=framerate:20 +a=quality:7 +a=grayed:0 + +From 209.1.118.230.9875 +v=0 +o=Administrator 868490998 868548530 IN IP4 209.1.118.230 +s=Ginacarlo's TV +i=Giancarlo's TV Feed from ICAST in Los Gatos +u=http://www.icast.com/ +e=sales@icast.com +p=+01 408 8740700 +t=3080337120 3080689920 +r=79200 7200 0 +a=recvonly +a=tool:ICAST TCC Server V1.0/Build 1-1010 +m=audio 4640 RTP/AVP 0 +c=IN IP4 224.2.100.120/127 +m=video 4920 RTP/AVP 31 +c=IN IP4 224.2.100.120/127 +b=AS:123 +a=framerate:20 +a=quality:7 +a=grayed:0 + +From 128.146.222.100.32915 +v=0 +o=maf 3076346251 3077639429 IN IP4 128.146.222.100 +s=Recent Advances in Networking Seminar at OSU +i=Live Transmission of Professor Raj Jain's class CIS788.08q: Recent Advances in Networking every Tuesday and Thursday at 17:30 to 18:45 EDT, Open to public. E-mail questions to mbone@netlab.ohio-state.edu. See URL for list of topics. +u=http://www.cis.ohio-state.edu/~jain/cis788-97/schedule.htm +p=Mark Fullmer (Ohio State) 614-292-6159 +e=Mark Fullmer (Ohio State) +t=3078163800 3079380600 +r=604800 7200 0 +a=tool:sdr v2.3a1 +a=type:broadcast +m=audio 19922 RTP/AVP 0 +c=IN IP4 224.2.232.28/127 +a=ptime:40 +m=video 60266 RTP/AVP 31 +c=IN IP4 224.2.159.63/127 + +From 128.146.222.100.32915 +v=0 +o=maf 3076346251 3077639429 IN IP4 128.146.222.100 +s=Recent Advances in Networking Seminar at OSU +i=Live Transmission of Professor Raj Jain's class CIS788.08q: Recent Advances in Networking every Tuesday and Thursday at 17:30 to 18:45 EDT, Open to public. E-mail questions to mbone@netlab.ohio-state.edu. See URL for list of topics. +u=http://www.cis.ohio-state.edu/~jain/cis788-97/schedule.htm +p=Mark Fullmer (Ohio State) 614-292-6159 +e=Mark Fullmer (Ohio State) +t=3078163800 3079380600 +r=604800 7200 0 +a=tool:sdr v2.3a1 +a=type:broadcast +m=audio 19922 RTP/AVP 0 +c=IN IP4 224.2.232.28/127 +a=ptime:40 +m=video 60266 RTP/AVP 31 +c=IN IP4 224.2.159.63/127 + +From 128.93.25.32.9875 +v=0 +o=mbone 1782678111 3077454111 IN IP4 128.93.25.32 +s=WebCanal Test Channel +i=Test of WebCanal push channel. For more information, please refer to http://webcanal.inria.fr/ +u=http://webcanal.inria.fr/ +e=mbone@monet.inria.fr +t=0 0 +a=tool:WCaster1.0b +a=pub:mbone +a=logo:http://webcanal.inria.fr/icons/webcanal.gif +a=cat:Test +a=aud:All +a=subs:Public Free +m=midp 47130/2 MIDP/LRMP 0 +c=IN IP4 224.3.88.205/127/2 +b=AS:64 + +From 128.93.25.32.9875 +v=0 +o=mbone 1782678111 3077454111 IN IP4 128.93.25.32 +s=WebCanal Test Channel +i=Test of WebCanal push channel. For more information, please refer to http://webcanal.inria.fr/ +u=http://webcanal.inria.fr/ +e=mbone@monet.inria.fr +t=0 0 +a=tool:WCaster1.0b +a=pub:mbone +a=logo:http://webcanal.inria.fr/icons/webcanal.gif +a=cat:Test +a=aud:All +a=subs:Public Free +m=midp 47130/2 MIDP/LRMP 0 +c=IN IP4 224.3.88.205/127/2 +b=AS:64 + +From 36.24.0.23.35912 +v=0 +o=- 19357 1 IN IP4 171.64.2.89 +s=The Stanford Channel +i=In order to support testing and to provide a consistent source of audio and video material, Stanford University is transmitting the Stanford Channel, M-F, 1-5p PDT. +u=http://tsc.stanford.edu/tsc/ +a=admin:Jim Knox +e=Jim Knox +p=Jim Knox <415-723-5100> +t=3076084800 3084048000 +r=7d 4h 0 1d 2d 3d 4d +a=type:broadcast +a=live +a=channel:External Stanford Channel +a=tool:IP/TV Program Guide 1.5.97 +m=video 62970 RTP/AVP 31 32 96 +c=IN IP4 224.2.205.145/127 +b=AS:2500 +a=quality:7 +a=framerate:15 +a=rtpmap:96 WBIH/90000 +m=audio 17754 RTP/AVP 3 +c=IN IP4 224.2.170.73/127 + +From 210.115.193.22.32819 +v=0 +o=root 3076799605 3076799657 IN IP4 210.115.193.22 +s=KBS 1 TV +i=Korean Broadcasting System TV +u=www.kbs.co.kr +p=KBS 1 TV 82-2-781-2562 +e=KBS 1 TV +t=3076799400 3079225800 +r=1209600 7200 0 +m=audio 20698 RTP/AVP 0 +c=IN IP4 224.2.235.192/127 +m=video 58150 RTP/AVP 31 +c=IN IP4 224.2.202.109/127 + +From 36.24.0.23.35912 +v=0 +o=- 9787 3 IN IP4 36.85.0.135 +s=45th Annual SIAM Meeting +i=MSRI, with the cooperation of Stanford University and SIAM, will broadcast six of the principal lectures from the 45th annual SIAM meeting. Notes available at http://www.msri.org/lecturenotes/97/SIAM/ +u=http://www.siam.org +a=admin:David Hoffman +e=David Hoffman +p=David Hoffman <510-643-6071> +t=3077967600 3078183600 +r=7d 12h 0 1d 2d +a=type:broadcast +a=live +a=channel:MSRI Channel +a=tool:IP/TV Program Guide 1.5.97 +m=video 52704 RTP/AVP 31 32 96 +c=IN IP4 224.2.220.253/127 +b=AS:128 +a=quality:7 +a=framerate:15 +a=rtpmap:96 WBIH/90000 +m=audio 30372 RTP/AVP 0 14 3 5 96 97 98 99 100 101 102 103 +c=IN IP4 224.2.141.197/127 +a=rtpmap:96 L8/22050/2 +a=rtpmap:97 L8/22050 +a=rtpmap:98 L8/11025/2 +a=rtpmap:99 L8/11025 +a=rtpmap:100 L16/22050/2 +a=rtpmap:101 L16/22050 +a=rtpmap:102 L16/11025/2 +a=rtpmap:103 L16/11025 + +From 146.139.72.5.32924 +v=0 +o=root 3077452673 3077455201 IN IP4 146.139.72.5 +s=ANL TelePresence Microscopy Site/Materials MicroCharacterization Collaboratory +i=This is ANL TelePresence Microscopy Site which is part of the DoE 2000 Materials Microcharacterization Collaboratory. It facilitates on-line access to unique resourses at the ANL AAEM and through the MMC, other resources in the Collaboratory at member sites (ORNL, LBNL, Univ. of Illinois and NIST). More information about the TPM and the MMC can be found at http://tpm.amc.anl.gov/mmc +u=http://tpm.amc.anl.gov +p=Nestor J. Zaluzec 630-252-7901 +e=Nestor J. Zaluzec +t=3077445600 3079900800 +r=86400 36000 0 +a=tool:sdr v2.3a1 +a=type:meeting +m=audio 27028 RTP/AVP 0 +c=IN IP4 224.2.222.131/127 +a=ptime:40 +m=video 58800 RTP/AVP 31 +c=IN IP4 224.2.141.204/127 + +From 146.139.72.5.32924 +v=0 +o=root 3077452673 3077455201 IN IP4 146.139.72.5 +s=ANL TelePresence Microscopy Site/Materials MicroCharacterization Collaboratory +i=This is ANL TelePresence Microscopy Site which is part of the DoE 2000 Materials Microcharacterization Collaboratory. It facilitates on-line access to unique resourses at the ANL AAEM and through the MMC, other resources in the Collaboratory at member sites (ORNL, LBNL, Univ. of Illinois and NIST). More information about the TPM and the MMC can be found at http://tpm.amc.anl.gov/mmc +u=http://tpm.amc.anl.gov +p=Nestor J. Zaluzec 630-252-7901 +e=Nestor J. Zaluzec +t=3077445600 3079900800 +r=86400 36000 0 +a=tool:sdr v2.3a1 +a=type:meeting +m=audio 27028 RTP/AVP 0 +c=IN IP4 224.2.222.131/127 +a=ptime:40 +m=video 58800 RTP/AVP 31 +c=IN IP4 224.2.141.204/127 + +From 128.102.84.134.1085 +v=0 +o=shuttle 3075630923 3075633526 IN IP4 128.102.84.134 +s=NASA Space Shuttle STS-94 +i=Video/Audio broadcast of NASA space shuttle mission STS-94, Microgravity Science Laboratory-1. This session is being broadcast as a service to the MBONE community by NASA-Ames Reseach Center. +u=http://www-pao.ksc.nasa.gov/kscpao/kscpao.htm +e=NASA - ARC Digital Video Lab +e=Referenzzentrum __ +e=IN IP4 224.2.212.30/75 +p=NASA - ARC Digital Video Lab (415) 604-6145 +p=Brian Tonner (at LBL) 510-486-5590 +p=Brian Tonner (at UWM) 414-229-4626 +c=IN IP4 224.2.210.20/127 +t=3076354800 3078774000 +m=audio 24680 RTP/AVP 0 +c=IN IP4 224.2.210.20/127 +m=video 56062 RTP/AVP 31 +c=IN IP4 224.2.210.20/127 + +From 129.89.142.50.1175 +v=0 +o=james 3054298051 3054298223 IN IP4 129.89.142.50 +s=FreeBSD Lounge +i=Channel to discuss FreeBSD related issues. Please keep video bandwidth below 64kbps. +e=Jim Lowe +p=Jim Lowe (414) 229-6634 +c=IN IP4 224.2.100.100/127 +t=0 0 +a=tool:sdr v2.2a23 +a=type:test +m=audio 16400 RTP/AVP 0 +c=IN IP4 224.2.100.100/127 +a=ptime:40 +m=video 49200 RTP/AVP 31 +c=IN IP4 224.2.100.102/127 +m=whiteboard 32800 udp wb +c=IN IP4 224.2.100.101/127 +a=orient:portrait +m=text 32900 udp nt +c=IN IP4 224.2.100.103/127 + +From 129.89.142.50.1175 +v=0 +o=james 3054298051 3054298223 IN IP4 129.89.142.50 +s=FreeBSD Lounge +i=Channel to discuss FreeBSD related issues. Please keep video bandwidth below 64kbps. +e=Jim Lowe +p=Jim Lowe (414) 229-6634 +c=IN IP4 224.2.100.100/127 +t=0 0 +a=tool:sdr v2.2a23 +a=type:test +m=audio 16400 RTP/AVP 0 +c=IN IP4 224.2.100.100/127 +a=ptime:40 +m=video 49200 RTP/AVP 31 +c=IN IP4 224.2.100.102/127 +m=whiteboard 32800 udp wb +c=IN IP4 224.2.100.101/127 +a=orient:portrait +m=text 32900 udp nt +c=IN IP4 224.2.100.103/127 + +From 209.1.118.230.9875 +v=0 +o=Administrator 868490998 868548530 IN IP4 209.1.118.230 +s=Ginacarlo's TV +i=Giancarlo's TV Feed from ICAST in Los Gatos +u=http://www.icast.com/ +e=sales@icast.com +p=+01 408 8740700 +t=3080337120 3080689920 +r=79200 7200 0 +a=recvonly +a=tool:ICAST TCC Server V1.0/Build 1-1010 +m=audio 4640 RTP/AVP 0 +c=IN IP4 224.2.100.120/127 +m=video 4920 RTP/AVP 31 +c=IN IP4 224.2.100.120/127 +b=AS:123 +a=framerate:20 +a=quality:7 +a=grayed:0 + +From 128.93.25.32.9875 +v=0 +o=mbone 1782678111 3077454111 IN IP4 128.93.25.32 +s=WebCanal Test Channel +i=Test of WebCanal push channel. For more information, please refer to http://webcanal.inria.fr/ +u=http://webcanal.inria.fr/ +e=mbone@monet.inria.fr +t=0 0 +a=tool:WCaster1.0b +a=pub:mbone +a=logo:http://webcanal.inria.fr/icons/webcanal.gif +a=cat:Test +a=aud:All +a=subs:Public Free +m=midp 47130/2 MIDP/LRMP 0 +c=IN IP4 224.3.88.205/127/2 +b=AS:64 + +From 128.93.25.32.9875 +v=0 +o=mbone 1782678111 3077454111 IN IP4 128.93.25.32 +s=WebCanal Test Channel +i=Test of WebCanal push channel. For more information, please refer to http://webcanal.inria.fr/ +u=http://webcanal.inria.fr/ +e=mbone@monet.inria.fr +t=0 0 +a=tool:WCaster1.0b +a=pub:mbone +a=logo:http://webcanal.inria.fr/icons/webcanal.gif +a=cat:Test +a=aud:All +a=subs:Public Free +m=midp 47130/2 MIDP/LRMP 0 +c=IN IP4 224.3.88.205/127/2 +b=AS:64 + +From 198.147.175.43.5434 +v=0 +o=- 53099 27 IN IP4 198.147.175.59 +s=The World +i=live feed of daily global radio news show +a=admin:Bob Lyons +e=Bob Lyons +t=3076945200 3079465200 +r=1d 4h 0 +a=type:broadcast +a=live +a=channel:WGBH +a=tool:IP/TV Program Guide 1.5.93 +m=video 65036 RTP/AVP 31 32 96 +c=IN IP4 224.2.227.248/127 +b=AS:100 +a=quality:7 +a=framerate:15 +a=rtpmap:96 WBIH/90000 +m=audio 30970 RTP/AVP 0 14 3 5 96 97 98 99 100 101 102 103 +c=IN IP4 224.2.140.132/127 +a=rtpmap:96 L8/22050/2 +a=rtpmap:97 L8/22050 +a=rtpmap:98 L8/11025/2 +a=rtpmap:99 L8/11025 +a=rtpmap:100 L16/22050/2 +a=rtpmap:101 L16/22050 +a=rtpmap:102 L16/11025/2 +a=rtpmap:103 L16/11025 + +From 198.147.175.43.5434 +v=0 +o=- 53099 27 IN IP4 198.147.175.59 +s=The World +i=live feed of daily global radio news show +a=admin:Bob Lyons +e=Bob Lyons +t=3076945200 3079465200 +r=1d 4h 0 +a=type:broadcast +a=live +a=channel:WGBH +a=tool:IP/TV Program Guide 1.5.93 +m=video 65036 RTP/AVP 31 32 96 +c=IN IP4 224.2.227.248/127 +b=AS:100 +a=quality:7 +a=framerate:15 +a=rtpmap:96 WBIH/90000 +m=audio 30970 RTP/AVP 0 14 3 5 96 97 98 99 100 101 102 103 +c=IN IP4 224.2.140.132/127 +a=rtpmap:96 L8/22050/2 +a=rtpmap:97 L8/22050 +a=rtpmap:98 L8/11025/2 +a=rtpmap:99 L8/11025 +a=rtpmap:100 L16/22050/2 +a=rtpmap:101 L16/22050 +a=rtpmap:102 L16/11025/2 +a=rtpmap:103 L16/11025 + +From 128.223.32.151.40710 +v=0 +o=llynch 3075129061 3075129246 IN IP4 128.223.32.151 +s=UO Presents KWAX Classical Radio +i=University of Oregon sponsored classical radio station KWAX-FM +u=http://darkwing.uoregon.edu/~uocomm/ +e=Lucy Lynch (University of Oregon) +p=Lucy Lynch (University of Oregon) (541) 346-1774 +c=IN IP4 224.2.246.13/127 +t=0 0 +a=tool:sdr v2.3a1 +a=type:test +m=audio 30554 RTP/AVP 0 +c=IN IP4 224.2.246.13/127 +a=ptime:40 + +From 130.240.64.67.32877 +v=0 +o=demo 3066564173 3066564269 IN IP4 130.240.64.67 +s=Places all over the world +i=Low bandwidth video (10 kb/s) with views from all over the world. It is probably wise to limit the overall bandwidth to 100 kb/s (that is, a maximum of ten 10 kb/s streams). Audio is primarily for feedback for the senders of video. +e=Hakan Lennestal +c=IN IP4 224.2.172.238/127 +t=0 0 +a=tool:CDT mAnnouncer 1.1.1 +a=type:broadcast +m=video 51482 RTP/AVP 31 +c=IN IP4 224.2.172.238/127 +m=audio 20154 RTP/AVP 121 +c=IN IP4 224.2.213.113/127 +a=rtpred1:5 +a=ptime:40 +a=rtpred2:5 +a=rtpmap:121 red/8000 + +From 130.240.64.67.32877 +v=0 +o=demo 3066564173 3066564269 IN IP4 130.240.64.67 +s=Places all over the world +i=Low bandwidth video (10 kb/s) with views from all over the world. It is probably wise to limit the overall bandwidth to 100 kb/s (that is, a maximum of ten 10 kb/s streams). Audio is primarily for feedback for the senders of video. +e=Hakan Lennestal +c=IN IP4 224.2.172.238/127 +t=0 0 +a=tool:CDT mAnnouncer 1.1.1 +a=type:broadcast +m=video 51482 RTP/AVP 31 +c=IN IP4 224.2.172.238/127 +m=audio 20154 RTP/AVP 121 +c=IN IP4 224.2.213.113/127 +a=rtpred1:5 +a=ptime:40 +a=rtpred2:5 +a=rtpmap:121 red/8000 + +From 199.94.220.184.1277 +v=0 +o=jhawk 3048365419 3049230379 IN IP4 199.94.220.184 +s=MBone RTP Audio +i=Audio conference on vat's former default multicast address. This replaces sd's "MBone Audio". +e=John Hawkinson +p=John Hawkinson +1 617 873 3180 +c=IN IP4 224.2.0.1/191 +t=3048724800 3082593600 +a=tool:sdr v2.3a1+jhawk's gdb script +a=type:meeting +m=audio 23456 RTP/AVP 0 +c=IN IP4 224.2.0.1/191 +a=ptime:40 + +From 199.94.220.184.1277 +v=0 +o=jhawk 3048365419 3049230379 IN IP4 199.94.220.184 +s=MBone RTP Audio +i=Audio conference on vat's former default multicast address. This replaces sd's "MBone Audio". +e=John Hawkinson +p=John Hawkinson +1 617 873 3180 +c=IN IP4 224.2.0.1/191 +t=3048724800 3082593600 +a=tool:sdr v2.3a1+jhawk's gdb script +a=type:meeting +m=audio 23456 RTP/AVP 0 +c=IN IP4 224.2.0.1/191 +a=ptime:40 + +From 36.24.0.23.35920 +v=0 +o=- 19357 1 IN IP4 171.64.2.89 +s=The Stanford Channel +i=In order to support testing and to provide a consistent source of audio and video material, Stanford University is transmitting the Stanford Channel, M-F, 1-5p PDT. +u=http://tsc.stanford.edu/tsc/ +a=admin:Jim Knox +e=Jim Knox +p=Jim Knox <415-723-5100> +t=3076084800 3084048000 +r=7d 4h 0 1d 2d 3d 4d +a=type:broadcast +a=live +a=channel:External Stanford Channel +a=tool:IP/TV Program Guide 1.5.97 +m=video 62970 RTP/AVP 31 32 96 +c=IN IP4 224.2.205.145/127 +b=AS:2500 +a=quality:7 +a=framerate:15 +a=rtpmap:96 WBIH/90000 +m=audio 17754 RTP/AVP 3 +c=IN IP4 224.2.170.73/127 + +From 146.246.238.52.33095 +v=0 +o=dgomes 3076197571 3076936543 IN IP4 146.246.238.52 +s=Diesel Combustion Collaboratory +i=This is a research MBone session initiated from the Sandia National Laboratory, California site. This session will facilitate collaboration among the participants in a distributed research project, specifically the Heavy Duty Diesel Combustion CRADA using standard MBone A/V tools. For more information, http://www-collab.ca.sandia.gov/ +u=www-collab.ca.sandia.gov/ +e=Diesel Combustion Collaboratory +p=Diesel Combustion Collaboratory 510-294-1479 +c=IN IP4 239.32.1.200/127 +t=3076142400 3078648000 +r=86400 86400 0 +a=tool:sdr v2.3a1 +a=type:meeting +m=audio 23164 RTP/AVP 0 +c=IN IP4 239.32.1.200/127 +a=ptime:40 +m=video 53626 RTP/AVP 31 +c=IN IP4 239.32.1.200/127 +m=whiteboard 33870 udp wb +c=IN IP4 239.32.1.200/127 +a=orient:portrait + +From 36.24.0.23.35920 +v=0 +o=- 9787 3 IN IP4 36.85.0.135 +s=45th Annual SIAM Meeting +i=MSRI, with the cooperation of Stanford University and SIAM, will broadcast six of the principal lectures from the 45th annual SIAM meeting. Notes available at http://www.msri.org/lecturenotes/97/SIAM/ +u=http://www.siam.org +a=admin:David Hoffman +e=David Hoffman +p=David Hoffman <510-643-6071> +t=3077967600 3078183600 +r=7d 12h 0 1d 2d +a=type:broadcast +a=live +a=channel:MSRI Channel +a=tool:IP/TV Program Guide 1.5.97 +m=video 52704 RTP/AVP 31 32 96 +c=IN IP4 224.2.220.253/127 +b=AS:128 +a=quality:7 +a=framerate:15 +a=rtpmap:96 WBIH/90000 +m=audio 30372 RTP/AVP 0 14 3 5 96 97 98 99 100 101 102 103 +c=IN IP4 224.2.141.197/127 +a=rtpmap:96 L8/22050/2 +a=rtpmap:97 L8/22050 +a=rtpmap:98 L8/11025/2 +a=rtpmap:99 L8/11025 +a=rtpmap:100 L16/22050/2 +a=rtpmap:101 L16/22050 +a=rtpmap:102 L16/11025/2 +a=rtpmap:103 L16/11025 + +From 128.9.160.43.1290 +v=0 +o=estrin 3077287048 3077287168 IN IP4 128.9.160.43 +s=PIM +i=Weekly discussion of PIM and related issues +p=310 822 1511 x253 +e=estrin@isi.edu +t=3077287200 3079713600 +r=604800 7200 0 +a=tool:sdr v2.2a23 +a=type:test +m=audio 26446 RTP/AVP 5 +c=IN IP4 224.2.237.137/127 +a=ptime:40 +m=whiteboard 48894 udp wb +c=IN IP4 224.2.213.254/127 +m=text 60262 udp nt +c=IN IP4 224.2.186.221/127 + +From 210.115.193.22.32819 +v=0 +o=root 3076799605 3076799657 IN IP4 210.115.193.22 +s=KBS 1 TV +i=Korean Broadcasting System TV +u=www.kbs.co.kr +p=KBS 1 TV 82-2-781-2562 +e=KBS 1 TV +t=3076799400 3079225800 +r=1209600 7200 0 +m=audio 20698 RTP/AVP 0 +c=IN IP4 224.2.235.192/127 +m=video 58150 RTP/AVP 31 +c=IN IP4 224.2.202.109/127 + +From 141.213.8.193.32800 +v=0 +o=sugih 3066072073 3066072112 IN IP4 141.213.8.193 +s=UMich IRL (private) +i=UMich private use +u=http://irl.eecs.umich.edu/jamin/ +e=UMich IRL +p=UMich IRL +1 313 763 1583 +c=IN IP4 224.2.143.56/127 +t=0 0 +a=tool:sdr v2.3a1 +a=type:test +m=audio 21690 RTP/AVP 0 +c=IN IP4 224.2.143.56/127 +a=ptime:40 +m=video 51990 RTP/AVP 31 +c=IN IP4 224.2.200.96/127 +m=whiteboard 47284 udp wb +c=IN IP4 224.2.239.141/127 +m=text 54906 udp nt +c=IN IP4 224.2.242.3/127 + +From 141.213.8.193.32800 +v=0 +o=sugih 3066072073 3066072112 IN IP4 141.213.8.193 +s=UMich IRL (private) +i=UMich private use +u=http://irl.eecs.umich.edu/jamin/ +e=UMich IRL +p=UMich IRL +1 313 763 1583 +c=IN IP4 224.2.143.56/127 +t=0 0 +a=tool:sdr v2.3a1 +a=type:test +m=audio 21690 RTP/AVP 0 +c=IN IP4 224.2.143.56/127 +a=ptime:40 +m=video 51990 RTP/AVP 31 +c=IN IP4 224.2.200.96/127 +m=whiteboard 47284 udp wb +c=IN IP4 224.2.239.141/127 +m=text 54906 udp nt +c=IN IP4 224.2.242.3/127 + +From 209.1.118.230.9875 +v=0 +o=Administrator 868490998 868548530 IN IP4 209.1.118.230 +s=Ginacarlo's TV +i=Giancarlo's TV Feed from ICAST in Los Gatos +u=http://www.icast.com/ +e=sales@icast.com +p=+01 408 8740700 +t=3080337120 3080689920 +r=79200 7200 0 +a=recvonly +a=tool:ICAST TCC Server V1.0/Build 1-1010 +m=audio 4640 RTP/AVP 0 +c=IN IP4 224.2.100.120/127 +m=video 4920 RTP/AVP 31 +c=IN IP4 224.2.100.120/127 +b=AS:123 +a=framerate:20 +a=quality:7 +a=grayed:0 + +From 128.93.25.32.9875 +v=0 +o=mbone 1782678111 3077454111 IN IP4 128.93.25.32 +s=WebCanal Test Channel +i=Test of WebCanal push channel. For more information, please refer to http://webcanal.inria.fr/ +u=http://webcanal.inria.fr/ +e=mbone@monet.inria.fr +t=0 0 +a=tool:WCaster1.0b +a=pub:mbone +a=logo:http://webcanal.inria.fr/icons/webcanal.gif +a=cat:Test +a=aud:All +a=subs:Public Free +m=midp 47130/2 MIDP/LRMP 0 +c=IN IP4 224.3.88.205/127/2 +b=AS:64 + +From 128.93.25.32.9875 +v=0 +o=mbone 1782678111 3077454111 IN IP4 128.93.25.32 +s=WebCanal Test Channel +i=Test of WebCanal push channel. For more information, please refer to http://webcanal.inria.fr/ +u=http://webcanal.inria.fr/ +e=mbone@monet.inria.fr +t=0 0 +a=tool:WCaster1.0b +a=pub:mbone +a=logo:http://webcanal.inria.fr/icons/webcanal.gif +a=cat:Test +a=aud:All +a=subs:Public Free +m=midp 47130/2 MIDP/LRMP 0 +c=IN IP4 224.3.88.205/127/2 +b=AS:64 + +From 128.223.32.151.40710 +v=0 +o=llynch 3073936480 3075057183 IN IP4 128.223.32.151 +s=UO Presents KWVA Campus Radio +i=University of Oregon alternative radio +u=http://gladstone.uoregon.edu/~kwva/ +e=Lucy Lynch (University of Oregon) +p=Lucy Lynch (University of Oregon) (541) 346-1774 +c=IN IP4 224.2.240.123/127 +t=0 0 +a=tool:sdr v2.3a1 +a=type:test +m=audio 24676 RTP/AVP 0 +c=IN IP4 224.2.240.123/127 +a=ptime:40 + +From 128.102.84.134.1085 +v=0 +o=shuttle 3075630923 3075633526 IN IP4 128.102.84.134 +s=NASA Space Shuttle STS-94 +i=Video/Audio broadcast of NASA space shuttle mission STS-94, Microgravity Science Laboratory-1. This session is being broadcast as a service to the MBONE community by NASA-Ames Reseach Center. +u=http://www-pao.ksc.nasa.gov/kscpao/kscpao.htm +e=NASA - ARC Digital Video Lab +e=Referenzzentrum __ +e=IN IP4 224.2.212.30/75 +p=NASA - ARC Digital Video Lab (415) 604-6145 +p=Brian Tonner (at LBL) 510-486-5590 +p=Brian Tonner (at UWM) 414-229-4626 +c=IN IP4 224.2.210.20/127 +t=3076354800 3078774000 +m=audio 24680 RTP/AVP 0 +c=IN IP4 224.2.210.20/127 +m=video 56062 RTP/AVP 31 +c=IN IP4 224.2.210.20/127 + +From 134.95.100.200.58695 +v=0 +o=maho 3077528617 3077529148 IN IP4 134.95.19.9 +s=Munich IETF Meeting - 1 +c=IN IP4 224.2.224.236/127 +i=The thirty-nineth IETF meeting will be held in Munich, Germany, 11-15 August 1997. Channel 1 contains sessions in room Congress AB. +u=http://www.ietf.org/meetings/Munich.html +e=Martin Horneffer (RRZK) +p=Martin Horneffer (RRZK) +49-221-4785587 +k= +t=3080271600 3080617200 +a=tool:CDT sapAnnouncer 1.1 +a=type:test +m=audio 30284 RTP/AVP 0 +c=IN IP4 224.2.224.236/127 +a=ptime:40 +m=video 64318 RTP/AVP 31 +c=IN IP4 224.2.191.28/127 +m=whiteboard 43063 udp wb +c=IN IP4 224.2.164.26/127 +m=text 65035 udp nt +c=IN IP4 224.2.148.199/127 + +From 134.95.100.200.58695 +v=0 +o=maho 3077529159 3077529337 IN IP4 134.95.19.9 +s=Munich IETF Meeting - 2 +c=IN IP4 224.2.128.106/127 +i=The thirty-nineth IETF meeting will be held in Munich, Germany, 11-15 August 1997. Channel 1 contains sessions in room Congress 1. +u=http://www.ietf.org/meetings/Munich.html +e=Martin Horneffer (RRZK) +p=Martin Horneffer (RRZK) +49-221-4785587 +k= +t=3080271600 3080617200 +a=tool:CDT sapAnnouncer 1.1 +a=type:test +m=audio 25056 RTP/AVP 0 +c=IN IP4 224.2.128.106/127 +a=ptime:40 +m=video 55020 RTP/AVP 31 +c=IN IP4 224.2.216.39/127 +m=whiteboard 47819 udp wb +c=IN IP4 224.2.139.138/127 +m=text 50930 udp nt +c=IN IP4 224.2.161.177/127 + +From 134.95.100.200.58695 +v=0 +o=maho 3077528617 3077529148 IN IP4 134.95.19.9 +s=Munich IETF Meeting - 1 +c=IN IP4 224.2.224.236/127 +i=The thirty-nineth IETF meeting will be held in Munich, Germany, 11-15 August 1997. Channel 1 contains sessions in room Congress AB. +u=http://www.ietf.org/meetings/Munich.html +e=Martin Horneffer (RRZK) +p=Martin Horneffer (RRZK) +49-221-4785587 +k= +t=3080271600 3080617200 +a=tool:CDT sapAnnouncer 1.1 +a=type:test +m=audio 30284 RTP/AVP 0 +c=IN IP4 224.2.224.236/127 +a=ptime:40 +m=video 64318 RTP/AVP 31 +c=IN IP4 224.2.191.28/127 +m=whiteboard 43063 udp wb +c=IN IP4 224.2.164.26/127 +m=text 65035 udp nt +c=IN IP4 224.2.148.199/127 + +From 128.9.160.67.1286 +v=0 +o=kannan 3077640111 3077640271 IN IP4 128.9.160.67 +s=VINT (private) +i=Virtual conference room for VINT developers +u=http://netweb.usc.edu/vint +e=Kannan Varadhan +p=Kannan Varadhan +1 310 822 1511 x742 +c=IN IP4 224.2.211.93/127 +t=0 0 +a=tool:sdr v2.4a6 +a=type:meeting +m=audio 32390 RTP/AVP 5 +c=IN IP4 224.2.211.93/127 +a=ptime:40 +m=whiteboard 44600 udp wb +c=IN IP4 224.2.163.53/127 +a=orient:landscape +m=text 51493 udp nt +c=IN IP4 224.2.208.110/127 + +From 128.146.222.100.32915 +v=0 +o=maf 3076346251 3077639429 IN IP4 128.146.222.100 +s=Recent Advances in Networking Seminar at OSU +i=Live Transmission of Professor Raj Jain's class CIS788.08q: Recent Advances in Networking every Tuesday and Thursday at 17:30 to 18:45 EDT, Open to public. E-mail questions to mbone@netlab.ohio-state.edu. See URL for list of topics. +u=http://www.cis.ohio-state.edu/~jain/cis788-97/schedule.htm +p=Mark Fullmer (Ohio State) 614-292-6159 +e=Mark Fullmer (Ohio State) +t=3078163800 3079380600 +r=604800 7200 0 +a=tool:sdr v2.3a1 +a=type:broadcast +m=audio 19922 RTP/AVP 0 +c=IN IP4 224.2.232.28/127 +a=ptime:40 +m=video 60266 RTP/AVP 31 +c=IN IP4 224.2.159.63/127 + +From 128.146.222.100.32915 +v=0 +o=maf 3076346251 3077639429 IN IP4 128.146.222.100 +s=Recent Advances in Networking Seminar at OSU +i=Live Transmission of Professor Raj Jain's class CIS788.08q: Recent Advances in Networking every Tuesday and Thursday at 17:30 to 18:45 EDT, Open to public. E-mail questions to mbone@netlab.ohio-state.edu. See URL for list of topics. +u=http://www.cis.ohio-state.edu/~jain/cis788-97/schedule.htm +p=Mark Fullmer (Ohio State) 614-292-6159 +e=Mark Fullmer (Ohio State) +t=3078163800 3079380600 +r=604800 7200 0 +a=tool:sdr v2.3a1 +a=type:broadcast +m=audio 19922 RTP/AVP 0 +c=IN IP4 224.2.232.28/127 +a=ptime:40 +m=video 60266 RTP/AVP 31 +c=IN IP4 224.2.159.63/127 + +From 128.9.160.67.1286 +v=0 +o=kannan 3076332385 3076332494 IN IP4 128.9.160.67 +s=USC-CS dgroup VR conference room (private) +i=Watering hole for the USC-NIL lab members +u=http://netweb.usc.edu/ +e=Kannan Varadhan +p=Kannan Varadhan +1 310 822 1511 x742 +c=IN IP4 224.2.212.30/75 +t=0 0 +a=tool:sdr v2.3a1 +a=type:meeting +m=audio 45144 RTP/AVP 5 +c=IN IP4 224.2.212.30/75 +a=ptime:40 +m=whiteboard 65304 udp wb +c=IN IP4 224.2.212.30/75 +a=orient:landscape + +From 198.147.175.43.5435 +v=0 +o=- 53099 27 IN IP4 198.147.175.59 +s=The World +i=live feed of daily global radio news show +a=admin:Bob Lyons +e=Bob Lyons +t=3076945200 3079465200 +r=1d 4h 0 +a=type:broadcast +a=live +a=channel:WGBH +a=tool:IP/TV Program Guide 1.5.93 +m=video 65036 RTP/AVP 31 32 96 +c=IN IP4 224.2.227.248/127 +b=AS:100 +a=quality:7 +a=framerate:15 +a=rtpmap:96 WBIH/90000 +m=audio 30970 RTP/AVP 0 14 3 5 96 97 98 99 100 101 102 103 +c=IN IP4 224.2.140.132/127 +a=rtpmap:96 L8/22050/2 +a=rtpmap:97 L8/22050 +a=rtpmap:98 L8/11025/2 +a=rtpmap:99 L8/11025 +a=rtpmap:100 L16/22050/2 +a=rtpmap:101 L16/22050 +a=rtpmap:102 L16/11025/2 +a=rtpmap:103 L16/11025 + +From 198.147.175.43.5435 +v=0 +o=- 53099 27 IN IP4 198.147.175.59 +s=The World +i=live feed of daily global radio news show +a=admin:Bob Lyons +e=Bob Lyons +t=3076945200 3079465200 +r=1d 4h 0 +a=type:broadcast +a=live +a=channel:WGBH +a=tool:IP/TV Program Guide 1.5.93 +m=video 65036 RTP/AVP 31 32 96 +c=IN IP4 224.2.227.248/127 +b=AS:100 +a=quality:7 +a=framerate:15 +a=rtpmap:96 WBIH/90000 +m=audio 30970 RTP/AVP 0 14 3 5 96 97 98 99 100 101 102 103 +c=IN IP4 224.2.140.132/127 +a=rtpmap:96 L8/22050/2 +a=rtpmap:97 L8/22050 +a=rtpmap:98 L8/11025/2 +a=rtpmap:99 L8/11025 +a=rtpmap:100 L16/22050/2 +a=rtpmap:101 L16/22050 +a=rtpmap:102 L16/11025/2 +a=rtpmap:103 L16/11025 + +From 146.139.72.5.32924 +v=0 +o=root 3077452673 3077455201 IN IP4 146.139.72.5 +s=ANL TelePresence Microscopy Site/Materials MicroCharacterization Collaboratory +i=This is ANL TelePresence Microscopy Site which is part of the DoE 2000 Materials Microcharacterization Collaboratory. It facilitates on-line access to unique resourses at the ANL AAEM and through the MMC, other resources in the Collaboratory at member sites (ORNL, LBNL, Univ. of Illinois and NIST). More information about the TPM and the MMC can be found at http://tpm.amc.anl.gov/mmc +u=http://tpm.amc.anl.gov +p=Nestor J. Zaluzec 630-252-7901 +e=Nestor J. Zaluzec +t=3077445600 3079900800 +r=86400 36000 0 +a=tool:sdr v2.3a1 +a=type:meeting +m=audio 27028 RTP/AVP 0 +c=IN IP4 224.2.222.131/127 +a=ptime:40 +m=video 58800 RTP/AVP 31 +c=IN IP4 224.2.141.204/127 + +From 146.139.72.5.32924 +v=0 +o=root 3077452673 3077455201 IN IP4 146.139.72.5 +s=ANL TelePresence Microscopy Site/Materials MicroCharacterization Collaboratory +i=This is ANL TelePresence Microscopy Site which is part of the DoE 2000 Materials Microcharacterization Collaboratory. It facilitates on-line access to unique resourses at the ANL AAEM and through the MMC, other resources in the Collaboratory at member sites (ORNL, LBNL, Univ. of Illinois and NIST). More information about the TPM and the MMC can be found at http://tpm.amc.anl.gov/mmc +u=http://tpm.amc.anl.gov +p=Nestor J. Zaluzec 630-252-7901 +e=Nestor J. Zaluzec +t=3077445600 3079900800 +r=86400 36000 0 +a=tool:sdr v2.3a1 +a=type:meeting +m=audio 27028 RTP/AVP 0 +c=IN IP4 224.2.222.131/127 +a=ptime:40 +m=video 58800 RTP/AVP 31 +c=IN IP4 224.2.141.204/127 + +From 140.247.157.193.1047 +v=0 +o=karp 3077576976 3077577964 IN IP4 140.247.157.193 +s=Harvard's Aiken Computation Lab DEMOLITION +i=Live broadcast of the demolition of Harvard University's Aiken Computation Lab, to make way for the new Computer Science building, Maxwell-Dworkin. Broadcast will include commentary on the event by Harvard faculty, administrators, and students. Filmed in Destruct-O-Vision, from an unmanned camera INSIDE Aiken. +u=http://www.eecs.harvard.edu/aiken-go-boom +e=Brad Karp +p=Brad Karp +1 617-661-4979 +c=IN IP4 224.2.156.29/127 +t=3078820800 3080030400 +a=tool:sdr v2.4a6 +a=type:broadcast +m=audio 21226 RTP/AVP 5 +c=IN IP4 224.2.156.29/127 +a=ptime:40 +m=video 49998 RTP/AVP 31 +c=IN IP4 224.2.237.48/127 + +From 140.247.157.193.1047 +v=0 +o=karp 3077576976 3077577964 IN IP4 140.247.157.193 +s=Harvard's Aiken Computation Lab DEMOLITION +i=Live broadcast of the demolition of Harvard University's Aiken Computation Lab, to make way for the new Computer Science building, Maxwell-Dworkin. Broadcast will include commentary on the event by Harvard faculty, administrators, and students. Filmed in Destruct-O-Vision, from an unmanned camera INSIDE Aiken. +u=http://www.eecs.harvard.edu/aiken-go-boom +e=Brad Karp +p=Brad Karp +1 617-661-4979 +c=IN IP4 224.2.156.29/127 +t=3078820800 3080030400 +a=tool:sdr v2.4a6 +a=type:broadcast +m=audio 21226 RTP/AVP 5 +c=IN IP4 224.2.156.29/127 +a=ptime:40 +m=video 49998 RTP/AVP 31 +c=IN IP4 224.2.237.48/127 + +From 209.1.118.230.9875 +v=0 +o=Administrator 868490998 868548530 IN IP4 209.1.118.230 +s=Ginacarlo's TV +i=Giancarlo's TV Feed from ICAST in Los Gatos +u=http://www.icast.com/ +e=sales@icast.com +p=+01 408 8740700 +t=3080337120 3080689920 +r=79200 7200 0 +a=recvonly +a=tool:ICAST TCC Server V1.0/Build 1-1010 +m=audio 4640 RTP/AVP 0 +c=IN IP4 224.2.100.120/127 +m=video 4920 RTP/AVP 31 +c=IN IP4 224.2.100.120/127 +b=AS:123 +a=framerate:20 +a=quality:7 +a=grayed:0 + +From 128.93.25.32.9875 +v=0 +o=mbone 1782678111 3077454111 IN IP4 128.93.25.32 +s=WebCanal Test Channel +i=Test of WebCanal push channel. For more information, please refer to http://webcanal.inria.fr/ +u=http://webcanal.inria.fr/ +e=mbone@monet.inria.fr +t=0 0 +a=tool:WCaster1.0b +a=pub:mbone +a=logo:http://webcanal.inria.fr/icons/webcanal.gif +a=cat:Test +a=aud:All +a=subs:Public Free +m=midp 47130/2 MIDP/LRMP 0 +c=IN IP4 224.3.88.205/127/2 +b=AS:64 + +From 128.93.25.32.9875 +v=0 +o=mbone 1782678111 3077454111 IN IP4 128.93.25.32 +s=WebCanal Test Channel +i=Test of WebCanal push channel. For more information, please refer to http://webcanal.inria.fr/ +u=http://webcanal.inria.fr/ +e=mbone@monet.inria.fr +t=0 0 +a=tool:WCaster1.0b +a=pub:mbone +a=logo:http://webcanal.inria.fr/icons/webcanal.gif +a=cat:Test +a=aud:All +a=subs:Public Free +m=midp 47130/2 MIDP/LRMP 0 +c=IN IP4 224.3.88.205/127/2 +b=AS:64 + +From 130.240.64.67.32877 +v=0 +o=demo 3066564173 3066564269 IN IP4 130.240.64.67 +s=Places all over the world +i=Low bandwidth video (10 kb/s) with views from all over the world. It is probably wise to limit the overall bandwidth to 100 kb/s (that is, a maximum of ten 10 kb/s streams). Audio is primarily for feedback for the senders of video. +e=Hakan Lennestal +c=IN IP4 224.2.172.238/127 +t=0 0 +a=tool:CDT mAnnouncer 1.1.1 +a=type:broadcast +m=video 51482 RTP/AVP 31 +c=IN IP4 224.2.172.238/127 +m=audio 20154 RTP/AVP 121 +c=IN IP4 224.2.213.113/127 +a=rtpred1:5 +a=ptime:40 +a=rtpred2:5 +a=rtpmap:121 red/8000 + +From 130.240.64.67.32877 +v=0 +o=demo 3066564173 3066564269 IN IP4 130.240.64.67 +s=Places all over the world +i=Low bandwidth video (10 kb/s) with views from all over the world. It is probably wise to limit the overall bandwidth to 100 kb/s (that is, a maximum of ten 10 kb/s streams). Audio is primarily for feedback for the senders of video. +e=Hakan Lennestal +c=IN IP4 224.2.172.238/127 +t=0 0 +a=tool:CDT mAnnouncer 1.1.1 +a=type:broadcast +m=video 51482 RTP/AVP 31 +c=IN IP4 224.2.172.238/127 +m=audio 20154 RTP/AVP 121 +c=IN IP4 224.2.213.113/127 +a=rtpred1:5 +a=ptime:40 +a=rtpred2:5 +a=rtpmap:121 red/8000 + +From 129.89.142.50.1175 +v=0 +o=james 3054298051 3054298223 IN IP4 129.89.142.50 +s=FreeBSD Lounge +i=Channel to discuss FreeBSD related issues. Please keep video bandwidth below 64kbps. +e=Jim Lowe +p=Jim Lowe (414) 229-6634 +c=IN IP4 224.2.100.100/127 +t=0 0 +a=tool:sdr v2.2a23 +a=type:test +m=audio 16400 RTP/AVP 0 +c=IN IP4 224.2.100.100/127 +a=ptime:40 +m=video 49200 RTP/AVP 31 +c=IN IP4 224.2.100.102/127 +m=whiteboard 32800 udp wb +c=IN IP4 224.2.100.101/127 +a=orient:portrait +m=text 32900 udp nt +c=IN IP4 224.2.100.103/127 + +From 129.89.142.50.1175 +v=0 +o=james 3054298051 3054298223 IN IP4 129.89.142.50 +s=FreeBSD Lounge +i=Channel to discuss FreeBSD related issues. Please keep video bandwidth below 64kbps. +e=Jim Lowe +p=Jim Lowe (414) 229-6634 +c=IN IP4 224.2.100.100/127 +t=0 0 +a=tool:sdr v2.2a23 +a=type:test +m=audio 16400 RTP/AVP 0 +c=IN IP4 224.2.100.100/127 +a=ptime:40 +m=video 49200 RTP/AVP 31 +c=IN IP4 224.2.100.102/127 +m=whiteboard 32800 udp wb +c=IN IP4 224.2.100.101/127 +a=orient:portrait +m=text 32900 udp nt +c=IN IP4 224.2.100.103/127 + +From 36.24.0.23.35921 +v=0 +o=- 19357 1 IN IP4 171.64.2.89 +s=The Stanford Channel +i=In order to support testing and to provide a consistent source of audio and video material, Stanford University is transmitting the Stanford Channel, M-F, 1-5p PDT. +u=http://tsc.stanford.edu/tsc/ +a=admin:Jim Knox +e=Jim Knox +p=Jim Knox <415-723-5100> +t=3076084800 3084048000 +r=7d 4h 0 1d 2d 3d 4d +a=type:broadcast +a=live +a=channel:External Stanford Channel +a=tool:IP/TV Program Guide 1.5.97 +m=video 62970 RTP/AVP 31 32 96 +c=IN IP4 224.2.205.145/127 +b=AS:2500 +a=quality:7 +a=framerate:15 +a=rtpmap:96 WBIH/90000 +m=audio 17754 RTP/AVP 3 +c=IN IP4 224.2.170.73/127 + +From 36.24.0.23.35921 +v=0 +o=- 9787 3 IN IP4 36.85.0.135 +s=45th Annual SIAM Meeting +i=MSRI, with the cooperation of Stanford University and SIAM, will broadcast six of the principal lectures from the 45th annual SIAM meeting. Notes available at http://www.msri.org/lecturenotes/97/SIAM/ +u=http://www.siam.org +a=admin:David Hoffman +e=David Hoffman +p=David Hoffman <510-643-6071> +t=3077967600 3078183600 +r=7d 12h 0 1d 2d +a=type:broadcast +a=live +a=channel:MSRI Channel +a=tool:IP/TV Program Guide 1.5.97 +m=video 52704 RTP/AVP 31 32 96 +c=IN IP4 224.2.220.253/127 +b=AS:128 +a=quality:7 +a=framerate:15 +a=rtpmap:96 WBIH/90000 +m=audio 30372 RTP/AVP 0 14 3 5 96 97 98 99 100 101 102 103 +c=IN IP4 224.2.141.197/127 +a=rtpmap:96 L8/22050/2 +a=rtpmap:97 L8/22050 +a=rtpmap:98 L8/11025/2 +a=rtpmap:99 L8/11025 +a=rtpmap:100 L16/22050/2 +a=rtpmap:101 L16/22050 +a=rtpmap:102 L16/11025/2 +a=rtpmap:103 L16/11025 + +From 128.102.84.134.1085 +v=0 +o=shuttle 3075630923 3075633526 IN IP4 128.102.84.134 +s=NASA Space Shuttle STS-94 +i=Video/Audio broadcast of NASA space shuttle mission STS-94, Microgravity Science Laboratory-1. This session is being broadcast as a service to the MBONE community by NASA-Ames Reseach Center. +u=http://www-pao.ksc.nasa.gov/kscpao/kscpao.htm +e=NASA - ARC Digital Video Lab +e=Referenzzentrum __ +e=IN IP4 224.2.212.30/75 +p=NASA - ARC Digital Video Lab (415) 604-6145 +p=Brian Tonner (at LBL) 510-486-5590 +p=Brian Tonner (at UWM) 414-229-4626 +c=IN IP4 224.2.210.20/127 +t=3076354800 3078774000 +m=audio 24680 RTP/AVP 0 +c=IN IP4 224.2.210.20/127 +m=video 56062 RTP/AVP 31 +c=IN IP4 224.2.210.20/127 + +From 146.246.238.52.33095 +v=0 +o=dgomes 3076197571 3076936543 IN IP4 146.246.238.52 +s=Diesel Combustion Collaboratory +i=This is a research MBone session initiated from the Sandia National Laboratory, California site. This session will facilitate collaboration among the participants in a distributed research project, specifically the Heavy Duty Diesel Combustion CRADA using standard MBone A/V tools. For more information, http://www-collab.ca.sandia.gov/ +u=www-collab.ca.sandia.gov/ +e=Diesel Combustion Collaboratory +p=Diesel Combustion Collaboratory 510-294-1479 +c=IN IP4 239.32.1.200/127 +t=3076142400 3078648000 +r=86400 86400 0 +a=tool:sdr v2.3a1 +a=type:meeting +m=audio 23164 RTP/AVP 0 +c=IN IP4 239.32.1.200/127 +a=ptime:40 +m=video 53626 RTP/AVP 31 +c=IN IP4 239.32.1.200/127 +m=whiteboard 33870 udp wb +c=IN IP4 239.32.1.200/127 +a=orient:portrait + +From 210.115.193.22.32819 +v=0 +o=root 3076799605 3076799657 IN IP4 210.115.193.22 +s=KBS 1 TV +i=Korean Broadcasting System TV +u=www.kbs.co.kr +p=KBS 1 TV 82-2-781-2562 +e=KBS 1 TV +t=3076799400 3079225800 +r=1209600 7200 0 +m=audio 20698 RTP/AVP 0 +c=IN IP4 224.2.235.192/127 +m=video 58150 RTP/AVP 31 +c=IN IP4 224.2.202.109/127 + +From 199.94.220.184.1277 +v=0 +o=jhawk 3048365419 3049230379 IN IP4 199.94.220.184 +s=MBone RTP Audio +i=Audio conference on vat's former default multicast address. This replaces sd's "MBone Audio". +e=John Hawkinson +p=John Hawkinson +1 617 873 3180 +c=IN IP4 224.2.0.1/191 +t=3048724800 3082593600 +a=tool:sdr v2.3a1+jhawk's gdb script +a=type:meeting +m=audio 23456 RTP/AVP 0 +c=IN IP4 224.2.0.1/191 +a=ptime:40 + +From 199.94.220.184.1277 +v=0 +o=jhawk 3048365419 3049230379 IN IP4 199.94.220.184 +s=MBone RTP Audio +i=Audio conference on vat's former default multicast address. This replaces sd's "MBone Audio". +e=John Hawkinson +p=John Hawkinson +1 617 873 3180 +c=IN IP4 224.2.0.1/191 +t=3048724800 3082593600 +a=tool:sdr v2.3a1+jhawk's gdb script +a=type:meeting +m=audio 23456 RTP/AVP 0 +c=IN IP4 224.2.0.1/191 +a=ptime:40 + +From 128.223.32.151.40710 +v=0 +o=llynch 3075129061 3075129246 IN IP4 128.223.32.151 +s=UO Presents KWAX Classical Radio +i=University of Oregon sponsored classical radio station KWAX-FM +u=http://darkwing.uoregon.edu/~uocomm/ +e=Lucy Lynch (University of Oregon) +p=Lucy Lynch (University of Oregon) (541) 346-1774 +c=IN IP4 224.2.246.13/127 +t=0 0 +a=tool:sdr v2.3a1 +a=type:test +m=audio 30554 RTP/AVP 0 +c=IN IP4 224.2.246.13/127 +a=ptime:40 + +From 209.1.118.230.9875 +v=0 +o=Administrator 868490998 868548530 IN IP4 209.1.118.230 +s=Ginacarlo's TV +i=Giancarlo's TV Feed from ICAST in Los Gatos +u=http://www.icast.com/ +e=sales@icast.com +p=+01 408 8740700 +t=3080337120 3080689920 +r=79200 7200 0 +a=recvonly +a=tool:ICAST TCC Server V1.0/Build 1-1010 +m=audio 4640 RTP/AVP 0 +c=IN IP4 224.2.100.120/127 +m=video 4920 RTP/AVP 31 +c=IN IP4 224.2.100.120/127 +b=AS:123 +a=framerate:20 +a=quality:7 +a=grayed:0 + +From 198.147.175.43.5436 +v=0 +o=- 53099 27 IN IP4 198.147.175.59 +s=The World +i=live feed of daily global radio news show +a=admin:Bob Lyons +e=Bob Lyons +t=3076945200 3079465200 +r=1d 4h 0 +a=type:broadcast +a=live +a=channel:WGBH +a=tool:IP/TV Program Guide 1.5.93 +m=video 65036 RTP/AVP 31 32 96 +c=IN IP4 224.2.227.248/127 +b=AS:100 +a=quality:7 +a=framerate:15 +a=rtpmap:96 WBIH/90000 +m=audio 30970 RTP/AVP 0 14 3 5 96 97 98 99 100 101 102 103 +c=IN IP4 224.2.140.132/127 +a=rtpmap:96 L8/22050/2 +a=rtpmap:97 L8/22050 +a=rtpmap:98 L8/11025/2 +a=rtpmap:99 L8/11025 +a=rtpmap:100 L16/22050/2 +a=rtpmap:101 L16/22050 +a=rtpmap:102 L16/11025/2 +a=rtpmap:103 L16/11025 + +From 141.213.8.193.32800 +v=0 +o=sugih 3066072073 3066072112 IN IP4 141.213.8.193 +s=UMich IRL (private) +i=UMich private use +u=http://irl.eecs.umich.edu/jamin/ +e=UMich IRL +p=UMich IRL +1 313 763 1583 +c=IN IP4 224.2.143.56/127 +t=0 0 +a=tool:sdr v2.3a1 +a=type:test +m=audio 21690 RTP/AVP 0 +c=IN IP4 224.2.143.56/127 +a=ptime:40 +m=video 51990 RTP/AVP 31 +c=IN IP4 224.2.200.96/127 +m=whiteboard 47284 udp wb +c=IN IP4 224.2.239.141/127 +m=text 54906 udp nt +c=IN IP4 224.2.242.3/127 + +From 141.213.8.193.32800 +v=0 +o=sugih 3066072073 3066072112 IN IP4 141.213.8.193 +s=UMich IRL (private) +i=UMich private use +u=http://irl.eecs.umich.edu/jamin/ +e=UMich IRL +p=UMich IRL +1 313 763 1583 +c=IN IP4 224.2.143.56/127 +t=0 0 +a=tool:sdr v2.3a1 +a=type:test +m=audio 21690 RTP/AVP 0 +c=IN IP4 224.2.143.56/127 +a=ptime:40 +m=video 51990 RTP/AVP 31 +c=IN IP4 224.2.200.96/127 +m=whiteboard 47284 udp wb +c=IN IP4 224.2.239.141/127 +m=text 54906 udp nt +c=IN IP4 224.2.242.3/127 + +From 128.9.160.67.1286 +v=0 +o=kannan 3076332385 3076332494 IN IP4 128.9.160.67 +s=USC-CS dgroup VR conference room (private) +i=Watering hole for the USC-NIL lab members +u=http://netweb.usc.edu/ +e=Kannan Varadhan +p=Kannan Varadhan +1 310 822 1511 x742 +c=IN IP4 224.2.212.30/75 +t=0 0 +a=tool:sdr v2.3a1 +a=type:meeting +m=audio 45144 RTP/AVP 5 +c=IN IP4 224.2.212.30/75 +a=ptime:40 +m=whiteboard 65304 udp wb +c=IN IP4 224.2.212.30/75 +a=orient:landscape + +From 146.139.72.5.32924 +v=0 +o=root 3077452673 3077455201 IN IP4 146.139.72.5 +s=ANL TelePresence Microscopy Site/Materials MicroCharacterization Collaboratory +i=This is ANL TelePresence Microscopy Site which is part of the DoE 2000 Materials Microcharacterization Collaboratory. It facilitates on-line access to unique resourses at the ANL AAEM and through the MMC, other resources in the Collaboratory at member sites (ORNL, LBNL, Univ. of Illinois and NIST). More information about the TPM and the MMC can be found at http://tpm.amc.anl.gov/mmc +u=http://tpm.amc.anl.gov +p=Nestor J. Zaluzec 630-252-7901 +e=Nestor J. Zaluzec +t=3077445600 3079900800 +r=86400 36000 0 +a=tool:sdr v2.3a1 +a=type:meeting +m=audio 27028 RTP/AVP 0 +c=IN IP4 224.2.222.131/127 +a=ptime:40 +m=video 58800 RTP/AVP 31 +c=IN IP4 224.2.141.204/127 + +From 146.139.72.5.32924 +v=0 +o=root 3077452673 3077455201 IN IP4 146.139.72.5 +s=ANL TelePresence Microscopy Site/Materials MicroCharacterization Collaboratory +i=This is ANL TelePresence Microscopy Site which is part of the DoE 2000 Materials Microcharacterization Collaboratory. It facilitates on-line access to unique resourses at the ANL AAEM and through the MMC, other resources in the Collaboratory at member sites (ORNL, LBNL, Univ. of Illinois and NIST). More information about the TPM and the MMC can be found at http://tpm.amc.anl.gov/mmc +u=http://tpm.amc.anl.gov +p=Nestor J. Zaluzec 630-252-7901 +e=Nestor J. Zaluzec +t=3077445600 3079900800 +r=86400 36000 0 +a=tool:sdr v2.3a1 +a=type:meeting +m=audio 27028 RTP/AVP 0 +c=IN IP4 224.2.222.131/127 +a=ptime:40 +m=video 58800 RTP/AVP 31 +c=IN IP4 224.2.141.204/127 + +From 130.240.64.67.32877 +v=0 +o=demo 3066564173 3066564269 IN IP4 130.240.64.67 +s=Places all over the world +i=Low bandwidth video (10 kb/s) with views from all over the world. It is probably wise to limit the overall bandwidth to 100 kb/s (that is, a maximum of ten 10 kb/s streams). Audio is primarily for feedback for the senders of video. +e=Hakan Lennestal +c=IN IP4 224.2.172.238/127 +t=0 0 +a=tool:CDT mAnnouncer 1.1.1 +a=type:broadcast +m=video 51482 RTP/AVP 31 +c=IN IP4 224.2.172.238/127 +m=audio 20154 RTP/AVP 121 +c=IN IP4 224.2.213.113/127 +a=rtpred1:5 +a=ptime:40 +a=rtpred2:5 +a=rtpmap:121 red/8000 + +From 130.240.64.67.32877 +v=0 +o=demo 3066564173 3066564269 IN IP4 130.240.64.67 +s=Places all over the world +i=Low bandwidth video (10 kb/s) with views from all over the world. It is probably wise to limit the overall bandwidth to 100 kb/s (that is, a maximum of ten 10 kb/s streams). Audio is primarily for feedback for the senders of video. +e=Hakan Lennestal +c=IN IP4 224.2.172.238/127 +t=0 0 +a=tool:CDT mAnnouncer 1.1.1 +a=type:broadcast +m=video 51482 RTP/AVP 31 +c=IN IP4 224.2.172.238/127 +m=audio 20154 RTP/AVP 121 +c=IN IP4 224.2.213.113/127 +a=rtpred1:5 +a=ptime:40 +a=rtpred2:5 +a=rtpmap:121 red/8000 + +From 128.102.84.134.1085 +v=0 +o=shuttle 3075630923 3075633526 IN IP4 128.102.84.134 +s=NASA Space Shuttle STS-94 +i=Video/Audio broadcast of NASA space shuttle mission STS-94, Microgravity Science Laboratory-1. This session is being broadcast as a service to the MBONE community by NASA-Ames Reseach Center. +u=http://www-pao.ksc.nasa.gov/kscpao/kscpao.htm +e=NASA - ARC Digital Video Lab +e=Referenzzentrum __ +e=IN IP4 224.2.212.30/75 +p=NASA - ARC Digital Video Lab (415) 604-6145 +p=Brian Tonner (at LBL) 510-486-5590 +p=Brian Tonner (at UWM) 414-229-4626 +c=IN IP4 224.2.210.20/127 +t=3076354800 3078774000 +m=audio 24680 RTP/AVP 0 +c=IN IP4 224.2.210.20/127 +m=video 56062 RTP/AVP 31 +c=IN IP4 224.2.210.20/127 + +^?kohala % exit + +script done on Sat Jul 12 16:08:04 1997 diff --git a/names/Makefile b/names/Makefile new file mode 100644 index 0000000..f2463a2 --- /dev/null +++ b/names/Makefile @@ -0,0 +1,74 @@ +include ../Make.defines + +PROGS = daytimetcpcli daytimetcpcli1 daytimetcpsrv1 daytimetcpsrv2 \ + daytimetcpsrv3 daytimetcpsrv4 \ + daytimeudpcli1 daytimetcpcli2 daytimetcpcli3 \ + daytimeudpcli2 daytimeudpsrv2 daytimeudpsrv3 \ + hostent hostent2 hostent3 \ + netent prmyaddrs prmyaddrs1 test1 + +all: ${PROGS} + +daytimetcpcli: daytimetcpcli.o + ${CC} ${CFLAGS} -o $@ daytimetcpcli.o ${LIBS} + +daytimetcpcli1: daytimetcpcli1.o + ${CC} ${CFLAGS} -o $@ daytimetcpcli1.o ${LIBS} + +daytimetcpcli2: daytimetcpcli2.o + ${CC} ${CFLAGS} -o $@ daytimetcpcli2.o ${LIBS} + +daytimetcpcli3: daytimetcpcli3.o + ${CC} ${CFLAGS} -o $@ daytimetcpcli3.o ${LIBS} + +daytimetcpsrv1: daytimetcpsrv1.o + ${CC} ${CFLAGS} -o $@ daytimetcpsrv1.o ${LIBS} + +daytimetcpsrv2: daytimetcpsrv2.o + ${CC} ${CFLAGS} -o $@ daytimetcpsrv2.o ${LIBS} + +daytimetcpsrv3: daytimetcpsrv3.o + ${CC} ${CFLAGS} -o $@ daytimetcpsrv3.o ${LIBS} + +daytimetcpsrv4: daytimetcpsrv4.o + ${CC} ${CFLAGS} -o $@ daytimetcpsrv4.o ${LIBS} + +daytimeudpcli1: daytimeudpcli1.o + ${CC} ${CFLAGS} -o $@ daytimeudpcli1.o ${LIBS} + +daytimeudpcli2: daytimeudpcli2.o + ${CC} ${CFLAGS} -o $@ daytimeudpcli2.o ${LIBS} + +daytimeudpsrv2: daytimeudpsrv2.o + ${CC} ${CFLAGS} -o $@ daytimeudpsrv2.o ${LIBS} + +daytimeudpsrv3: daytimeudpsrv3.o udp_server_reuseaddr.o + ${CC} ${CFLAGS} -o $@ daytimeudpsrv3.o udp_server_reuseaddr.o \ + ${LIBS} + +hostent: hostent.o + ${CC} ${CFLAGS} -o $@ hostent.o ${LIBS} + +hostent2: hostent2.o + ${CC} ${CFLAGS} -o $@ hostent2.o ${LIBS} + +hostent3: hostent3.o + ${CC} ${CFLAGS} -o $@ hostent3.o ${LIBS} + +netent: netent.o + ${CC} ${CFLAGS} -o $@ netent.o ${LIBS} + +prmyaddrs: prmyaddrs.o + ${CC} ${CFLAGS} -o $@ prmyaddrs.o ${LIBS} + +prmyaddrs1: prmyaddrs1.o myaddrs1.o + ${CC} ${CFLAGS} -o $@ prmyaddrs1.o myaddrs1.o ${LIBS} + +test1: test1.o + ${CC} ${CFLAGS} -o $@ test1.o ${LIBS} + +test2: test2.o + ${CC} ${CFLAGS} -o $@ test2.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/names/daytimetcpcli.c b/names/daytimetcpcli.c new file mode 100644 index 0000000..5c14621 --- /dev/null +++ b/names/daytimetcpcli.c @@ -0,0 +1,25 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n; + char recvline[MAXLINE + 1]; + socklen_t len; + struct sockaddr_storage ss; + + if (argc != 3) + err_quit("usage: daytimetcpcli "); + + sockfd = Tcp_connect(argv[1], argv[2]); + + len = sizeof(ss); + Getpeername(sockfd, (SA *)&ss, &len); + printf("connected to %s\n", Sock_ntop_host((SA *)&ss, len)); + + while ( (n = Read(sockfd, recvline, MAXLINE)) > 0) { + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } + exit(0); +} diff --git a/names/daytimetcpcli1.c b/names/daytimetcpcli1.c new file mode 100644 index 0000000..bc37101 --- /dev/null +++ b/names/daytimetcpcli1.c @@ -0,0 +1,56 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n; + char recvline[MAXLINE + 1]; + struct sockaddr_in servaddr; + struct in_addr **pptr; + struct in_addr *inetaddrp[2]; + struct in_addr inetaddr; + struct hostent *hp; + struct servent *sp; + + if (argc != 3) + err_quit("usage: daytimetcpcli1 "); + + if ( (hp = gethostbyname(argv[1])) == NULL) { + if (inet_aton(argv[1], &inetaddr) == 0) { + err_quit("hostname error for %s: %s", argv[1], hstrerror(h_errno)); + } else { + inetaddrp[0] = &inetaddr; + inetaddrp[1] = NULL; + pptr = inetaddrp; + } + } else { + pptr = (struct in_addr **) hp->h_addr_list; + } + + if ( (sp = getservbyname(argv[2], "tcp")) == NULL) + err_quit("getservbyname error for %s", argv[2]); + + for ( ; *pptr != NULL; pptr++) { + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = sp->s_port; + memcpy(&servaddr.sin_addr, *pptr, sizeof(struct in_addr)); + printf("trying %s\n", + Sock_ntop((SA *) &servaddr, sizeof(servaddr))); + + if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) == 0) + break; /* success */ + err_ret("connect error"); + close(sockfd); + } + if (*pptr == NULL) + err_quit("unable to connect"); + + while ( (n = Read(sockfd, recvline, MAXLINE)) > 0) { + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } + exit(0); +} diff --git a/names/daytimetcpcli1.lc b/names/daytimetcpcli1.lc new file mode 100644 index 0000000..99581c0 --- /dev/null +++ b/names/daytimetcpcli1.lc @@ -0,0 +1,56 @@ +#include "unp.h"## 1 ##src/names/daytimetcpcli1.c## + +int## 2 ##src/names/daytimetcpcli1.c## +main(int argc, char **argv)## 3 ##src/names/daytimetcpcli1.c## +{## 4 ##src/names/daytimetcpcli1.c## + int sockfd, n;## 5 ##src/names/daytimetcpcli1.c## + char recvline[MAXLINE + 1];## 6 ##src/names/daytimetcpcli1.c## + struct sockaddr_in servaddr;## 7 ##src/names/daytimetcpcli1.c## + struct in_addr **pptr;## 8 ##src/names/daytimetcpcli1.c## + struct in_addr *inetaddrp[2];## 9 ##src/names/daytimetcpcli1.c## + struct in_addr inetaddr;## 10 ##src/names/daytimetcpcli1.c## + struct hostent *hp;## 11 ##src/names/daytimetcpcli1.c## + struct servent *sp;## 12 ##src/names/daytimetcpcli1.c## + + if (argc != 3)## 13 ##src/names/daytimetcpcli1.c## + err_quit("usage: daytimetcpcli1 ");## 14 ##src/names/daytimetcpcli1.c## + + if ((hp = gethostbyname(argv[1])) == NULL) {## 15 ##src/names/daytimetcpcli1.c## + if (inet_aton(argv[1], &inetaddr) == 0) {## 16 ##src/names/daytimetcpcli1.c## + err_quit("hostname error for %s: %s", argv[1],## 17 ##src/names/daytimetcpcli1.c## + hstrerror(h_errno));## 18 ##src/names/daytimetcpcli1.c## + } else {## 19 ##src/names/daytimetcpcli1.c## + inetaddrp[0] = &inetaddr;## 20 ##src/names/daytimetcpcli1.c## + inetaddrp[1] = NULL;## 21 ##src/names/daytimetcpcli1.c## + pptr = inetaddrp;## 22 ##src/names/daytimetcpcli1.c## + }## 23 ##src/names/daytimetcpcli1.c## + } else {## 24 ##src/names/daytimetcpcli1.c## + pptr = (struct in_addr **) hp->h_addr_list;## 25 ##src/names/daytimetcpcli1.c## + }## 26 ##src/names/daytimetcpcli1.c## + + if ((sp = getservbyname(argv[2], "tcp")) == NULL)## 27 ##src/names/daytimetcpcli1.c## + err_quit("getservbyname error for %s", argv[2]);## 28 ##src/names/daytimetcpcli1.c## + + for (; *pptr != NULL; pptr++) {## 29 ##src/names/daytimetcpcli1.c## + sockfd = Socket(AF_INET, SOCK_STREAM, 0);## 30 ##src/names/daytimetcpcli1.c## + + bzero(&servaddr, sizeof(servaddr));## 31 ##src/names/daytimetcpcli1.c## + servaddr.sin_family = AF_INET;## 32 ##src/names/daytimetcpcli1.c## + servaddr.sin_port = sp->s_port;## 33 ##src/names/daytimetcpcli1.c## + memcpy(&servaddr.sin_addr, *pptr, sizeof(struct in_addr));## 34 ##src/names/daytimetcpcli1.c## + printf("trying %s\n", Sock_ntop((SA *) &servaddr, sizeof(servaddr)));## 35 ##src/names/daytimetcpcli1.c## + + if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) == 0)## 36 ##src/names/daytimetcpcli1.c## + break; /* success */## 37 ##src/names/daytimetcpcli1.c## + err_ret("connect error");## 38 ##src/names/daytimetcpcli1.c## + close(sockfd);## 39 ##src/names/daytimetcpcli1.c## + }## 40 ##src/names/daytimetcpcli1.c## + if (*pptr == NULL)## 41 ##src/names/daytimetcpcli1.c## + err_quit("unable to connect");## 42 ##src/names/daytimetcpcli1.c## + + while ((n = Read(sockfd, recvline, MAXLINE)) > 0) {## 43 ##src/names/daytimetcpcli1.c## + recvline[n] = 0; /* null terminate */## 44 ##src/names/daytimetcpcli1.c## + Fputs(recvline, stdout);## 45 ##src/names/daytimetcpcli1.c## + }## 46 ##src/names/daytimetcpcli1.c## + exit(0);## 47 ##src/names/daytimetcpcli1.c## +}## 48 ##src/names/daytimetcpcli1.c## diff --git a/names/daytimetcpcli2.c b/names/daytimetcpcli2.c new file mode 100644 index 0000000..04e5d76 --- /dev/null +++ b/names/daytimetcpcli2.c @@ -0,0 +1,55 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n; + char recvline[MAXLINE + 1]; + struct sockaddr_in servaddr; + struct in_addr **pptr, *addrs[2]; + struct hostent *hp; + struct servent *sp; + + if (argc != 3) + err_quit("usage: daytimetcpcli2 "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + + if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) == 1) { + addrs[0] = &servaddr.sin_addr; + addrs[1] = NULL; + pptr = &addrs[0]; + } else if ( (hp = gethostbyname(argv[1])) != NULL) { + pptr = (struct in_addr **) hp->h_addr_list; + } else + err_quit("hostname error for %s: %s", argv[1], hstrerror(h_errno)); + + if ( (n = atoi(argv[2])) > 0) + servaddr.sin_port = htons(n); + else if ( (sp = getservbyname(argv[2], "tcp")) != NULL) + servaddr.sin_port = sp->s_port; + else + err_quit("getservbyname error for %s", argv[2]); + + for ( ; *pptr != NULL; pptr++) { + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + memmove(&servaddr.sin_addr, *pptr, sizeof(struct in_addr)); + printf("trying %s\n", + Sock_ntop((SA *) &servaddr, sizeof(servaddr))); + + if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) == 0) + break; /* success */ + err_ret("connect error"); + close(sockfd); + } + if (*pptr == NULL) + err_quit("unable to connect"); + + while ( (n = Read(sockfd, recvline, MAXLINE)) > 0) { + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } + exit(0); +} diff --git a/names/daytimetcpcli2.lc b/names/daytimetcpcli2.lc new file mode 100644 index 0000000..f306b08 --- /dev/null +++ b/names/daytimetcpcli2.lc @@ -0,0 +1,54 @@ +#include "unp.h"## 1 ##src/names/daytimetcpcli2.c## + +int## 2 ##src/names/daytimetcpcli2.c## +main(int argc, char **argv)## 3 ##src/names/daytimetcpcli2.c## +{## 4 ##src/names/daytimetcpcli2.c## + int sockfd, n;## 5 ##src/names/daytimetcpcli2.c## + char recvline[MAXLINE + 1];## 6 ##src/names/daytimetcpcli2.c## + struct sockaddr_in servaddr;## 7 ##src/names/daytimetcpcli2.c## + struct in_addr **pptr, *addrs[2];## 8 ##src/names/daytimetcpcli2.c## + struct hostent *hp;## 9 ##src/names/daytimetcpcli2.c## + struct servent *sp;## 10 ##src/names/daytimetcpcli2.c## + + if (argc != 3)## 11 ##src/names/daytimetcpcli2.c## + err_quit("usage: daytimetcpcli2 ");## 12 ##src/names/daytimetcpcli2.c## + + bzero(&servaddr, sizeof(servaddr));## 13 ##src/names/daytimetcpcli2.c## + servaddr.sin_family = AF_INET;## 14 ##src/names/daytimetcpcli2.c## + + if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) == 1) {## 15 ##src/names/daytimetcpcli2.c## + addrs[0] = &servaddr.sin_addr;## 16 ##src/names/daytimetcpcli2.c## + addrs[1] = NULL;## 17 ##src/names/daytimetcpcli2.c## + pptr = &addrs[0];## 18 ##src/names/daytimetcpcli2.c## + } else if ((hp = gethostbyname(argv[1])) != NULL) {## 19 ##src/names/daytimetcpcli2.c## + pptr = (struct in_addr **) hp->h_addr_list;## 20 ##src/names/daytimetcpcli2.c## + } else## 21 ##src/names/daytimetcpcli2.c## + err_quit("hostname error for %s: %s", argv[1], hstrerror(h_errno));## 22 ##src/names/daytimetcpcli2.c## + + if ((n = atoi(argv[2])) > 0)## 23 ##src/names/daytimetcpcli2.c## + servaddr.sin_port = htons(n);## 24 ##src/names/daytimetcpcli2.c## + else if ((sp = getservbyname(argv[2], "tcp")) != NULL)## 25 ##src/names/daytimetcpcli2.c## + servaddr.sin_port = sp->s_port;## 26 ##src/names/daytimetcpcli2.c## + else## 27 ##src/names/daytimetcpcli2.c## + err_quit("getservbyname error for %s", argv[2]);## 28 ##src/names/daytimetcpcli2.c## + + for (; *pptr != NULL; pptr++) {## 29 ##src/names/daytimetcpcli2.c## + sockfd = Socket(AF_INET, SOCK_STREAM, 0);## 30 ##src/names/daytimetcpcli2.c## + + memmove(&servaddr.sin_addr, *pptr, sizeof(struct in_addr));## 31 ##src/names/daytimetcpcli2.c## + printf("trying %s\n", Sock_ntop((SA *) &servaddr, sizeof(servaddr)));## 32 ##src/names/daytimetcpcli2.c## + + if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) == 0)## 33 ##src/names/daytimetcpcli2.c## + break; /* success */## 34 ##src/names/daytimetcpcli2.c## + err_ret("connect error");## 35 ##src/names/daytimetcpcli2.c## + close(sockfd);## 36 ##src/names/daytimetcpcli2.c## + }## 37 ##src/names/daytimetcpcli2.c## + if (*pptr == NULL)## 38 ##src/names/daytimetcpcli2.c## + err_quit("unable to connect");## 39 ##src/names/daytimetcpcli2.c## + + while ((n = Read(sockfd, recvline, MAXLINE)) > 0) {## 40 ##src/names/daytimetcpcli2.c## + recvline[n] = 0; /* null terminate */## 41 ##src/names/daytimetcpcli2.c## + Fputs(recvline, stdout);## 42 ##src/names/daytimetcpcli2.c## + }## 43 ##src/names/daytimetcpcli2.c## + exit(0);## 44 ##src/names/daytimetcpcli2.c## +}## 45 ##src/names/daytimetcpcli2.c## diff --git a/names/daytimetcpcli3.c b/names/daytimetcpcli3.c new file mode 100644 index 0000000..946ef59 --- /dev/null +++ b/names/daytimetcpcli3.c @@ -0,0 +1,58 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n; + char recvline[MAXLINE + 1]; + struct sockaddr_in servaddr; + struct sockaddr_in6 servaddr6; + struct sockaddr *sa; + socklen_t salen; + struct in_addr **pptr; + struct hostent *hp; + struct servent *sp; + + if (argc != 3) + err_quit("usage: daytimetcpcli3 "); + + if ( (hp = gethostbyname(argv[1])) == NULL) + err_quit("hostname error for %s: %s", argv[1], hstrerror(h_errno)); + + if ( (sp = getservbyname(argv[2], "tcp")) == NULL) + err_quit("getservbyname error for %s", argv[2]); + + pptr = (struct in_addr **) hp->h_addr_list; + for ( ; *pptr != NULL; pptr++) { + sockfd = Socket(hp->h_addrtype, SOCK_STREAM, 0); + + if (hp->h_addrtype == AF_INET) { + sa = (SA *) &servaddr; + salen = sizeof(servaddr); + } else if (hp->h_addrtype == AF_INET6) { + sa = (SA *) &servaddr6; + salen = sizeof(servaddr6); + } else + err_quit("unknown addrtype %d", hp->h_addrtype); + + bzero(sa, salen); + sa->sa_family = hp->h_addrtype; + sock_set_port(sa, salen, sp->s_port); + sock_set_addr(sa, salen, *pptr); + + printf("trying %s\n", Sock_ntop(sa, salen)); + + if (connect(sockfd, sa, salen) == 0) + break; /* success */ + err_ret("connect error"); + close(sockfd); + } + if (*pptr == NULL) + err_quit("unable to connect"); + + while ( (n = Read(sockfd, recvline, MAXLINE)) > 0) { + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } + exit(0); +} diff --git a/names/daytimetcpcli3.lc b/names/daytimetcpcli3.lc new file mode 100644 index 0000000..4c4a5d8 --- /dev/null +++ b/names/daytimetcpcli3.lc @@ -0,0 +1,58 @@ +#include "unp.h"## 1 ##src/names/daytimetcpcli3.c## + +int## 2 ##src/names/daytimetcpcli3.c## +main(int argc, char **argv)## 3 ##src/names/daytimetcpcli3.c## +{## 4 ##src/names/daytimetcpcli3.c## + int sockfd, n;## 5 ##src/names/daytimetcpcli3.c## + char recvline[MAXLINE + 1];## 6 ##src/names/daytimetcpcli3.c## + struct sockaddr_in servaddr;## 7 ##src/names/daytimetcpcli3.c## + struct sockaddr_in6 servaddr6;## 8 ##src/names/daytimetcpcli3.c## + struct sockaddr *sa;## 9 ##src/names/daytimetcpcli3.c## + socklen_t salen;## 10 ##src/names/daytimetcpcli3.c## + struct in_addr **pptr;## 11 ##src/names/daytimetcpcli3.c## + struct hostent *hp;## 12 ##src/names/daytimetcpcli3.c## + struct servent *sp;## 13 ##src/names/daytimetcpcli3.c## + + if (argc != 3)## 14 ##src/names/daytimetcpcli3.c## + err_quit("usage: daytimetcpcli3 ");## 15 ##src/names/daytimetcpcli3.c## + + if ((hp = gethostbyname(argv[1])) == NULL)## 16 ##src/names/daytimetcpcli3.c## + err_quit("hostname error for %s: %s", argv[1], hstrerror(h_errno));## 17 ##src/names/daytimetcpcli3.c## + + if ((sp = getservbyname(argv[2], "tcp")) == NULL)## 18 ##src/names/daytimetcpcli3.c## + err_quit("getservbyname error for %s", argv[2]);## 19 ##src/names/daytimetcpcli3.c## + + pptr = (struct in_addr **) hp->h_addr_list;## 20 ##src/names/daytimetcpcli3.c## + for (; *pptr != NULL; pptr++) {## 21 ##src/names/daytimetcpcli3.c## + sockfd = Socket(hp->h_addrtype, SOCK_STREAM, 0);## 22 ##src/names/daytimetcpcli3.c## + + if (hp->h_addrtype == AF_INET) {## 23 ##src/names/daytimetcpcli3.c## + sa = (SA *) &servaddr;## 24 ##src/names/daytimetcpcli3.c## + salen = sizeof(servaddr);## 25 ##src/names/daytimetcpcli3.c## + } else if (hp->h_addrtype == AF_INET6) {## 26 ##src/names/daytimetcpcli3.c## + sa = (SA *) &servaddr6;## 27 ##src/names/daytimetcpcli3.c## + salen = sizeof(servaddr6);## 28 ##src/names/daytimetcpcli3.c## + } else## 29 ##src/names/daytimetcpcli3.c## + err_quit("unknown addrtype %d", hp->h_addrtype);## 30 ##src/names/daytimetcpcli3.c## + + bzero(sa, salen);## 31 ##src/names/daytimetcpcli3.c## + sa->sa_family = hp->h_addrtype;## 32 ##src/names/daytimetcpcli3.c## + sock_set_port(sa, salen, sp->s_port);## 33 ##src/names/daytimetcpcli3.c## + sock_set_addr(sa, salen, *pptr);## 34 ##src/names/daytimetcpcli3.c## + + printf("trying %s\n", Sock_ntop(sa, salen));## 35 ##src/names/daytimetcpcli3.c## + + if (connect(sockfd, sa, salen) == 0)## 36 ##src/names/daytimetcpcli3.c## + break; /* success */## 37 ##src/names/daytimetcpcli3.c## + err_ret("connect error");## 38 ##src/names/daytimetcpcli3.c## + close(sockfd);## 39 ##src/names/daytimetcpcli3.c## + }## 40 ##src/names/daytimetcpcli3.c## + if (*pptr == NULL)## 41 ##src/names/daytimetcpcli3.c## + err_quit("unable to connect");## 42 ##src/names/daytimetcpcli3.c## + + while ((n = Read(sockfd, recvline, MAXLINE)) > 0) {## 43 ##src/names/daytimetcpcli3.c## + recvline[n] = 0; /* null terminate */## 44 ##src/names/daytimetcpcli3.c## + Fputs(recvline, stdout);## 45 ##src/names/daytimetcpcli3.c## + }## 46 ##src/names/daytimetcpcli3.c## + exit(0);## 47 ##src/names/daytimetcpcli3.c## +}## 48 ##src/names/daytimetcpcli3.c## diff --git a/names/daytimetcpsrv1.c b/names/daytimetcpsrv1.c new file mode 100644 index 0000000..f643413 --- /dev/null +++ b/names/daytimetcpsrv1.c @@ -0,0 +1,29 @@ +#include "unp.h" +#include + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + socklen_t len; + char buff[MAXLINE]; + time_t ticks; + struct sockaddr_storage cliaddr; + + if (argc != 2) + err_quit("usage: daytimetcpsrv1 "); + + listenfd = Tcp_listen(NULL, argv[1], NULL); + + for ( ; ; ) { + len = sizeof(cliaddr); + connfd = Accept(listenfd, (SA *)&cliaddr, &len); + printf("connection from %s\n", Sock_ntop((SA *)&cliaddr, len)); + + ticks = time(NULL); + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); + Write(connfd, buff, strlen(buff)); + + Close(connfd); + } +} diff --git a/names/daytimetcpsrv2.c b/names/daytimetcpsrv2.c new file mode 100644 index 0000000..e897643 --- /dev/null +++ b/names/daytimetcpsrv2.c @@ -0,0 +1,31 @@ +#include "unp.h" +#include + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + socklen_t len, addrlen; + char buff[MAXLINE]; + time_t ticks; + struct sockaddr_storage cliaddr; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: daytimetcpsrv2 [ ] "); + + for ( ; ; ) { + len = sizeof(cliaddr); + connfd = Accept(listenfd, (SA *)&cliaddr, &len); + printf("connection from %s\n", Sock_ntop((SA *)&cliaddr, len)); + + ticks = time(NULL); + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); + Write(connfd, buff, strlen(buff)); + + Close(connfd); + } +} diff --git a/names/daytimetcpsrv3.c b/names/daytimetcpsrv3.c new file mode 100644 index 0000000..20c6cc0 --- /dev/null +++ b/names/daytimetcpsrv3.c @@ -0,0 +1,40 @@ +#include "unp.h" +#include + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + socklen_t addrlen, len; + struct sockaddr *cliaddr; + struct linger ling; + char buff[MAXLINE]; + time_t ticks; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: daytimetcpsrv3 [ ] "); + + cliaddr = Malloc(addrlen); + + for ( ; ; ) { + len = addrlen; + connfd = Accept(listenfd, cliaddr, &len); + printf("connection from %s\n", Sock_ntop(cliaddr, len)); + + /* force RST instead of FIN after data */ + ling.l_onoff = 1; + ling.l_linger = 0; + Setsockopt(connfd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)); + + ticks = time(NULL); + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); + Write(connfd, buff, strlen(buff)); + + sleep(2); /* let data get across before RST */ + Close(connfd); + } +} diff --git a/names/daytimetcpsrv4.c b/names/daytimetcpsrv4.c new file mode 100644 index 0000000..277b17e --- /dev/null +++ b/names/daytimetcpsrv4.c @@ -0,0 +1,35 @@ +#include "unp.h" +#include + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + socklen_t addrlen, len; + struct sockaddr *cliaddr; + char buff[MAXLINE], host[NI_MAXHOST], serv[NI_MAXSERV]; + time_t ticks; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: daytimetcpsrv4 [ ] "); + + cliaddr = Malloc(addrlen); + + for ( ; ; ) { + len = addrlen; + connfd = Accept(listenfd, cliaddr, &len); + if (getnameinfo(cliaddr, len, host, NI_MAXHOST, serv, NI_MAXSERV, + NI_NUMERICHOST | NI_NUMERICSERV) == 0) + printf("connection from %s.%s\n", host, serv); + + ticks = time(NULL); + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); + Write(connfd, buff, strlen(buff)); + + Close(connfd); + } +} diff --git a/names/daytimeudpcli1.c b/names/daytimeudpcli1.c new file mode 100644 index 0000000..efca6ec --- /dev/null +++ b/names/daytimeudpcli1.c @@ -0,0 +1,25 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n; + char recvline[MAXLINE + 1]; + socklen_t salen; + struct sockaddr *sa; + + if (argc != 3) + err_quit("usage: daytimeudpcli1 "); + + sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen); + + printf("sending to %s\n", Sock_ntop_host(sa, salen)); + + Sendto(sockfd, "", 1, 0, sa, salen); /* send 1-byte datagram */ + + n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL); + recvline[n] = '\0'; /* null terminate */ + Fputs(recvline, stdout); + + exit(0); +} diff --git a/names/daytimeudpcli1.lc b/names/daytimeudpcli1.lc new file mode 100644 index 0000000..4d03bee --- /dev/null +++ b/names/daytimeudpcli1.lc @@ -0,0 +1,26 @@ +#include "unp.h"## 1 ##src/names/daytimeudpcli1.c## + +int## 2 ##src/names/daytimeudpcli1.c## +main(int argc, char **argv)## 3 ##src/names/daytimeudpcli1.c## +{## 4 ##src/names/daytimeudpcli1.c## + int sockfd, n;## 5 ##src/names/daytimeudpcli1.c## + char recvline[MAXLINE + 1];## 6 ##src/names/daytimeudpcli1.c## + socklen_t salen;## 7 ##src/names/daytimeudpcli1.c## + struct sockaddr *sa;## 8 ##src/names/daytimeudpcli1.c## + + if (argc != 3)## 9 ##src/names/daytimeudpcli1.c## + err_quit## 10 ##src/names/daytimeudpcli1.c## + ("usage: daytimeudpcli1 ");## 11 ##src/names/daytimeudpcli1.c## + + sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen);## 12 ##src/names/daytimeudpcli1.c## + + printf("sending to %s\n", Sock_ntop_host(sa, salen));## 13 ##src/names/daytimeudpcli1.c## + + Sendto(sockfd, "", 1, 0, sa, salen); /* send 1-byte datagram */## 14 ##src/names/daytimeudpcli1.c## + + n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);## 15 ##src/names/daytimeudpcli1.c## + recvline[n] = '\0'; /* null terminate */## 16 ##src/names/daytimeudpcli1.c## + Fputs(recvline, stdout);## 17 ##src/names/daytimeudpcli1.c## + + exit(0);## 18 ##src/names/daytimeudpcli1.c## +}## 19 ##src/names/daytimeudpcli1.c## diff --git a/names/daytimeudpcli2.c b/names/daytimeudpcli2.c new file mode 100644 index 0000000..a61bf49 --- /dev/null +++ b/names/daytimeudpcli2.c @@ -0,0 +1,21 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n; + char recvline[MAXLINE + 1]; + + if (argc != 3) + err_quit("usage: daytimeudpcli2 "); + + sockfd = Udp_connect(argv[1], argv[2]); + + Write(sockfd, "", 1); /* send 1-byte datagram */ + + n = Read(sockfd, recvline, MAXLINE); + recvline[n] = '\0'; /* null terminate */ + Fputs(recvline, stdout); + + exit(0); +} diff --git a/names/daytimeudpsrv2.c b/names/daytimeudpsrv2.c new file mode 100644 index 0000000..9d7e8bc --- /dev/null +++ b/names/daytimeudpsrv2.c @@ -0,0 +1,30 @@ +#include "unp.h" +#include + +int +main(int argc, char **argv) +{ + int sockfd; + ssize_t n; + char buff[MAXLINE]; + time_t ticks; + socklen_t len; + struct sockaddr_storage cliaddr; + + if (argc == 2) + sockfd = Udp_server(NULL, argv[1], NULL); + else if (argc == 3) + sockfd = Udp_server(argv[1], argv[2], NULL); + else + err_quit("usage: daytimeudpsrv [ ] "); + + for ( ; ; ) { + len = sizeof(cliaddr); + n = Recvfrom(sockfd, buff, MAXLINE, 0, (SA *)&cliaddr, &len); + printf("datagram from %s\n", Sock_ntop((SA *)&cliaddr, len)); + + ticks = time(NULL); + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); + Sendto(sockfd, buff, strlen(buff), 0, (SA *)&cliaddr, len); + } +} diff --git a/names/daytimeudpsrv3.c b/names/daytimeudpsrv3.c new file mode 100644 index 0000000..41732aa --- /dev/null +++ b/names/daytimeudpsrv3.c @@ -0,0 +1,30 @@ +#include "unp.h" +#include + +int +main(int argc, char **argv) +{ + int sockfd; + ssize_t n; + char buff[MAXLINE]; + time_t ticks; + socklen_t len; + struct sockaddr_storage cliaddr; + + if (argc == 2) + sockfd = Udp_server_reuseaddr(NULL, argv[1], NULL); + else if (argc == 3) + sockfd = Udp_server_reuseaddr(argv[1], argv[2], NULL); + else + err_quit("usage: daytimeudpsrv [ ] "); + + for ( ; ; ) { + len = sizeof(cliaddr); + n = Recvfrom(sockfd, buff, MAXLINE, 0, (SA *)&cliaddr, &len); + printf("datagram from %s\n", Sock_ntop((SA *)&cliaddr, len)); + + ticks = time(NULL); + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); + Sendto(sockfd, buff, strlen(buff), 0, (SA *)&cliaddr, len); + } +} diff --git a/names/hostent.c b/names/hostent.c new file mode 100644 index 0000000..2fdb382 --- /dev/null +++ b/names/hostent.c @@ -0,0 +1,36 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + char *ptr, **pptr; + char str[INET_ADDRSTRLEN]; + struct hostent *hptr; + + while (--argc > 0) { + ptr = *++argv; + if ( (hptr = gethostbyname(ptr)) == NULL) { + err_msg("gethostbyname error for host: %s: %s", + ptr, hstrerror(h_errno)); + continue; + } + printf("official hostname: %s\n", hptr->h_name); + + for (pptr = hptr->h_aliases; *pptr != NULL; pptr++) + printf("\talias: %s\n", *pptr); + + switch (hptr->h_addrtype) { + case AF_INET: + pptr = hptr->h_addr_list; + for ( ; *pptr != NULL; pptr++) + printf("\taddress: %s\n", + Inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str))); + break; + + default: + err_ret("unknown address type"); + break; + } + } + exit(0); +} diff --git a/names/hostent.lc b/names/hostent.lc new file mode 100644 index 0000000..57c7759 --- /dev/null +++ b/names/hostent.lc @@ -0,0 +1,36 @@ +#include "unp.h"## 1 ##src/names/hostent.c## + +int## 2 ##src/names/hostent.c## +main(int argc, char **argv)## 3 ##src/names/hostent.c## +{## 4 ##src/names/hostent.c## + char *ptr, **pptr;## 5 ##src/names/hostent.c## + char str[INET_ADDRSTRLEN];## 6 ##src/names/hostent.c## + struct hostent *hptr;## 7 ##src/names/hostent.c## + + while (--argc > 0) {## 8 ##src/names/hostent.c## + ptr = *++argv;## 9 ##src/names/hostent.c## + if ((hptr = gethostbyname(ptr)) == NULL) {## 10 ##src/names/hostent.c## + err_msg("gethostbyname error for host: %s: %s",## 11 ##src/names/hostent.c## + ptr, hstrerror(h_errno));## 12 ##src/names/hostent.c## + continue;## 13 ##src/names/hostent.c## + }## 14 ##src/names/hostent.c## + printf("official hostname: %s\n", hptr->h_name);## 15 ##src/names/hostent.c## + + for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)## 16 ##src/names/hostent.c## + printf("\talias: %s\n", *pptr);## 17 ##src/names/hostent.c## + + switch (hptr->h_addrtype) {## 18 ##src/names/hostent.c## + case AF_INET:## 19 ##src/names/hostent.c## + pptr = hptr->h_addr_list;## 20 ##src/names/hostent.c## + for (; *pptr != NULL; pptr++)## 21 ##src/names/hostent.c## + printf("\taddress: %s\n",## 22 ##src/names/hostent.c## + Inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));## 23 ##src/names/hostent.c## + break;## 24 ##src/names/hostent.c## + + default:## 25 ##src/names/hostent.c## + err_ret("unknown address type");## 26 ##src/names/hostent.c## + break;## 27 ##src/names/hostent.c## + }## 28 ##src/names/hostent.c## + }## 29 ##src/names/hostent.c## + exit(0);## 30 ##src/names/hostent.c## +}## 31 ##src/names/hostent.c## diff --git a/names/hostent2.c b/names/hostent2.c new file mode 100644 index 0000000..df81cb2 --- /dev/null +++ b/names/hostent2.c @@ -0,0 +1,48 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + char *ptr, **pptr; + char str[INET6_ADDRSTRLEN]; + struct hostent *hptr; + + while (--argc > 0) { + ptr = *++argv; + if ( (hptr = gethostbyname(ptr)) == NULL) { + err_msg("gethostbyname error for host: %s: %s", + ptr, hstrerror(h_errno)); + continue; + } + printf("official hostname: %s\n", hptr->h_name); + + for (pptr = hptr->h_aliases; *pptr != NULL; pptr++) + printf(" alias: %s\n", *pptr); + + switch (hptr->h_addrtype) { + case AF_INET: +#ifdef AF_INET6 + case AF_INET6: +#endif + pptr = hptr->h_addr_list; + for ( ; *pptr != NULL; pptr++) { + printf("\taddress: %s\n", + Inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str))); + + if ( (hptr = gethostbyaddr(*pptr, hptr->h_length, + hptr->h_addrtype)) == NULL) + printf("\t(gethostbyaddr failed)\n"); + else if (hptr->h_name != NULL) + printf("\tname = %s\n", hptr->h_name); + else + printf("\t(no hostname returned by gethostbyaddr)\n"); + } + break; + + default: + err_ret("unknown address type"); + break; + } + } + exit(0); +} diff --git a/names/hostent2.lc b/names/hostent2.lc new file mode 100644 index 0000000..40f9b7e --- /dev/null +++ b/names/hostent2.lc @@ -0,0 +1,48 @@ +#include "unp.h"## 1 ##src/names/hostent2.c## + +int## 2 ##src/names/hostent2.c## +main(int argc, char **argv)## 3 ##src/names/hostent2.c## +{## 4 ##src/names/hostent2.c## + char *ptr, **pptr;## 5 ##src/names/hostent2.c## + char str[INET6_ADDRSTRLEN];## 6 ##src/names/hostent2.c## + struct hostent *hptr;## 7 ##src/names/hostent2.c## + + while (--argc > 0) {## 8 ##src/names/hostent2.c## + ptr = *++argv;## 9 ##src/names/hostent2.c## + if ((hptr = gethostbyname(ptr)) == NULL) {## 10 ##src/names/hostent2.c## + err_msg("gethostbyname error for host: %s: %s",## 11 ##src/names/hostent2.c## + ptr, hstrerror(h_errno));## 12 ##src/names/hostent2.c## + continue;## 13 ##src/names/hostent2.c## + }## 14 ##src/names/hostent2.c## + printf("official hostname: %s\n", hptr->h_name);## 15 ##src/names/hostent2.c## + + for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)## 16 ##src/names/hostent2.c## + printf(" alias: %s\n", *pptr);## 17 ##src/names/hostent2.c## + + switch (hptr->h_addrtype) {## 18 ##src/names/hostent2.c## + case AF_INET:## 19 ##src/names/hostent2.c## +#ifdef AF_INET6## 20 ##src/names/hostent2.c## + case AF_INET6:## 21 ##src/names/hostent2.c## +#endif## 22 ##src/names/hostent2.c## + pptr = hptr->h_addr_list;## 23 ##src/names/hostent2.c## + for (; *pptr != NULL; pptr++) {## 24 ##src/names/hostent2.c## + printf("\taddress: %s\n",## 25 ##src/names/hostent2.c## + Inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));## 26 ##src/names/hostent2.c## + + if ((hptr = gethostbyaddr(*pptr, hptr->h_length,## 27 ##src/names/hostent2.c## + hptr->h_addrtype)) == NULL)## 28 ##src/names/hostent2.c## + printf("\t(gethostbyaddr failed)\n");## 29 ##src/names/hostent2.c## + else if (hptr->h_name != NULL)## 30 ##src/names/hostent2.c## + printf("\tname = %s\n", hptr->h_name);## 31 ##src/names/hostent2.c## + else## 32 ##src/names/hostent2.c## + printf("\t(no hostname returned by gethostbyaddr)\n");## 33 ##src/names/hostent2.c## + }## 34 ##src/names/hostent2.c## + break;## 35 ##src/names/hostent2.c## + + default:## 36 ##src/names/hostent2.c## + err_ret("unknown address type");## 37 ##src/names/hostent2.c## + break;## 38 ##src/names/hostent2.c## + }## 39 ##src/names/hostent2.c## + }## 40 ##src/names/hostent2.c## + exit(0);## 41 ##src/names/hostent2.c## +}## 42 ##src/names/hostent2.c## diff --git a/names/hostent3.c b/names/hostent3.c new file mode 100644 index 0000000..b460dc0 --- /dev/null +++ b/names/hostent3.c @@ -0,0 +1,64 @@ +#include "unp.h" + +void pr_ipv4(char **); + +int +main(int argc, char **argv) +{ + char *ptr, **pptr; + struct hostent *hptr; + + while (--argc > 0) { + ptr = *++argv; + if ( (hptr = gethostbyname(ptr)) == NULL) { + err_msg("gethostbyname error for host: %s: %s", + ptr, hstrerror(h_errno)); + continue; + } + printf("official host name: %s\n", hptr->h_name); + + for (pptr = hptr->h_aliases; *pptr != NULL; pptr++) + printf(" alias: %s\n", *pptr); + + switch (hptr->h_addrtype) { + case AF_INET: + pr_ipv4(hptr->h_addr_list); + break; + + default: + err_ret("unknown address type"); + break; + } + } + exit(0); +} + +/* + * Print the array of IPv4 addresses that is returned. + * Also call gethostbyaddr_r() for each IP address and print the name. + */ + +/* begin pr_ipv4 */ +void +pr_ipv4(char **listptr) +{ + struct in_addr inaddr; + struct hostent *hptr, hent; + char buf[8192]; + int h_errno; + + for ( ; *listptr != NULL; listptr++) { + inaddr = *((struct in_addr *) (*listptr)); + printf(" IPv4 address: %s", Inet_ntoa(inaddr)); + + if ( (hptr = gethostbyaddr_r((char *) &inaddr, sizeof(struct in_addr), + AF_INET, &hent, + buf, sizeof(buf), &h_errno)) == NULL) + printf(" (gethostbyaddr failed: %s)\n", hstrerror(h_errno)); + else if (hptr->h_name != NULL) + printf(" name = %s\n", hptr->h_name); + else + printf(" (no hostname returned by gethostbyaddr)\n"); + } +} +/* end pr_ipv4 */ diff --git a/names/myaddrs1.c b/names/myaddrs1.c new file mode 100644 index 0000000..d85d963 --- /dev/null +++ b/names/myaddrs1.c @@ -0,0 +1,18 @@ +#include "unp.h" +#include + +char ** +my_addrs(int *addrtype) +{ + struct hostent *hptr; + char myname[MAXHOSTNAMELEN]; + + if (gethostname(myname, sizeof(myname)) < 0) + return(NULL); + + if ( (hptr = gethostbyname(myname)) == NULL) + return(NULL); + + *addrtype = hptr->h_addrtype; + return(hptr->h_addr_list); +} diff --git a/names/myaddrs1.lc b/names/myaddrs1.lc new file mode 100644 index 0000000..6ca323d --- /dev/null +++ b/names/myaddrs1.lc @@ -0,0 +1,18 @@ +#include "unp.h"## 1 ##src/names/myaddrs1.c## +#include ## 2 ##src/names/myaddrs1.c## + +char **## 3 ##src/names/myaddrs1.c## +my_addrs(int *addrtype)## 4 ##src/names/myaddrs1.c## +{## 5 ##src/names/myaddrs1.c## + struct hostent *hptr;## 6 ##src/names/myaddrs1.c## + char myname[MAXHOSTNAMELEN];## 7 ##src/names/myaddrs1.c## + + if (gethostname(myname, sizeof(myname)) < 0)## 8 ##src/names/myaddrs1.c## + return (NULL);## 9 ##src/names/myaddrs1.c## + + if ((hptr = gethostbyname(myname)) == NULL)## 10 ##src/names/myaddrs1.c## + return (NULL);## 11 ##src/names/myaddrs1.c## + + *addrtype = hptr->h_addrtype;## 12 ##src/names/myaddrs1.c## + return (hptr->h_addr_list);## 13 ##src/names/myaddrs1.c## +}## 14 ##src/names/myaddrs1.c## diff --git a/names/netent.c b/names/netent.c new file mode 100644 index 0000000..6204737 --- /dev/null +++ b/names/netent.c @@ -0,0 +1,34 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + char *ptr, **pptr; + struct netent *nptr; + + while (--argc > 0) { + ptr = *++argv; + if ( (nptr = getnetbyname(ptr)) == NULL) { + err_msg("getnetbyname error for net: %s: %s", + ptr, hstrerror(h_errno)); + continue; + } + printf("official netname: %s\n", nptr->n_name); + + for (pptr = nptr->n_aliases; *pptr != NULL; pptr++) + printf(" alias: %s\n", *pptr); + + switch (nptr->n_addrtype) { + case AF_INET: +#ifdef AF_INET6 + case AF_INET6: +#endif + break; + + default: + err_ret("unknown address type"); + break; + } + } + exit(0); +} diff --git a/names/prmyaddrs.c b/names/prmyaddrs.c new file mode 100644 index 0000000..fc2e0a7 --- /dev/null +++ b/names/prmyaddrs.c @@ -0,0 +1,19 @@ +#include "unp.h" + +char **my_addrs(int *); + +int +main(int argc, char **argv) +{ + int addrtype; + char **pptr, buf[INET6_ADDRSTRLEN]; + + if ( (pptr = my_addrs(&addrtype)) == NULL) + err_quit("my_addrs error"); + + for ( ; *pptr != NULL; pptr++) + printf("\taddress: %s\n", + Inet_ntop(addrtype, *pptr, buf, sizeof(buf))); + + exit(0); +} diff --git a/names/prmyaddrs1.c b/names/prmyaddrs1.c new file mode 100644 index 0000000..fc2e0a7 --- /dev/null +++ b/names/prmyaddrs1.c @@ -0,0 +1,19 @@ +#include "unp.h" + +char **my_addrs(int *); + +int +main(int argc, char **argv) +{ + int addrtype; + char **pptr, buf[INET6_ADDRSTRLEN]; + + if ( (pptr = my_addrs(&addrtype)) == NULL) + err_quit("my_addrs error"); + + for ( ; *pptr != NULL; pptr++) + printf("\taddress: %s\n", + Inet_ntop(addrtype, *pptr, buf, sizeof(buf))); + + exit(0); +} diff --git a/names/prmyaddrs1.lc b/names/prmyaddrs1.lc new file mode 100644 index 0000000..1b24441 --- /dev/null +++ b/names/prmyaddrs1.lc @@ -0,0 +1,19 @@ +#include "unp.h"## 1 ##src/names/prmyaddrs1.c## + +char **my_addrs(int *);## 2 ##src/names/prmyaddrs1.c## + +int## 3 ##src/names/prmyaddrs1.c## +main(int argc, char **argv)## 4 ##src/names/prmyaddrs1.c## +{## 5 ##src/names/prmyaddrs1.c## + int addrtype;## 6 ##src/names/prmyaddrs1.c## + char **pptr, buf[INET6_ADDRSTRLEN];## 7 ##src/names/prmyaddrs1.c## + + if ((pptr = my_addrs(&addrtype)) == NULL)## 8 ##src/names/prmyaddrs1.c## + err_quit("my_addrs error");## 9 ##src/names/prmyaddrs1.c## + + for (; *pptr != NULL; pptr++)## 10 ##src/names/prmyaddrs1.c## + printf("\taddress: %s\n",## 11 ##src/names/prmyaddrs1.c## + Inet_ntop(addrtype, *pptr, buf, sizeof(buf)));## 12 ##src/names/prmyaddrs1.c## + + exit(0);## 13 ##src/names/prmyaddrs1.c## +}## 14 ##src/names/prmyaddrs1.c## diff --git a/names/test1.c b/names/test1.c new file mode 100644 index 0000000..c07147d --- /dev/null +++ b/names/test1.c @@ -0,0 +1,50 @@ +#include "unp.h" + +void pr_ipv4(char **); + +int +main(int argc, char **argv) +{ + char *ptr, **pptr, **listptr, buf[INET6_ADDRSTRLEN]; + char *list[100]; + int i, addrtype, addrlen; + struct hostent *hptr; + + while (--argc > 0) { + ptr = *++argv; + if ( (hptr = gethostbyname(ptr)) == NULL) { + err_msg("gethostbyname error for host: %s: %s", + ptr, hstrerror(h_errno)); + continue; + } + printf("official host name: %s\n", hptr->h_name); + + for (pptr = hptr->h_aliases; *pptr != NULL; pptr++) + printf(" alias: %s\n", *pptr); + addrtype = hptr->h_addrtype; + addrlen = hptr->h_length; + + /* copy array of pointers, so we can call gethostbyaddr() */ + for (i = 0, listptr = hptr->h_addr_list; *listptr != NULL; listptr++) { + list[i++] = *listptr; + } + list[i] = NULL; + + for (listptr = list; *listptr != NULL; listptr++) { + printf("\taddress: %s\n", + Inet_ntop(addrtype, *listptr, buf, sizeof(buf))); + + if ( (hptr = gethostbyaddr(*listptr, addrlen, addrtype)) == NULL) + printf("\t\t(gethostbyaddr failed)\n"); + else if (hptr->h_name != NULL) + printf("\t\tname = %s\n", hptr->h_name); + else + printf("\t\t(no hostname returned by gethostbyaddr)\n"); + + printf("\t\tofficial host name: %s\n", hptr->h_name); + + for (pptr = hptr->h_aliases; *pptr != NULL; pptr++) + printf("\t\talias: %s\n", *pptr); + } + } +} diff --git a/names/test2.c b/names/test2.c new file mode 100644 index 0000000..51aeb4e --- /dev/null +++ b/names/test2.c @@ -0,0 +1,32 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n; + char recvline[MAXLINE + 1]; + socklen_t salen; + struct sockaddr *sa, *sabind; + + if (argc != 3) + err_quit("usage: test2 "); + + sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen); + + /* Same as daytimeudpcli1, but we explicitly bind the wildcard */ + sabind = Malloc(salen); + bzero(sabind, salen); + sabind->sa_family = sa->sa_family; + Bind(sockfd, sabind, salen); + printf("bound %s\n", Sock_ntop(sabind, salen)); + + printf("sending to %s\n", Sock_ntop_host(sa, salen)); + + Sendto(sockfd, "", 1, 0, sa, salen); /* send 1-byte datagram */ + + n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL); + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + + exit(0); +} diff --git a/names/udp_server_reuseaddr.c b/names/udp_server_reuseaddr.c new file mode 100644 index 0000000..f3cdecb --- /dev/null +++ b/names/udp_server_reuseaddr.c @@ -0,0 +1,49 @@ +/* include udp_server */ +#include "unp.h" + +int +udp_server_reuseaddr(const char *host, const char *serv, socklen_t *addrlenp) +{ + int sockfd, n; + const int on = 1; + struct addrinfo hints, *res, *ressave; + + bzero(&hints, sizeof(struct addrinfo)); + hints.ai_flags = AI_PASSIVE; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + + if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0) + err_quit("udp_server error for %s, %s: %s", + host, serv, gai_strerror(n)); + ressave = res; + + do { + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (sockfd < 0) + continue; /* error, try next one */ + + Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + if (bind(sockfd, res->ai_addr, res->ai_addrlen) == 0) + break; /* success */ + + Close(sockfd); /* bind error, close and try next one */ + } while ( (res = res->ai_next) != NULL); + + if (res == NULL) /* errno from final socket() or bind() */ + err_sys("udp_server error for %s, %s", host, serv); + + if (addrlenp) + *addrlenp = res->ai_addrlen; /* return size of protocol address */ + + freeaddrinfo(ressave); + + return(sockfd); +} +/* end udp_server */ + +int +Udp_server_reuseaddr(const char *host, const char *serv, socklen_t *addrlenp) +{ + return(udp_server_reuseaddr(host, serv, addrlenp)); +} diff --git a/nonblock/Makefile b/nonblock/Makefile new file mode 100644 index 0000000..ad39f2f --- /dev/null +++ b/nonblock/Makefile @@ -0,0 +1,30 @@ +include ../Make.defines + +PROGS = daytimetcpcli tcpcli01 tcpcli02 tcpcli03 tcpcli04 tcpservselect02 web + +all: ${PROGS} + +daytimetcpcli: daytimetcpcli.o + ${CC} ${CFLAGS} -o $@ daytimetcpcli.o ${LIBS} + +tcpcli01: tcpcli01.o strclifork.o + ${CC} ${CFLAGS} -o $@ tcpcli01.o strclifork.o ${LIBS} + +tcpcli02: tcpcli02.o strclinonb.o + ${CC} ${CFLAGS} -o $@ tcpcli02.o strclinonb.o ${LIBS} + +tcpcli03: tcpcli03.o + ${CC} ${CFLAGS} -o $@ tcpcli03.o ${LIBS} + +tcpcli04: tcpcli04.o + ${CC} ${CFLAGS} -o $@ tcpcli04.o ${LIBS} + +tcpservselect03: tcpservselect03.o + ${CC} ${CFLAGS} -o $@ tcpservselect03.o ${LIBS} + +web: web.o home_page.o start_connect.o write_get_cmd.o + ${CC} ${CFLAGS} -o $@ web.o home_page.o start_connect.o \ + write_get_cmd.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/nonblock/daytimetcpcli.c b/nonblock/daytimetcpcli.c new file mode 100644 index 0000000..fbb1cc7 --- /dev/null +++ b/nonblock/daytimetcpcli.c @@ -0,0 +1,32 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n; + struct sockaddr_in servaddr; + char recvline[MAXLINE + 1]; + + if ( (sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) + err_sys("socket error"); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = inet_addr(argv[1]); + servaddr.sin_port = htons(13); /* daytime server */ + + if (connect_nonb(sockfd, (SA *) &servaddr, sizeof(servaddr), 0) < 0) + err_sys("connect error"); + + for ( ; ; ) { + if ( (n = read(sockfd, recvline, MAXLINE)) <= 0) { + if (n == 0) + break; /* server closed connection */ + else + err_sys("read error"); + } + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } + exit(0); +} diff --git a/nonblock/doit.1 b/nonblock/doit.1 new file mode 100755 index 0000000..673bf98 --- /dev/null +++ b/nonblock/doit.1 @@ -0,0 +1,18 @@ +#!/bin/sh + +case $# in +1) break ;; +*) echo "one argument (#simultaneous connections) required" 1>&2 + exit 1 ;; +esac + +time ./web $1 192.207.117.2 / \ + /img/logo/awl_logo_blue_50x40.gif \ + /img/a_world_of_learning.gif \ + /img/toolbar_soptions.gif \ + /img/toolbar_purchase.gif \ + /img/toolbar_feedback.gif \ + /img/toolbar_top_hilite.gif \ + /img/toolbar_qsearch.gif \ + /img/blue_dot.gif \ + /img/logo/pearson_logo_50.gif diff --git a/nonblock/home_page.c b/nonblock/home_page.c new file mode 100644 index 0000000..02d9691 --- /dev/null +++ b/nonblock/home_page.c @@ -0,0 +1,23 @@ +#include "web.h" + +void +home_page(const char *host, const char *fname) +{ + int fd, n; + char line[MAXLINE]; + + fd = Tcp_connect(host, SERV); /* blocking connect() */ + + n = snprintf(line, sizeof(line), GET_CMD, fname); + Writen(fd, line, n); + + for ( ; ; ) { + if ( (n = Read(fd, line, MAXLINE)) == 0) + break; /* server closed connection */ + + printf("read %d bytes of home page\n", n); + /* do whatever with data */ + } + printf("end-of-file on home page\n"); + Close(fd); +} diff --git a/nonblock/script.1.sh b/nonblock/script.1.sh new file mode 100644 index 0000000..a7940aa --- /dev/null +++ b/nonblock/script.1.sh @@ -0,0 +1,28 @@ +10:18:34.491482: read 4096 bytes from stdin +10:18:34.519016: wrote 4096 bytes to socket +10:18:34.544636: read 4096 bytes from stdin +10:18:34.568505: read 3508 bytes from socket +10:18:34.593354: wrote 3508 bytes to stdout +10:18:34.618062: wrote 4096 bytes to socket +10:18:34.643524: read 4096 bytes from stdin +10:18:34.667305: read 2636 bytes from socket +10:18:34.691039: wrote 2636 bytes to stdout +10:18:34.697238: wrote 4096 bytes to socket +10:18:34.700582: read 4096 bytes from stdin +10:18:34.703809: read 2048 bytes from socket +10:18:34.708440: wrote 2048 bytes to stdout +10:18:34.712738: wrote 4096 bytes to socket +10:18:34.716194: read 4096 bytes from stdin +10:18:34.719832: read 4096 bytes from socket +10:18:34.724106: wrote 4096 bytes to stdout +10:18:34.728503: wrote 4096 bytes to socket +10:18:34.731839: read 3649 bytes from stdin +10:18:34.735129: read 4096 bytes from socket +10:18:34.778481: wrote 4096 bytes to stdout +10:18:34.803742: wrote 3649 bytes to socket +10:18:34.829483: EOF on stdin +10:18:34.849752: read 4096 bytes from socket +10:18:34.874733: wrote 4096 bytes to stdout +10:18:34.898581: read 3649 bytes from socket +10:18:34.923059: wrote 3649 bytes to stdout +10:18:34.946892: EOF on socket diff --git a/nonblock/script.1.tcpd b/nonblock/script.1.tcpd new file mode 100644 index 0000000..407c8e6 --- /dev/null +++ b/nonblock/script.1.tcpd @@ -0,0 +1,62 @@ +10:18:34.486392 kohala.33621 > kalae.echo: S 1802738644:1802738644(0) win 8760 (DF) +10:18:34.488278 kalae.echo > kohala.33621: S 3212986316:3212986316(0) ack 1802738645 win 8760 +10:18:34.488490 kohala.33621 > kalae.echo: . ack 1 win 8760 (DF) +10:18:34.518663 kohala.33621 > kalae.echo: P 1:1461(1460) ack 1 win 8760 (DF) +10:18:34.528529 kalae.echo > kohala.33621: P 1:1461(1460) ack 1461 win 8760 +10:18:34.528785 kohala.33621 > kalae.echo: . 1461:2921(1460) ack 1461 win 8760 (DF) +10:18:34.528900 kohala.33621 > kalae.echo: P 2921:4097(1176) ack 1461 win 8760 (DF) +10:18:34.528958 kohala.33621 > kalae.echo: . ack 1461 win 8760 (DF) +10:18:34.536193 kalae.echo > kohala.33621: . 1461:2921(1460) ack 4097 win 8760 +10:18:34.536697 kalae.echo > kohala.33621: P 2921:3509(588) ack 4097 win 8760 +10:18:34.580373 kohala.33621 > kalae.echo: . ack 3509 win 8760 (DF) +10:18:34.582244 kalae.echo > kohala.33621: P 3509:4097(588) ack 4097 win 8760 +10:18:34.617272 kohala.33621 > kalae.echo: P 4097:5557(1460) ack 4097 win 8760 (DF) +10:18:34.617610 kohala.33621 > kalae.echo: P 5557:7017(1460) ack 4097 win 8760 (DF) +10:18:34.617908 kohala.33621 > kalae.echo: P 7017:8193(1176) ack 4097 win 8760 (DF) +10:18:34.623310 kalae.echo > kohala.33621: . ack 8193 win 8760 +10:18:34.626129 kalae.echo > kohala.33621: . 4097:5557(1460) ack 8193 win 8760 +10:18:34.626339 kohala.33621 > kalae.echo: . ack 5557 win 8760 (DF) +10:18:34.626611 kalae.echo > kohala.33621: P 5557:6145(588) ack 8193 win 8760 +10:18:34.628396 kalae.echo > kohala.33621: . 6145:7605(1460) ack 8193 win 8760 +10:18:34.670324 kohala.33621 > kalae.echo: . ack 7605 win 8760 (DF) +10:18:34.672221 kalae.echo > kohala.33621: P 7605:8193(588) ack 8193 win 8760 +10:18:34.696426 kohala.33621 > kalae.echo: P 8193:9653(1460) ack 8193 win 8760 (DF) +10:18:34.696768 kohala.33621 > kalae.echo: P 9653:11113(1460) ack 8193 win 8760 (DF) +10:18:34.697077 kohala.33621 > kalae.echo: P 11113:12289(1176) ack 8193 win 8760 (DF) +10:18:34.702449 kalae.echo > kohala.33621: . ack 12289 win 8760 +10:18:34.705393 kalae.echo > kohala.33621: . 8193:9653(1460) ack 12289 win 8760 +10:18:34.705795 kalae.echo > kohala.33621: P 9653:10241(588) ack 12289 win 8760 +10:18:34.705908 kohala.33621 > kalae.echo: . ack 9653 win 8760 (DF) +10:18:34.707441 kalae.echo > kohala.33621: . 10241:11701(1460) ack 12289 win 8760 +10:18:34.711917 kohala.33621 > kalae.echo: P 12289:13749(1460) ack 11701 win 8760 (DF) +10:18:34.712264 kohala.33621 > kalae.echo: P 13749:15209(1460) ack 11701 win 8760 (DF) +10:18:34.712579 kohala.33621 > kalae.echo: P 15209:16385(1176) ack 11701 win 8760 (DF) +10:18:34.717363 kalae.echo > kohala.33621: P 11701:12289(588) ack 13749 win 7300 +10:18:34.718793 kalae.echo > kohala.33621: . ack 16385 win 8760 +10:18:34.721546 kalae.echo > kohala.33621: . 12289:13749(1460) ack 16385 win 8760 +10:18:34.723149 kalae.echo > kohala.33621: . 13749:15209(1460) ack 16385 win 8760 +10:18:34.723343 kohala.33621 > kalae.echo: . ack 15209 win 8760 (DF) +10:18:34.726008 kalae.echo > kohala.33621: P 15209:16385(1176) ack 16385 win 8760 +10:18:34.727659 kohala.33621 > kalae.echo: P 16385:17845(1460) ack 16385 win 8760 (DF) +10:18:34.728011 kohala.33621 > kalae.echo: P 17845:19305(1460) ack 16385 win 8760 (DF) +10:18:34.728337 kohala.33621 > kalae.echo: P 19305:20481(1176) ack 16385 win 8760 (DF) +10:18:34.733691 kalae.echo > kohala.33621: . ack 20481 win 8760 +10:18:34.736411 kalae.echo > kohala.33621: . 16385:17845(1460) ack 20481 win 8760 +10:18:34.736942 kalae.echo > kohala.33621: P 17845:18433(588) ack 20481 win 8760 +10:18:34.738753 kalae.echo > kohala.33621: . 18433:19893(1460) ack 20481 win 8760 +10:18:34.738968 kohala.33621 > kalae.echo: . ack 19893 win 8760 (DF) +10:18:34.740856 kalae.echo > kohala.33621: P 19893:20481(588) ack 20481 win 8760 +10:18:34.790367 kohala.33621 > kalae.echo: . ack 20481 win 8760 (DF) +10:18:34.802928 kohala.33621 > kalae.echo: P 20481:21941(1460) ack 20481 win 8760 (DF) +10:18:34.803290 kohala.33621 > kalae.echo: P 21941:23401(1460) ack 20481 win 8760 (DF) +10:18:34.803575 kohala.33621 > kalae.echo: P 23401:24130(729) ack 20481 win 8760 (DF) +10:18:34.808732 kalae.echo > kohala.33621: . ack 24130 win 8760 +10:18:34.811468 kalae.echo > kohala.33621: . 20481:21941(1460) ack 24130 win 8760 +10:18:34.811994 kalae.echo > kohala.33621: P 21941:22529(588) ack 24130 win 8760 +10:18:34.813713 kalae.echo > kohala.33621: . 22529:23989(1460) ack 24130 win 8760 +10:18:34.813937 kohala.33621 > kalae.echo: . ack 23989 win 8760 (DF) +10:18:34.815274 kalae.echo > kohala.33621: P 23989:24130(141) ack 24130 win 8760 +10:18:34.849338 kohala.33621 > kalae.echo: F 24130:24130(0) ack 24130 win 8760 (DF) +10:18:34.850471 kalae.echo > kohala.33621: . ack 24131 win 8760 +10:18:34.852790 kalae.echo > kohala.33621: F 24130:24130(0) ack 24131 win 8760 +10:18:34.853086 kohala.33621 > kalae.echo: . ack 24131 win 8760 (DF) diff --git a/nonblock/start_connect.c b/nonblock/start_connect.c new file mode 100644 index 0000000..1546f69 --- /dev/null +++ b/nonblock/start_connect.c @@ -0,0 +1,31 @@ +#include "web.h" + +void +start_connect(struct file *fptr) +{ + int fd, flags, n; + struct addrinfo *ai; + + ai = Host_serv(fptr->f_host, SERV, 0, SOCK_STREAM); + + fd = Socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + fptr->f_fd = fd; + printf("start_connect for %s, fd %d\n", fptr->f_name, fd); + + /* 4Set socket nonblocking */ + flags = Fcntl(fd, F_GETFL, 0); + Fcntl(fd, F_SETFL, flags | O_NONBLOCK); + + /* 4Initiate nonblocking connect to the server. */ + if ( (n = connect(fd, ai->ai_addr, ai->ai_addrlen)) < 0) { + if (errno != EINPROGRESS) + err_sys("nonblocking connect error"); + fptr->f_flags = F_CONNECTING; + FD_SET(fd, &rset); /* select for reading and writing */ + FD_SET(fd, &wset); + if (fd > maxfd) + maxfd = fd; + + } else if (n >= 0) /* connect is already done */ + write_get_cmd(fptr); /* write() the GET command */ +} diff --git a/nonblock/strclifork.c b/nonblock/strclifork.c new file mode 100644 index 0000000..2ff702d --- /dev/null +++ b/nonblock/strclifork.c @@ -0,0 +1,24 @@ +#include "unp.h" + +void +str_cli(FILE *fp, int sockfd) +{ + pid_t pid; + char sendline[MAXLINE], recvline[MAXLINE]; + + if ( (pid = Fork()) == 0) { /* child: server -> stdout */ + while (Readline(sockfd, recvline, MAXLINE) > 0) + Fputs(recvline, stdout); + + kill(getppid(), SIGTERM); /* in case parent still running */ + exit(0); + } + + /* parent: stdin -> server */ + while (Fgets(sendline, MAXLINE, fp) != NULL) + Writen(sockfd, sendline, strlen(sendline)); + + Shutdown(sockfd, SHUT_WR); /* EOF on stdin, send FIN */ + pause(); + return; +} diff --git a/nonblock/strclinonb.c b/nonblock/strclinonb.c new file mode 100644 index 0000000..a06e126 --- /dev/null +++ b/nonblock/strclinonb.c @@ -0,0 +1,125 @@ +/* include nonb1 */ +#include "unp.h" + +void +str_cli(FILE *fp, int sockfd) +{ + int maxfdp1, val, stdineof; + ssize_t n, nwritten; + fd_set rset, wset; + char to[MAXLINE], fr[MAXLINE]; + char *toiptr, *tooptr, *friptr, *froptr; + + val = Fcntl(sockfd, F_GETFL, 0); + Fcntl(sockfd, F_SETFL, val | O_NONBLOCK); + + val = Fcntl(STDIN_FILENO, F_GETFL, 0); + Fcntl(STDIN_FILENO, F_SETFL, val | O_NONBLOCK); + + val = Fcntl(STDOUT_FILENO, F_GETFL, 0); + Fcntl(STDOUT_FILENO, F_SETFL, val | O_NONBLOCK); + + toiptr = tooptr = to; /* initialize buffer pointers */ + friptr = froptr = fr; + stdineof = 0; + + maxfdp1 = max(max(STDIN_FILENO, STDOUT_FILENO), sockfd) + 1; + for ( ; ; ) { + FD_ZERO(&rset); + FD_ZERO(&wset); + if (stdineof == 0 && toiptr < &to[MAXLINE]) + FD_SET(STDIN_FILENO, &rset); /* read from stdin */ + if (friptr < &fr[MAXLINE]) + FD_SET(sockfd, &rset); /* read from socket */ + if (tooptr != toiptr) + FD_SET(sockfd, &wset); /* data to write to socket */ + if (froptr != friptr) + FD_SET(STDOUT_FILENO, &wset); /* data to write to stdout */ + + Select(maxfdp1, &rset, &wset, NULL, NULL); +/* end nonb1 */ +/* include nonb2 */ + if (FD_ISSET(STDIN_FILENO, &rset)) { + if ( (n = read(STDIN_FILENO, toiptr, &to[MAXLINE] - toiptr)) < 0) { + if (errno != EWOULDBLOCK) + err_sys("read error on stdin"); + + } else if (n == 0) { +#ifdef VOL2 + fprintf(stderr, "%s: EOF on stdin\n", gf_time()); +#endif + stdineof = 1; /* all done with stdin */ + if (tooptr == toiptr) + Shutdown(sockfd, SHUT_WR);/* send FIN */ + + } else { +#ifdef VOL2 + fprintf(stderr, "%s: read %d bytes from stdin\n", gf_time(), n); +#endif + toiptr += n; /* # just read */ + FD_SET(sockfd, &wset); /* try and write to socket below */ + } + } + + if (FD_ISSET(sockfd, &rset)) { + if ( (n = read(sockfd, friptr, &fr[MAXLINE] - friptr)) < 0) { + if (errno != EWOULDBLOCK) + err_sys("read error on socket"); + + } else if (n == 0) { +#ifdef VOL2 + fprintf(stderr, "%s: EOF on socket\n", gf_time()); +#endif + if (stdineof) + return; /* normal termination */ + else + err_quit("str_cli: server terminated prematurely"); + + } else { +#ifdef VOL2 + fprintf(stderr, "%s: read %d bytes from socket\n", + gf_time(), n); +#endif + friptr += n; /* # just read */ + FD_SET(STDOUT_FILENO, &wset); /* try and write below */ + } + } +/* end nonb2 */ +/* include nonb3 */ + if (FD_ISSET(STDOUT_FILENO, &wset) && ( (n = friptr - froptr) > 0)) { + if ( (nwritten = write(STDOUT_FILENO, froptr, n)) < 0) { + if (errno != EWOULDBLOCK) + err_sys("write error to stdout"); + + } else { +#ifdef VOL2 + fprintf(stderr, "%s: wrote %d bytes to stdout\n", + gf_time(), nwritten); +#endif + froptr += nwritten; /* # just written */ + if (froptr == friptr) + froptr = friptr = fr; /* back to beginning of buffer */ + } + } + + if (FD_ISSET(sockfd, &wset) && ( (n = toiptr - tooptr) > 0)) { + if ( (nwritten = write(sockfd, tooptr, n)) < 0) { + if (errno != EWOULDBLOCK) + err_sys("write error to socket"); + + } else { +#ifdef VOL2 + fprintf(stderr, "%s: wrote %d bytes to socket\n", + gf_time(), nwritten); +#endif + tooptr += nwritten; /* # just written */ + if (tooptr == toiptr) { + toiptr = tooptr = to; /* back to beginning of buffer */ + if (stdineof) + Shutdown(sockfd, SHUT_WR); /* send FIN */ + } + } + } + } +} +/* end nonb3 */ diff --git a/nonblock/strclinonb.lc b/nonblock/strclinonb.lc new file mode 100644 index 0000000..3e9631b --- /dev/null +++ b/nonblock/strclinonb.lc @@ -0,0 +1,114 @@ +/* include nonb1 */ +#include "unp.h"## 1 ##src/nonblock/strclinonb.c## + +void## 2 ##src/nonblock/strclinonb.c## +str_cli(FILE *fp, int sockfd)## 3 ##src/nonblock/strclinonb.c## +{## 4 ##src/nonblock/strclinonb.c## + int maxfdp1, val, stdineof;## 5 ##src/nonblock/strclinonb.c## + ssize_t n, nwritten;## 6 ##src/nonblock/strclinonb.c## + fd_set rset, wset;## 7 ##src/nonblock/strclinonb.c## + char to[MAXLINE], fr[MAXLINE];## 8 ##src/nonblock/strclinonb.c## + char *toiptr, *tooptr, *friptr, *froptr;## 9 ##src/nonblock/strclinonb.c## + + val = Fcntl(sockfd, F_GETFL, 0);## 10 ##src/nonblock/strclinonb.c## + Fcntl(sockfd, F_SETFL, val | O_NONBLOCK);## 11 ##src/nonblock/strclinonb.c## + + val = Fcntl(STDIN_FILENO, F_GETFL, 0);## 12 ##src/nonblock/strclinonb.c## + Fcntl(STDIN_FILENO, F_SETFL, val | O_NONBLOCK);## 13 ##src/nonblock/strclinonb.c## + + val = Fcntl(STDOUT_FILENO, F_GETFL, 0);## 14 ##src/nonblock/strclinonb.c## + Fcntl(STDOUT_FILENO, F_SETFL, val | O_NONBLOCK);## 15 ##src/nonblock/strclinonb.c## + + toiptr = tooptr = to; /* initialize buffer pointers */## 16 ##src/nonblock/strclinonb.c## + friptr = froptr = fr;## 17 ##src/nonblock/strclinonb.c## + stdineof = 0;## 18 ##src/nonblock/strclinonb.c## + + maxfdp1 = max(max(STDIN_FILENO, STDOUT_FILENO), sockfd) + 1;## 19 ##src/nonblock/strclinonb.c## + for (;;) {## 20 ##src/nonblock/strclinonb.c## + FD_ZERO(&rset);## 21 ##src/nonblock/strclinonb.c## + FD_ZERO(&wset);## 22 ##src/nonblock/strclinonb.c## + if (stdineof == 0 && toiptr < &to[MAXLINE])## 23 ##src/nonblock/strclinonb.c## + FD_SET(STDIN_FILENO, &rset); /* read from stdin */## 24 ##src/nonblock/strclinonb.c## + if (friptr < &fr[MAXLINE])## 25 ##src/nonblock/strclinonb.c## + FD_SET(sockfd, &rset); /* read from socket */## 26 ##src/nonblock/strclinonb.c## + if (tooptr != toiptr)## 27 ##src/nonblock/strclinonb.c## + FD_SET(sockfd, &wset); /* data to write to socket */## 28 ##src/nonblock/strclinonb.c## + if (froptr != friptr)## 29 ##src/nonblock/strclinonb.c## + FD_SET(STDOUT_FILENO, &wset); /* data to write to stdout */## 30 ##src/nonblock/strclinonb.c## + + Select(maxfdp1, &rset, &wset, NULL, NULL);## 31 ##src/nonblock/strclinonb.c## +/* end nonb1 */ +/* include nonb2 */ + if (FD_ISSET(STDIN_FILENO, &rset)) {## 32 ##src/nonblock/strclinonb.c## + if ((n = read(STDIN_FILENO, toiptr, &to[MAXLINE] - toiptr)) < 0) {## 33 ##src/nonblock/strclinonb.c## + if (errno != EWOULDBLOCK)## 34 ##src/nonblock/strclinonb.c## + err_sys("read error on stdin");## 35 ##src/nonblock/strclinonb.c## + + } else if (n == 0) {## 36 ##src/nonblock/strclinonb.c## + fprintf(stderr, "%s: EOF on stdin\n", gf_time());## 37 ##src/nonblock/strclinonb.c## + stdineof = 1; /* all done with stdin */## 38 ##src/nonblock/strclinonb.c## + if (tooptr == toiptr)## 39 ##src/nonblock/strclinonb.c## + Shutdown(sockfd, SHUT_WR); /* send FIN */## 40 ##src/nonblock/strclinonb.c## + + } else {## 41 ##src/nonblock/strclinonb.c## + fprintf(stderr, "%s: read %d bytes from stdin\n", gf_time(),## 42 ##src/nonblock/strclinonb.c## + n);## 43 ##src/nonblock/strclinonb.c## + toiptr += n; /* # just read */## 44 ##src/nonblock/strclinonb.c## + FD_SET(sockfd, &wset); /* try and write to socket below */## 45 ##src/nonblock/strclinonb.c## + }## 46 ##src/nonblock/strclinonb.c## + }## 47 ##src/nonblock/strclinonb.c## + + if (FD_ISSET(sockfd, &rset)) {## 48 ##src/nonblock/strclinonb.c## + if ((n = read(sockfd, friptr, &fr[MAXLINE] - friptr)) < 0) {## 49 ##src/nonblock/strclinonb.c## + if (errno != EWOULDBLOCK)## 50 ##src/nonblock/strclinonb.c## + err_sys("read error on socket");## 51 ##src/nonblock/strclinonb.c## + + } else if (n == 0) {## 52 ##src/nonblock/strclinonb.c## + fprintf(stderr, "%s: EOF on socket\n", gf_time());## 53 ##src/nonblock/strclinonb.c## + if (stdineof)## 54 ##src/nonblock/strclinonb.c## + return; /* normal termination */## 55 ##src/nonblock/strclinonb.c## + else## 56 ##src/nonblock/strclinonb.c## + err_quit("str_cli: server terminated prematurely");## 57 ##src/nonblock/strclinonb.c## + + } else {## 58 ##src/nonblock/strclinonb.c## + fprintf(stderr, "%s: read %d bytes from socket\n",## 59 ##src/nonblock/strclinonb.c## + gf_time(), n);## 60 ##src/nonblock/strclinonb.c## + friptr += n; /* # just read */## 61 ##src/nonblock/strclinonb.c## + FD_SET(STDOUT_FILENO, &wset); /* try and write below */## 62 ##src/nonblock/strclinonb.c## + }## 63 ##src/nonblock/strclinonb.c## + }## 64 ##src/nonblock/strclinonb.c## +/* end nonb2 */ +/* include nonb3 */ + if (FD_ISSET(STDOUT_FILENO, &wset) && ((n = friptr - froptr) > 0)) {## 65 ##src/nonblock/strclinonb.c## + if ((nwritten = write(STDOUT_FILENO, froptr, n)) < 0) {## 66 ##src/nonblock/strclinonb.c## + if (errno != EWOULDBLOCK)## 67 ##src/nonblock/strclinonb.c## + err_sys("write error to stdout");## 68 ##src/nonblock/strclinonb.c## + + } else {## 69 ##src/nonblock/strclinonb.c## + fprintf(stderr, "%s: wrote %d bytes to stdout\n",## 70 ##src/nonblock/strclinonb.c## + gf_time(), nwritten);## 71 ##src/nonblock/strclinonb.c## + froptr += nwritten; /* # just written */## 72 ##src/nonblock/strclinonb.c## + if (froptr == friptr)## 73 ##src/nonblock/strclinonb.c## + froptr = friptr = fr; /* back to beginning of buffer */## 74 ##src/nonblock/strclinonb.c## + }## 75 ##src/nonblock/strclinonb.c## + }## 76 ##src/nonblock/strclinonb.c## + + if (FD_ISSET(sockfd, &wset) && ((n = toiptr - tooptr) > 0)) {## 77 ##src/nonblock/strclinonb.c## + if ((nwritten = write(sockfd, tooptr, n)) < 0) {## 78 ##src/nonblock/strclinonb.c## + if (errno != EWOULDBLOCK)## 79 ##src/nonblock/strclinonb.c## + err_sys("write error to socket");## 80 ##src/nonblock/strclinonb.c## + + } else {## 81 ##src/nonblock/strclinonb.c## + fprintf(stderr, "%s: wrote %d bytes to socket\n",## 82 ##src/nonblock/strclinonb.c## + gf_time(), nwritten);## 83 ##src/nonblock/strclinonb.c## + tooptr += nwritten; /* # just written */## 84 ##src/nonblock/strclinonb.c## + if (tooptr == toiptr) {## 85 ##src/nonblock/strclinonb.c## + toiptr = tooptr = to; /* back to beginning of buffer */## 86 ##src/nonblock/strclinonb.c## + if (stdineof)## 87 ##src/nonblock/strclinonb.c## + Shutdown(sockfd, SHUT_WR); /* send FIN */## 88 ##src/nonblock/strclinonb.c## + }## 89 ##src/nonblock/strclinonb.c## + }## 90 ##src/nonblock/strclinonb.c## + }## 91 ##src/nonblock/strclinonb.c## + }## 92 ##src/nonblock/strclinonb.c## +}## 93 ##src/nonblock/strclinonb.c## +/* end nonb3 */ diff --git a/nonblock/tcpcli01.c b/nonblock/tcpcli01.c new file mode 100644 index 0000000..8c62186 --- /dev/null +++ b/nonblock/tcpcli01.c @@ -0,0 +1,24 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(7); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/nonblock/tcpcli02.c b/nonblock/tcpcli02.c new file mode 100644 index 0000000..8c62186 --- /dev/null +++ b/nonblock/tcpcli02.c @@ -0,0 +1,24 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(7); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/nonblock/tcpcli03.c b/nonblock/tcpcli03.c new file mode 100644 index 0000000..749c6eb --- /dev/null +++ b/nonblock/tcpcli03.c @@ -0,0 +1,28 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct linger ling; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + ling.l_onoff = 1; /* cause RST to be sent on close() */ + ling.l_linger = 0; + Setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)); + Close(sockfd); + + exit(0); +} diff --git a/nonblock/tcpcli03.lc b/nonblock/tcpcli03.lc new file mode 100644 index 0000000..29a9ecb --- /dev/null +++ b/nonblock/tcpcli03.lc @@ -0,0 +1,28 @@ +#include "unp.h"## 1 ##src/nonblock/tcpcli03.c## + +int## 2 ##src/nonblock/tcpcli03.c## +main(int argc, char **argv)## 3 ##src/nonblock/tcpcli03.c## +{## 4 ##src/nonblock/tcpcli03.c## + int sockfd;## 5 ##src/nonblock/tcpcli03.c## + struct linger ling;## 6 ##src/nonblock/tcpcli03.c## + struct sockaddr_in servaddr;## 7 ##src/nonblock/tcpcli03.c## + + if (argc != 2)## 8 ##src/nonblock/tcpcli03.c## + err_quit("usage: tcpcli ");## 9 ##src/nonblock/tcpcli03.c## + + sockfd = Socket(AF_INET, SOCK_STREAM, 0);## 10 ##src/nonblock/tcpcli03.c## + + bzero(&servaddr, sizeof(servaddr));## 11 ##src/nonblock/tcpcli03.c## + servaddr.sin_family = AF_INET;## 12 ##src/nonblock/tcpcli03.c## + servaddr.sin_port = htons(SERV_PORT);## 13 ##src/nonblock/tcpcli03.c## + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);## 14 ##src/nonblock/tcpcli03.c## + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));## 15 ##src/nonblock/tcpcli03.c## + + ling.l_onoff = 1; /* cause RST to be sent on close() */## 16 ##src/nonblock/tcpcli03.c## + ling.l_linger = 0;## 17 ##src/nonblock/tcpcli03.c## + Setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));## 18 ##src/nonblock/tcpcli03.c## + Close(sockfd);## 19 ##src/nonblock/tcpcli03.c## + + exit(0);## 20 ##src/nonblock/tcpcli03.c## +}## 21 ##src/nonblock/tcpcli03.c## diff --git a/nonblock/tcpcli04.c b/nonblock/tcpcli04.c new file mode 100644 index 0000000..ecdb446 --- /dev/null +++ b/nonblock/tcpcli04.c @@ -0,0 +1,29 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct linger ling; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + ling.l_onoff = 1; /* cause RST to be sent on close() */ + ling.l_linger = 0; + Setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/nonblock/tcpservselect03.c b/nonblock/tcpservselect03.c new file mode 100644 index 0000000..a530424 --- /dev/null +++ b/nonblock/tcpservselect03.c @@ -0,0 +1,82 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int i, maxi, maxfd, listenfd, connfd, sockfd; + int nready, client[FD_SETSIZE]; + ssize_t n; + fd_set rset, allset; + char line[MAXLINE]; + socklen_t clilen; + struct sockaddr_in cliaddr, servaddr; + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + maxfd = listenfd; /* initialize */ + maxi = -1; /* index into client[] array */ + for (i = 0; i < FD_SETSIZE; i++) + client[i] = -1; /* -1 indicates available entry */ + FD_ZERO(&allset); + FD_SET(listenfd, &allset); + + for ( ; ; ) { + rset = allset; + nready = Select(maxfd+1, &rset, NULL, NULL, NULL); + + if (FD_ISSET(listenfd, &rset)) { /* new client connection */ + printf("listening socket readable\n"); + sleep(5); + clilen = sizeof(cliaddr); + connfd = Accept(listenfd, (SA *) &cliaddr, &clilen); +#ifdef NOTDEF + printf("new client: %s, port %d\n", + Inet_ntop(AF_INET, &cliaddr.sin_addr, 4, NULL), + ntohs(cliaddr.sin_port)); +#endif + + for (i = 0; i < FD_SETSIZE; i++) + if (client[i] < 0) { + client[i] = connfd; /* save descriptor */ + break; + } + if (i == FD_SETSIZE) + err_quit("too many clients"); + + FD_SET(connfd, &allset); /* add new descriptor to set */ + if (connfd > maxfd) + maxfd = connfd; /* for select */ + if (i > maxi) + maxi = i; /* max index in client[] array */ + + if (--nready <= 0) + continue; /* no more readable descriptors */ + } + + for (i = 0; i <= maxi; i++) { /* check all clients for data */ + if ( (sockfd = client[i]) < 0) + continue; + if (FD_ISSET(sockfd, &rset)) { + if ( (n = Readline(sockfd, line, MAXLINE)) == 0) { + /* connection closed by client */ + Close(sockfd); + FD_CLR(sockfd, &allset); + client[i] = -1; + } + Writen(sockfd, line, n); + + if (--nready <= 0) + break; /* no more readable descriptors */ + } + } + } +} diff --git a/nonblock/web.c b/nonblock/web.c new file mode 100644 index 0000000..637706b --- /dev/null +++ b/nonblock/web.c @@ -0,0 +1,83 @@ +/* include web1 */ +#include "web.h" + +int +main(int argc, char **argv) +{ + int i, fd, n, maxnconn, flags, error; + char buf[MAXLINE]; + fd_set rs, ws; + + if (argc < 5) + err_quit("usage: web <#conns> ..."); + maxnconn = atoi(argv[1]); + + nfiles = min(argc - 4, MAXFILES); + for (i = 0; i < nfiles; i++) { + file[i].f_name = argv[i + 4]; + file[i].f_host = argv[2]; + file[i].f_flags = 0; + } + printf("nfiles = %d\n", nfiles); + + home_page(argv[2], argv[3]); + + FD_ZERO(&rset); + FD_ZERO(&wset); + maxfd = -1; + nlefttoread = nlefttoconn = nfiles; + nconn = 0; +/* end web1 */ +/* include web2 */ + while (nlefttoread > 0) { + while (nconn < maxnconn && nlefttoconn > 0) { + /* 4find a file to read */ + for (i = 0 ; i < nfiles; i++) + if (file[i].f_flags == 0) + break; + if (i == nfiles) + err_quit("nlefttoconn = %d but nothing found", nlefttoconn); + start_connect(&file[i]); + nconn++; + nlefttoconn--; + } + + rs = rset; + ws = wset; + n = Select(maxfd+1, &rs, &ws, NULL, NULL); + + for (i = 0; i < nfiles; i++) { + flags = file[i].f_flags; + if (flags == 0 || flags & F_DONE) + continue; + fd = file[i].f_fd; + if (flags & F_CONNECTING && + (FD_ISSET(fd, &rs) || FD_ISSET(fd, &ws))) { + n = sizeof(error); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &n) < 0 || + error != 0) { + err_ret("nonblocking connect failed for %s", + file[i].f_name); + } + /* 4connection established */ + printf("connection established for %s\n", file[i].f_name); + FD_CLR(fd, &wset); /* no more writeability test */ + write_get_cmd(&file[i]);/* write() the GET command */ + + } else if (flags & F_READING && FD_ISSET(fd, &rs)) { + if ( (n = Read(fd, buf, sizeof(buf))) == 0) { + printf("end-of-file on %s\n", file[i].f_name); + Close(fd); + file[i].f_flags = F_DONE; /* clears F_READING */ + FD_CLR(fd, &rset); + nconn--; + nlefttoread--; + } else { + printf("read %d bytes from %s\n", n, file[i].f_name); + } + } + } + } + exit(0); +} +/* end web2 */ diff --git a/nonblock/web.h b/nonblock/web.h new file mode 100644 index 0000000..eeac086 --- /dev/null +++ b/nonblock/web.h @@ -0,0 +1,26 @@ +#include "unp.h" + +#define MAXFILES 20 +#define SERV "80" /* port number or service name */ + +struct file { + char *f_name; /* filename */ + char *f_host; /* hostname or IPv4/IPv6 address */ + int f_fd; /* descriptor */ + int f_flags; /* F_xxx below */ +} file[MAXFILES]; + +#define F_CONNECTING 1 /* connect() in progress */ +#define F_READING 2 /* connect() complete; now reading */ +#define F_DONE 4 /* all done */ + +#define GET_CMD "GET %s HTTP/1.0\r\n\r\n" + + /* globals */ +int nconn, nfiles, nlefttoconn, nlefttoread, maxfd; +fd_set rset, wset; + + /* function prototypes */ +void home_page(const char *, const char *); +void start_connect(struct file *); +void write_get_cmd(struct file *); diff --git a/nonblock/web.lc b/nonblock/web.lc new file mode 100644 index 0000000..c5141c4 --- /dev/null +++ b/nonblock/web.lc @@ -0,0 +1,83 @@ +/* include web1 */ +#include "web.h"## 1 ##src/nonblock/web.c## + +int## 2 ##src/nonblock/web.c## +main(int argc, char **argv)## 3 ##src/nonblock/web.c## +{## 4 ##src/nonblock/web.c## + int i, fd, n, maxnconn, flags, error;## 5 ##src/nonblock/web.c## + char buf[MAXLINE];## 6 ##src/nonblock/web.c## + fd_set rs, ws;## 7 ##src/nonblock/web.c## + + if (argc < 5)## 8 ##src/nonblock/web.c## + err_quit("usage: web <#conns> ...");## 9 ##src/nonblock/web.c## + maxnconn = atoi(argv[1]);## 10 ##src/nonblock/web.c## + + nfiles = min(argc - 4, MAXFILES);## 11 ##src/nonblock/web.c## + for (i = 0; i < nfiles; i++) {## 12 ##src/nonblock/web.c## + file[i].f_name = argv[i + 4];## 13 ##src/nonblock/web.c## + file[i].f_host = argv[2];## 14 ##src/nonblock/web.c## + file[i].f_flags = 0;## 15 ##src/nonblock/web.c## + }## 16 ##src/nonblock/web.c## + printf("nfiles = %d\n", nfiles);## 17 ##src/nonblock/web.c## + + home_page(argv[2], argv[3]);## 18 ##src/nonblock/web.c## + + FD_ZERO(&rset);## 19 ##src/nonblock/web.c## + FD_ZERO(&wset);## 20 ##src/nonblock/web.c## + maxfd = -1;## 21 ##src/nonblock/web.c## + nlefttoread = nlefttoconn = nfiles;## 22 ##src/nonblock/web.c## + nconn = 0;## 23 ##src/nonblock/web.c## +/* end web1 */ +/* include web2 */ + while (nlefttoread > 0) {## 24 ##src/nonblock/web.c## + while (nconn < maxnconn && nlefttoconn > 0) {## 25 ##src/nonblock/web.c## + /* 4find a file to read */## 26 ##src/nonblock/web.c## + for (i = 0; i < nfiles; i++)## 27 ##src/nonblock/web.c## + if (file[i].f_flags == 0)## 28 ##src/nonblock/web.c## + break;## 29 ##src/nonblock/web.c## + if (i == nfiles)## 30 ##src/nonblock/web.c## + err_quit("nlefttoconn = %d but nothing found", nlefttoconn);## 31 ##src/nonblock/web.c## + start_connect(&file[i]);## 32 ##src/nonblock/web.c## + nconn++;## 33 ##src/nonblock/web.c## + nlefttoconn--;## 34 ##src/nonblock/web.c## + }## 35 ##src/nonblock/web.c## + + rs = rset;## 36 ##src/nonblock/web.c## + ws = wset;## 37 ##src/nonblock/web.c## + n = Select(maxfd + 1, &rs, &ws, NULL, NULL);## 38 ##src/nonblock/web.c## + + for (i = 0; i < nfiles; i++) {## 39 ##src/nonblock/web.c## + flags = file[i].f_flags;## 40 ##src/nonblock/web.c## + if (flags == 0 || flags & F_DONE)## 41 ##src/nonblock/web.c## + continue;## 42 ##src/nonblock/web.c## + fd = file[i].f_fd;## 43 ##src/nonblock/web.c## + if (flags & F_CONNECTING &&## 44 ##src/nonblock/web.c## + (FD_ISSET(fd, &rs) || FD_ISSET(fd, &ws))) {## 45 ##src/nonblock/web.c## + n = sizeof(error);## 46 ##src/nonblock/web.c## + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &n) < 0 ||## 47 ##src/nonblock/web.c## + error != 0) {## 48 ##src/nonblock/web.c## + err_ret("nonblocking connect failed for %s",## 49 ##src/nonblock/web.c## + file[i].f_name);## 50 ##src/nonblock/web.c## + }## 51 ##src/nonblock/web.c## + /* 4connection established */## 52 ##src/nonblock/web.c## + printf("connection established for %s\n", file[i].f_name);## 53 ##src/nonblock/web.c## + FD_CLR(fd, &wset); /* no more writeability test */## 54 ##src/nonblock/web.c## + write_get_cmd(&file[i]); /* write() the GET command */## 55 ##src/nonblock/web.c## + + } else if (flags & F_READING && FD_ISSET(fd, &rs)) {## 56 ##src/nonblock/web.c## + if ((n = Read(fd, buf, sizeof(buf))) == 0) {## 57 ##src/nonblock/web.c## + printf("end-of-file on %s\n", file[i].f_name);## 58 ##src/nonblock/web.c## + Close(fd);## 59 ##src/nonblock/web.c## + file[i].f_flags = F_DONE; /* clears F_READING */## 60 ##src/nonblock/web.c## + FD_CLR(fd, &rset);## 61 ##src/nonblock/web.c## + nconn--;## 62 ##src/nonblock/web.c## + nlefttoread--;## 63 ##src/nonblock/web.c## + } else {## 64 ##src/nonblock/web.c## + printf("read %d bytes from %s\n", n, file[i].f_name);## 65 ##src/nonblock/web.c## + }## 66 ##src/nonblock/web.c## + }## 67 ##src/nonblock/web.c## + }## 68 ##src/nonblock/web.c## + }## 69 ##src/nonblock/web.c## + exit(0);## 70 ##src/nonblock/web.c## +}## 71 ##src/nonblock/web.c## +/* end web2 */ diff --git a/nonblock/write_get_cmd.c b/nonblock/write_get_cmd.c new file mode 100644 index 0000000..e93da3f --- /dev/null +++ b/nonblock/write_get_cmd.c @@ -0,0 +1,18 @@ +#include "web.h" + +void +write_get_cmd(struct file *fptr) +{ + int n; + char line[MAXLINE]; + + n = snprintf(line, sizeof(line), GET_CMD, fptr->f_name); + Writen(fptr->f_fd, line, n); + printf("wrote %d bytes for %s\n", n, fptr->f_name); + + fptr->f_flags = F_READING; /* clears F_CONNECTING */ + + FD_SET(fptr->f_fd, &rset); /* will read server's reply */ + if (fptr->f_fd > maxfd) + maxfd = fptr->f_fd; +} diff --git a/oob/Makefile b/oob/Makefile new file mode 100644 index 0000000..7abc621 --- /dev/null +++ b/oob/Makefile @@ -0,0 +1,56 @@ +include ../Make.defines + +# XXX get autoconf to put tcprecv03p in here if the system supports poll +PROGS = tcprecv01 tcprecv02 tcprecv03 tcprecv04 tcprecv05 tcprecv06 \ + tcpsend01 tcpsend02 tcpsend03 tcpsend04 tcpsend05 tcpsend06 \ + tcpcli02 tcpserv02 + +all: ${PROGS} + +tcprecv01: tcprecv01.o + ${CC} ${CFLAGS} -o $@ tcprecv01.o ${LIBS} + +tcpsend01: tcpsend01.o + ${CC} ${CFLAGS} -o $@ tcpsend01.o ${LIBS} + +tcprecv02: tcprecv02.o + ${CC} ${CFLAGS} -o $@ tcprecv02.o ${LIBS} + +tcpsend02: tcpsend02.o + ${CC} ${CFLAGS} -o $@ tcpsend02.o ${LIBS} + +tcprecv03: tcprecv03.o + ${CC} ${CFLAGS} -o $@ tcprecv03.o ${LIBS} + +tcprecv03p: tcprecv03p.o + ${CC} ${CFLAGS} -o $@ tcprecv03p.o ${LIBS} + +tcpsend03: tcpsend03.o + ${CC} ${CFLAGS} -o $@ tcpsend03.o ${LIBS} + +tcprecv04: tcprecv04.o + ${CC} ${CFLAGS} -o $@ tcprecv04.o ${LIBS} + +tcpsend04: tcpsend04.o + ${CC} ${CFLAGS} -o $@ tcpsend04.o ${LIBS} + +tcprecv05: tcprecv05.o + ${CC} ${CFLAGS} -o $@ tcprecv05.o ${LIBS} + +tcpsend05: tcpsend05.o + ${CC} ${CFLAGS} -o $@ tcpsend05.o ${LIBS} + +tcprecv06: tcprecv06.o + ${CC} ${CFLAGS} -o $@ tcprecv06.o ${LIBS} + +tcpsend06: tcpsend06.o + ${CC} ${CFLAGS} -o $@ tcpsend06.o ${LIBS} + +tcpcli02: tcpcli02.o strcliselect02.o heartbeatcli.o + ${CC} ${CFLAGS} -o $@ tcpcli02.o strcliselect02.o heartbeatcli.o ${LIBS} + +tcpserv02: tcpserv02.o strecho02.o heartbeatserv.o sigchldwaitpid.o + ${CC} ${CFLAGS} -o $@ tcpserv02.o strecho02.o heartbeatserv.o sigchldwaitpid.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/oob/heartbeatcli.c b/oob/heartbeatcli.c new file mode 100644 index 0000000..d1458b3 --- /dev/null +++ b/oob/heartbeatcli.c @@ -0,0 +1,50 @@ +#include "unp.h" + +static int servfd; +static int nsec; /* #seconds betweeen each alarm */ +static int maxnprobes; /* #probes w/no response before quit */ +static int nprobes; /* #probes since last server response */ +static void sig_urg(int), sig_alrm(int); + +void +heartbeat_cli(int servfd_arg, int nsec_arg, int maxnprobes_arg) +{ + servfd = servfd_arg; /* set globals for signal handlers */ + if ( (nsec = nsec_arg) < 1) + nsec = 1; + if ( (maxnprobes = maxnprobes_arg) < nsec) + maxnprobes = nsec; + nprobes = 0; + + Signal(SIGURG, sig_urg); + Fcntl(servfd, F_SETOWN, getpid()); + + Signal(SIGALRM, sig_alrm); + alarm(nsec); +} + +static void +sig_urg(int signo) +{ + int n; + char c; + + if ( (n = recv(servfd, &c, 1, MSG_OOB)) < 0) { + if (errno != EWOULDBLOCK) + err_sys("recv error"); + } + nprobes = 0; /* reset counter */ + return; /* may interrupt client code */ +} + +static void +sig_alrm(int signo) +{ + if (++nprobes > maxnprobes) { + fprintf(stderr, "server is unreachable\n"); + exit(0); + } + Send(servfd, "1", 1, MSG_OOB); + alarm(nsec); + return; /* may interrupt client code */ +} diff --git a/oob/heartbeatserv.c b/oob/heartbeatserv.c new file mode 100644 index 0000000..fc7b2a7 --- /dev/null +++ b/oob/heartbeatserv.c @@ -0,0 +1,50 @@ +#include "unp.h" + +static int servfd; +static int nsec; /* #seconds between each alarm */ +static int maxnalarms; /* #alarms w/no client probe before quit */ +static int nprobes; /* #alarms since last client probe */ +static void sig_urg(int), sig_alrm(int); + +void +heartbeat_serv(int servfd_arg, int nsec_arg, int maxnalarms_arg) +{ + servfd = servfd_arg; /* set globals for signal handlers */ + if ( (nsec = nsec_arg) < 1) + nsec = 1; + if ( (maxnalarms = maxnalarms_arg) < nsec) + maxnalarms = nsec; + + Signal(SIGURG, sig_urg); + Fcntl(servfd, F_SETOWN, getpid()); + + Signal(SIGALRM, sig_alrm); + alarm(nsec); +} + +static void +sig_urg(int signo) +{ + int n; + char c; + + if ( (n = recv(servfd, &c, 1, MSG_OOB)) < 0) { + if (errno != EWOULDBLOCK) + err_sys("recv error"); + } + Send(servfd, &c, 1, MSG_OOB); /* echo back out-of-band byte */ + + nprobes = 0; /* reset counter */ + return; /* may interrupt server code */ +} + +static void +sig_alrm(int signo) +{ + if (++nprobes > maxnalarms) { + printf("no probes from client\n"); + exit(0); + } + alarm(nsec); + return; /* may interrupt server code */ +} diff --git a/oob/sigchldwaitpid.c b/oob/sigchldwaitpid.c new file mode 100644 index 0000000..5fa9cbf --- /dev/null +++ b/oob/sigchldwaitpid.c @@ -0,0 +1,13 @@ +#include "unp.h" + +void +sig_chld(int signo) +{ + pid_t pid; + int stat; + + while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) { + printf("child %d terminated\n", pid); + } + return; +} diff --git a/oob/strcliselect02.c b/oob/strcliselect02.c new file mode 100644 index 0000000..1b8d9c3 --- /dev/null +++ b/oob/strcliselect02.c @@ -0,0 +1,48 @@ +#include "unp.h" + +void +str_cli(FILE *fp, int sockfd) +{ + int maxfdp1, stdineof = 0; + fd_set rset; + char sendline[MAXLINE], recvline[MAXLINE]; + + heartbeat_cli(sockfd, 1, 5); + + FD_ZERO(&rset); + for ( ; ; ) { + if (stdineof == 0) + FD_SET(fileno(fp), &rset); + FD_SET(sockfd, &rset); + maxfdp1 = max(fileno(fp), sockfd) + 1; + if (select(maxfdp1, &rset, NULL, NULL, NULL) < 0) { + if (errno == EINTR) + continue; + else + err_sys("select error"); + } + + if (FD_ISSET(sockfd, &rset)) { /* socket is readable */ + if (Readline(sockfd, recvline, MAXLINE) == 0) { + if (stdineof == 1) + return; /* normal termination */ + else + err_quit("str_cli: server terminated prematurely"); + } + + Writen(STDOUT_FILENO, recvline, strlen(recvline)); + } + + if (FD_ISSET(fileno(fp), &rset)) { /* input is readable */ + if (Fgets(sendline, MAXLINE, fp) == NULL) { + stdineof = 1; + alarm(0); /* turn off heartbeat */ + Shutdown(sockfd, SHUT_WR); /* send FIN */ + FD_CLR(fileno(fp), &rset); + continue; + } + + Writen(sockfd, sendline, strlen(sendline)); + } + } +} diff --git a/oob/strecho02.c b/oob/strecho02.c new file mode 100644 index 0000000..d3c2b6d --- /dev/null +++ b/oob/strecho02.c @@ -0,0 +1,17 @@ +#include "unp.h" + +void +str_echo(int sockfd) +{ + ssize_t n; + char line[MAXLINE]; + + heartbeat_serv(sockfd, 1, 5); + + for ( ; ; ) { + if ( (n = Readline(sockfd, line, MAXLINE)) == 0) + return; /* connection closed by other end */ + + Writen(sockfd, line, n); + } +} diff --git a/oob/tcpcli02.c b/oob/tcpcli02.c new file mode 100644 index 0000000..af1f1bf --- /dev/null +++ b/oob/tcpcli02.c @@ -0,0 +1,24 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/oob/tcprecv01.c b/oob/tcprecv01.c new file mode 100644 index 0000000..f41a0db --- /dev/null +++ b/oob/tcprecv01.c @@ -0,0 +1,45 @@ +#include "unp.h" + +int listenfd, connfd; + +void sig_urg(int); + +int +main(int argc, char **argv) +{ + int n; + char buff[100]; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], NULL); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], NULL); + else + err_quit("usage: tcprecv01 [ ] "); + + connfd = Accept(listenfd, NULL, NULL); + + Signal(SIGURG, sig_urg); + Fcntl(connfd, F_SETOWN, getpid()); + + for ( ; ; ) { + if ( (n = Read(connfd, buff, sizeof(buff)-1)) == 0) { + printf("received EOF\n"); + exit(0); + } + buff[n] = 0; /* null terminate */ + printf("read %d bytes: %s\n", n, buff); + } +} + +void +sig_urg(int signo) +{ + int n; + char buff[100]; + + printf("SIGURG received\n"); + n = Recv(connfd, buff, sizeof(buff)-1, MSG_OOB); + buff[n] = 0; /* null terminate */ + printf("read %d OOB byte: %s\n", n, buff); +} diff --git a/oob/tcprecv01.lc b/oob/tcprecv01.lc new file mode 100644 index 0000000..ded74d4 --- /dev/null +++ b/oob/tcprecv01.lc @@ -0,0 +1,45 @@ +#include "unp.h"## 1 ##src/oob/tcprecv01.c## + +int listenfd, connfd;## 2 ##src/oob/tcprecv01.c## + +void sig_urg(int);## 3 ##src/oob/tcprecv01.c## + +int## 4 ##src/oob/tcprecv01.c## +main(int argc, char **argv)## 5 ##src/oob/tcprecv01.c## +{## 6 ##src/oob/tcprecv01.c## + int n;## 7 ##src/oob/tcprecv01.c## + char buff[100];## 8 ##src/oob/tcprecv01.c## + + if (argc == 2)## 9 ##src/oob/tcprecv01.c## + listenfd = Tcp_listen(NULL, argv[1], NULL);## 10 ##src/oob/tcprecv01.c## + else if (argc == 3)## 11 ##src/oob/tcprecv01.c## + listenfd = Tcp_listen(argv[1], argv[2], NULL);## 12 ##src/oob/tcprecv01.c## + else## 13 ##src/oob/tcprecv01.c## + err_quit("usage: tcprecv01 [ ] ");## 14 ##src/oob/tcprecv01.c## + + connfd = Accept(listenfd, NULL, NULL);## 15 ##src/oob/tcprecv01.c## + + Signal(SIGURG, sig_urg);## 16 ##src/oob/tcprecv01.c## + Fcntl(connfd, F_SETOWN, getpid());## 17 ##src/oob/tcprecv01.c## + + for (;;) {## 18 ##src/oob/tcprecv01.c## + if ((n = Read(connfd, buff, sizeof(buff) - 1)) == 0) {## 19 ##src/oob/tcprecv01.c## + printf("received EOF\n");## 20 ##src/oob/tcprecv01.c## + exit(0);## 21 ##src/oob/tcprecv01.c## + }## 22 ##src/oob/tcprecv01.c## + buff[n] = 0; /* null terminate */## 23 ##src/oob/tcprecv01.c## + printf("read %d bytes: %s\n", n, buff);## 24 ##src/oob/tcprecv01.c## + }## 25 ##src/oob/tcprecv01.c## +}## 26 ##src/oob/tcprecv01.c## + +void## 27 ##src/oob/tcprecv01.c## +sig_urg(int signo)## 28 ##src/oob/tcprecv01.c## +{## 29 ##src/oob/tcprecv01.c## + int n;## 30 ##src/oob/tcprecv01.c## + char buff[100];## 31 ##src/oob/tcprecv01.c## + + printf("SIGURG received\n");## 32 ##src/oob/tcprecv01.c## + n = Recv(connfd, buff, sizeof(buff) - 1, MSG_OOB);## 33 ##src/oob/tcprecv01.c## + buff[n] = 0; /* null terminate */## 34 ##src/oob/tcprecv01.c## + printf("read %d OOB byte: %s\n", n, buff);## 35 ##src/oob/tcprecv01.c## +}## 36 ##src/oob/tcprecv01.c## diff --git a/oob/tcprecv02.c b/oob/tcprecv02.c new file mode 100644 index 0000000..7b18d93 --- /dev/null +++ b/oob/tcprecv02.c @@ -0,0 +1,42 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd, n; + char buff[100]; + fd_set rset, xset; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], NULL); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], NULL); + else + err_quit("usage: tcprecv02 [ ] "); + + connfd = Accept(listenfd, NULL, NULL); + + FD_ZERO(&rset); + FD_ZERO(&xset); + for ( ; ; ) { + FD_SET(connfd, &rset); + FD_SET(connfd, &xset); + + Select(connfd + 1, &rset, NULL, &xset, NULL); + + if (FD_ISSET(connfd, &xset)) { + n = Recv(connfd, buff, sizeof(buff)-1, MSG_OOB); + buff[n] = 0; /* null terminate */ + printf("read %d OOB byte: %s\n", n, buff); + } + + if (FD_ISSET(connfd, &rset)) { + if ( (n = Read(connfd, buff, sizeof(buff)-1)) == 0) { + printf("received EOF\n"); + exit(0); + } + buff[n] = 0; /* null terminate */ + printf("read %d bytes: %s\n", n, buff); + } + } +} diff --git a/oob/tcprecv02.lc b/oob/tcprecv02.lc new file mode 100644 index 0000000..c573406 --- /dev/null +++ b/oob/tcprecv02.lc @@ -0,0 +1,42 @@ +#include "unp.h"## 1 ##src/oob/tcprecv02.c## + +int## 2 ##src/oob/tcprecv02.c## +main(int argc, char **argv)## 3 ##src/oob/tcprecv02.c## +{## 4 ##src/oob/tcprecv02.c## + int listenfd, connfd, n;## 5 ##src/oob/tcprecv02.c## + char buff[100];## 6 ##src/oob/tcprecv02.c## + fd_set rset, xset;## 7 ##src/oob/tcprecv02.c## + + if (argc == 2)## 8 ##src/oob/tcprecv02.c## + listenfd = Tcp_listen(NULL, argv[1], NULL);## 9 ##src/oob/tcprecv02.c## + else if (argc == 3)## 10 ##src/oob/tcprecv02.c## + listenfd = Tcp_listen(argv[1], argv[2], NULL);## 11 ##src/oob/tcprecv02.c## + else## 12 ##src/oob/tcprecv02.c## + err_quit("usage: tcprecv02 [ ] ");## 13 ##src/oob/tcprecv02.c## + + connfd = Accept(listenfd, NULL, NULL);## 14 ##src/oob/tcprecv02.c## + + FD_ZERO(&rset);## 15 ##src/oob/tcprecv02.c## + FD_ZERO(&xset);## 16 ##src/oob/tcprecv02.c## + for (;;) {## 17 ##src/oob/tcprecv02.c## + FD_SET(connfd, &rset);## 18 ##src/oob/tcprecv02.c## + FD_SET(connfd, &xset);## 19 ##src/oob/tcprecv02.c## + + Select(connfd + 1, &rset, NULL, &xset, NULL);## 20 ##src/oob/tcprecv02.c## + + if (FD_ISSET(connfd, &xset)) {## 21 ##src/oob/tcprecv02.c## + n = Recv(connfd, buff, sizeof(buff) - 1, MSG_OOB);## 22 ##src/oob/tcprecv02.c## + buff[n] = 0; /* null terminate */## 23 ##src/oob/tcprecv02.c## + printf("read %d OOB byte: %s\n", n, buff);## 24 ##src/oob/tcprecv02.c## + }## 25 ##src/oob/tcprecv02.c## + + if (FD_ISSET(connfd, &rset)) {## 26 ##src/oob/tcprecv02.c## + if ((n = Read(connfd, buff, sizeof(buff) - 1)) == 0) {## 27 ##src/oob/tcprecv02.c## + printf("received EOF\n");## 28 ##src/oob/tcprecv02.c## + exit(0);## 29 ##src/oob/tcprecv02.c## + }## 30 ##src/oob/tcprecv02.c## + buff[n] = 0; /* null terminate */## 31 ##src/oob/tcprecv02.c## + printf("read %d bytes: %s\n", n, buff);## 32 ##src/oob/tcprecv02.c## + }## 33 ##src/oob/tcprecv02.c## + }## 34 ##src/oob/tcprecv02.c## +}## 35 ##src/oob/tcprecv02.c## diff --git a/oob/tcprecv03.c b/oob/tcprecv03.c new file mode 100644 index 0000000..4a686d4 --- /dev/null +++ b/oob/tcprecv03.c @@ -0,0 +1,46 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd, n, justreadoob = 0; + char buff[100]; + fd_set rset, xset; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], NULL); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], NULL); + else + err_quit("usage: tcprecv03 [ ] "); + + connfd = Accept(listenfd, NULL, NULL); + + FD_ZERO(&rset); + FD_ZERO(&xset); + for ( ; ; ) { + FD_SET(connfd, &rset); + if (justreadoob == 0) + FD_SET(connfd, &xset); + + Select(connfd + 1, &rset, NULL, &xset, NULL); + + if (FD_ISSET(connfd, &xset)) { + n = Recv(connfd, buff, sizeof(buff)-1, MSG_OOB); + buff[n] = 0; /* null terminate */ + printf("read %d OOB byte: %s\n", n, buff); + justreadoob = 1; + FD_CLR(connfd, &xset); + } + + if (FD_ISSET(connfd, &rset)) { + if ( (n = Read(connfd, buff, sizeof(buff)-1)) == 0) { + printf("received EOF\n"); + exit(0); + } + buff[n] = 0; /* null terminate */ + printf("read %d bytes: %s\n", n, buff); + justreadoob = 0; + } + } +} diff --git a/oob/tcprecv03p.c b/oob/tcprecv03p.c new file mode 100644 index 0000000..a059947 --- /dev/null +++ b/oob/tcprecv03p.c @@ -0,0 +1,45 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd, n, justreadoob = 0; + char buff[100]; + struct pollfd pollfd[1]; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], NULL); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], NULL); + else + err_quit("usage: tcprecv03p [ ] "); + + connfd = Accept(listenfd, NULL, NULL); + + pollfd[0].fd = connfd; + pollfd[0].events = POLLRDNORM; + for ( ; ; ) { + if (justreadoob == 0) + pollfd[0].events |= POLLRDBAND; + + Poll(pollfd, 1, INFTIM); + + if (pollfd[0].revents & POLLRDBAND) { + n = Recv(connfd, buff, sizeof(buff)-1, MSG_OOB); + buff[n] = 0; /* null terminate */ + printf("read %d OOB byte: %s\n", n, buff); + justreadoob = 1; + pollfd[0].events &= ~POLLRDBAND; /* turn bit off */ + } + + if (pollfd[0].revents & POLLRDNORM) { + if ( (n = Read(connfd, buff, sizeof(buff)-1)) == 0) { + printf("received EOF\n"); + exit(0); + } + buff[n] = 0; /* null terminate */ + printf("read %d bytes: %s\n", n, buff); + justreadoob = 0; + } + } +} diff --git a/oob/tcprecv03p.lc b/oob/tcprecv03p.lc new file mode 100644 index 0000000..698b47c --- /dev/null +++ b/oob/tcprecv03p.lc @@ -0,0 +1,45 @@ +#include "unp.h"## 1 ##src/oob/tcprecv03p.c## + +int## 2 ##src/oob/tcprecv03p.c## +main(int argc, char **argv)## 3 ##src/oob/tcprecv03p.c## +{## 4 ##src/oob/tcprecv03p.c## + int listenfd, connfd, n, justreadoob = 0;## 5 ##src/oob/tcprecv03p.c## + char buff[100];## 6 ##src/oob/tcprecv03p.c## + struct pollfd pollfd[1];## 7 ##src/oob/tcprecv03p.c## + + if (argc == 2)## 8 ##src/oob/tcprecv03p.c## + listenfd = Tcp_listen(NULL, argv[1], NULL);## 9 ##src/oob/tcprecv03p.c## + else if (argc == 3)## 10 ##src/oob/tcprecv03p.c## + listenfd = Tcp_listen(argv[1], argv[2], NULL);## 11 ##src/oob/tcprecv03p.c## + else## 12 ##src/oob/tcprecv03p.c## + err_quit("usage: tcprecv03p [ ] ");## 13 ##src/oob/tcprecv03p.c## + + connfd = Accept(listenfd, NULL, NULL);## 14 ##src/oob/tcprecv03p.c## + + pollfd[0].fd = connfd;## 15 ##src/oob/tcprecv03p.c## + pollfd[0].events = POLLRDNORM;## 16 ##src/oob/tcprecv03p.c## + for (;;) {## 17 ##src/oob/tcprecv03p.c## + if (justreadoob == 0)## 18 ##src/oob/tcprecv03p.c## + pollfd[0].events |= POLLRDBAND;## 19 ##src/oob/tcprecv03p.c## + + Poll(pollfd, 1, INFTIM);## 20 ##src/oob/tcprecv03p.c## + + if (pollfd[0].revents & POLLRDBAND) {## 21 ##src/oob/tcprecv03p.c## + n = Recv(connfd, buff, sizeof(buff) - 1, MSG_OOB);## 22 ##src/oob/tcprecv03p.c## + buff[n] = 0; /* null terminate */## 23 ##src/oob/tcprecv03p.c## + printf("read %d OOB byte: %s\n", n, buff);## 24 ##src/oob/tcprecv03p.c## + justreadoob = 1;## 25 ##src/oob/tcprecv03p.c## + pollfd[0].events &= ~POLLRDBAND; /* turn bit off */## 26 ##src/oob/tcprecv03p.c## + }## 27 ##src/oob/tcprecv03p.c## + + if (pollfd[0].revents & POLLRDNORM) {## 28 ##src/oob/tcprecv03p.c## + if ((n = Read(connfd, buff, sizeof(buff) - 1)) == 0) {## 29 ##src/oob/tcprecv03p.c## + printf("received EOF\n");## 30 ##src/oob/tcprecv03p.c## + exit(0);## 31 ##src/oob/tcprecv03p.c## + }## 32 ##src/oob/tcprecv03p.c## + buff[n] = 0; /* null terminate */## 33 ##src/oob/tcprecv03p.c## + printf("read %d bytes: %s\n", n, buff);## 34 ##src/oob/tcprecv03p.c## + justreadoob = 0;## 35 ##src/oob/tcprecv03p.c## + }## 36 ##src/oob/tcprecv03p.c## + }## 37 ##src/oob/tcprecv03p.c## +}## 38 ##src/oob/tcprecv03p.c## diff --git a/oob/tcprecv04.c b/oob/tcprecv04.c new file mode 100644 index 0000000..ac823bf --- /dev/null +++ b/oob/tcprecv04.c @@ -0,0 +1,32 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd, n, on=1; + char buff[100]; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], NULL); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], NULL); + else + err_quit("usage: tcprecv04 [ ] "); + + Setsockopt(listenfd, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)); + + connfd = Accept(listenfd, NULL, NULL); + sleep(5); + + for ( ; ; ) { + if (Sockatmark(connfd)) + printf("at OOB mark\n"); + + if ( (n = Read(connfd, buff, sizeof(buff)-1)) == 0) { + printf("received EOF\n"); + exit(0); + } + buff[n] = 0; /* null terminate */ + printf("read %d bytes: %s\n", n, buff); + } +} diff --git a/oob/tcprecv04.lc b/oob/tcprecv04.lc new file mode 100644 index 0000000..8a879c4 --- /dev/null +++ b/oob/tcprecv04.lc @@ -0,0 +1,32 @@ +#include "unp.h"## 1 ##src/oob/tcprecv04.c## + +int## 2 ##src/oob/tcprecv04.c## +main(int argc, char **argv)## 3 ##src/oob/tcprecv04.c## +{## 4 ##src/oob/tcprecv04.c## + int listenfd, connfd, n, on = 1;## 5 ##src/oob/tcprecv04.c## + char buff[100];## 6 ##src/oob/tcprecv04.c## + + if (argc == 2)## 7 ##src/oob/tcprecv04.c## + listenfd = Tcp_listen(NULL, argv[1], NULL);## 8 ##src/oob/tcprecv04.c## + else if (argc == 3)## 9 ##src/oob/tcprecv04.c## + listenfd = Tcp_listen(argv[1], argv[2], NULL);## 10 ##src/oob/tcprecv04.c## + else## 11 ##src/oob/tcprecv04.c## + err_quit("usage: tcprecv04 [ ] ");## 12 ##src/oob/tcprecv04.c## + + Setsockopt(listenfd, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on));## 13 ##src/oob/tcprecv04.c## + + connfd = Accept(listenfd, NULL, NULL);## 14 ##src/oob/tcprecv04.c## + sleep(5);## 15 ##src/oob/tcprecv04.c## + + for (;;) {## 16 ##src/oob/tcprecv04.c## + if (Sockatmark(connfd))## 17 ##src/oob/tcprecv04.c## + printf("at OOB mark\n");## 18 ##src/oob/tcprecv04.c## + + if ((n = Read(connfd, buff, sizeof(buff) - 1)) == 0) {## 19 ##src/oob/tcprecv04.c## + printf("received EOF\n");## 20 ##src/oob/tcprecv04.c## + exit(0);## 21 ##src/oob/tcprecv04.c## + }## 22 ##src/oob/tcprecv04.c## + buff[n] = 0; /* null terminate */## 23 ##src/oob/tcprecv04.c## + printf("read %d bytes: %s\n", n, buff);## 24 ##src/oob/tcprecv04.c## + }## 25 ##src/oob/tcprecv04.c## +}## 26 ##src/oob/tcprecv04.c## diff --git a/oob/tcprecv05.c b/oob/tcprecv05.c new file mode 100644 index 0000000..9dc185f --- /dev/null +++ b/oob/tcprecv05.c @@ -0,0 +1,41 @@ +#include "unp.h" + +int listenfd, connfd; + +void sig_urg(int); + +int +main(int argc, char **argv) +{ + int size; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], NULL); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], NULL); + else + err_quit("usage: tcprecv05 [ ] "); + + size = 4096; + Setsockopt(listenfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); + + connfd = Accept(listenfd, NULL, NULL); + + Signal(SIGURG, sig_urg); + Fcntl(connfd, F_SETOWN, getpid()); + + for ( ; ; ) + pause(); +} + +void +sig_urg(int signo) +{ + int n; + char buff[2048]; + + printf("SIGURG received\n"); + n = Recv(connfd, buff, sizeof(buff)-1, MSG_OOB); + buff[n] = 0; /* null terminate */ + printf("read %d OOB byte\n", n); +} diff --git a/oob/tcprecv06.c b/oob/tcprecv06.c new file mode 100644 index 0000000..756223f --- /dev/null +++ b/oob/tcprecv06.c @@ -0,0 +1,32 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd, n, on=1; + char buff[100]; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], NULL); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], NULL); + else + err_quit("usage: tcprecv06 [ ] "); + + Setsockopt(listenfd, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)); + + connfd = Accept(listenfd, NULL, NULL); + sleep(5); + + for ( ; ; ) { + if (Sockatmark(connfd)) + printf("at OOB mark\n"); + + if ( (n = Read(connfd, buff, sizeof(buff)-1)) == 0) { + printf("received EOF\n"); + exit(0); + } + buff[n] = 0; /* null terminate */ + printf("read %d bytes: %s\n", n, buff); + } +} diff --git a/oob/tcpsend01.c b/oob/tcpsend01.c new file mode 100644 index 0000000..093c834 --- /dev/null +++ b/oob/tcpsend01.c @@ -0,0 +1,34 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + + if (argc != 3) + err_quit("usage: tcpsend01 "); + + sockfd = Tcp_connect(argv[1], argv[2]); + + Write(sockfd, "123", 3); + printf("wrote 3 bytes of normal data\n"); + sleep(1); + + Send(sockfd, "4", 1, MSG_OOB); + printf("wrote 1 byte of OOB data\n"); + sleep(1); + + Write(sockfd, "56", 2); + printf("wrote 2 bytes of normal data\n"); + sleep(1); + + Send(sockfd, "7", 1, MSG_OOB); + printf("wrote 1 byte of OOB data\n"); + sleep(1); + + Write(sockfd, "89", 2); + printf("wrote 2 bytes of normal data\n"); + sleep(1); + + exit(0); +} diff --git a/oob/tcpsend01.lc b/oob/tcpsend01.lc new file mode 100644 index 0000000..7098715 --- /dev/null +++ b/oob/tcpsend01.lc @@ -0,0 +1,34 @@ +#include "unp.h"## 1 ##src/oob/tcpsend01.c## + +int## 2 ##src/oob/tcpsend01.c## +main(int argc, char **argv)## 3 ##src/oob/tcpsend01.c## +{## 4 ##src/oob/tcpsend01.c## + int sockfd;## 5 ##src/oob/tcpsend01.c## + + if (argc != 3)## 6 ##src/oob/tcpsend01.c## + err_quit("usage: tcpsend01 ");## 7 ##src/oob/tcpsend01.c## + + sockfd = Tcp_connect(argv[1], argv[2]);## 8 ##src/oob/tcpsend01.c## + + Write(sockfd, "123", 3);## 9 ##src/oob/tcpsend01.c## + printf("wrote 3 bytes of normal data\n");## 10 ##src/oob/tcpsend01.c## + sleep(1);## 11 ##src/oob/tcpsend01.c## + + Send(sockfd, "4", 1, MSG_OOB);## 12 ##src/oob/tcpsend01.c## + printf("wrote 1 byte of OOB data\n");## 13 ##src/oob/tcpsend01.c## + sleep(1);## 14 ##src/oob/tcpsend01.c## + + Write(sockfd, "56", 2);## 15 ##src/oob/tcpsend01.c## + printf("wrote 2 bytes of normal data\n");## 16 ##src/oob/tcpsend01.c## + sleep(1);## 17 ##src/oob/tcpsend01.c## + + Send(sockfd, "7", 1, MSG_OOB);## 18 ##src/oob/tcpsend01.c## + printf("wrote 1 byte of OOB data\n");## 19 ##src/oob/tcpsend01.c## + sleep(1);## 20 ##src/oob/tcpsend01.c## + + Write(sockfd, "89", 2);## 21 ##src/oob/tcpsend01.c## + printf("wrote 2 bytes of normal data\n");## 22 ##src/oob/tcpsend01.c## + sleep(1);## 23 ##src/oob/tcpsend01.c## + + exit(0);## 24 ##src/oob/tcpsend01.c## +}## 25 ##src/oob/tcpsend01.c## diff --git a/oob/tcpsend02.c b/oob/tcpsend02.c new file mode 100644 index 0000000..d7857fb --- /dev/null +++ b/oob/tcpsend02.c @@ -0,0 +1,34 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + + if (argc != 3) + err_quit("usage: tcpsend02 "); + + sockfd = Tcp_connect(argv[1], argv[2]); + + Write(sockfd, "123", 3); + printf("wrote 3 bytes of normal data\n"); + sleep(1); + + Send(sockfd, "4", 1, MSG_OOB); + printf("wrote 1 byte of OOB data\n"); + sleep(1); + + Write(sockfd, "56", 2); + printf("wrote 2 bytes of normal data\n"); + sleep(1); + + Send(sockfd, "7", 1, MSG_OOB); + printf("wrote 1 byte of OOB data\n"); + sleep(1); + + Write(sockfd, "89", 2); + printf("wrote 2 bytes of normal data\n"); + sleep(1); + + exit(0); +} diff --git a/oob/tcpsend03.c b/oob/tcpsend03.c new file mode 100644 index 0000000..8b397f4 --- /dev/null +++ b/oob/tcpsend03.c @@ -0,0 +1,34 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + + if (argc != 3) + err_quit("usage: tcpsend03 "); + + sockfd = Tcp_connect(argv[1], argv[2]); + + Write(sockfd, "123", 3); + printf("wrote 3 bytes of normal data\n"); + sleep(1); + + Send(sockfd, "4", 1, MSG_OOB); + printf("wrote 1 byte of OOB data\n"); + sleep(1); + + Write(sockfd, "56", 2); + printf("wrote 2 bytes of normal data\n"); + sleep(1); + + Send(sockfd, "7", 1, MSG_OOB); + printf("wrote 1 byte of OOB data\n"); + sleep(1); + + Write(sockfd, "89", 2); + printf("wrote 2 bytes of normal data\n"); + sleep(1); + + exit(0); +} diff --git a/oob/tcpsend04.c b/oob/tcpsend04.c new file mode 100644 index 0000000..962b880 --- /dev/null +++ b/oob/tcpsend04.c @@ -0,0 +1,23 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + + if (argc != 3) + err_quit("usage: tcpsend04 "); + + sockfd = Tcp_connect(argv[1], argv[2]); + + Write(sockfd, "123", 3); + printf("wrote 3 bytes of normal data\n"); + + Send(sockfd, "4", 1, MSG_OOB); + printf("wrote 1 byte of OOB data\n"); + + Write(sockfd, "5", 1); + printf("wrote 1 byte of normal data\n"); + + exit(0); +} diff --git a/oob/tcpsend04.lc b/oob/tcpsend04.lc new file mode 100644 index 0000000..e3185c8 --- /dev/null +++ b/oob/tcpsend04.lc @@ -0,0 +1,23 @@ +#include "unp.h"## 1 ##src/oob/tcpsend04.c## + +int## 2 ##src/oob/tcpsend04.c## +main(int argc, char **argv)## 3 ##src/oob/tcpsend04.c## +{## 4 ##src/oob/tcpsend04.c## + int sockfd;## 5 ##src/oob/tcpsend04.c## + + if (argc != 3)## 6 ##src/oob/tcpsend04.c## + err_quit("usage: tcpsend04 ");## 7 ##src/oob/tcpsend04.c## + + sockfd = Tcp_connect(argv[1], argv[2]);## 8 ##src/oob/tcpsend04.c## + + Write(sockfd, "123", 3);## 9 ##src/oob/tcpsend04.c## + printf("wrote 3 bytes of normal data\n");## 10 ##src/oob/tcpsend04.c## + + Send(sockfd, "4", 1, MSG_OOB);## 11 ##src/oob/tcpsend04.c## + printf("wrote 1 byte of OOB data\n");## 12 ##src/oob/tcpsend04.c## + + Write(sockfd, "5", 1);## 13 ##src/oob/tcpsend04.c## + printf("wrote 1 byte of normal data\n");## 14 ##src/oob/tcpsend04.c## + + exit(0);## 15 ##src/oob/tcpsend04.c## +}## 16 ##src/oob/tcpsend04.c## diff --git a/oob/tcpsend05.c b/oob/tcpsend05.c new file mode 100644 index 0000000..225d886 --- /dev/null +++ b/oob/tcpsend05.c @@ -0,0 +1,28 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, size; + char buff[16384]; + + if (argc != 3) + err_quit("usage: tcpsend05 "); + + sockfd = Tcp_connect(argv[1], argv[2]); + + size = 32768; + Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); + + Write(sockfd, buff, 16384); + printf("wrote 16384 bytes of normal data\n"); + sleep(5); + + Send(sockfd, "a", 1, MSG_OOB); + printf("wrote 1 byte of OOB data\n"); + + Write(sockfd, buff, 1024); + printf("wrote 1024 bytes of normal data\n"); + + exit(0); +} diff --git a/oob/tcpsend05.lc b/oob/tcpsend05.lc new file mode 100644 index 0000000..deeed32 --- /dev/null +++ b/oob/tcpsend05.lc @@ -0,0 +1,28 @@ +#include "unp.h"## 1 ##src/oob/tcpsend05.c## + +int## 2 ##src/oob/tcpsend05.c## +main(int argc, char **argv)## 3 ##src/oob/tcpsend05.c## +{## 4 ##src/oob/tcpsend05.c## + int sockfd, size;## 5 ##src/oob/tcpsend05.c## + char buff[16384];## 6 ##src/oob/tcpsend05.c## + + if (argc != 3)## 7 ##src/oob/tcpsend05.c## + err_quit("usage: tcpsend05 ");## 8 ##src/oob/tcpsend05.c## + + sockfd = Tcp_connect(argv[1], argv[2]);## 9 ##src/oob/tcpsend05.c## + + size = 32768;## 10 ##src/oob/tcpsend05.c## + Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));## 11 ##src/oob/tcpsend05.c## + + Write(sockfd, buff, 16384);## 12 ##src/oob/tcpsend05.c## + printf("wrote 16384 bytes of normal data\n");## 13 ##src/oob/tcpsend05.c## + sleep(5);## 14 ##src/oob/tcpsend05.c## + + Send(sockfd, "a", 1, MSG_OOB);## 15 ##src/oob/tcpsend05.c## + printf("wrote 1 byte of OOB data\n");## 16 ##src/oob/tcpsend05.c## + + Write(sockfd, buff, 1024);## 17 ##src/oob/tcpsend05.c## + printf("wrote 1024 bytes of normal data\n");## 18 ##src/oob/tcpsend05.c## + + exit(0);## 19 ##src/oob/tcpsend05.c## +}## 20 ##src/oob/tcpsend05.c## diff --git a/oob/tcpsend06.c b/oob/tcpsend06.c new file mode 100644 index 0000000..aa04ae4 --- /dev/null +++ b/oob/tcpsend06.c @@ -0,0 +1,29 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + + if (argc != 3) + err_quit("usage: tcpsend06 "); + + sockfd = Tcp_connect(argv[1], argv[2]); + + Write(sockfd, "123", 3); + printf("wrote 3 bytes of normal data\n"); + + Send(sockfd, "4", 1, MSG_OOB); + printf("wrote 1 byte of OOB data\n"); + + Write(sockfd, "5", 1); + printf("wrote 1 byte of normal data\n"); + + Send(sockfd, "6", 1, MSG_OOB); + printf("wrote 1 byte of OOB data\n"); + + Write(sockfd, "7", 1); + printf("wrote 1 byte of normal data\n"); + + exit(0); +} diff --git a/oob/tcpsend06.lc b/oob/tcpsend06.lc new file mode 100644 index 0000000..ee9caa7 --- /dev/null +++ b/oob/tcpsend06.lc @@ -0,0 +1,29 @@ +#include "unp.h"## 1 ##src/oob/tcpsend06.c## + +int## 2 ##src/oob/tcpsend06.c## +main(int argc, char **argv)## 3 ##src/oob/tcpsend06.c## +{## 4 ##src/oob/tcpsend06.c## + int sockfd;## 5 ##src/oob/tcpsend06.c## + + if (argc != 3)## 6 ##src/oob/tcpsend06.c## + err_quit("usage: tcpsend06 ");## 7 ##src/oob/tcpsend06.c## + + sockfd = Tcp_connect(argv[1], argv[2]);## 8 ##src/oob/tcpsend06.c## + + Write(sockfd, "123", 3);## 9 ##src/oob/tcpsend06.c## + printf("wrote 3 bytes of normal data\n");## 10 ##src/oob/tcpsend06.c## + + Send(sockfd, "4", 1, MSG_OOB);## 11 ##src/oob/tcpsend06.c## + printf("wrote 1 byte of OOB data\n");## 12 ##src/oob/tcpsend06.c## + + Write(sockfd, "5", 1);## 13 ##src/oob/tcpsend06.c## + printf("wrote 1 byte of normal data\n");## 14 ##src/oob/tcpsend06.c## + + Send(sockfd, "6", 1, MSG_OOB);## 15 ##src/oob/tcpsend06.c## + printf("wrote 1 byte of OOB data\n");## 16 ##src/oob/tcpsend06.c## + + Write(sockfd, "7", 1);## 17 ##src/oob/tcpsend06.c## + printf("wrote 1 byte of normal data\n");## 18 ##src/oob/tcpsend06.c## + + exit(0);## 19 ##src/oob/tcpsend06.c## +}## 20 ##src/oob/tcpsend06.c## diff --git a/oob/tcpserv02.c b/oob/tcpserv02.c new file mode 100644 index 0000000..a964276 --- /dev/null +++ b/oob/tcpserv02.c @@ -0,0 +1,41 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + pid_t childpid; + socklen_t clilen; + struct sockaddr_in cliaddr, servaddr; + void sig_chld(int); + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + Signal(SIGCHLD, sig_chld); + + for ( ; ; ) { + clilen = sizeof(cliaddr); + if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) { + if (errno == EINTR) + continue; /* back to for() */ + else + err_sys("accept error"); + } + + if ( (childpid = Fork()) == 0) { /* child process */ + Close(listenfd); /* close listening socket */ + str_echo(connfd); /* process the request */ + exit(0); + } + Close(connfd); /* parent closes connected socket */ + } +} diff --git a/ping/Makefile b/ping/Makefile new file mode 100644 index 0000000..bf630c8 --- /dev/null +++ b/ping/Makefile @@ -0,0 +1,13 @@ +include ../Make.defines + +OBJS = init_v6.o main.o proc_v4.o proc_v6.o readloop.o \ + send_v4.o send_v6.o sig_alrm.o tv_sub.o +PROGS = ping + +all: ${PROGS} + +ping: ${OBJS} + ${CC} ${CFLAGS} -o $@ ${OBJS} ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/ping/bsdping.c b/ping/bsdping.c new file mode 100644 index 0000000..04d1848 --- /dev/null +++ b/ping/bsdping.c @@ -0,0 +1,1009 @@ +/* BSDI ping.c,v 2.3 1996/01/21 17:56:50 jch Exp */ + +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Muuss. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1989, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93"; +#endif /* not lint */ + +/* + * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, + * measure round-trip-delays and packet loss across network paths. + * + * Author - + * Mike Muuss + * U. S. Army Ballistic Research Laboratory + * December, 1983 + * + * Status - + * Public Domain. Distribution Unlimited. + * Bugs - + * More statistics could always be gathered. + * This program has to run SUID to ROOT to access the ICMP socket. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFDATALEN (64 - 8) /* default data length */ +#define MAXIPLEN 60 +#define MAXICMPLEN 76 +#define MAXPACKET (65536 - 60 - 8)/* max packet size */ +#define NROUTES 9 /* number of record route slots */ + +#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */ +#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */ +#define SET(bit) (A(bit) |= B(bit)) +#define CLR(bit) (A(bit) &= (~B(bit))) +#define TST(bit) (A(bit) & B(bit)) + +#define F_FLOOD 0x0001 +#define F_INTERVAL 0x0002 +#define F_NUMERIC 0x0004 +#define F_PINGFILLED 0x0008 +#define F_QUIET 0x0010 +#define F_RROUTE 0x0020 +#define F_SO_DEBUG 0x0040 +#define F_SO_DONTROUTE 0x0080 +#define F_VERBOSE 0x0100 +u_int options; + +/* + * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum + * number of received sequence numbers we can keep track of. Change 128 + * to 8192 for complete accuracy... + */ +#define MAX_DUP_CHK (8 * 8192) +int mx_dup_ck = MAX_DUP_CHK; +char rcvd_tbl[MAX_DUP_CHK / 8]; + +struct sockaddr whereto; /* who to ping */ +int datalen = DEFDATALEN; +int s; /* socket file descriptor */ +u_char outpack[MAXPACKET]; +char BSPACE = '\b'; /* characters written for flood */ +char DOT = '.'; +char *hostname; +int ident; /* process id to identify our packets */ + +/* counters */ +long npackets; /* max packets to transmit */ +long nreceived; /* # of packets we got back */ +long nrepeats; /* number of duplicates */ +long ntransmitted; /* sequence # for outbound packets = #sent */ +int interval = 1; /* interval between packets */ + +/* timing */ +int timing; /* flag to do timing */ +double tmin = 999999999.0; /* minimum round trip time */ +double tmax = 0.0; /* maximum round trip time */ +double tsum = 0.0; /* sum of all times, for doing average */ + +void fill __P((char *, char *)); +u_short in_cksum __P((u_short *, int)); +void onalrm __P((int)); +void oninfo __P((int)); +void onint __P((int)); +void pinger __P((void)); +char *pr_addr __P((u_long)); +void pr_icmph __P((struct icmp *)); +void pr_iph __P((struct ip *)); +void pr_pack __P((char *, int, struct sockaddr_in *)); +void pr_retip __P((struct ip *)); +void summary __P((void)); +void tvsub __P((struct timeval *, struct timeval *)); +void usage __P((void)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern int errno, optind; + extern char *optarg; + struct hostent *hp; + struct itimerval itimer; + struct protoent *proto; + struct sockaddr_in *to, from; + struct timeval timeout; + fd_set fdset; + register int cc, i; + int ch, fromlen, hold, packlen, preload; + u_char *datap, *packet; + char *e, *target, hnamebuf[MAXHOSTNAMELEN]; +#ifdef IP_OPTIONS + char rspace[3 + 4 * NROUTES + 1]; /* record route space */ +#endif + + preload = 0; + datap = &outpack[8 + sizeof(struct timeval)]; + while ((ch = getopt(argc, argv, "c:dfi:l:np:qRrs:v")) != -1) + switch(ch) { + case 'c': + npackets = strtol(optarg, &e, 10); + if (npackets <= 0 || *optarg == '\0' || *e != '\0') + errx(1, + "illegal number of packets -- %s", optarg); + break; + case 'd': + options |= F_SO_DEBUG; + break; + case 'f': + if (getuid()) { + errno = EPERM; + err(1, NULL); + } + options |= F_FLOOD; + setbuf(stdout, (char *)NULL); + break; + case 'i': /* wait between sending packets */ + interval = strtol(optarg, &e, 10); + if (interval <= 0 || *optarg == '\0' || *e != '\0') + errx(1, + "illegal timing interval -- %s", optarg); + options |= F_INTERVAL; + break; + case 'l': + preload = strtol(optarg, &e, 10); + if (preload < 0 || *optarg == '\0' || *e != '\0') + errx(1, "illegal preload value -- %s", optarg); + break; + case 'n': + options |= F_NUMERIC; + break; + case 'p': /* fill buffer with user pattern */ + options |= F_PINGFILLED; + fill((char *)datap, optarg); + break; + case 'q': + options |= F_QUIET; + break; + case 'R': + options |= F_RROUTE; + break; + case 'r': + options |= F_SO_DONTROUTE; + break; + case 's': /* size of packet to send */ + datalen = strtol(optarg, &e, 10); + if (datalen <= 0 || *optarg == '\0' || *e != '\0') + errx(1, "illegal datalen value -- %s", optarg); + if (datalen > MAXPACKET) + errx(1, + "datalen value too large, maximum is %d", + MAXPACKET); + break; + case 'v': + options |= F_VERBOSE; + break; + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 1) + usage(); + target = *argv; + + memset(&whereto, 0, sizeof(struct sockaddr)); + to = (struct sockaddr_in *)&whereto; + to->sin_family = AF_INET; + to->sin_addr.s_addr = inet_addr(target); + if (to->sin_addr.s_addr != (u_int)-1) + hostname = target; + else { + hp = gethostbyname(target); + if (!hp) + errx(1, "unknown host %s", target); + to->sin_family = hp->h_addrtype; + memmove(&to->sin_addr, hp->h_addr, hp->h_length); + (void)strncpy(hnamebuf, hp->h_name, sizeof(hnamebuf) - 1); + hostname = hnamebuf; + } + + if (options & F_FLOOD && options & F_INTERVAL) + errx(1, "-f and -i incompatible options"); + + if (datalen >= sizeof(struct timeval)) /* can we time transfer */ + timing = 1; + packlen = datalen + MAXIPLEN + MAXICMPLEN; + if (!(packet = (u_char *)malloc((u_int)packlen))) + err(1, NULL); + if (!(options & F_PINGFILLED)) + for (i = 8; i < datalen; ++i) + *datap++ = i; + + ident = getpid() & 0xFFFF; + + if (!(proto = getprotobyname("icmp"))) + errx(1, "unknown protocol icmp"); + if ((s = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0) + err(1, "socket"); + hold = 1; + if (options & F_SO_DEBUG) + (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold, + sizeof(hold)); + if (options & F_SO_DONTROUTE) + (void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&hold, + sizeof(hold)); + + /* record route option */ + if (options & F_RROUTE) { +#ifdef IP_OPTIONS + rspace[IPOPT_OPTVAL] = IPOPT_RR; + rspace[IPOPT_OLEN] = sizeof(rspace)-1; + rspace[IPOPT_OFFSET] = IPOPT_MINOFF; + if (setsockopt(s, IPPROTO_IP, IP_OPTIONS, rspace, + sizeof(rspace)) < 0) + err(1, "record route"); +#else + errx(1, "record route not available in this implementation"); +#endif + } + + /* + * When pinging the broadcast address, you can get a lot of answers. + * Doing something so evil is useful if you are trying to stress the + * ethernet, or just want to fill the arp cache to get some stuff for + * /etc/ethers. + */ + hold = 48 * 1024; + (void)setsockopt(s, + SOL_SOCKET, SO_RCVBUF, (char *)&hold, sizeof(hold)); + + if (to->sin_family == AF_INET) + (void)printf("PING %s (%s): %d data bytes\n", hostname, + inet_ntoa(*(struct in_addr *)&to->sin_addr.s_addr), + datalen); + else + (void)printf("PING %s: %d data bytes\n", hostname, datalen); + + while (preload--) /* Fire off them quickies. */ + pinger(); + + (void)signal(SIGINT, onint); + (void)signal(SIGINFO, oninfo); + + if ((options & F_FLOOD) == 0) { + (void)signal(SIGALRM, onalrm); + itimer.it_interval.tv_sec = interval; + itimer.it_interval.tv_usec = 0; + itimer.it_value.tv_sec = 0; + itimer.it_value.tv_usec = 1; + (void)setitimer(ITIMER_REAL, &itimer, NULL); + } + + FD_ZERO(&fdset); + timeout.tv_sec = 0; + timeout.tv_usec = 10000; + for (;;) { + if (options & F_FLOOD) { + pinger(); + FD_SET(s, &fdset); + if (select(s + 1, &fdset, NULL, NULL, &timeout) < 1) + continue; + } + fromlen = sizeof(from); + if ((cc = recvfrom(s, (char *)packet, packlen, 0, + (struct sockaddr *)&from, &fromlen)) < 0) { + if (errno == EINTR) + continue; + warn("recvfrom"); + continue; + } + pr_pack((char *)packet, cc, &from); + if (npackets && nreceived >= npackets) + break; + } + summary(); + exit(nreceived == 0); +} + +/* + * onalrm -- + * This routine transmits another ping. + */ +void +onalrm(signo) + int signo; +{ + struct itimerval itimer; + + if (!npackets || ntransmitted < npackets) { + pinger(); + return; + } + + /* + * If we're not transmitting any more packets, change the timer + * to wait two round-trip times if we've received any packets or + * ten seconds if we haven't. + */ +#define MAXWAIT 10 + if (nreceived) { + itimer.it_value.tv_sec = 2 * tmax / 1000; + if (itimer.it_value.tv_sec == 0) + itimer.it_value.tv_sec = 1; + } else + itimer.it_value.tv_sec = MAXWAIT; + itimer.it_interval.tv_sec = 0; + itimer.it_interval.tv_usec = 0; + itimer.it_value.tv_usec = 0; + + (void)signal(SIGALRM, onint); + (void)setitimer(ITIMER_REAL, &itimer, NULL); +} + +/* + * pinger -- + * Compose and transmit an ICMP ECHO REQUEST packet. The IP packet + * will be added on by the kernel. The ID field is our UNIX process ID, + * and the sequence number is an ascending integer. The first 8 bytes + * of the data portion are used to hold a UNIX "timeval" struct in VAX + * byte-order, to compute the round-trip time. + */ +void +pinger() +{ + register struct icmp *icp; + register int cc; + int i; + + icp = (struct icmp *)outpack; + icp->icmp_type = ICMP_ECHO; + icp->icmp_code = 0; + icp->icmp_cksum = 0; + icp->icmp_seq = ntransmitted++; + icp->icmp_id = ident; /* ID */ + + CLR(icp->icmp_seq % mx_dup_ck); + + if (timing) + (void)gettimeofday((struct timeval *)&outpack[8], NULL); + + cc = datalen + 8; /* skips ICMP portion */ + + /* compute ICMP checksum here */ + icp->icmp_cksum = in_cksum((u_short *)icp, cc); + + i = sendto(s, (char *)outpack, cc, 0, &whereto, + sizeof(struct sockaddr)); + + if (i < 0 || i != cc) { + if (i < 0) + warn("sendto"); + (void)printf("ping: wrote %s %d chars, ret=%d\n", + hostname, cc, i); + } + if (!(options & F_QUIET) && options & F_FLOOD) + (void)write(STDOUT_FILENO, &DOT, 1); +} + +/* + * pr_pack -- + * Print out the packet, if it came from us. This logic is necessary + * because ALL readers of the ICMP socket get a copy of ALL ICMP packets + * which arrive ('tis only fair). This permits multiple copies of this + * program to be run without having intermingled output (or statistics!). + */ +void +pr_pack(buf, cc, from) + char *buf; + int cc; + struct sockaddr_in *from; +{ + register struct icmp *icp; + register u_long l; + register int i, j; + register u_char *cp,*dp; + static int old_rrlen; + static char old_rr[MAX_IPOPTLEN]; + struct ip *ip; + struct timeval tv, *tp; + double triptime; + int hlen, dupflag; + + (void)gettimeofday(&tv, NULL); + + /* Check the IP header */ + ip = (struct ip *)buf; + hlen = ip->ip_hl << 2; + if (cc < hlen + ICMP_MINLEN) { + if (options & F_VERBOSE) + warnx("packet too short (%d bytes) from %s\n", cc, + inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr)); + return; + } + + /* Now the ICMP part */ + cc -= hlen; + icp = (struct icmp *)(buf + hlen); + if (icp->icmp_type == ICMP_ECHOREPLY) { + if (icp->icmp_id != ident) + return; /* 'Twas not our ECHO */ + ++nreceived; + if (timing) { +#ifndef icmp_data + tp = (struct timeval *)&icp->icmp_ip; +#else + tp = (struct timeval *)icp->icmp_data; +#endif + tvsub(&tv, tp); + triptime = ((double)tv.tv_sec) * 1000.0 + + ((double)tv.tv_usec) / 1000.0; + tsum += triptime; + if (triptime < tmin) + tmin = triptime; + if (triptime > tmax) + tmax = triptime; + } + + if (TST(icp->icmp_seq % mx_dup_ck)) { + ++nrepeats; + --nreceived; + dupflag = 1; + } else { + SET(icp->icmp_seq % mx_dup_ck); + dupflag = 0; + } + + if (options & F_QUIET) + return; + + if (options & F_FLOOD) + (void)write(STDOUT_FILENO, &BSPACE, 1); + else { + (void)printf("%d bytes from %s: icmp_seq=%u", cc, + inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr), + icp->icmp_seq); + (void)printf(" ttl=%d", ip->ip_ttl); + if (timing) + (void)printf(" time=%g ms", triptime); + if (dupflag) + (void)printf(" (DUP!)"); + /* check the data */ + cp = (u_char*)&icp->icmp_data[8]; + dp = &outpack[8 + sizeof(struct timeval)]; + for (i = 8; i < datalen; ++i, ++cp, ++dp) { + if (*cp != *dp) { + (void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x", + i, *dp, *cp); + cp = (u_char*)&icp->icmp_data[0]; + for (i = 8; i < datalen; ++i, ++cp) { + if ((i % 32) == 8) + (void)printf("\n\t"); + (void)printf("%x ", *cp); + } + break; + } + } + } + } else { + /* We've got something other than an ECHOREPLY */ + if (!(options & F_VERBOSE)) + return; + (void)printf("%d bytes from %s: ", cc, + pr_addr(from->sin_addr.s_addr)); + pr_icmph(icp); + } + + /* Display any IP options */ + cp = (u_char *)buf + sizeof(struct ip); + + for (; hlen > (int)sizeof(struct ip); --hlen, ++cp) + switch (*cp) { + case IPOPT_EOL: + hlen = 0; + break; + case IPOPT_LSRR: + (void)printf("\nLSRR: "); + hlen -= 2; + j = *++cp; + ++cp; + if (j > IPOPT_MINOFF) + for (;;) { + l = *++cp; + l = (l<<8) + *++cp; + l = (l<<8) + *++cp; + l = (l<<8) + *++cp; + if (l == 0) + (void)printf("\t0.0.0.0"); + else + (void)printf("\t%s", pr_addr(ntohl(l))); + hlen -= 4; + j -= 4; + if (j <= IPOPT_MINOFF) + break; + (void)putchar('\n'); + } + break; + case IPOPT_RR: + j = *++cp; /* get length */ + i = *++cp; /* and pointer */ + hlen -= 2; + if (i > j) + i = j; + i -= IPOPT_MINOFF; + if (i <= 0) + continue; + if (i == old_rrlen + && cp == (u_char *)buf + sizeof(struct ip) + 2 + && !memcmp((char *)cp, old_rr, i) + && !(options & F_FLOOD)) { + (void)printf("\t(same route)"); + i = ((i + 3) / 4) * 4; + hlen -= i; + cp += i; + break; + } + old_rrlen = i; + memmove(old_rr, cp, i); + (void)printf("\nRR: "); + for (;;) { + l = *++cp; + l = (l<<8) + *++cp; + l = (l<<8) + *++cp; + l = (l<<8) + *++cp; + if (l == 0) + (void)printf("\t0.0.0.0"); + else + (void)printf("\t%s", pr_addr(ntohl(l))); + hlen -= 4; + i -= 4; + if (i <= 0) + break; + (void)putchar('\n'); + } + break; + case IPOPT_NOP: + (void)printf("\nNOP"); + break; + default: + (void)printf("\nunknown option %x", *cp); + break; + } + if (!(options & F_FLOOD)) { + (void)putchar('\n'); + (void)fflush(stdout); + } +} + +/* + * in_cksum -- + * Checksum routine for Internet Protocol family headers (C Version) + */ +u_short +in_cksum(addr, len) + u_short *addr; + int len; +{ + register int nleft = len; + register u_short *w = addr; + register int sum = 0; + u_short answer = 0; + + /* + * Our algorithm is simple, using a 32 bit accumulator (sum), we add + * sequential 16 bit words to it, and at the end, fold back all the + * carry bits from the top 16 bits into the lower 16 bits. + */ + while (nleft > 1) { + sum += *w++; + nleft -= 2; + } + + /* mop up an odd byte, if necessary */ + if (nleft == 1) { + *(u_char *)(&answer) = *(u_char *)w ; + sum += answer; + } + + /* add back carry outs from top 16 bits to low 16 bits */ + sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ + sum += (sum >> 16); /* add carry */ + answer = ~sum; /* truncate to 16 bits */ + return (answer); +} + +/* + * tvsub -- + * Subtract 2 timeval structs: out = out - in. Out is assumed to + * be >= in. + */ +void +tvsub(out, in) + register struct timeval *out, *in; +{ + if ((out->tv_usec -= in->tv_usec) < 0) { + --out->tv_sec; + out->tv_usec += 1000000; + } + out->tv_sec -= in->tv_sec; +} + +/* + * oninfo -- + * SIGINFO handler. + */ +void +oninfo(notused) + int notused; +{ + summary(); +} + +/* + * onint -- + * SIGINT handler. + */ +void +onint(notused) + int notused; +{ + summary(); + + (void)signal(SIGINT, SIG_DFL); + (void)kill(getpid(), SIGINT); + + /* NOTREACHED */ + exit(1); +} + +/* + * summary -- + * Print out statistics. + */ +void +summary() +{ + register int i; + + (void)printf("\n--- %s ping statistics ---\n", hostname); + (void)printf("%ld packets transmitted, ", ntransmitted); + (void)printf("%ld packets received, ", nreceived); + if (nrepeats) + (void)printf("+%ld duplicates, ", nrepeats); + if (ntransmitted) + if (nreceived > ntransmitted) + (void)printf("-- somebody's printing up packets!"); + else + (void)printf("%d%% packet loss", + (int) (((ntransmitted - nreceived) * 100) / + ntransmitted)); + (void)putchar('\n'); + if (nreceived && timing) { + /* Only display average to microseconds */ + i = 1000.0 * tsum / (nreceived + nrepeats); + (void)printf("round-trip min/avg/max = %g/%g/%g ms\n", + tmin, ((double)i) / 1000.0, tmax); + } +} + +#ifdef notdef +static char *ttab[] = { + "Echo Reply", /* ip + seq + udata */ + "Dest Unreachable", /* net, host, proto, port, frag, sr + IP */ + "Source Quench", /* IP */ + "Redirect", /* redirect type, gateway, + IP */ + "Echo", + "Time Exceeded", /* transit, frag reassem + IP */ + "Parameter Problem", /* pointer + IP */ + "Timestamp", /* id + seq + three timestamps */ + "Timestamp Reply", /* " */ + "Info Request", /* id + sq */ + "Info Reply" /* " */ +}; +#endif + +/* + * pr_icmph -- + * Print a descriptive string about an ICMP header. + */ +void +pr_icmph(icp) + struct icmp *icp; +{ + switch(icp->icmp_type) { + case ICMP_ECHOREPLY: + (void)printf("Echo Reply\n"); + /* XXX ID + Seq + Data */ + break; + case ICMP_UNREACH: + switch(icp->icmp_code) { + case ICMP_UNREACH_NET: + (void)printf("Destination Net Unreachable\n"); + break; + case ICMP_UNREACH_HOST: + (void)printf("Destination Host Unreachable\n"); + break; + case ICMP_UNREACH_PROTOCOL: + (void)printf("Destination Protocol Unreachable\n"); + break; + case ICMP_UNREACH_PORT: + (void)printf("Destination Port Unreachable\n"); + break; + case ICMP_UNREACH_NEEDFRAG: + (void)printf("frag needed and DF set\n"); + break; + case ICMP_UNREACH_SRCFAIL: + (void)printf("Source Route Failed\n"); + break; + default: + (void)printf("Dest Unreachable, Bad Code: %d\n", + icp->icmp_code); + break; + } + /* Print returned IP header information */ +#ifndef icmp_data + pr_retip(&icp->icmp_ip); +#else + pr_retip((struct ip *)icp->icmp_data); +#endif + break; + case ICMP_SOURCEQUENCH: + (void)printf("Source Quench\n"); +#ifndef icmp_data + pr_retip(&icp->icmp_ip); +#else + pr_retip((struct ip *)icp->icmp_data); +#endif + break; + case ICMP_REDIRECT: + switch(icp->icmp_code) { + case ICMP_REDIRECT_NET: + (void)printf("Redirect Network"); + break; + case ICMP_REDIRECT_HOST: + (void)printf("Redirect Host"); + break; + case ICMP_REDIRECT_TOSNET: + (void)printf("Redirect Type of Service and Network"); + break; + case ICMP_REDIRECT_TOSHOST: + (void)printf("Redirect Type of Service and Host"); + break; + default: + (void)printf("Redirect, Bad Code: %d", icp->icmp_code); + break; + } + (void)printf("(New addr: 0x%08lx)\n", icp->icmp_gwaddr.s_addr); +#ifndef icmp_data + pr_retip(&icp->icmp_ip); +#else + pr_retip((struct ip *)icp->icmp_data); +#endif + break; + case ICMP_ECHO: + (void)printf("Echo Request\n"); + /* XXX ID + Seq + Data */ + break; + case ICMP_TIMXCEED: + switch(icp->icmp_code) { + case ICMP_TIMXCEED_INTRANS: + (void)printf("Time to live exceeded\n"); + break; + case ICMP_TIMXCEED_REASS: + (void)printf("Frag reassembly time exceeded\n"); + break; + default: + (void)printf("Time exceeded, Bad Code: %d\n", + icp->icmp_code); + break; + } +#ifndef icmp_data + pr_retip(&icp->icmp_ip); +#else + pr_retip((struct ip *)icp->icmp_data); +#endif + break; + case ICMP_PARAMPROB: + (void)printf("Parameter problem: pointer = 0x%02x\n", + icp->icmp_hun.ih_pptr); +#ifndef icmp_data + pr_retip(&icp->icmp_ip); +#else + pr_retip((struct ip *)icp->icmp_data); +#endif + break; + case ICMP_TSTAMP: + (void)printf("Timestamp\n"); + /* XXX ID + Seq + 3 timestamps */ + break; + case ICMP_TSTAMPREPLY: + (void)printf("Timestamp Reply\n"); + /* XXX ID + Seq + 3 timestamps */ + break; + case ICMP_IREQ: + (void)printf("Information Request\n"); + /* XXX ID + Seq */ + break; + case ICMP_IREQREPLY: + (void)printf("Information Reply\n"); + /* XXX ID + Seq */ + break; +#ifdef ICMP_MASKREQ + case ICMP_MASKREQ: + (void)printf("Address Mask Request\n"); + break; +#endif +#ifdef ICMP_MASKREPLY + case ICMP_MASKREPLY: + (void)printf("Address Mask Reply\n"); + break; +#endif + default: + (void)printf("Bad ICMP type: %d\n", icp->icmp_type); + } +} + +/* + * pr_iph -- + * Print an IP header with options. + */ +void +pr_iph(ip) + struct ip *ip; +{ + int hlen; + u_char *cp; + + hlen = ip->ip_hl << 2; + cp = (u_char *)ip + 20; /* point to options */ + + (void)printf("Vr HL TOS Len ID Flg off TTL Pro cks Src Dst Data\n"); + (void)printf(" %1x %1x %02x %04x %04x", + ip->ip_v, ip->ip_hl, ip->ip_tos, ip->ip_len, ip->ip_id); + (void)printf(" %1x %04x", ((ip->ip_off) & 0xe000) >> 13, + (ip->ip_off) & 0x1fff); + (void)printf(" %02x %02x %04x", ip->ip_ttl, ip->ip_p, ip->ip_sum); + (void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_src.s_addr)); + (void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_dst.s_addr)); + /* dump and option bytes */ + while (hlen-- > 20) + (void)printf("%02x", *cp++); + (void)putchar('\n'); +} + +/* + * pr_addr -- + * Return an ascii host address as a dotted quad and optionally with + * a hostname. + */ +char * +pr_addr(l) + u_long l; +{ + struct hostent *hp; + static char buf[80]; + + if ((options & F_NUMERIC) || + !(hp = gethostbyaddr((char *)&l, 4, AF_INET))) + (void)sprintf(buf, "%s", inet_ntoa(*(struct in_addr *)&l)); + else + (void)snprintf(buf, sizeof(buf), + "%s (%s)", hp->h_name, inet_ntoa(*(struct in_addr *)&l)); + return (buf); +} + +/* + * pr_retip -- + * Dump some info on a returned (via ICMP) IP packet. + */ +void +pr_retip(ip) + struct ip *ip; +{ + int hlen; + u_char *cp; + + pr_iph(ip); + hlen = ip->ip_hl << 2; + cp = (u_char *)ip + hlen; + + if (ip->ip_p == 6) + (void)printf("TCP: from port %u, to port %u (decimal)\n", + (*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3))); + else if (ip->ip_p == 17) + (void)printf("UDP: from port %u, to port %u (decimal)\n", + (*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3))); +} + +void +fill(bp, patp) + char *bp, *patp; +{ + register int ii, jj, kk; + int pat[16]; + char *cp; + + for (cp = patp; *cp; cp++) + if (!isxdigit(*cp)) + errx(1, "patterns must be specified as hex digits"); + ii = sscanf(patp, + "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", + &pat[0], &pat[1], &pat[2], &pat[3], &pat[4], &pat[5], &pat[6], + &pat[7], &pat[8], &pat[9], &pat[10], &pat[11], &pat[12], + &pat[13], &pat[14], &pat[15]); + + if (ii > 0) + for (kk = 0; + kk <= MAXPACKET - (8 + sizeof(struct timeval) + ii); + kk += ii) + for (jj = 0; jj < ii; ++jj) + bp[jj + kk] = pat[jj]; + if (!(options & F_QUIET)) { + (void)printf("PATTERN: 0x"); + for (jj = 0; jj < ii; ++jj) + (void)printf("%02x", bp[jj] & 0xFF); + (void)printf("\n"); + } +} + +void +usage() +{ + (void)fprintf(stderr, +"usage: ping [-dfnqRrv] [-c count] [-i wait] [-l preload] [-p pattern]\n\ + [-s packetsize] host\n"); + exit(1); +} diff --git a/ping/init_v6.c b/ping/init_v6.c new file mode 100644 index 0000000..bb7c63d --- /dev/null +++ b/ping/init_v6.c @@ -0,0 +1,27 @@ +#include "ping.h" + +void +init_v6() +{ +#ifdef IPV6 + int on = 1; + + if (verbose == 0) { + /* install a filter that only passes ICMP6_ECHO_REPLY unless verbose */ + struct icmp6_filter myfilt; + ICMP6_FILTER_SETBLOCKALL(&myfilt); + ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &myfilt); + setsockopt(sockfd, IPPROTO_IPV6, ICMP6_FILTER, &myfilt, sizeof(myfilt)); + /* ignore error return; the filter is an optimization */ + } + + /* ignore error returned below; we just won't receive the hop limit */ +#ifdef IPV6_RECVHOPLIMIT + /* RFC 3542 */ + setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, sizeof(on)); +#else + /* RFC 2292 */ + setsockopt(sockfd, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, sizeof(on)); +#endif +#endif +} diff --git a/ping/main.c b/ping/main.c new file mode 100644 index 0000000..34aab8b --- /dev/null +++ b/ping/main.c @@ -0,0 +1,64 @@ +#include "ping.h" + +struct proto proto_v4 = { proc_v4, send_v4, NULL, NULL, NULL, 0, IPPROTO_ICMP }; + +#ifdef IPV6 +struct proto proto_v6 = { proc_v6, send_v6, init_v6, NULL, NULL, 0, IPPROTO_ICMPV6 }; +#endif + +int datalen = 56; /* data that goes with ICMP echo request */ + +int +main(int argc, char **argv) +{ + int c; + struct addrinfo *ai; + char *h; + + opterr = 0; /* don't want getopt() writing to stderr */ + while ( (c = getopt(argc, argv, "v")) != -1) { + switch (c) { + case 'v': + verbose++; + break; + + case '?': + err_quit("unrecognized option: %c", c); + } + } + + if (optind != argc-1) + err_quit("usage: ping [ -v ] "); + host = argv[optind]; + + pid = getpid() & 0xffff; /* ICMP ID field is 16 bits */ + Signal(SIGALRM, sig_alrm); + + ai = Host_serv(host, NULL, 0, 0); + + h = Sock_ntop_host(ai->ai_addr, ai->ai_addrlen); + printf("PING %s (%s): %d data bytes\n", + ai->ai_canonname ? ai->ai_canonname : h, + h, datalen); + + /* 4initialize according to protocol */ + if (ai->ai_family == AF_INET) { + pr = &proto_v4; +#ifdef IPV6 + } else if (ai->ai_family == AF_INET6) { + pr = &proto_v6; + if (IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *) + ai->ai_addr)->sin6_addr))) + err_quit("cannot ping IPv4-mapped IPv6 address"); +#endif + } else + err_quit("unknown address family %d", ai->ai_family); + + pr->sasend = ai->ai_addr; + pr->sarecv = Calloc(1, ai->ai_addrlen); + pr->salen = ai->ai_addrlen; + + readloop(); + + exit(0); +} diff --git a/ping/main.lc b/ping/main.lc new file mode 100644 index 0000000..08b91e2 --- /dev/null +++ b/ping/main.lc @@ -0,0 +1,61 @@ +#include "ping.h"## 1 ##src/ping/main.c## + +struct proto proto_v4 = { proc_v4, send_v4, NULL, NULL, 0, IPPROTO_ICMP };## 2 ##src/ping/main.c## + +#ifdef IPV6## 3 ##src/ping/main.c## +struct proto proto_v6 = { proc_v6, send_v6, NULL, NULL, 0, IPPROTO_ICMPV6 };## 4 ##src/ping/main.c## +#endif## 5 ##src/ping/main.c## + +int datalen = 56; /* data that goes with ICMP echo request */## 6 ##src/ping/main.c## + +int## 7 ##src/ping/main.c## +main(int argc, char **argv)## 8 ##src/ping/main.c## +{## 9 ##src/ping/main.c## + int c;## 10 ##src/ping/main.c## + struct addrinfo *ai;## 11 ##src/ping/main.c## + + opterr = 0; /* don't want getopt() writing to stderr */## 12 ##src/ping/main.c## + while ((c = getopt(argc, argv, "v")) != -1) {## 13 ##src/ping/main.c## + switch (c) {## 14 ##src/ping/main.c## + case 'v':## 15 ##src/ping/main.c## + verbose++;## 16 ##src/ping/main.c## + break;## 17 ##src/ping/main.c## + + case '?':## 18 ##src/ping/main.c## + err_quit("unrecognized option: %c", c);## 19 ##src/ping/main.c## + }## 20 ##src/ping/main.c## + }## 21 ##src/ping/main.c## + + if (optind != argc - 1)## 22 ##src/ping/main.c## + err_quit("usage: ping [ -v ] ");## 23 ##src/ping/main.c## + host = argv[optind];## 24 ##src/ping/main.c## + + pid = getpid();## 25 ##src/ping/main.c## + Signal(SIGALRM, sig_alrm);## 26 ##src/ping/main.c## + + ai = Host_serv(host, NULL, 0, 0);## 27 ##src/ping/main.c## + + printf("PING %s (%s): %d data bytes\n", ai->ai_canonname,## 28 ##src/ping/main.c## + Sock_ntop_host(ai->ai_addr, ai->ai_addrlen), datalen);## 29 ##src/ping/main.c## + + /* 4initialize according to protocol */## 30 ##src/ping/main.c## + if (ai->ai_family == AF_INET) {## 31 ##src/ping/main.c## + pr = &proto_v4;## 32 ##src/ping/main.c## +#ifdef IPV6## 33 ##src/ping/main.c## + } else if (ai->ai_family == AF_INET6) {## 34 ##src/ping/main.c## + pr = &proto_v6;## 35 ##src/ping/main.c## + if (IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *)## 36 ##src/ping/main.c## + ai->ai_addr)->sin6_addr)))## 37 ##src/ping/main.c## + err_quit("cannot ping IPv4-mapped IPv6 address");## 38 ##src/ping/main.c## +#endif## 39 ##src/ping/main.c## + } else## 40 ##src/ping/main.c## + err_quit("unknown address family %d", ai->ai_family);## 41 ##src/ping/main.c## + + pr->sasend = ai->ai_addr;## 42 ##src/ping/main.c## + pr->sarecv = Calloc(1, ai->ai_addrlen);## 43 ##src/ping/main.c## + pr->salen = ai->ai_addrlen;## 44 ##src/ping/main.c## + + readloop();## 45 ##src/ping/main.c## + + exit(0);## 46 ##src/ping/main.c## +}## 47 ##src/ping/main.c## diff --git a/ping/old/icmp6.h b/ping/old/icmp6.h new file mode 100644 index 0000000..b3d8929 --- /dev/null +++ b/ping/old/icmp6.h @@ -0,0 +1,46 @@ +struct icmp6hdr { + u_int8_t icmp6_type; /* Type field */ + u_int8_t icmp6_code; /* Code field */ + u_int16_t icmp6_cksum; /* Checksum field */ + union { + u_int32_t un_data32[1]; /* Type-specific field */ + u_int16_t un_data16[2]; /* Type-specific field */ + u_int8_t un_data8[4]; /* Type-specific field */ + } icmp6_dataun; +}; + +#define icmp6_data32 icmp6_dataun.un_data32 +#define icmp6_data16 icmp6_dataun.un_data16 +#define icmp6_data8 icmp6_dataun.un_data8 +#define icmp6_pptr icmp6_data32[0] /* PARAMPROB */ +#define icmp6_mtu icmp6_data32[0] /* PKT_TOOBIG */ +#define icmp6_id icmp6_data16[0] /* ECHO */ +#define icmp6_seq icmp6_data16[1] /* ECHO */ +#define icmp6_maxdelay icmp6_data16[0] /* MGM_xxx */ + +#define ICMPV6_DEST_UNREACH 1 +#define ICMPV6_PKT_TOOBIG 2 +#define ICMPV6_TIME_EXCEED 3 +#define ICMPV6_PARAMPROB 4 + +#define ICMPV6_INFOMSG_MASK 0x80 /* all informational messages */ + +#define ICMPV6_ECHORQST 128 +#define ICMPV6_ECHORPLY 129 +#define ICMPV6_MGM_QUERY 130 +#define ICMPV6_MGM_REPORT 131 +#define ICMPV6_MGM_REDUCTION 132 + +#define ICMPV6_DEST_UNREACH_NOROUTE 0 /* no route to destination */ +#define ICMPV6_DEST_UNREACH_ADMIN 1 /* communication with destination */ + /* administratively prohibited */ +#define ICMPV6_DEST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor */ +#define ICMPV6_DEST_UNREACH_ADDR 3 /* address unreachable */ +#define ICMPV6_DEST_UNREACH_NOPORT 4 /* bad port */ + +#define ICMPV6_TIME_EXCEED_HOPS 0 /* Hop Limit == 0 in transit */ +#define ICMPV6_TIME_EXCEED_REASSEMBLY 1 /* Reassembly time out */ + +#define ICMPV6_PARAMPROB_HDR 0 /* erroneous header field */ +#define ICMPV6_PARAMPROB_NXT_HDR 1 /* unrecognized Next Header */ +#define ICMPV6_PARAMPROB_OPTS 2 /* unrecognized IPv6 option */ diff --git a/ping/old/ip6.h b/ping/old/ip6.h new file mode 100644 index 0000000..1c23950 --- /dev/null +++ b/ping/old/ip6.h @@ -0,0 +1,20 @@ +struct ip6hdr { + union { + struct ip6hdrctl { + u_int32_t ctl6_flow; /* 24 bits of flow-ID */ + u_int16_t ctl6_plen; /* payload length */ + u_int8_t ctl6_nxt; /* next header */ + u_int8_t ctl6_hlim; /* hop limit */ + } un_ctl6; + u_int8_t un_vfc; /* 4 bits version, 4 bits reserved */ + } ip6_ctlun; + struct in6_addr ip6_src; /* source address */ + struct in6_addr ip6_dst; /* destination address */ +}; + +#define ip6_vfc ip6_ctlun.un_vfc +#define ip6_flow ip6_ctlun.un_ctl6.ctl6_flow +#define ip6_plen ip6_ctlun.un_ctl6.ctl6_plen +#define ip6_nxt ip6_ctlun.un_ctl6.ctl6_nxt +#define ip6_hlim ip6_ctlun.un_ctl6.ctl6_hlim +#define ip6_hops ip6_ctlun.un_ctl6.ctl6_hlim diff --git a/ping/ping.h b/ping/ping.h new file mode 100644 index 0000000..062b87a --- /dev/null +++ b/ping/ping.h @@ -0,0 +1,43 @@ +#include "unp.h" +#include +#include +#include + +#define BUFSIZE 1500 + + /* globals */ +char sendbuf[BUFSIZE]; + +int datalen; /* # bytes of data following ICMP header */ +char *host; +int nsent; /* add 1 for each sendto() */ +pid_t pid; /* our PID */ +int sockfd; +int verbose; + + /* function prototypes */ +void init_v6(void); +void proc_v4(char *, ssize_t, struct msghdr *, struct timeval *); +void proc_v6(char *, ssize_t, struct msghdr *, struct timeval *); +void send_v4(void); +void send_v6(void); +void readloop(void); +void sig_alrm(int); +void tv_sub(struct timeval *, struct timeval *); + +struct proto { + void (*fproc)(char *, ssize_t, struct msghdr *, struct timeval *); + void (*fsend)(void); + void (*finit)(void); + struct sockaddr *sasend; /* sockaddr{} for send, from getaddrinfo */ + struct sockaddr *sarecv; /* sockaddr{} for receiving */ + socklen_t salen; /* length of sockaddr{}s */ + int icmpproto; /* IPPROTO_xxx value for ICMP */ +} *pr; + +#ifdef IPV6 + +#include +#include + +#endif diff --git a/ping/ping_v4.c b/ping/ping_v4.c new file mode 100644 index 0000000..3bd7cdf --- /dev/null +++ b/ping/ping_v4.c @@ -0,0 +1,33 @@ +#include "ping.h" + +void +ping_v4(struct hostent *hptr) +{ + int size; + char recvbuf[BUFSIZE]; + socklen_t len; + ssize_t n; + struct timeval tval; + + setuid(getuid()); /* don't need special permissions any more */ + + size = 60 * 1024; /* OK if setsockopt fails */ + setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); + + + sig_alrm(SIGALRM); /* send first packet */ + + for ( ; ; ) { + len = salen; + n = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, sarecv, &len); + if (n < 0) { + if (errno == EINTR) + continue; + else + err_sys("recvfrom error"); + } + + Gettimeofday(&tval, NULL); + (*fptrs.proc_f)(recvbuf, n, &tval); + } +} diff --git a/ping/proc_v4.c b/ping/proc_v4.c new file mode 100644 index 0000000..6b175ce --- /dev/null +++ b/ping/proc_v4.c @@ -0,0 +1,40 @@ +#include "ping.h" + +void +proc_v4(char *ptr, ssize_t len, struct msghdr *msg, struct timeval *tvrecv) +{ + int hlen1, icmplen; + double rtt; + struct ip *ip; + struct icmp *icmp; + struct timeval *tvsend; + + ip = (struct ip *) ptr; /* start of IP header */ + hlen1 = ip->ip_hl << 2; /* length of IP header */ + if (ip->ip_p != IPPROTO_ICMP) + return; /* not ICMP */ + + icmp = (struct icmp *) (ptr + hlen1); /* start of ICMP header */ + if ( (icmplen = len - hlen1) < 8) + return; /* malformed packet */ + + if (icmp->icmp_type == ICMP_ECHOREPLY) { + if (icmp->icmp_id != pid) + return; /* not a response to our ECHO_REQUEST */ + if (icmplen < 16) + return; /* not enough data to use */ + + tvsend = (struct timeval *) icmp->icmp_data; + tv_sub(tvrecv, tvsend); + rtt = tvrecv->tv_sec * 1000.0 + tvrecv->tv_usec / 1000.0; + + printf("%d bytes from %s: seq=%u, ttl=%d, rtt=%.3f ms\n", + icmplen, Sock_ntop_host(pr->sarecv, pr->salen), + icmp->icmp_seq, ip->ip_ttl, rtt); + + } else if (verbose) { + printf(" %d bytes from %s: type = %d, code = %d\n", + icmplen, Sock_ntop_host(pr->sarecv, pr->salen), + icmp->icmp_type, icmp->icmp_code); + } +} diff --git a/ping/proc_v4.lc b/ping/proc_v4.lc new file mode 100644 index 0000000..1ec03fa --- /dev/null +++ b/ping/proc_v4.lc @@ -0,0 +1,38 @@ +#include "ping.h"## 1 ##src/ping/proc_v4.c## + +void## 2 ##src/ping/proc_v4.c## +proc_v4(char *ptr, ssize_t len, struct timeval *tvrecv)## 3 ##src/ping/proc_v4.c## +{## 4 ##src/ping/proc_v4.c## + int hlen1, icmplen;## 5 ##src/ping/proc_v4.c## + double rtt;## 6 ##src/ping/proc_v4.c## + struct ip *ip;## 7 ##src/ping/proc_v4.c## + struct icmp *icmp;## 8 ##src/ping/proc_v4.c## + struct timeval *tvsend;## 9 ##src/ping/proc_v4.c## + + ip = (struct ip *) ptr; /* start of IP header */## 10 ##src/ping/proc_v4.c## + hlen1 = ip->ip_hl << 2; /* length of IP header */## 11 ##src/ping/proc_v4.c## + + icmp = (struct icmp *) (ptr + hlen1); /* start of ICMP header */## 12 ##src/ping/proc_v4.c## + if ((icmplen = len - hlen1) < 8)## 13 ##src/ping/proc_v4.c## + err_quit("icmplen (%d) < 8", icmplen);## 14 ##src/ping/proc_v4.c## + + if (icmp->icmp_type == ICMP_ECHOREPLY) {## 15 ##src/ping/proc_v4.c## + if (icmp->icmp_id != pid)## 16 ##src/ping/proc_v4.c## + return; /* not a response to our ECHO_REQUEST */## 17 ##src/ping/proc_v4.c## + if (icmplen < 16)## 18 ##src/ping/proc_v4.c## + err_quit("icmplen (%d) < 16", icmplen);## 19 ##src/ping/proc_v4.c## + + tvsend = (struct timeval *) icmp->icmp_data;## 20 ##src/ping/proc_v4.c## + tv_sub(tvrecv, tvsend);## 21 ##src/ping/proc_v4.c## + rtt = tvrecv->tv_sec * 1000.0 + tvrecv->tv_usec / 1000.0;## 22 ##src/ping/proc_v4.c## + + printf("%d bytes from %s: seq=%u, ttl=%d, rtt=%.3f ms\n",## 23 ##src/ping/proc_v4.c## + icmplen, Sock_ntop_host(pr->sarecv, pr->salen),## 24 ##src/ping/proc_v4.c## + icmp->icmp_seq, ip->ip_ttl, rtt);## 25 ##src/ping/proc_v4.c## + + } else if (verbose) {## 26 ##src/ping/proc_v4.c## + printf(" %d bytes from %s: type = %d, code = %d\n",## 27 ##src/ping/proc_v4.c## + icmplen, Sock_ntop_host(pr->sarecv, pr->salen),## 28 ##src/ping/proc_v4.c## + icmp->icmp_type, icmp->icmp_code);## 29 ##src/ping/proc_v4.c## + }## 30 ##src/ping/proc_v4.c## +}## 31 ##src/ping/proc_v4.c## diff --git a/ping/proc_v6.c b/ping/proc_v6.c new file mode 100644 index 0000000..3609bf0 --- /dev/null +++ b/ping/proc_v6.c @@ -0,0 +1,49 @@ +#include "ping.h" + +void +proc_v6(char *ptr, ssize_t len, struct msghdr *msg, struct timeval* tvrecv) +{ +#ifdef IPV6 + double rtt; + struct icmp6_hdr *icmp6; + struct timeval *tvsend; + struct cmsghdr *cmsg; + int hlim; + + icmp6 = (struct icmp6_hdr *) ptr; + if (len < 8) + return; /* malformed packet */ + + if (icmp6->icmp6_type == ICMP6_ECHO_REPLY) { + if (icmp6->icmp6_id != pid) + return; /* not a response to our ECHO_REQUEST */ + if (len < 16) + return; /* not enough data to use */ + + tvsend = (struct timeval *) (icmp6 + 1); + tv_sub(tvrecv, tvsend); + rtt = tvrecv->tv_sec * 1000.0 + tvrecv->tv_usec / 1000.0; + + hlim = -1; + for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) { + if (cmsg->cmsg_level == IPPROTO_IPV6 && + cmsg->cmsg_type == IPV6_HOPLIMIT) { + hlim = *(u_int32_t *)CMSG_DATA(cmsg); + break; + } + } + printf("%d bytes from %s: seq=%u, hlim=", + len, Sock_ntop_host(pr->sarecv, pr->salen), + icmp6->icmp6_seq); + if (hlim == -1) + printf("???"); /* ancillary data missing */ + else + printf("%d", hlim); + printf(", rtt=%.3f ms\n", rtt); + } else if (verbose) { + printf(" %d bytes from %s: type = %d, code = %d\n", + len, Sock_ntop_host(pr->sarecv, pr->salen), + icmp6->icmp6_type, icmp6->icmp6_code); + } +#endif /* IPV6 */ +} diff --git a/ping/proc_v6.lc b/ping/proc_v6.lc new file mode 100644 index 0000000..4885cc3 --- /dev/null +++ b/ping/proc_v6.lc @@ -0,0 +1,42 @@ +#include "ping.h"## 1 ##src/ping/proc_v6.c## + +void## 2 ##src/ping/proc_v6.c## +proc_v6(char *ptr, ssize_t len, struct timeval *tvrecv)## 3 ##src/ping/proc_v6.c## +{## 4 ##src/ping/proc_v6.c## +#ifdef IPV6## 5 ##src/ping/proc_v6.c## + int hlen1, icmp6len;## 6 ##src/ping/proc_v6.c## + double rtt;## 7 ##src/ping/proc_v6.c## + struct ip6_hdr *ip6;## 8 ##src/ping/proc_v6.c## + struct icmp6_hdr *icmp6;## 9 ##src/ping/proc_v6.c## + struct timeval *tvsend;## 10 ##src/ping/proc_v6.c## + + ip6 = (struct ip6_hdr *) ptr; /* start of IPv6 header */## 11 ##src/ping/proc_v6.c## + hlen1 = sizeof(struct ip6_hdr);## 12 ##src/ping/proc_v6.c## + if (ip6->ip6_nxt != IPPROTO_ICMPV6)## 13 ##src/ping/proc_v6.c## + err_quit("next header not IPPROTO_ICMPV6");## 14 ##src/ping/proc_v6.c## + + icmp6 = (struct icmp6_hdr *) (ptr + hlen1);## 15 ##src/ping/proc_v6.c## + if ((icmp6len = len - hlen1) < 8)## 16 ##src/ping/proc_v6.c## + err_quit("icmp6len (%d) < 8", icmp6len);## 17 ##src/ping/proc_v6.c## + + if (icmp6->icmp6_type == ICMP6_ECHO_REPLY) {## 18 ##src/ping/proc_v6.c## + if (icmp6->icmp6_id != pid)## 19 ##src/ping/proc_v6.c## + return; /* not a response to our ECHO_REQUEST */## 20 ##src/ping/proc_v6.c## + if (icmp6len < 16)## 21 ##src/ping/proc_v6.c## + err_quit("icmp6len (%d) < 16", icmp6len);## 22 ##src/ping/proc_v6.c## + + tvsend = (struct timeval *) (icmp6 + 1);## 23 ##src/ping/proc_v6.c## + tv_sub(tvrecv, tvsend);## 24 ##src/ping/proc_v6.c## + rtt = tvrecv->tv_sec * 1000.0 + tvrecv->tv_usec / 1000.0;## 25 ##src/ping/proc_v6.c## + + printf("%d bytes from %s: seq=%u, hlim=%d, rtt=%.3f ms\n",## 26 ##src/ping/proc_v6.c## + icmp6len, Sock_ntop_host(pr->sarecv, pr->salen),## 27 ##src/ping/proc_v6.c## + icmp6->icmp6_seq, ip6->ip6_hlim, rtt);## 28 ##src/ping/proc_v6.c## + + } else if (verbose) {## 29 ##src/ping/proc_v6.c## + printf(" %d bytes from %s: type = %d, code = %d\n",## 30 ##src/ping/proc_v6.c## + icmp6len, Sock_ntop_host(pr->sarecv, pr->salen),## 31 ##src/ping/proc_v6.c## + icmp6->icmp6_type, icmp6->icmp6_code);## 32 ##src/ping/proc_v6.c## + }## 33 ##src/ping/proc_v6.c## +#endif /* IPV6 */## 34 ##src/ping/proc_v6.c## +}## 35 ##src/ping/proc_v6.c## diff --git a/ping/readloop.c b/ping/readloop.c new file mode 100644 index 0000000..dc6f483 --- /dev/null +++ b/ping/readloop.c @@ -0,0 +1,44 @@ +#include "ping.h" + +void +readloop(void) +{ + int size; + char recvbuf[BUFSIZE]; + char controlbuf[BUFSIZE]; + struct msghdr msg; + struct iovec iov; + ssize_t n; + struct timeval tval; + + sockfd = Socket(pr->sasend->sa_family, SOCK_RAW, pr->icmpproto); + setuid(getuid()); /* don't need special permissions any more */ + if (pr->finit) + (*pr->finit)(); + + size = 60 * 1024; /* OK if setsockopt fails */ + setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); + + sig_alrm(SIGALRM); /* send first packet */ + + iov.iov_base = recvbuf; + iov.iov_len = sizeof(recvbuf); + msg.msg_name = pr->sarecv; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = controlbuf; + for ( ; ; ) { + msg.msg_namelen = pr->salen; + msg.msg_controllen = sizeof(controlbuf); + n = recvmsg(sockfd, &msg, 0); + if (n < 0) { + if (errno == EINTR) + continue; + else + err_sys("recvmsg error"); + } + + Gettimeofday(&tval, NULL); + (*pr->fproc)(recvbuf, n, &msg, &tval); + } +} diff --git a/ping/send_v4.c b/ping/send_v4.c new file mode 100644 index 0000000..455f95a --- /dev/null +++ b/ping/send_v4.c @@ -0,0 +1,22 @@ +#include "ping.h" + +void +send_v4(void) +{ + int len; + struct icmp *icmp; + + icmp = (struct icmp *) sendbuf; + icmp->icmp_type = ICMP_ECHO; + icmp->icmp_code = 0; + icmp->icmp_id = pid; + icmp->icmp_seq = nsent++; + memset(icmp->icmp_data, 0xa5, datalen); /* fill with pattern */ + Gettimeofday((struct timeval *) icmp->icmp_data, NULL); + + len = 8 + datalen; /* checksum ICMP header and data */ + icmp->icmp_cksum = 0; + icmp->icmp_cksum = in_cksum((u_short *) icmp, len); + + Sendto(sockfd, sendbuf, len, 0, pr->sasend, pr->salen); +} diff --git a/ping/send_v6.c b/ping/send_v6.c new file mode 100644 index 0000000..c76e12d --- /dev/null +++ b/ping/send_v6.c @@ -0,0 +1,23 @@ +#include "ping.h" + +void +send_v6() +{ +#ifdef IPV6 + int len; + struct icmp6_hdr *icmp6; + + icmp6 = (struct icmp6_hdr *) sendbuf; + icmp6->icmp6_type = ICMP6_ECHO_REQUEST; + icmp6->icmp6_code = 0; + icmp6->icmp6_id = pid; + icmp6->icmp6_seq = nsent++; + memset((icmp6 + 1), 0xa5, datalen); /* fill with pattern */ + Gettimeofday((struct timeval *) (icmp6 + 1), NULL); + + len = 8 + datalen; /* 8-byte ICMPv6 header */ + + Sendto(sockfd, sendbuf, len, 0, pr->sasend, pr->salen); + /* 4kernel calculates and stores checksum for us */ +#endif /* IPV6 */ +} diff --git a/ping/sig_alrm.c b/ping/sig_alrm.c new file mode 100644 index 0000000..f32e803 --- /dev/null +++ b/ping/sig_alrm.c @@ -0,0 +1,10 @@ +#include "ping.h" + +void +sig_alrm(int signo) +{ + (*pr->fsend)(); + + alarm(1); + return; +} diff --git a/ping/sig_alrm.lc b/ping/sig_alrm.lc new file mode 100644 index 0000000..e13c21e --- /dev/null +++ b/ping/sig_alrm.lc @@ -0,0 +1,10 @@ +#include "ping.h"## 1 ##src/ping/sig_alrm.c## + +void## 2 ##src/ping/sig_alrm.c## +sig_alrm(int signo)## 3 ##src/ping/sig_alrm.c## +{## 4 ##src/ping/sig_alrm.c## + (*pr->fsend) ();## 5 ##src/ping/sig_alrm.c## + + alarm(1);## 6 ##src/ping/sig_alrm.c## + return; /* probably interrupts recvfrom() */## 7 ##src/ping/sig_alrm.c## +}## 8 ##src/ping/sig_alrm.c## diff --git a/ping/tv_sub.c b/ping/tv_sub.c new file mode 100644 index 0000000..7ad7830 --- /dev/null +++ b/ping/tv_sub.c @@ -0,0 +1,11 @@ +#include "unp.h" + +void +tv_sub(struct timeval *out, struct timeval *in) +{ + if ( (out->tv_usec -= in->tv_usec) < 0) { /* out -= in */ + --out->tv_sec; + out->tv_usec += 1000000; + } + out->tv_sec -= in->tv_sec; +} diff --git a/route/Makefile b/route/Makefile new file mode 100644 index 0000000..cb9cab5 --- /dev/null +++ b/route/Makefile @@ -0,0 +1,30 @@ +include ../Make.defines + +PROGS = checkudpsum getrt mynetstat \ + prifinfo prifindex prifname prifnameindex + +all: ${PROGS} + +checkudpsum: checkudpsum.o + ${CC} ${CFLAGS} -o $@ checkudpsum.o ${LIBS} + +getrt: getrt.o + ${CC} ${CFLAGS} -o $@ getrt.o ${LIBS} + +prifinfo: prifinfo.o get_ifi_info.o + ${CC} ${CFLAGS} -o $@ prifinfo.o get_ifi_info.o ${LIBS} + +prifindex: prifindex.o + ${CC} ${CFLAGS} -o $@ prifindex.o ${LIBS} + +prifname: prifname.o + ${CC} ${CFLAGS} -o $@ prifname.o ${LIBS} + +prifnameindex: prifnameindex.o + ${CC} ${CFLAGS} -o $@ prifnameindex.o ${LIBS} + +mynetstat: mynetstat.o + ${CC} ${CFLAGS} -o $@ mynetstat.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/route/checkudpsum.c b/route/checkudpsum.c new file mode 100644 index 0000000..e0360e1 --- /dev/null +++ b/route/checkudpsum.c @@ -0,0 +1,22 @@ +#include "unproute.h" +#include +#include +#include /* for UDPCTL_xxx constants */ + +int +main(int argc, char **argv) +{ + int mib[4], val; + size_t len; + + mib[0] = CTL_NET; + mib[1] = AF_INET; + mib[2] = IPPROTO_UDP; + mib[3] = UDPCTL_CHECKSUM; + + len = sizeof(val); + Sysctl(mib, 4, &val, &len, NULL, 0); + printf("udp checksum flag: %d\n", val); + + exit(0); +} diff --git a/route/get_ifi_info.c b/route/get_ifi_info.c new file mode 100644 index 0000000..f96ab78 --- /dev/null +++ b/route/get_ifi_info.c @@ -0,0 +1,126 @@ +#include "unpifi.h" +#include "unproute.h" + +/* include get_ifi_info1 */ +struct ifi_info * +get_ifi_info(int family, int doaliases) +{ + int flags; + char *buf, *next, *lim; + size_t len; + struct if_msghdr *ifm; + struct ifa_msghdr *ifam; + struct sockaddr *sa, *rti_info[RTAX_MAX]; + struct sockaddr_dl *sdl; + struct ifi_info *ifi, *ifisave, *ifihead, **ifipnext; + + buf = Net_rt_iflist(family, 0, &len); + + ifihead = NULL; + ifipnext = &ifihead; + + lim = buf + len; + for (next = buf; next < lim; next += ifm->ifm_msglen) { + ifm = (struct if_msghdr *) next; + if (ifm->ifm_type == RTM_IFINFO) { + if ( ((flags = ifm->ifm_flags) & IFF_UP) == 0) + continue; /* ignore if interface not up */ + + sa = (struct sockaddr *) (ifm + 1); + get_rtaddrs(ifm->ifm_addrs, sa, rti_info); + if ( (sa = rti_info[RTAX_IFP]) != NULL) { + ifi = Calloc(1, sizeof(struct ifi_info)); + *ifipnext = ifi; /* prev points to this new one */ + ifipnext = &ifi->ifi_next; /* ptr to next one goes here */ + + ifi->ifi_flags = flags; + if (sa->sa_family == AF_LINK) { + sdl = (struct sockaddr_dl *) sa; + ifi->ifi_index = sdl->sdl_index; + if (sdl->sdl_nlen > 0) + snprintf(ifi->ifi_name, IFI_NAME, "%*s", + sdl->sdl_nlen, &sdl->sdl_data[0]); + else + snprintf(ifi->ifi_name, IFI_NAME, "index %d", + sdl->sdl_index); + + if ( (ifi->ifi_hlen = sdl->sdl_alen) > 0) + memcpy(ifi->ifi_haddr, LLADDR(sdl), + min(IFI_HADDR, sdl->sdl_alen)); + } + } +/* end get_ifi_info1 */ + +/* include get_ifi_info3 */ + } else if (ifm->ifm_type == RTM_NEWADDR) { + if (ifi->ifi_addr) { /* already have an IP addr for i/f */ + if (doaliases == 0) + continue; + + /* 4we have a new IP addr for existing interface */ + ifisave = ifi; + ifi = Calloc(1, sizeof(struct ifi_info)); + *ifipnext = ifi; /* prev points to this new one */ + ifipnext = &ifi->ifi_next; /* ptr to next one goes here */ + ifi->ifi_flags = ifisave->ifi_flags; + ifi->ifi_index = ifisave->ifi_index; + ifi->ifi_hlen = ifisave->ifi_hlen; + memcpy(ifi->ifi_name, ifisave->ifi_name, IFI_NAME); + memcpy(ifi->ifi_haddr, ifisave->ifi_haddr, IFI_HADDR); + } + + ifam = (struct ifa_msghdr *) next; + sa = (struct sockaddr *) (ifam + 1); + get_rtaddrs(ifam->ifam_addrs, sa, rti_info); + + if ( (sa = rti_info[RTAX_IFA]) != NULL) { + ifi->ifi_addr = Calloc(1, sa->sa_len); + memcpy(ifi->ifi_addr, sa, sa->sa_len); + } + + if ((flags & IFF_BROADCAST) && + (sa = rti_info[RTAX_BRD]) != NULL) { + ifi->ifi_brdaddr = Calloc(1, sa->sa_len); + memcpy(ifi->ifi_brdaddr, sa, sa->sa_len); + } + + if ((flags & IFF_POINTOPOINT) && + (sa = rti_info[RTAX_BRD]) != NULL) { + ifi->ifi_dstaddr = Calloc(1, sa->sa_len); + memcpy(ifi->ifi_dstaddr, sa, sa->sa_len); + } + + } else + err_quit("unexpected message type %d", ifm->ifm_type); + } + /* "ifihead" points to the first structure in the linked list */ + return(ifihead); /* ptr to first structure in linked list */ +} +/* end get_ifi_info3 */ + +void +free_ifi_info(struct ifi_info *ifihead) +{ + struct ifi_info *ifi, *ifinext; + + for (ifi = ifihead; ifi != NULL; ifi = ifinext) { + if (ifi->ifi_addr != NULL) + free(ifi->ifi_addr); + if (ifi->ifi_brdaddr != NULL) + free(ifi->ifi_brdaddr); + if (ifi->ifi_dstaddr != NULL) + free(ifi->ifi_dstaddr); + ifinext = ifi->ifi_next; /* can't fetch ifi_next after free() */ + free(ifi); /* the ifi_info{} itself */ + } +} + +struct ifi_info * +Get_ifi_info(int family, int doaliases) +{ + struct ifi_info *ifi; + + if ( (ifi = get_ifi_info(family, doaliases)) == NULL) + err_quit("get_ifi_info error"); + return(ifi); +} diff --git a/route/get_ifi_info.lc b/route/get_ifi_info.lc new file mode 100644 index 0000000..c02f2f5 --- /dev/null +++ b/route/get_ifi_info.lc @@ -0,0 +1,123 @@ +#include "unpifi.h"## 1 ##src/route/get_ifi_info.c## +#include "unproute.h"## 2 ##src/route/get_ifi_info.c## + +/* include get_ifi_info1 */ +struct ifi_info *## 3 ##src/route/get_ifi_info.c## +get_ifi_info(int family, int doaliases)## 4 ##src/route/get_ifi_info.c## +{## 5 ##src/route/get_ifi_info.c## + int flags;## 6 ##src/route/get_ifi_info.c## + char *buf, *next, *lim;## 7 ##src/route/get_ifi_info.c## + size_t len;## 8 ##src/route/get_ifi_info.c## + struct if_msghdr *ifm;## 9 ##src/route/get_ifi_info.c## + struct ifa_msghdr *ifam;## 10 ##src/route/get_ifi_info.c## + struct sockaddr *sa, *rti_info[RTAX_MAX];## 11 ##src/route/get_ifi_info.c## + struct sockaddr_dl *sdl;## 12 ##src/route/get_ifi_info.c## + struct ifi_info *ifi, *ifisave, *ifihead, **ifipnext;## 13 ##src/route/get_ifi_info.c## + + buf = Net_rt_iflist(family, 0, &len);## 14 ##src/route/get_ifi_info.c## + + ifihead = NULL;## 15 ##src/route/get_ifi_info.c## + ifipnext = &ifihead;## 16 ##src/route/get_ifi_info.c## + + lim = buf + len;## 17 ##src/route/get_ifi_info.c## + for (next = buf; next < lim; next += ifm->ifm_msglen) {## 18 ##src/route/get_ifi_info.c## + ifm = (struct if_msghdr *) next;## 19 ##src/route/get_ifi_info.c## + if (ifm->ifm_type == RTM_IFINFO) {## 20 ##src/route/get_ifi_info.c## + if (((flags = ifm->ifm_flags) & IFF_UP) == 0)## 21 ##src/route/get_ifi_info.c## + continue; /* ignore if interface not up */## 22 ##src/route/get_ifi_info.c## + + sa = (struct sockaddr *) (ifm + 1);## 23 ##src/route/get_ifi_info.c## + get_rtaddrs(ifm->ifm_addrs, sa, rti_info);## 24 ##src/route/get_ifi_info.c## + if ((sa = rti_info[RTAX_IFP]) != NULL) {## 25 ##src/route/get_ifi_info.c## + ifi = Calloc(1, sizeof(struct ifi_info));## 26 ##src/route/get_ifi_info.c## + *ifipnext = ifi; /* prev points to this new one */## 27 ##src/route/get_ifi_info.c## + ifipnext = &ifi->ifi_next; /* ptr to next one goes here */## 28 ##src/route/get_ifi_info.c## + + ifi->ifi_flags = flags;## 29 ##src/route/get_ifi_info.c## + if (sa->sa_family == AF_LINK) {## 30 ##src/route/get_ifi_info.c## + sdl = (struct sockaddr_dl *) sa;## 31 ##src/route/get_ifi_info.c## + if (sdl->sdl_nlen > 0)## 32 ##src/route/get_ifi_info.c## + snprintf(ifi->ifi_name, IFI_NAME, "%*s",## 33 ##src/route/get_ifi_info.c## + sdl->sdl_nlen, &sdl->sdl_data[0]);## 34 ##src/route/get_ifi_info.c## + else## 35 ##src/route/get_ifi_info.c## + snprintf(ifi->ifi_name, IFI_NAME, "index %d",## 36 ##src/route/get_ifi_info.c## + sdl->sdl_index);## 37 ##src/route/get_ifi_info.c## + + if ((ifi->ifi_hlen = sdl->sdl_alen) > 0)## 38 ##src/route/get_ifi_info.c## + memcpy(ifi->ifi_haddr, LLADDR(sdl),## 39 ##src/route/get_ifi_info.c## + min(IFI_HADDR, sdl->sdl_alen));## 40 ##src/route/get_ifi_info.c## + }## 41 ##src/route/get_ifi_info.c## + }## 42 ##src/route/get_ifi_info.c## +/* end get_ifi_info1 */ + +/* include get_ifi_info3 */ + } else if (ifm->ifm_type == RTM_NEWADDR) {## 43 ##src/route/get_ifi_info.c## + if (ifi->ifi_addr) { /* already have an IP addr for i/f */## 44 ##src/route/get_ifi_info.c## + if (doaliases == 0)## 45 ##src/route/get_ifi_info.c## + continue;## 46 ##src/route/get_ifi_info.c## + + /* 4we have a new IP addr for existing interface */## 47 ##src/route/get_ifi_info.c## + ifisave = ifi;## 48 ##src/route/get_ifi_info.c## + ifi = Calloc(1, sizeof(struct ifi_info));## 49 ##src/route/get_ifi_info.c## + *ifipnext = ifi; /* prev points to this new one */## 50 ##src/route/get_ifi_info.c## + ifipnext = &ifi->ifi_next; /* ptr to next one goes here */## 51 ##src/route/get_ifi_info.c## + ifi->ifi_flags = ifisave->ifi_flags;## 52 ##src/route/get_ifi_info.c## + ifi->ifi_hlen = ifisave->ifi_hlen;## 53 ##src/route/get_ifi_info.c## + memcpy(ifi->ifi_name, ifisave->ifi_name, IFI_NAME);## 54 ##src/route/get_ifi_info.c## + memcpy(ifi->ifi_haddr, ifisave->ifi_haddr, IFI_HADDR);## 55 ##src/route/get_ifi_info.c## + }## 56 ##src/route/get_ifi_info.c## + + ifam = (struct ifa_msghdr *) next;## 57 ##src/route/get_ifi_info.c## + sa = (struct sockaddr *) (ifam + 1);## 58 ##src/route/get_ifi_info.c## + get_rtaddrs(ifam->ifam_addrs, sa, rti_info);## 59 ##src/route/get_ifi_info.c## + + if ((sa = rti_info[RTAX_IFA]) != NULL) {## 60 ##src/route/get_ifi_info.c## + ifi->ifi_addr = Calloc(1, sa->sa_len);## 61 ##src/route/get_ifi_info.c## + memcpy(ifi->ifi_addr, sa, sa->sa_len);## 62 ##src/route/get_ifi_info.c## + }## 63 ##src/route/get_ifi_info.c## + + if ((flags & IFF_BROADCAST) && (sa = rti_info[RTAX_BRD]) != NULL) {## 64 ##src/route/get_ifi_info.c## + ifi->ifi_brdaddr = Calloc(1, sa->sa_len);## 65 ##src/route/get_ifi_info.c## + memcpy(ifi->ifi_brdaddr, sa, sa->sa_len);## 66 ##src/route/get_ifi_info.c## + }## 67 ##src/route/get_ifi_info.c## + + if ((flags & IFF_POINTOPOINT) &&## 68 ##src/route/get_ifi_info.c## + (sa = rti_info[RTAX_BRD]) != NULL) {## 69 ##src/route/get_ifi_info.c## + ifi->ifi_dstaddr = Calloc(1, sa->sa_len);## 70 ##src/route/get_ifi_info.c## + memcpy(ifi->ifi_dstaddr, sa, sa->sa_len);## 71 ##src/route/get_ifi_info.c## + }## 72 ##src/route/get_ifi_info.c## + + } else## 73 ##src/route/get_ifi_info.c## + err_quit("unexpected message type %d", ifm->ifm_type);## 74 ##src/route/get_ifi_info.c## + }## 75 ##src/route/get_ifi_info.c## + /* "ifihead" points to the first structure in the linked list */## 76 ##src/route/get_ifi_info.c## + return (ifihead); /* ptr to first structure in linked list */## 77 ##src/route/get_ifi_info.c## +}## 78 ##src/route/get_ifi_info.c## +/* end get_ifi_info3 */ + +void## 79 ##src/route/get_ifi_info.c## +free_ifi_info(struct ifi_info *ifihead)## 80 ##src/route/get_ifi_info.c## +{## 81 ##src/route/get_ifi_info.c## + struct ifi_info *ifi, *ifinext;## 82 ##src/route/get_ifi_info.c## + + for (ifi = ifihead; ifi != NULL; ifi = ifinext) {## 83 ##src/route/get_ifi_info.c## + if (ifi->ifi_addr != NULL)## 84 ##src/route/get_ifi_info.c## + free(ifi->ifi_addr);## 85 ##src/route/get_ifi_info.c## + if (ifi->ifi_brdaddr != NULL)## 86 ##src/route/get_ifi_info.c## + free(ifi->ifi_brdaddr);## 87 ##src/route/get_ifi_info.c## + if (ifi->ifi_dstaddr != NULL)## 88 ##src/route/get_ifi_info.c## + free(ifi->ifi_dstaddr);## 89 ##src/route/get_ifi_info.c## + ifinext = ifi->ifi_next; /* can't fetch ifi_next after free() */## 90 ##src/route/get_ifi_info.c## + free(ifi); /* the ifi_info{} itself */## 91 ##src/route/get_ifi_info.c## + }## 92 ##src/route/get_ifi_info.c## +}## 93 ##src/route/get_ifi_info.c## + +struct ifi_info *## 94 ##src/route/get_ifi_info.c## +Get_ifi_info(int family, int doaliases)## 95 ##src/route/get_ifi_info.c## +{## 96 ##src/route/get_ifi_info.c## + struct ifi_info *ifi;## 97 ##src/route/get_ifi_info.c## + + if ((ifi = get_ifi_info(family, doaliases)) == NULL)## 98 ##src/route/get_ifi_info.c## + err_quit("get_ifi_info error");## 99 ##src/route/get_ifi_info.c## + return (ifi);##100 ##src/route/get_ifi_info.c## +}##101 ##src/route/get_ifi_info.c## diff --git a/route/getrt.c b/route/getrt.c new file mode 100644 index 0000000..4d2143a --- /dev/null +++ b/route/getrt.c @@ -0,0 +1,65 @@ +/* include getrt1 */ +#include "unproute.h" + +#define BUFLEN (sizeof(struct rt_msghdr) + 512) + /* sizeof(struct sockaddr_in6) * 8 = 192 */ +#define SEQ 9999 + +int +main(int argc, char **argv) +{ + int sockfd; + char *buf; + pid_t pid; + ssize_t n; + struct rt_msghdr *rtm; + struct sockaddr *sa, *rti_info[RTAX_MAX]; + struct sockaddr_in *sin; + + if (argc != 2) + err_quit("usage: getrt "); + + sockfd = Socket(AF_ROUTE, SOCK_RAW, 0); /* need superuser privileges */ + + buf = Calloc(1, BUFLEN); /* and initialized to 0 */ + + rtm = (struct rt_msghdr *) buf; + rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in); + rtm->rtm_version = RTM_VERSION; + rtm->rtm_type = RTM_GET; + rtm->rtm_addrs = RTA_DST; + rtm->rtm_pid = pid = getpid(); + rtm->rtm_seq = SEQ; + + sin = (struct sockaddr_in *) (rtm + 1); + sin->sin_len = sizeof(struct sockaddr_in); + sin->sin_family = AF_INET; + Inet_pton(AF_INET, argv[1], &sin->sin_addr); + + Write(sockfd, rtm, rtm->rtm_msglen); + + do { + n = Read(sockfd, rtm, BUFLEN); + } while (rtm->rtm_type != RTM_GET || rtm->rtm_seq != SEQ || + rtm->rtm_pid != pid); +/* end getrt1 */ + +/* include getrt2 */ + rtm = (struct rt_msghdr *) buf; + sa = (struct sockaddr *) (rtm + 1); + get_rtaddrs(rtm->rtm_addrs, sa, rti_info); + if ( (sa = rti_info[RTAX_DST]) != NULL) + printf("dest: %s\n", Sock_ntop_host(sa, sa->sa_len)); + + if ( (sa = rti_info[RTAX_GATEWAY]) != NULL) + printf("gateway: %s\n", Sock_ntop_host(sa, sa->sa_len)); + + if ( (sa = rti_info[RTAX_NETMASK]) != NULL) + printf("netmask: %s\n", Sock_masktop(sa, sa->sa_len)); + + if ( (sa = rti_info[RTAX_GENMASK]) != NULL) + printf("genmask: %s\n", Sock_masktop(sa, sa->sa_len)); + + exit(0); +} +/* end getrt2 */ diff --git a/route/getrt.lc b/route/getrt.lc new file mode 100644 index 0000000..6fe6e4d --- /dev/null +++ b/route/getrt.lc @@ -0,0 +1,65 @@ +/* include getrt1 */ +#include "unproute.h"## 1 ##src/route/getrt.c## + +#define BUFLEN (sizeof(struct rt_msghdr) + 512)## 2 ##src/route/getrt.c## + /* sizeof(struct sockaddr_in6) * 8 = 192 */## 3 ##src/route/getrt.c## +#define SEQ 9999## 4 ##src/route/getrt.c## + +int## 5 ##src/route/getrt.c## +main(int argc, char **argv)## 6 ##src/route/getrt.c## +{## 7 ##src/route/getrt.c## + int sockfd;## 8 ##src/route/getrt.c## + char *buf;## 9 ##src/route/getrt.c## + pid_t pid;## 10 ##src/route/getrt.c## + ssize_t n;## 11 ##src/route/getrt.c## + struct rt_msghdr *rtm;## 12 ##src/route/getrt.c## + struct sockaddr *sa, *rti_info[RTAX_MAX];## 13 ##src/route/getrt.c## + struct sockaddr_in *sin;## 14 ##src/route/getrt.c## + + if (argc != 2)## 15 ##src/route/getrt.c## + err_quit("usage: getrt ");## 16 ##src/route/getrt.c## + + sockfd = Socket(AF_ROUTE, SOCK_RAW, 0); /* need superuser privileges */## 17 ##src/route/getrt.c## + + buf = Calloc(1, BUFLEN); /* and initialized to 0 */## 18 ##src/route/getrt.c## + + rtm = (struct rt_msghdr *) buf;## 19 ##src/route/getrt.c## + rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);## 20 ##src/route/getrt.c## + rtm->rtm_version = RTM_VERSION;## 21 ##src/route/getrt.c## + rtm->rtm_type = RTM_GET;## 22 ##src/route/getrt.c## + rtm->rtm_addrs = RTA_DST;## 23 ##src/route/getrt.c## + rtm->rtm_pid = pid = getpid();## 24 ##src/route/getrt.c## + rtm->rtm_seq = SEQ;## 25 ##src/route/getrt.c## + + sin = (struct sockaddr_in *) (rtm + 1);## 26 ##src/route/getrt.c## + sin->sin_len = sizeof(struct sockaddr_in);## 27 ##src/route/getrt.c## + sin->sin_family = AF_INET;## 28 ##src/route/getrt.c## + Inet_pton(AF_INET, argv[1], &sin->sin_addr);## 29 ##src/route/getrt.c## + + Write(sockfd, rtm, rtm->rtm_msglen);## 30 ##src/route/getrt.c## + + do {## 31 ##src/route/getrt.c## + n = Read(sockfd, rtm, BUFLEN);## 32 ##src/route/getrt.c## + } while (rtm->rtm_type != RTM_GET || rtm->rtm_seq != SEQ ||## 33 ##src/route/getrt.c## + rtm->rtm_pid != pid);## 34 ##src/route/getrt.c## +/* end getrt1 */ + +/* include getrt2 */ + rtm = (struct rt_msghdr *) buf;## 35 ##src/route/getrt.c## + sa = (struct sockaddr *) (rtm + 1);## 36 ##src/route/getrt.c## + get_rtaddrs(rtm->rtm_addrs, sa, rti_info);## 37 ##src/route/getrt.c## + if ((sa = rti_info[RTAX_DST]) != NULL)## 38 ##src/route/getrt.c## + printf("dest: %s\n", Sock_ntop_host(sa, sa->sa_len));## 39 ##src/route/getrt.c## + + if ((sa = rti_info[RTAX_GATEWAY]) != NULL)## 40 ##src/route/getrt.c## + printf("gateway: %s\n", Sock_ntop_host(sa, sa->sa_len));## 41 ##src/route/getrt.c## + + if ((sa = rti_info[RTAX_NETMASK]) != NULL)## 42 ##src/route/getrt.c## + printf("netmask: %s\n", Sock_masktop(sa, sa->sa_len));## 43 ##src/route/getrt.c## + + if ((sa = rti_info[RTAX_GENMASK]) != NULL)## 44 ##src/route/getrt.c## + printf("genmask: %s\n", Sock_masktop(sa, sa->sa_len));## 45 ##src/route/getrt.c## + + exit(0);## 46 ##src/route/getrt.c## +}## 47 ##src/route/getrt.c## +/* end getrt2 */ diff --git a/route/mynetstat.c b/route/mynetstat.c new file mode 100644 index 0000000..acb1357 --- /dev/null +++ b/route/mynetstat.c @@ -0,0 +1,108 @@ +#include "unproute.h" + +void pr_rtable(int); +void pr_iflist(int); + +int +main(int argc, char **argv) +{ + int family; + + if (argc != 2) + err_quit("usage: mynetstat "); + if (strcmp(argv[1], "inet4") == 0) + family = AF_INET; +#ifdef AF_INET6 + else if (strcmp(argv[1], "inet6") == 0) + family = AF_INET6; +#endif + else if (strcmp(argv[1], "all") == 0) + family = 0; + else + err_quit("invalid "); + + pr_rtable(family); + + pr_iflist(family); + + exit(0); +} + +void +pr_rtable(int family) +{ + char *buf, *next, *lim; + size_t len; + struct rt_msghdr *rtm; + struct sockaddr *sa, *rti_info[RTAX_MAX]; + + buf = Net_rt_dump(family, 0, &len); + + lim = buf + len; + for (next = buf; next < lim; next += rtm->rtm_msglen) { + rtm = (struct rt_msghdr *) next; + sa = (struct sockaddr *)(rtm + 1); + get_rtaddrs(rtm->rtm_addrs, sa, rti_info); + if ( (sa = rti_info[RTAX_DST]) != NULL) + printf("dest: %s", sock_ntop(sa, sa->sa_len)); + + if ( (sa = rti_info[RTAX_GATEWAY]) != NULL) + printf(", gateway: %s", sock_ntop(sa, sa->sa_len)); + + printf("\n"); + } +} + +void +pr_iflist(int family) +{ + int flags; + char *buf, *next, *lim; + u_char *ptr; + size_t len; + struct if_msghdr *ifm; + struct ifa_msghdr *ifam; + struct sockaddr *sa, *rti_info[RTAX_MAX]; + struct sockaddr_dl *sdl; + + buf = Net_rt_iflist(family, 0, &len); + + lim = buf + len; + for (next = buf; next < lim; next += ifm->ifm_msglen) { + ifm = (struct if_msghdr *) next; + if (ifm->ifm_type == RTM_IFINFO) { + sa = (struct sockaddr *)(ifm + 1); + get_rtaddrs(ifm->ifm_addrs, sa, rti_info); + if ( (sa = rti_info[RTAX_IFP]) != NULL) { + if (((flags = ifm->ifm_flags) & IFF_UP) == 0) + continue; + printf("interface: %s: <", Sock_ntop(sa, sa->sa_len)); + if (flags & IFF_UP) printf("UP "); + if (flags & IFF_BROADCAST) printf("BCAST "); + if (flags & IFF_MULTICAST) printf("MCAST "); + if (flags & IFF_LOOPBACK) printf("LOOP "); + if (flags & IFF_POINTOPOINT) printf("P2P "); + printf(">\n"); + + if (sa->sa_family == AF_LINK && + (sdl = (struct sockaddr_dl *) sa) && + (sdl->sdl_alen > 0)) { + ptr = (u_char *) &sdl->sdl_data[sdl->sdl_nlen]; + printf(" %x:%x:%x:%x:%x:%x\n", *ptr, *(ptr+1), + *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)); + } + } + + } else if (ifm->ifm_type == RTM_NEWADDR) { + ifam = (struct ifa_msghdr *) next; + sa = (struct sockaddr *)(ifam + 1); + get_rtaddrs(ifam->ifam_addrs, sa, rti_info); + if ( (sa = rti_info[RTAX_IFA]) != NULL) + printf(" IP addr: %s\n", Sock_ntop(sa, sa->sa_len)); + if ((flags & IFF_BROADCAST) && (sa = rti_info[RTAX_BRD])) + printf(" bcast addr: %s\n", Sock_ntop(sa, sa->sa_len)); + + } else + err_quit("unexpected message type %d", ifm->ifm_type); + } +} diff --git a/route/prifindex.c b/route/prifindex.c new file mode 100644 index 0000000..0b8e565 --- /dev/null +++ b/route/prifindex.c @@ -0,0 +1,11 @@ +#include "unpifi.h" + +int +main(int argc, char **argv) +{ + if (argc != 2) + err_quit("usage: prifname "); + + printf("interface index = %d\n", If_nametoindex(argv[1])); + exit(0); +} diff --git a/route/prifinfo.c b/route/prifinfo.c new file mode 100644 index 0000000..767fc4b --- /dev/null +++ b/route/prifinfo.c @@ -0,0 +1,50 @@ +#include "unpifi.h" + +int +main(int argc, char **argv) +{ + struct ifi_info *ifi, *ifihead; + struct sockaddr *sa; + u_char *ptr; + int i, family, doaliases; + + if (argc != 3) + err_quit("usage: prifinfo "); + if (strcmp(argv[1], "inet4") == 0) + family = AF_INET; +#ifdef AF_INET6 + else if (strcmp(argv[1], "inet6") == 0) + family = AF_INET6; +#endif + else + err_quit("invalid "); + doaliases = atoi(argv[2]); + + for (ifihead = ifi = Get_ifi_info(family, doaliases); + ifi != NULL; ifi = ifi->ifi_next) { + printf("%s: <", ifi->ifi_name); + if (ifi->ifi_flags & IFF_UP) printf("UP "); + if (ifi->ifi_flags & IFF_BROADCAST) printf("BCAST "); + if (ifi->ifi_flags & IFF_MULTICAST) printf("MCAST "); + if (ifi->ifi_flags & IFF_LOOPBACK) printf("LOOP "); + if (ifi->ifi_flags & IFF_POINTOPOINT) printf("P2P "); + printf(">\n"); + + if ( (i = ifi->ifi_hlen) > 0) { + ptr = ifi->ifi_haddr; + do { + printf("%s%x", (i == ifi->ifi_hlen) ? " " : ":", *ptr++); + } while (--i > 0); + printf("\n"); + } + + if ( (sa = ifi->ifi_addr) != NULL) + printf(" IP addr: %s\n", Sock_ntop(sa, sa->sa_len)); + if ( (sa = ifi->ifi_brdaddr) != NULL) + printf(" broadcast addr: %s\n", Sock_ntop(sa, sa->sa_len)); + if ( (sa = ifi->ifi_dstaddr) != NULL) + printf(" destination addr: %s\n", Sock_ntop(sa, sa->sa_len)); + } + free_ifi_info(ifihead); + exit(0); +} diff --git a/route/prifname.c b/route/prifname.c new file mode 100644 index 0000000..3cfd820 --- /dev/null +++ b/route/prifname.c @@ -0,0 +1,13 @@ +#include "unpifi.h" + +int +main(int argc, char **argv) +{ + char name[16]; + + if (argc != 2) + err_quit("usage: prifname "); + + printf("interface name = %s\n", If_indextoname(atoi(argv[1]), name)); + exit(0); +} diff --git a/route/prifnameindex.c b/route/prifnameindex.c new file mode 100644 index 0000000..f67a0e1 --- /dev/null +++ b/route/prifnameindex.c @@ -0,0 +1,41 @@ +#include "unpifi.h" + +int +main(int argc, char **argv) +{ + int n; + char ifname[IFNAMSIZ]; + struct if_nameindex *ifptr, *save; + + if (argc != 1) + err_quit("usage: prifnameindex"); + + /* print all the interface names and indexes */ + for (save = ifptr = If_nameindex(); ifptr->if_index > 0; ifptr++) { + printf("name = %s, index = %d\n", ifptr->if_name, ifptr->if_index);; + + if ( (n = If_nametoindex(ifptr->if_name)) != ifptr->if_index) + err_quit("if_nametoindex returned %d, expected %d, for %s", + n, ifptr->if_index, ifptr->if_name); + + If_indextoname(ifptr->if_index, ifname); + if (strcmp(ifname, ifptr->if_name) != 0) + err_quit("if_indextoname returned %s, expected %s, for %d", + ifname, ifptr->if_name, ifptr->if_index); + } + + n = if_nametoindex("fkjhkjhgjhgjhgdjhguyetiuyiuyhkjhkjdh"); + if (n != 0) + err_quit("if_nametoindex returned %d for fkjh...", n); + n = if_nametoindex(""); + if (n != 0) + err_quit("if_nametoindex returned %d for (null)", n); + + if (if_indextoname(0, ifname) != NULL) + err_quit("if_indextoname error for 0"); + if (if_indextoname(888888, ifname) != NULL) + err_quit("if_indextoname error for 888888"); + + if_freenameindex(save); + exit(0); +} diff --git a/route/unproute.h b/route/unproute.h new file mode 100644 index 0000000..3043c63 --- /dev/null +++ b/route/unproute.h @@ -0,0 +1,20 @@ +#include "unp.h" +#include /* if_msghdr{} */ +#include /* sockaddr_sdl{} */ +#include /* RTA_xxx constants */ +#include + +#ifdef HAVE_SYS_SYSCTL_H +#include /* sysctl() */ +#endif + + /* function prototypes */ +void get_rtaddrs(int, struct sockaddr *, struct sockaddr **); +char *net_rt_iflist(int, int, size_t *); +char *net_rt_dump(int, int, size_t *); +char *sock_masktop(struct sockaddr *, socklen_t); + + /* wrapper functions */ +char *Net_rt_iflist(int, int, size_t *); +char *Net_rt_dump(int, int, size_t *); +#define Sock_masktop(a,b) sock_masktop((a), (b)) diff --git a/rtt/Makefile b/rtt/Makefile new file mode 100644 index 0000000..9a4d923 --- /dev/null +++ b/rtt/Makefile @@ -0,0 +1,11 @@ +include ../Make.defines + +PROGS = udpcli01 + +all: ${PROGS} + +udpcli01: udpcli01.o dg_cli.o dg_send_recv.o + ${CC} ${CFLAGS} -o $@ udpcli01.o dg_cli.o dg_send_recv.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/rtt/dg_cli.c b/rtt/dg_cli.c new file mode 100644 index 0000000..4088036 --- /dev/null +++ b/rtt/dg_cli.c @@ -0,0 +1,20 @@ +#include "unp.h" + +ssize_t Dg_send_recv(int, const void *, size_t, void *, size_t, + const SA *, socklen_t); + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + ssize_t n; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + n = Dg_send_recv(sockfd, sendline, strlen(sendline), + recvline, MAXLINE, pservaddr, servlen); + + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } +} diff --git a/rtt/dg_cli.lc b/rtt/dg_cli.lc new file mode 100644 index 0000000..f279a61 --- /dev/null +++ b/rtt/dg_cli.lc @@ -0,0 +1,20 @@ +#include "unp.h"## 1 ##src/rtt/dg_cli.c## + +ssize_t Dg_send_recv(int, const void *, size_t, void *, size_t,## 2 ##src/rtt/dg_cli.c## + const SA *, socklen_t);## 3 ##src/rtt/dg_cli.c## + +void## 4 ##src/rtt/dg_cli.c## +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)## 5 ##src/rtt/dg_cli.c## +{## 6 ##src/rtt/dg_cli.c## + ssize_t n;## 7 ##src/rtt/dg_cli.c## + char sendline[MAXLINE], recvline[MAXLINE + 1];## 8 ##src/rtt/dg_cli.c## + + while (Fgets(sendline, MAXLINE, fp) != NULL) {## 9 ##src/rtt/dg_cli.c## + + n = Dg_send_recv(sockfd, sendline, strlen(sendline),## 10 ##src/rtt/dg_cli.c## + recvline, MAXLINE, pservaddr, servlen);## 11 ##src/rtt/dg_cli.c## + + recvline[n] = 0; /* null terminate */## 12 ##src/rtt/dg_cli.c## + Fputs(recvline, stdout);## 13 ##src/rtt/dg_cli.c## + }## 14 ##src/rtt/dg_cli.c## +}## 15 ##src/rtt/dg_cli.c## diff --git a/rtt/dg_echo.c b/rtt/dg_echo.c new file mode 100644 index 0000000..1a92230 --- /dev/null +++ b/rtt/dg_echo.c @@ -0,0 +1,16 @@ +#include "unp.h" + +void +dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen) +{ + int n; + socklen_t len; + char mesg[MAXLINE]; + + for ( ; ; ) { + len = clilen; + n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len); + + Sendto(sockfd, mesg, n, 0, pcliaddr, clilen); + } +} diff --git a/rtt/dg_send_recv.c b/rtt/dg_send_recv.c new file mode 100644 index 0000000..2a2e914 --- /dev/null +++ b/rtt/dg_send_recv.c @@ -0,0 +1,115 @@ +/* include dgsendrecv1 */ +#include "unprtt.h" +#include + +#define RTT_DEBUG + +static struct rtt_info rttinfo; +static int rttinit = 0; +static struct msghdr msgsend, msgrecv; /* assumed init to 0 */ +static struct hdr { + uint32_t seq; /* sequence # */ + uint32_t ts; /* timestamp when sent */ +} sendhdr, recvhdr; + +static void sig_alrm(int signo); +static sigjmp_buf jmpbuf; + +ssize_t +dg_send_recv(int fd, const void *outbuff, size_t outbytes, + void *inbuff, size_t inbytes, + const SA *destaddr, socklen_t destlen) +{ + ssize_t n; + struct iovec iovsend[2], iovrecv[2]; + + if (rttinit == 0) { + rtt_init(&rttinfo); /* first time we're called */ + rttinit = 1; + rtt_d_flag = 1; + } + + sendhdr.seq++; + msgsend.msg_name = destaddr; + msgsend.msg_namelen = destlen; + msgsend.msg_iov = iovsend; + msgsend.msg_iovlen = 2; + iovsend[0].iov_base = &sendhdr; + iovsend[0].iov_len = sizeof(struct hdr); + iovsend[1].iov_base = outbuff; + iovsend[1].iov_len = outbytes; + + msgrecv.msg_name = NULL; + msgrecv.msg_namelen = 0; + msgrecv.msg_iov = iovrecv; + msgrecv.msg_iovlen = 2; + iovrecv[0].iov_base = &recvhdr; + iovrecv[0].iov_len = sizeof(struct hdr); + iovrecv[1].iov_base = inbuff; + iovrecv[1].iov_len = inbytes; +/* end dgsendrecv1 */ + +/* include dgsendrecv2 */ + Signal(SIGALRM, sig_alrm); + rtt_newpack(&rttinfo); /* initialize for this packet */ + +sendagain: +#ifdef RTT_DEBUG + fprintf(stderr, "send %4d: ", sendhdr.seq); +#endif + sendhdr.ts = rtt_ts(&rttinfo); + Sendmsg(fd, &msgsend, 0); + + alarm(rtt_start(&rttinfo)); /* calc timeout value & start timer */ +#ifdef RTT_DEBUG + rtt_debug(&rttinfo); +#endif + + if (sigsetjmp(jmpbuf, 1) != 0) { + if (rtt_timeout(&rttinfo) < 0) { + err_msg("dg_send_recv: no response from server, giving up"); + rttinit = 0; /* reinit in case we're called again */ + errno = ETIMEDOUT; + return(-1); + } +#ifdef RTT_DEBUG + err_msg("dg_send_recv: timeout, retransmitting"); +#endif + goto sendagain; + } + + do { + n = Recvmsg(fd, &msgrecv, 0); +#ifdef RTT_DEBUG + fprintf(stderr, "recv %4d\n", recvhdr.seq); +#endif + } while (n < sizeof(struct hdr) || recvhdr.seq != sendhdr.seq); + + alarm(0); /* stop SIGALRM timer */ + /* 4calculate & store new RTT estimator values */ + rtt_stop(&rttinfo, rtt_ts(&rttinfo) - recvhdr.ts); + + return(n - sizeof(struct hdr)); /* return size of received datagram */ +} + +static void +sig_alrm(int signo) +{ + siglongjmp(jmpbuf, 1); +} +/* end dgsendrecv2 */ + +ssize_t +Dg_send_recv(int fd, const void *outbuff, size_t outbytes, + void *inbuff, size_t inbytes, + const SA *destaddr, socklen_t destlen) +{ + ssize_t n; + + n = dg_send_recv(fd, outbuff, outbytes, inbuff, inbytes, + destaddr, destlen); + if (n < 0) + err_quit("dg_send_recv error"); + + return(n); +} diff --git a/rtt/dg_send_recv.lc b/rtt/dg_send_recv.lc new file mode 100644 index 0000000..281277a --- /dev/null +++ b/rtt/dg_send_recv.lc @@ -0,0 +1,103 @@ +/* include dgsendrecv1 */ +#include "unprtt.h"## 1 ##src/rtt/dg_send_recv.c## +#include ## 2 ##src/rtt/dg_send_recv.c## + +#define RTT_DEBUG## 3 ##src/rtt/dg_send_recv.c## + +static struct rtt_info rttinfo;## 4 ##src/rtt/dg_send_recv.c## +static int rttinit = 0;## 5 ##src/rtt/dg_send_recv.c## +static struct msghdr msgsend, msgrecv; /* assumed init to 0 */## 6 ##src/rtt/dg_send_recv.c## +static struct hdr {## 7 ##src/rtt/dg_send_recv.c## + uint32_t seq; /* sequence # */## 8 ##src/rtt/dg_send_recv.c## + uint32_t ts; /* timestamp when sent */## 9 ##src/rtt/dg_send_recv.c## +} sendhdr, recvhdr;## 10 ##src/rtt/dg_send_recv.c## + +static void sig_alrm(int signo);## 11 ##src/rtt/dg_send_recv.c## +static sigjmp_buf jmpbuf;## 12 ##src/rtt/dg_send_recv.c## + +ssize_t## 13 ##src/rtt/dg_send_recv.c## +dg_send_recv(int fd, const void *outbuff, size_t outbytes,## 14 ##src/rtt/dg_send_recv.c## + void *inbuff, size_t inbytes,## 15 ##src/rtt/dg_send_recv.c## + const SA *destaddr, socklen_t destlen)## 16 ##src/rtt/dg_send_recv.c## +{## 17 ##src/rtt/dg_send_recv.c## + ssize_t n;## 18 ##src/rtt/dg_send_recv.c## + struct iovec iovsend[2], iovrecv[2];## 19 ##src/rtt/dg_send_recv.c## + + if (rttinit == 0) {## 20 ##src/rtt/dg_send_recv.c## + rtt_init(&rttinfo); /* first time we're called */## 21 ##src/rtt/dg_send_recv.c## + rttinit = 1;## 22 ##src/rtt/dg_send_recv.c## + rtt_d_flag = 1;## 23 ##src/rtt/dg_send_recv.c## + }## 24 ##src/rtt/dg_send_recv.c## + + sendhdr.seq++;## 25 ##src/rtt/dg_send_recv.c## + msgsend.msg_name = destaddr;## 26 ##src/rtt/dg_send_recv.c## + msgsend.msg_namelen = destlen;## 27 ##src/rtt/dg_send_recv.c## + msgsend.msg_iov = iovsend;## 28 ##src/rtt/dg_send_recv.c## + msgsend.msg_iovlen = 2;## 29 ##src/rtt/dg_send_recv.c## + iovsend[0].iov_base = &sendhdr;## 30 ##src/rtt/dg_send_recv.c## + iovsend[0].iov_len = sizeof(struct hdr);## 31 ##src/rtt/dg_send_recv.c## + iovsend[1].iov_base = outbuff;## 32 ##src/rtt/dg_send_recv.c## + iovsend[1].iov_len = outbytes;## 33 ##src/rtt/dg_send_recv.c## + + msgrecv.msg_name = NULL;## 34 ##src/rtt/dg_send_recv.c## + msgrecv.msg_namelen = 0;## 35 ##src/rtt/dg_send_recv.c## + msgrecv.msg_iov = iovrecv;## 36 ##src/rtt/dg_send_recv.c## + msgrecv.msg_iovlen = 2;## 37 ##src/rtt/dg_send_recv.c## + iovrecv[0].iov_base = &recvhdr;## 38 ##src/rtt/dg_send_recv.c## + iovrecv[0].iov_len = sizeof(struct hdr);## 39 ##src/rtt/dg_send_recv.c## + iovrecv[1].iov_base = inbuff;## 40 ##src/rtt/dg_send_recv.c## + iovrecv[1].iov_len = inbytes;## 41 ##src/rtt/dg_send_recv.c## +/* end dgsendrecv1 */ + +/* include dgsendrecv2 */ + Signal(SIGALRM, sig_alrm);## 42 ##src/rtt/dg_send_recv.c## + rtt_newpack(&rttinfo); /* initialize for this packet */## 43 ##src/rtt/dg_send_recv.c## + + sendagain:## 44 ##src/rtt/dg_send_recv.c## + sendhdr.ts = rtt_ts(&rttinfo);## 45 ##src/rtt/dg_send_recv.c## + Sendmsg(fd, &msgsend, 0);## 46 ##src/rtt/dg_send_recv.c## + + alarm(rtt_start(&rttinfo)); /* calc timeout value & start timer */## 47 ##src/rtt/dg_send_recv.c## + + if (sigsetjmp(jmpbuf, 1) != 0) {## 48 ##src/rtt/dg_send_recv.c## + if (rtt_timeout(&rttinfo) < 0) {## 49 ##src/rtt/dg_send_recv.c## + err_msg("dg_send_recv: no response from server, giving up");## 50 ##src/rtt/dg_send_recv.c## + rttinit = 0; /* reinit in case we're called again */## 51 ##src/rtt/dg_send_recv.c## + errno = ETIMEDOUT;## 52 ##src/rtt/dg_send_recv.c## + return (-1);## 53 ##src/rtt/dg_send_recv.c## + }## 54 ##src/rtt/dg_send_recv.c## + goto sendagain;## 55 ##src/rtt/dg_send_recv.c## + }## 56 ##src/rtt/dg_send_recv.c## + + do {## 57 ##src/rtt/dg_send_recv.c## + n = Recvmsg(fd, &msgrecv, 0);## 58 ##src/rtt/dg_send_recv.c## + } while (n < sizeof(struct hdr) || recvhdr.seq != sendhdr.seq);## 59 ##src/rtt/dg_send_recv.c## + + alarm(0); /* stop SIGALRM timer */## 60 ##src/rtt/dg_send_recv.c## + /* 4calculate & store new RTT estimator values */## 61 ##src/rtt/dg_send_recv.c## + rtt_stop(&rttinfo, rtt_ts(&rttinfo) - recvhdr.ts);## 62 ##src/rtt/dg_send_recv.c## + + return (n - sizeof(struct hdr)); /* return size of received datagram */## 63 ##src/rtt/dg_send_recv.c## +}## 64 ##src/rtt/dg_send_recv.c## + +static void## 65 ##src/rtt/dg_send_recv.c## +sig_alrm(int signo)## 66 ##src/rtt/dg_send_recv.c## +{## 67 ##src/rtt/dg_send_recv.c## + siglongjmp(jmpbuf, 1);## 68 ##src/rtt/dg_send_recv.c## +}## 69 ##src/rtt/dg_send_recv.c## +/* end dgsendrecv2 */ + +ssize_t## 70 ##src/rtt/dg_send_recv.c## +Dg_send_recv(int fd, const void *outbuff, size_t outbytes,## 71 ##src/rtt/dg_send_recv.c## + void *inbuff, size_t inbytes,## 72 ##src/rtt/dg_send_recv.c## + const SA *destaddr, socklen_t destlen)## 73 ##src/rtt/dg_send_recv.c## +{## 74 ##src/rtt/dg_send_recv.c## + ssize_t n;## 75 ##src/rtt/dg_send_recv.c## + + n = dg_send_recv(fd, outbuff, outbytes, inbuff, inbytes,## 76 ##src/rtt/dg_send_recv.c## + destaddr, destlen);## 77 ##src/rtt/dg_send_recv.c## + if (n < 0)## 78 ##src/rtt/dg_send_recv.c## + err_quit("dg_send_recv error");## 79 ##src/rtt/dg_send_recv.c## + + return (n);## 80 ##src/rtt/dg_send_recv.c## +}## 81 ##src/rtt/dg_send_recv.c## diff --git a/rtt/rtt.out.kumba.1 b/rtt/rtt.out.kumba.1 new file mode 100644 index 0000000..1d65120 --- /dev/null +++ b/rtt/rtt.out.kumba.1 @@ -0,0 +1,1516 @@ +send 1: rtt = 0.000, srtt = 0.000, rttvar = 0.750, rto = 3.000 +recv 1 +updated rto +send 2: rtt = 0.366, srtt = 0.046, rttvar = 0.654, rto = 2.662 +recv 2 +updated rto +send 3: rtt = 0.309, srtt = 0.079, rttvar = 0.556, rto = 2.304 +recv 3 +updated rto +send 4: rtt = 0.298, srtt = 0.106, rttvar = 0.472, rto = 2.000 +recv 4 +updated rto +send 5: rtt = 0.360, srtt = 0.138, rttvar = 0.418, rto = 2.000 +recv 5 +updated rto +send 6: rtt = 0.360, srtt = 0.166, rttvar = 0.369, rto = 2.000 +recv 6 +updated rto +send 7: rtt = 0.320, srtt = 0.185, rttvar = 0.315, rto = 2.000 +recv 7 +updated rto +send 8: rtt = 0.340, srtt = 0.204, rttvar = 0.275, rto = 2.000 +recv 8 +updated rto +send 9: rtt = 0.330, srtt = 0.220, rttvar = 0.238, rto = 2.000 +recv 9 +updated rto +send 10: rtt = 0.350, srtt = 0.236, rttvar = 0.211, rto = 2.000 +recv 10 +updated rto +send 11: rtt = 0.349, srtt = 0.250, rttvar = 0.186, rto = 2.000 +recv 11 +updated rto +send 12: rtt = 0.380, srtt = 0.267, rttvar = 0.172, rto = 2.000 +recv 12 +updated rto +send 13: rtt = 0.349, srtt = 0.277, rttvar = 0.150, rto = 2.000 +recv 13 +updated rto +send 14: rtt = 0.340, srtt = 0.285, rttvar = 0.128, rto = 2.000 +recv 14 +updated rto +send 15: rtt = 0.280, srtt = 0.284, rttvar = 0.097, rto = 2.000 +recv 15 +updated rto +send 16: rtt = 0.330, srtt = 0.290, rttvar = 0.084, rto = 2.000 +recv 16 +updated rto +send 17: rtt = 0.340, srtt = 0.296, rttvar = 0.076, rto = 2.000 +recv 17 +updated rto +send 18: rtt = 0.340, srtt = 0.302, rttvar = 0.068, rto = 2.000 +recv 18 +updated rto +send 19: rtt = 0.349, srtt = 0.308, rttvar = 0.063, rto = 2.000 +recv 19 +updated rto +send 20: rtt = 0.310, srtt = 0.308, rttvar = 0.048, rto = 2.000 +recv 20 +updated rto +send 21: rtt = 0.350, srtt = 0.313, rttvar = 0.046, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 21: rtt = 0.350, srtt = 0.313, rttvar = 0.046, rto = 4.000 +recv 21 +updated rto +send 22: rtt = 0.340, srtt = 0.316, rttvar = 0.041, rto = 2.000 +recv 22 +updated rto +send 23: rtt = 0.350, srtt = 0.321, rttvar = 0.039, rto = 2.000 +recv 23 +updated rto +send 24: rtt = 0.319, srtt = 0.320, rttvar = 0.030, rto = 2.000 +recv 24 +updated rto +send 25: rtt = 0.360, srtt = 0.325, rttvar = 0.032, rto = 2.000 +recv 25 +updated rto +send 26: rtt = 0.290, srtt = 0.321, rttvar = 0.033, rto = 2.000 +recv 26 +updated rto +send 27: rtt = 0.310, srtt = 0.320, rttvar = 0.028, rto = 2.000 +recv 27 +updated rto +send 28: rtt = 0.340, srtt = 0.322, rttvar = 0.026, rto = 2.000 +recv 28 +updated rto +send 29: rtt = 0.371, srtt = 0.328, rttvar = 0.032, rto = 2.000 +recv 29 +updated rto +send 30: rtt = 0.368, srtt = 0.333, rttvar = 0.034, rto = 2.000 +recv 30 +updated rto +send 31: rtt = 0.350, srtt = 0.335, rttvar = 0.029, rto = 2.000 +recv 31 +updated rto +send 32: rtt = 0.364, srtt = 0.339, rttvar = 0.029, rto = 2.000 +recv 32 +updated rto +send 33: rtt = 0.335, srtt = 0.338, rttvar = 0.023, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 33: rtt = 0.335, srtt = 0.338, rttvar = 0.023, rto = 4.000 +recv 33 +updated rto +send 34: rtt = 0.330, srtt = 0.337, rttvar = 0.019, rto = 2.000 +recv 34 +updated rto +send 35: rtt = 0.290, srtt = 0.331, rttvar = 0.026, rto = 2.000 +recv 35 +updated rto +send 36: rtt = 0.390, srtt = 0.339, rttvar = 0.034, rto = 2.000 +recv 36 +updated rto +send 37: rtt = 0.355, srtt = 0.341, rttvar = 0.030, rto = 2.000 +recv 37 +updated rto +send 38: rtt = 0.334, srtt = 0.340, rttvar = 0.024, rto = 2.000 +recv 38 +updated rto +send 39: rtt = 0.320, srtt = 0.337, rttvar = 0.023, rto = 2.000 +recv 39 +updated rto +send 40: rtt = 0.344, srtt = 0.338, rttvar = 0.019, rto = 2.000 +recv 40 +updated rto +send 41: rtt = 0.345, srtt = 0.339, rttvar = 0.016, rto = 2.000 +recv 41 +updated rto +send 42: rtt = 0.349, srtt = 0.340, rttvar = 0.014, rto = 2.000 +recv 42 +updated rto +send 43: rtt = 0.305, srtt = 0.336, rttvar = 0.020, rto = 2.000 +recv 43 +updated rto +send 44: rtt = 0.284, srtt = 0.329, rttvar = 0.028, rto = 2.000 +recv 44 +updated rto +send 45: rtt = 0.320, srtt = 0.328, rttvar = 0.023, rto = 2.000 +recv 45 +updated rto +send 46: rtt = 0.320, srtt = 0.327, rttvar = 0.019, rto = 2.000 +recv 46 +updated rto +send 47: rtt = 0.340, srtt = 0.329, rttvar = 0.018, rto = 2.000 +recv 47 +updated rto +send 48: rtt = 0.309, srtt = 0.326, rttvar = 0.018, rto = 2.000 +recv 48 +updated rto +send 49: rtt = 0.310, srtt = 0.324, rttvar = 0.018, rto = 2.000 +recv 49 +updated rto +send 50: rtt = 0.320, srtt = 0.324, rttvar = 0.014, rto = 2.000 +recv 50 +updated rto +send 51: rtt = 0.320, srtt = 0.323, rttvar = 0.012, rto = 2.000 +recv 51 +updated rto +send 52: rtt = 0.300, srtt = 0.320, rttvar = 0.015, rto = 2.000 +recv 52 +updated rto +send 53: rtt = 0.320, srtt = 0.320, rttvar = 0.011, rto = 2.000 +recv 53 +updated rto +send 54: rtt = 0.350, srtt = 0.324, rttvar = 0.016, rto = 2.000 +recv 54 +updated rto +send 55: rtt = 0.349, srtt = 0.327, rttvar = 0.018, rto = 2.000 +recv 55 +updated rto +send 56: rtt = 0.339, srtt = 0.329, rttvar = 0.016, rto = 2.000 +recv 56 +updated rto +send 57: rtt = 0.350, srtt = 0.331, rttvar = 0.018, rto = 2.000 +recv 57 +updated rto +send 58: rtt = 0.319, srtt = 0.330, rttvar = 0.016, rto = 2.000 +recv 58 +updated rto +send 59: rtt = 0.309, srtt = 0.327, rttvar = 0.017, rto = 2.000 +recv 59 +updated rto +send 60: rtt = 0.310, srtt = 0.325, rttvar = 0.017, rto = 2.000 +recv 60 +updated rto +send 61: rtt = 0.320, srtt = 0.324, rttvar = 0.014, rto = 2.000 +recv 61 +updated rto +send 62: rtt = 0.300, srtt = 0.321, rttvar = 0.017, rto = 2.000 +recv 62 +updated rto +send 63: rtt = 0.309, srtt = 0.320, rttvar = 0.016, rto = 2.000 +recv 63 +updated rto +send 64: rtt = 0.290, srtt = 0.316, rttvar = 0.019, rto = 2.000 +recv 64 +updated rto +send 65: rtt = 0.320, srtt = 0.317, rttvar = 0.015, rto = 2.000 +recv 65 +updated rto +send 66: rtt = 0.280, srtt = 0.312, rttvar = 0.021, rto = 2.000 +recv 66 +updated rto +send 67: rtt = 0.339, srtt = 0.315, rttvar = 0.022, rto = 2.000 +recv 67 +updated rto +send 68: rtt = 0.330, srtt = 0.317, rttvar = 0.020, rto = 2.000 +recv 68 +updated rto +send 69: rtt = 0.320, srtt = 0.318, rttvar = 0.016, rto = 2.000 +recv 69 +updated rto +send 70: rtt = 0.280, srtt = 0.313, rttvar = 0.021, rto = 2.000 +recv 70 +updated rto +send 71: rtt = 0.319, srtt = 0.314, rttvar = 0.018, rto = 2.000 +recv 71 +updated rto +send 72: rtt = 0.339, srtt = 0.317, rttvar = 0.020, rto = 2.000 +recv 72 +updated rto +send 73: rtt = 0.309, srtt = 0.316, rttvar = 0.017, rto = 2.000 +recv 73 +updated rto +send 74: rtt = 0.340, srtt = 0.319, rttvar = 0.018, rto = 2.000 +recv 74 +updated rto +send 75: rtt = 0.330, srtt = 0.320, rttvar = 0.017, rto = 2.000 +recv 75 +updated rto +send 76: rtt = 0.280, srtt = 0.315, rttvar = 0.023, rto = 2.000 +recv 76 +updated rto +send 77: rtt = 0.320, srtt = 0.316, rttvar = 0.018, rto = 2.000 +recv 77 +updated rto +send 78: rtt = 0.280, srtt = 0.311, rttvar = 0.023, rto = 2.000 +recv 78 +updated rto +send 79: rtt = 0.330, srtt = 0.314, rttvar = 0.022, rto = 2.000 +recv 79 +updated rto +send 80: rtt = 0.349, srtt = 0.318, rttvar = 0.025, rto = 2.000 +recv 80 +updated rto +send 81: rtt = 0.320, srtt = 0.318, rttvar = 0.019, rto = 2.000 +recv 81 +updated rto +send 82: rtt = 0.320, srtt = 0.319, rttvar = 0.015, rto = 2.000 +recv 82 +updated rto +send 83: rtt = 0.329, srtt = 0.320, rttvar = 0.014, rto = 2.000 +recv 83 +updated rto +send 84: rtt = 0.320, srtt = 0.320, rttvar = 0.010, rto = 2.000 +recv 84 +updated rto +send 85: rtt = 0.329, srtt = 0.321, rttvar = 0.010, rto = 2.000 +recv 85 +updated rto +send 86: rtt = 0.330, srtt = 0.322, rttvar = 0.010, rto = 2.000 +recv 86 +updated rto +send 87: rtt = 0.339, srtt = 0.324, rttvar = 0.012, rto = 2.000 +recv 87 +updated rto +send 88: rtt = 0.360, srtt = 0.329, rttvar = 0.018, rto = 2.000 +recv 88 +updated rto +send 89: rtt = 0.320, srtt = 0.328, rttvar = 0.015, rto = 2.000 +recv 89 +updated rto +send 90: rtt = 0.319, srtt = 0.327, rttvar = 0.014, rto = 2.000 +recv 90 +updated rto +send 91: rtt = 0.330, srtt = 0.327, rttvar = 0.011, rto = 2.000 +recv 91 +updated rto +send 92: rtt = 0.304, srtt = 0.324, rttvar = 0.014, rto = 2.000 +recv 92 +updated rto +send 93: rtt = 0.316, srtt = 0.323, rttvar = 0.013, rto = 2.000 +recv 93 +updated rto +send 94: rtt = 0.319, srtt = 0.323, rttvar = 0.010, rto = 2.000 +recv 94 +updated rto +send 95: rtt = 0.360, srtt = 0.327, rttvar = 0.017, rto = 2.000 +recv 95 +updated rto +send 96: rtt = 0.316, srtt = 0.326, rttvar = 0.016, rto = 2.000 +recv 96 +updated rto +send 97: rtt = 0.314, srtt = 0.324, rttvar = 0.015, rto = 2.000 +recv 97 +updated rto +send 98: rtt = 0.330, srtt = 0.325, rttvar = 0.012, rto = 2.000 +recv 98 +updated rto +send 99: rtt = 0.330, srtt = 0.326, rttvar = 0.011, rto = 2.000 +recv 99 +updated rto +send 100: rtt = 0.360, srtt = 0.330, rttvar = 0.017, rto = 2.000 +recv 100 +updated rto +send 101: rtt = 0.330, srtt = 0.330, rttvar = 0.012, rto = 2.000 +recv 101 +updated rto +send 102: rtt = 0.350, srtt = 0.332, rttvar = 0.014, rto = 2.000 +recv 102 +updated rto +send 103: rtt = 0.320, srtt = 0.331, rttvar = 0.014, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 103: rtt = 0.320, srtt = 0.331, rttvar = 0.014, rto = 4.000 +recv 103 +updated rto +send 104: rtt = 0.340, srtt = 0.332, rttvar = 0.013, rto = 2.000 +recv 104 +updated rto +send 105: rtt = 0.340, srtt = 0.333, rttvar = 0.011, rto = 2.000 +recv 105 +updated rto +send 106: rtt = 0.320, srtt = 0.331, rttvar = 0.012, rto = 2.000 +recv 106 +updated rto +send 107: rtt = 0.340, srtt = 0.332, rttvar = 0.011, rto = 2.000 +recv 107 +updated rto +send 108: rtt = 0.340, srtt = 0.333, rttvar = 0.010, rto = 2.000 +recv 108 +updated rto +send 109: rtt = 0.340, srtt = 0.334, rttvar = 0.009, rto = 2.000 +recv 109 +updated rto +send 110: rtt = 0.369, srtt = 0.339, rttvar = 0.016, rto = 2.000 +recv 110 +updated rto +send 111: rtt = 0.350, srtt = 0.340, rttvar = 0.015, rto = 2.000 +recv 111 +updated rto +send 112: rtt = 0.369, srtt = 0.344, rttvar = 0.018, rto = 2.000 +recv 112 +updated rto +send 113: rtt = 0.339, srtt = 0.343, rttvar = 0.015, rto = 2.000 +recv 113 +updated rto +send 114: rtt = 0.349, srtt = 0.344, rttvar = 0.013, rto = 2.000 +recv 114 +updated rto +send 115: rtt = 0.319, srtt = 0.341, rttvar = 0.016, rto = 2.000 +recv 115 +updated rto +send 116: rtt = 0.340, srtt = 0.341, rttvar = 0.012, rto = 2.000 +recv 116 +updated rto +send 117: rtt = 0.319, srtt = 0.338, rttvar = 0.014, rto = 2.000 +recv 117 +updated rto +send 118: rtt = 0.340, srtt = 0.338, rttvar = 0.011, rto = 2.000 +recv 118 +updated rto +send 119: rtt = 0.380, srtt = 0.343, rttvar = 0.019, rto = 2.000 +recv 119 +updated rto +send 120: rtt = 0.340, srtt = 0.343, rttvar = 0.015, rto = 2.000 +recv 120 +updated rto +send 121: rtt = 0.320, srtt = 0.340, rttvar = 0.017, rto = 2.000 +recv 121 +updated rto +send 122: rtt = 0.340, srtt = 0.340, rttvar = 0.013, rto = 2.000 +recv 122 +updated rto +send 123: rtt = 0.360, srtt = 0.343, rttvar = 0.015, rto = 2.000 +recv 123 +updated rto +send 124: rtt = 0.359, srtt = 0.345, rttvar = 0.015, rto = 2.000 +recv 124 +updated rto +send 125: rtt = 0.330, srtt = 0.343, rttvar = 0.015, rto = 2.000 +recv 125 +updated rto +send 126: rtt = 0.329, srtt = 0.341, rttvar = 0.015, rto = 2.000 +recv 126 +updated rto +send 127: rtt = 0.340, srtt = 0.341, rttvar = 0.011, rto = 2.000 +recv 127 +updated rto +send 128: rtt = 0.360, srtt = 0.343, rttvar = 0.013, rto = 2.000 +recv 128 +updated rto +send 129: rtt = 0.320, srtt = 0.340, rttvar = 0.016, rto = 2.000 +recv 129 +updated rto +send 130: rtt = 0.340, srtt = 0.340, rttvar = 0.012, rto = 2.000 +recv 130 +updated rto +send 131: rtt = 0.350, srtt = 0.342, rttvar = 0.011, rto = 2.000 +recv 131 +updated rto +send 132: rtt = 0.340, srtt = 0.341, rttvar = 0.009, rto = 2.000 +recv 132 +updated rto +send 133: rtt = 0.370, srtt = 0.345, rttvar = 0.014, rto = 2.000 +recv 133 +updated rto +send 134: rtt = 0.339, srtt = 0.344, rttvar = 0.012, rto = 2.000 +recv 134 +updated rto +send 135: rtt = 0.330, srtt = 0.342, rttvar = 0.012, rto = 2.000 +recv 135 +updated rto +send 136: rtt = 0.340, srtt = 0.342, rttvar = 0.010, rto = 2.000 +recv 136 +updated rto +send 137: rtt = 0.300, srtt = 0.337, rttvar = 0.018, rto = 2.000 +recv 137 +updated rto +send 138: rtt = 0.340, srtt = 0.337, rttvar = 0.014, rto = 2.000 +recv 138 +updated rto +send 139: rtt = 0.340, srtt = 0.338, rttvar = 0.011, rto = 2.000 +recv 139 +updated rto +send 140: rtt = 0.380, srtt = 0.343, rttvar = 0.019, rto = 2.000 +recv 140 +updated rto +send 141: rtt = 0.450, srtt = 0.356, rttvar = 0.041, rto = 2.000 +recv 141 +updated rto +send 142: rtt = 0.370, srtt = 0.358, rttvar = 0.034, rto = 2.000 +recv 142 +updated rto +send 143: rtt = 0.309, srtt = 0.352, rttvar = 0.038, rto = 2.000 +recv 143 +updated rto +send 144: rtt = 0.290, srtt = 0.344, rttvar = 0.044, rto = 2.000 +recv 144 +updated rto +send 145: rtt = 0.390, srtt = 0.350, rttvar = 0.044, rto = 2.000 +recv 145 +updated rto +send 146: rtt = 0.329, srtt = 0.347, rttvar = 0.039, rto = 2.000 +recv 146 +updated rto +send 147: rtt = 0.330, srtt = 0.345, rttvar = 0.033, rto = 2.000 +recv 147 +updated rto +send 148: rtt = 0.320, srtt = 0.342, rttvar = 0.031, rto = 2.000 +recv 148 +updated rto +send 149: rtt = 0.340, srtt = 0.342, rttvar = 0.024, rto = 2.000 +recv 149 +updated rto +send 150: rtt = 0.359, srtt = 0.344, rttvar = 0.022, rto = 2.000 +recv 150 +updated rto +send 151: rtt = 0.350, srtt = 0.345, rttvar = 0.018, rto = 2.000 +recv 151 +updated rto +send 152: rtt = 0.349, srtt = 0.345, rttvar = 0.015, rto = 2.000 +recv 152 +updated rto +send 153: rtt = 0.400, srtt = 0.352, rttvar = 0.025, rto = 2.000 +recv 153 +updated rto +send 154: rtt = 0.350, srtt = 0.352, rttvar = 0.019, rto = 2.000 +recv 154 +updated rto +send 155: rtt = 0.370, srtt = 0.354, rttvar = 0.019, rto = 2.000 +recv 155 +updated rto +send 156: rtt = 0.359, srtt = 0.355, rttvar = 0.015, rto = 2.000 +recv 156 +updated rto +send 157: rtt = 0.349, srtt = 0.354, rttvar = 0.013, rto = 2.000 +recv 157 +updated rto +send 158: rtt = 0.360, srtt = 0.355, rttvar = 0.011, rto = 2.000 +recv 158 +updated rto +send 159: rtt = 0.319, srtt = 0.350, rttvar = 0.017, rto = 2.000 +recv 159 +updated rto +send 160: rtt = 0.320, srtt = 0.346, rttvar = 0.021, rto = 2.000 +recv 160 +updated rto +send 161: rtt = 0.330, srtt = 0.344, rttvar = 0.020, rto = 2.000 +recv 161 +updated rto +send 162: rtt = 0.340, srtt = 0.344, rttvar = 0.016, rto = 2.000 +recv 162 +updated rto +send 163: rtt = 0.350, srtt = 0.345, rttvar = 0.013, rto = 2.000 +recv 163 +updated rto +send 164: rtt = 0.350, srtt = 0.345, rttvar = 0.011, rto = 2.000 +recv 164 +updated rto +send 165: rtt = 0.339, srtt = 0.345, rttvar = 0.010, rto = 2.000 +recv 165 +updated rto +send 166: rtt = 0.339, srtt = 0.344, rttvar = 0.009, rto = 2.000 +recv 166 +updated rto +send 167: rtt = 0.330, srtt = 0.342, rttvar = 0.010, rto = 2.000 +recv 167 +updated rto +send 168: rtt = 0.310, srtt = 0.338, rttvar = 0.016, rto = 2.000 +recv 168 +updated rto +send 169: rtt = 0.310, srtt = 0.335, rttvar = 0.019, rto = 2.000 +recv 169 +updated rto +send 170: rtt = 0.320, srtt = 0.333, rttvar = 0.018, rto = 2.000 +recv 170 +updated rto +send 171: rtt = 0.339, srtt = 0.334, rttvar = 0.015, rto = 2.000 +recv 171 +updated rto +send 172: rtt = 0.320, srtt = 0.332, rttvar = 0.015, rto = 2.000 +recv 172 +updated rto +send 173: rtt = 0.319, srtt = 0.330, rttvar = 0.014, rto = 2.000 +recv 173 +updated rto +send 174: rtt = 0.320, srtt = 0.329, rttvar = 0.013, rto = 2.000 +recv 174 +updated rto +send 175: rtt = 0.319, srtt = 0.328, rttvar = 0.012, rto = 2.000 +recv 175 +updated rto +send 176: rtt = 0.309, srtt = 0.325, rttvar = 0.014, rto = 2.000 +recv 176 +updated rto +send 177: rtt = 0.340, srtt = 0.327, rttvar = 0.014, rto = 2.000 +recv 177 +updated rto +send 178: rtt = 0.334, srtt = 0.328, rttvar = 0.012, rto = 2.000 +recv 178 +updated rto +send 179: rtt = 0.315, srtt = 0.326, rttvar = 0.012, rto = 2.000 +recv 179 +updated rto +send 180: rtt = 0.309, srtt = 0.324, rttvar = 0.014, rto = 2.000 +recv 180 +updated rto +send 181: rtt = 0.309, srtt = 0.322, rttvar = 0.014, rto = 2.000 +recv 181 +updated rto +send 182: rtt = 0.330, srtt = 0.323, rttvar = 0.012, rto = 2.000 +recv 182 +updated rto +send 183: rtt = 0.370, srtt = 0.329, rttvar = 0.021, rto = 2.000 +recv 183 +updated rto +send 184: rtt = 0.320, srtt = 0.328, rttvar = 0.018, rto = 2.000 +recv 184 +updated rto +send 185: rtt = 0.380, srtt = 0.334, rttvar = 0.027, rto = 2.000 +recv 185 +updated rto +send 186: rtt = 0.350, srtt = 0.336, rttvar = 0.024, rto = 2.000 +recv 186 +updated rto +send 187: rtt = 0.309, srtt = 0.333, rttvar = 0.025, rto = 2.000 +recv 187 +updated rto +send 188: rtt = 0.330, srtt = 0.333, rttvar = 0.019, rto = 2.000 +recv 188 +updated rto +send 189: rtt = 0.320, srtt = 0.331, rttvar = 0.018, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 189: rtt = 0.320, srtt = 0.331, rttvar = 0.018, rto = 4.000 +recv 189 +updated rto +send 190: rtt = 0.329, srtt = 0.331, rttvar = 0.014, rto = 2.000 +recv 190 +updated rto +send 191: rtt = 0.310, srtt = 0.328, rttvar = 0.015, rto = 2.000 +recv 191 +updated rto +send 192: rtt = 0.319, srtt = 0.327, rttvar = 0.014, rto = 2.000 +recv 192 +updated rto +send 193: rtt = 0.310, srtt = 0.325, rttvar = 0.015, rto = 2.000 +recv 193 +updated rto +send 194: rtt = 0.300, srtt = 0.322, rttvar = 0.017, rto = 2.000 +recv 194 +updated rto +send 195: rtt = 0.309, srtt = 0.320, rttvar = 0.016, rto = 2.000 +recv 195 +updated rto +send 196: rtt = 0.319, srtt = 0.320, rttvar = 0.012, rto = 2.000 +recv 196 +updated rto +send 197: rtt = 0.310, srtt = 0.319, rttvar = 0.012, rto = 2.000 +recv 197 +updated rto +send 198: rtt = 0.309, srtt = 0.318, rttvar = 0.011, rto = 2.000 +recv 198 +updated rto +send 199: rtt = 0.330, srtt = 0.319, rttvar = 0.012, rto = 2.000 +recv 199 +updated rto +send 200: rtt = 0.299, srtt = 0.317, rttvar = 0.014, rto = 2.000 +recv 200 +updated rto +send 201: rtt = 0.310, srtt = 0.316, rttvar = 0.012, rto = 2.000 +recv 201 +updated rto +send 202: rtt = 0.354, srtt = 0.321, rttvar = 0.019, rto = 2.000 +recv 202 +updated rto +send 203: rtt = 0.312, srtt = 0.319, rttvar = 0.016, rto = 2.000 +recv 203 +updated rto +send 204: rtt = 0.303, srtt = 0.317, rttvar = 0.016, rto = 2.000 +recv 204 +updated rto +send 205: rtt = 0.329, srtt = 0.319, rttvar = 0.015, rto = 2.000 +recv 205 +updated rto +send 206: rtt = 0.319, srtt = 0.319, rttvar = 0.011, rto = 2.000 +recv 206 +updated rto +send 207: rtt = 0.339, srtt = 0.321, rttvar = 0.013, rto = 2.000 +recv 207 +updated rto +send 208: rtt = 0.310, srtt = 0.320, rttvar = 0.013, rto = 2.000 +recv 208 +updated rto +send 209: rtt = 0.321, srtt = 0.320, rttvar = 0.010, rto = 2.000 +recv 209 +updated rto +send 210: rtt = 0.308, srtt = 0.319, rttvar = 0.011, rto = 2.000 +recv 210 +updated rto +send 211: rtt = 0.350, srtt = 0.323, rttvar = 0.016, rto = 2.000 +recv 211 +updated rto +send 212: rtt = 0.359, srtt = 0.327, rttvar = 0.021, rto = 2.000 +recv 212 +updated rto +send 213: rtt = 0.310, srtt = 0.325, rttvar = 0.020, rto = 2.000 +recv 213 +updated rto +send 214: rtt = 0.329, srtt = 0.325, rttvar = 0.016, rto = 2.000 +recv 214 +updated rto +send 215: rtt = 0.310, srtt = 0.324, rttvar = 0.016, rto = 2.000 +recv 215 +updated rto +send 216: rtt = 0.772, srtt = 0.380, rttvar = 0.124, rto = 2.000 +recv 216 +updated rto +send 217: rtt = 0.317, srtt = 0.372, rttvar = 0.109, rto = 2.000 +recv 217 +updated rto +send 218: rtt = 0.379, srtt = 0.373, rttvar = 0.083, rto = 2.000 +recv 218 +updated rto +send 219: rtt = 0.310, srtt = 0.365, rttvar = 0.078, rto = 2.000 +recv 219 +updated rto +send 220: rtt = 0.304, srtt = 0.357, rttvar = 0.074, rto = 2.000 +recv 220 +updated rto +send 221: rtt = 0.315, srtt = 0.352, rttvar = 0.066, rto = 2.000 +recv 221 +updated rto +send 222: rtt = 0.340, srtt = 0.350, rttvar = 0.052, rto = 2.000 +recv 222 +updated rto +send 223: rtt = 0.329, srtt = 0.348, rttvar = 0.045, rto = 2.000 +recv 223 +updated rto +send 224: rtt = 0.349, srtt = 0.348, rttvar = 0.034, rto = 2.000 +recv 224 +updated rto +send 225: rtt = 0.350, srtt = 0.348, rttvar = 0.026, rto = 2.000 +recv 225 +updated rto +send 226: rtt = 0.360, srtt = 0.350, rttvar = 0.022, rto = 2.000 +recv 226 +updated rto +send 227: rtt = 0.380, srtt = 0.353, rttvar = 0.024, rto = 2.000 +recv 227 +updated rto +send 228: rtt = 0.320, srtt = 0.349, rttvar = 0.027, rto = 2.000 +recv 228 +updated rto +send 229: rtt = 0.319, srtt = 0.345, rttvar = 0.028, rto = 2.000 +recv 229 +updated rto +send 230: rtt = 0.370, srtt = 0.349, rttvar = 0.027, rto = 2.000 +recv 230 +updated rto +send 231: rtt = 0.358, srtt = 0.350, rttvar = 0.022, rto = 2.000 +recv 231 +updated rto +send 232: rtt = 0.340, srtt = 0.349, rttvar = 0.019, rto = 2.000 +recv 232 +updated rto +send 233: rtt = 0.360, srtt = 0.350, rttvar = 0.017, rto = 2.000 +recv 233 +updated rto +send 234: rtt = 0.289, srtt = 0.342, rttvar = 0.028, rto = 2.000 +recv 234 +updated rto +send 235: rtt = 0.350, srtt = 0.343, rttvar = 0.023, rto = 2.000 +recv 235 +updated rto +send 236: rtt = 0.310, srtt = 0.339, rttvar = 0.026, rto = 2.000 +recv 236 +updated rto +send 237: rtt = 0.319, srtt = 0.337, rttvar = 0.024, rto = 2.000 +recv 237 +updated rto +send 238: rtt = 0.330, srtt = 0.336, rttvar = 0.020, rto = 2.000 +recv 238 +updated rto +send 239: rtt = 0.308, srtt = 0.332, rttvar = 0.022, rto = 2.000 +recv 239 +updated rto +send 240: rtt = 0.320, srtt = 0.331, rttvar = 0.019, rto = 2.000 +recv 240 +updated rto +send 241: rtt = 0.290, srtt = 0.326, rttvar = 0.025, rto = 2.000 +recv 241 +updated rto +send 242: rtt = 0.360, srtt = 0.330, rttvar = 0.027, rto = 2.000 +recv 242 +updated rto +send 243: rtt = 0.330, srtt = 0.330, rttvar = 0.020, rto = 2.000 +recv 243 +updated rto +send 244: rtt = 0.339, srtt = 0.331, rttvar = 0.018, rto = 2.000 +recv 244 +updated rto +send 245: rtt = 0.350, srtt = 0.333, rttvar = 0.018, rto = 2.000 +recv 245 +updated rto +send 246: rtt = 0.330, srtt = 0.333, rttvar = 0.014, rto = 2.000 +recv 246 +updated rto +send 247: rtt = 0.309, srtt = 0.330, rttvar = 0.017, rto = 2.000 +recv 247 +updated rto +send 248: rtt = 0.329, srtt = 0.330, rttvar = 0.013, rto = 2.000 +recv 248 +updated rto +send 249: rtt = 0.360, srtt = 0.334, rttvar = 0.017, rto = 2.000 +recv 249 +updated rto +send 250: rtt = 0.350, srtt = 0.336, rttvar = 0.017, rto = 2.000 +recv 250 +updated rto +send 251: rtt = 0.340, srtt = 0.336, rttvar = 0.014, rto = 2.000 +recv 251 +updated rto +send 252: rtt = 0.410, srtt = 0.345, rttvar = 0.029, rto = 2.000 +recv 252 +updated rto +send 253: rtt = 0.339, srtt = 0.345, rttvar = 0.023, rto = 2.000 +recv 253 +updated rto +send 254: rtt = 0.335, srtt = 0.343, rttvar = 0.020, rto = 2.000 +recv 254 +updated rto +send 255: rtt = 0.335, srtt = 0.342, rttvar = 0.017, rto = 2.000 +recv 255 +updated rto +send 256: rtt = 0.319, srtt = 0.339, rttvar = 0.019, rto = 2.000 +recv 256 +updated rto +send 257: rtt = 0.350, srtt = 0.341, rttvar = 0.017, rto = 2.000 +recv 257 +updated rto +send 258: rtt = 0.310, srtt = 0.337, rttvar = 0.020, rto = 2.000 +recv 258 +updated rto +send 259: rtt = 0.320, srtt = 0.335, rttvar = 0.019, rto = 2.000 +recv 259 +updated rto +send 260: rtt = 0.319, srtt = 0.333, rttvar = 0.018, rto = 2.000 +recv 260 +updated rto +send 261: rtt = 0.300, srtt = 0.329, rttvar = 0.022, rto = 2.000 +recv 261 +updated rto +send 262: rtt = 0.389, srtt = 0.336, rttvar = 0.032, rto = 2.000 +recv 262 +updated rto +send 263: rtt = 1.259, srtt = 0.452, rttvar = 0.254, rto = 2.000 +recv 263 +updated rto +send 264: rtt = 0.819, srtt = 0.498, rttvar = 0.283, rto = 2.000 +recv 264 +updated rto +send 265: rtt = 0.809, srtt = 0.536, rttvar = 0.290, rto = 2.000 +recv 265 +updated rto +send 266: rtt = 0.809, srtt = 0.571, rttvar = 0.286, rto = 2.000 +recv 266 +updated rto +send 267: rtt = 0.819, srtt = 0.602, rttvar = 0.276, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 267: rtt = 0.819, srtt = 0.602, rttvar = 0.276, rto = 4.000 +recv 267 +updated rto +send 268: rtt = 0.748, srtt = 0.620, rttvar = 0.244, rto = 2.000 +recv 268 +updated rto +send 269: rtt = 0.819, srtt = 0.645, rttvar = 0.233, rto = 2.000 +recv 269 +updated rto +send 270: rtt = 0.819, srtt = 0.667, rttvar = 0.218, rto = 2.000 +recv 270 +updated rto +send 271: rtt = 0.819, srtt = 0.686, rttvar = 0.202, rto = 2.000 +recv 271 +updated rto +send 272: rtt = 0.799, srtt = 0.700, rttvar = 0.180, rto = 2.000 +recv 272 +updated rto +send 273: rtt = 1.059, srtt = 0.745, rttvar = 0.224, rto = 2.000 +recv 273 +updated rto +send 274: rtt = 0.370, srtt = 0.698, rttvar = 0.262, rto = 2.000 +recv 274 +updated rto +send 275: rtt = 0.370, srtt = 0.657, rttvar = 0.278, rto = 2.000 +recv 275 +updated rto +send 276: rtt = 0.380, srtt = 0.622, rttvar = 0.278, rto = 2.000 +recv 276 +updated rto +send 277: rtt = 0.340, srtt = 0.587, rttvar = 0.279, rto = 2.000 +recv 277 +updated rto +send 278: rtt = 0.400, srtt = 0.564, rttvar = 0.256, rto = 2.000 +recv 278 +updated rto +send 279: rtt = 0.350, srtt = 0.537, rttvar = 0.245, rto = 2.000 +recv 279 +updated rto +send 280: rtt = 0.320, srtt = 0.510, rttvar = 0.238, rto = 2.000 +recv 280 +updated rto +send 281: rtt = 0.390, srtt = 0.495, rttvar = 0.209, rto = 2.000 +recv 281 +updated rto +send 282: rtt = 0.329, srtt = 0.474, rttvar = 0.198, rto = 2.000 +recv 282 +updated rto +send 283: rtt = 0.280, srtt = 0.450, rttvar = 0.197, rto = 2.000 +recv 283 +updated rto +send 284: rtt = 0.330, srtt = 0.435, rttvar = 0.178, rto = 2.000 +recv 284 +updated rto +send 285: rtt = 0.310, srtt = 0.419, rttvar = 0.164, rto = 2.000 +recv 285 +updated rto +send 286: rtt = 0.370, srtt = 0.413, rttvar = 0.136, rto = 2.000 +recv 286 +updated rto +send 287: rtt = 0.379, srtt = 0.409, rttvar = 0.110, rto = 2.000 +recv 287 +updated rto +send 288: rtt = 0.329, srtt = 0.399, rttvar = 0.103, rto = 2.000 +recv 288 +updated rto +send 289: rtt = 0.320, srtt = 0.389, rttvar = 0.097, rto = 2.000 +recv 289 +updated rto +send 290: rtt = 0.410, srtt = 0.392, rttvar = 0.078, rto = 2.000 +recv 290 +updated rto +send 291: rtt = 0.340, srtt = 0.385, rttvar = 0.071, rto = 2.000 +recv 291 +updated rto +send 292: rtt = 0.360, srtt = 0.382, rttvar = 0.060, rto = 2.000 +recv 292 +updated rto +send 293: rtt = 0.349, srtt = 0.378, rttvar = 0.053, rto = 2.000 +recv 293 +updated rto +send 294: rtt = 0.360, srtt = 0.376, rttvar = 0.044, rto = 2.000 +recv 294 +updated rto +send 295: rtt = 0.360, srtt = 0.374, rttvar = 0.037, rto = 2.000 +recv 295 +updated rto +send 296: rtt = 0.329, srtt = 0.368, rttvar = 0.039, rto = 2.000 +recv 296 +updated rto +send 297: rtt = 0.360, srtt = 0.367, rttvar = 0.031, rto = 2.000 +recv 297 +updated rto +send 298: rtt = 0.340, srtt = 0.364, rttvar = 0.030, rto = 2.000 +recv 298 +updated rto +send 299: rtt = 0.359, srtt = 0.363, rttvar = 0.024, rto = 2.000 +recv 299 +updated rto +send 300: rtt = 0.369, srtt = 0.364, rttvar = 0.019, rto = 2.000 +recv 300 +updated rto +send 301: rtt = 0.330, srtt = 0.360, rttvar = 0.023, rto = 2.000 +recv 301 +updated rto +send 302: rtt = 0.320, srtt = 0.355, rttvar = 0.027, rto = 2.000 +recv 302 +updated rto +send 303: rtt = 0.320, srtt = 0.350, rttvar = 0.029, rto = 2.000 +recv 303 +updated rto +send 304: rtt = 0.313, srtt = 0.346, rttvar = 0.031, rto = 2.000 +recv 304 +updated rto +send 305: rtt = 0.337, srtt = 0.345, rttvar = 0.025, rto = 2.000 +recv 305 +updated rto +send 306: rtt = 0.320, srtt = 0.342, rttvar = 0.025, rto = 2.000 +recv 306 +updated rto +send 307: rtt = 0.319, srtt = 0.339, rttvar = 0.025, rto = 2.000 +recv 307 +updated rto +send 308: rtt = 0.680, srtt = 0.381, rttvar = 0.104, rto = 2.000 +recv 308 +updated rto +send 309: rtt = 0.380, srtt = 0.381, rttvar = 0.078, rto = 2.000 +recv 309 +updated rto +send 310: rtt = 0.319, srtt = 0.373, rttvar = 0.074, rto = 2.000 +recv 310 +updated rto +send 311: rtt = 0.330, srtt = 0.368, rttvar = 0.066, rto = 2.000 +recv 311 +updated rto +send 312: rtt = 0.330, srtt = 0.363, rttvar = 0.059, rto = 2.000 +recv 312 +updated rto +send 313: rtt = 0.310, srtt = 0.357, rttvar = 0.058, rto = 2.000 +recv 313 +updated rto +send 314: rtt = 0.300, srtt = 0.350, rttvar = 0.058, rto = 2.000 +recv 314 +updated rto +send 315: rtt = 0.340, srtt = 0.348, rttvar = 0.046, rto = 2.000 +recv 315 +updated rto +send 316: rtt = 0.350, srtt = 0.349, rttvar = 0.035, rto = 2.000 +recv 316 +updated rto +send 317: rtt = 0.350, srtt = 0.349, rttvar = 0.026, rto = 2.000 +recv 317 +updated rto +send 318: rtt = 0.340, srtt = 0.348, rttvar = 0.022, rto = 2.000 +recv 318 +updated rto +send 319: rtt = 0.309, srtt = 0.343, rttvar = 0.026, rto = 2.000 +recv 319 +updated rto +send 320: rtt = 0.343, srtt = 0.343, rttvar = 0.020, rto = 2.000 +recv 320 +updated rto +send 321: rtt = 0.326, srtt = 0.341, rttvar = 0.019, rto = 2.000 +recv 321 +updated rto +send 322: rtt = 0.319, srtt = 0.338, rttvar = 0.020, rto = 2.000 +recv 322 +updated rto +send 323: rtt = 1.178, srtt = 0.443, rttvar = 0.225, rto = 2.000 +recv 323 +updated rto +send 324: rtt = 0.320, srtt = 0.428, rttvar = 0.199, rto = 2.000 +recv 324 +updated rto +send 325: rtt = 0.309, srtt = 0.413, rttvar = 0.179, rto = 2.000 +recv 325 +updated rto +send 326: rtt = 0.330, srtt = 0.402, rttvar = 0.155, rto = 2.000 +recv 326 +updated rto +send 327: rtt = 0.300, srtt = 0.390, rttvar = 0.142, rto = 2.000 +recv 327 +updated rto +send 328: rtt = 0.300, srtt = 0.378, rttvar = 0.129, rto = 2.000 +recv 328 +updated rto +send 329: rtt = 0.310, srtt = 0.370, rttvar = 0.114, rto = 2.000 +recv 329 +updated rto +send 330: rtt = 0.290, srtt = 0.360, rttvar = 0.105, rto = 2.000 +recv 330 +updated rto +send 331: rtt = 0.310, srtt = 0.354, rttvar = 0.091, rto = 2.000 +recv 331 +updated rto +send 332: rtt = 0.300, srtt = 0.347, rttvar = 0.082, rto = 2.000 +recv 332 +updated rto +send 333: rtt = 0.300, srtt = 0.341, rttvar = 0.073, rto = 2.000 +recv 333 +updated rto +send 334: rtt = 0.340, srtt = 0.341, rttvar = 0.055, rto = 2.000 +recv 334 +updated rto +send 335: rtt = 0.339, srtt = 0.341, rttvar = 0.042, rto = 2.000 +recv 335 +updated rto +send 336: rtt = 0.310, srtt = 0.337, rttvar = 0.039, rto = 2.000 +recv 336 +updated rto +send 337: rtt = 0.320, srtt = 0.335, rttvar = 0.034, rto = 2.000 +recv 337 +updated rto +send 338: rtt = 0.330, srtt = 0.334, rttvar = 0.026, rto = 2.000 +recv 338 +updated rto +send 339: rtt = 0.320, srtt = 0.332, rttvar = 0.023, rto = 2.000 +recv 339 +updated rto +send 340: rtt = 0.315, srtt = 0.330, rttvar = 0.022, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 340: rtt = 0.315, srtt = 0.330, rttvar = 0.022, rto = 4.000 +recv 340 +updated rto +send 341: rtt = 0.338, srtt = 0.331, rttvar = 0.018, rto = 2.000 +recv 341 +updated rto +send 342: rtt = 0.320, srtt = 0.330, rttvar = 0.017, rto = 2.000 +recv 342 +updated rto +send 343: rtt = 0.309, srtt = 0.327, rttvar = 0.018, rto = 2.000 +recv 343 +updated rto +send 344: rtt = 0.320, srtt = 0.326, rttvar = 0.015, rto = 2.000 +recv 344 +updated rto +send 345: rtt = 0.349, srtt = 0.329, rttvar = 0.017, rto = 2.000 +recv 345 +updated rto +send 346: rtt = 0.339, srtt = 0.330, rttvar = 0.015, rto = 2.000 +recv 346 +updated rto +send 347: rtt = 0.300, srtt = 0.327, rttvar = 0.019, rto = 2.000 +recv 347 +updated rto +send 348: rtt = 0.300, srtt = 0.323, rttvar = 0.021, rto = 2.000 +recv 348 +updated rto +send 349: rtt = 0.289, srtt = 0.319, rttvar = 0.024, rto = 2.000 +recv 349 +updated rto +send 350: rtt = 0.329, srtt = 0.320, rttvar = 0.021, rto = 2.000 +recv 350 +updated rto +send 351: rtt = 0.340, srtt = 0.323, rttvar = 0.020, rto = 2.000 +recv 351 +updated rto +send 352: rtt = 0.329, srtt = 0.323, rttvar = 0.017, rto = 2.000 +recv 352 +updated rto +send 353: rtt = 0.320, srtt = 0.323, rttvar = 0.014, rto = 2.000 +recv 353 +updated rto +send 354: rtt = 0.410, srtt = 0.334, rttvar = 0.032, rto = 2.000 +recv 354 +updated rto +send 355: rtt = 0.300, srtt = 0.330, rttvar = 0.032, rto = 2.000 +recv 355 +updated rto +send 356: rtt = 0.389, srtt = 0.337, rttvar = 0.039, rto = 2.000 +recv 356 +updated rto +send 357: rtt = 0.299, srtt = 0.332, rttvar = 0.039, rto = 2.000 +recv 357 +updated rto +send 358: rtt = 1.280, srtt = 0.451, rttvar = 0.266, rto = 2.000 +recv 358 +updated rto +send 359: rtt = 0.809, srtt = 0.496, rttvar = 0.289, rto = 2.000 +recv 359 +updated rto +send 360: rtt = 0.818, srtt = 0.536, rttvar = 0.297, rto = 2.000 +recv 360 +updated rto +send 361: rtt = 0.819, srtt = 0.571, rttvar = 0.294, rto = 2.000 +recv 361 +updated rto +send 362: rtt = 0.829, srtt = 0.603, rttvar = 0.285, rto = 2.000 +recv 362 +updated rto +send 363: rtt = 0.819, srtt = 0.630, rttvar = 0.268, rto = 2.000 +recv 363 +updated rto +send 364: rtt = 0.809, srtt = 0.653, rttvar = 0.245, rto = 2.000 +recv 364 +updated rto +send 365: rtt = 0.819, srtt = 0.674, rttvar = 0.226, rto = 2.000 +recv 365 +updated rto +send 366: rtt = 0.999, srtt = 0.714, rttvar = 0.251, rto = 2.000 +recv 366 +updated rto +send 367: rtt = 0.999, srtt = 0.750, rttvar = 0.259, rto = 2.000 +recv 367 +updated rto +send 368: rtt = 1.479, srtt = 0.841, rttvar = 0.377, rto = 2.347 +recv 368 +updated rto +send 369: rtt = 1.010, srtt = 0.862, rttvar = 0.325, rto = 2.161 +recv 369 +updated rto +send 370: rtt = 0.998, srtt = 0.879, rttvar = 0.278, rto = 2.000 +recv 370 +updated rto +send 371: rtt = 0.999, srtt = 0.894, rttvar = 0.238, rto = 2.000 +recv 371 +updated rto +send 372: rtt = 0.999, srtt = 0.907, rttvar = 0.205, rto = 2.000 +recv 372 +updated rto +send 373: rtt = 0.999, srtt = 0.919, rttvar = 0.177, rto = 2.000 +recv 373 +updated rto +send 374: rtt = 0.989, srtt = 0.927, rttvar = 0.150, rto = 2.000 +recv 374 +updated rto +send 375: rtt = 0.989, srtt = 0.935, rttvar = 0.128, rto = 2.000 +recv 375 +updated rto +send 376: rtt = 1.009, srtt = 0.944, rttvar = 0.114, rto = 2.000 +recv 376 +updated rto +send 377: rtt = 0.999, srtt = 0.951, rttvar = 0.099, rto = 2.000 +recv 377 +updated rto +send 378: rtt = 1.009, srtt = 0.958, rttvar = 0.089, rto = 2.000 +recv 378 +updated rto +send 379: rtt = 0.939, srtt = 0.956, rttvar = 0.072, rto = 2.000 +recv 379 +updated rto +send 380: rtt = 0.809, srtt = 0.938, rttvar = 0.090, rto = 2.000 +recv 380 +updated rto +send 381: rtt = 0.821, srtt = 0.923, rttvar = 0.097, rto = 2.000 +recv 381 +updated rto +send 382: rtt = 0.827, srtt = 0.911, rttvar = 0.097, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 382: rtt = 0.827, srtt = 0.911, rttvar = 0.097, rto = 4.000 +recv 382 +updated rto +send 383: rtt = 0.809, srtt = 0.898, rttvar = 0.098, rto = 2.000 +recv 383 +updated rto +send 384: rtt = 0.839, srtt = 0.891, rttvar = 0.088, rto = 2.000 +recv 384 +updated rto +send 385: rtt = 0.819, srtt = 0.882, rttvar = 0.084, rto = 2.000 +recv 385 +updated rto +send 386: rtt = 0.809, srtt = 0.873, rttvar = 0.081, rto = 2.000 +recv 386 +updated rto +send 387: rtt = 0.819, srtt = 0.866, rttvar = 0.075, rto = 2.000 +recv 387 +updated rto +send 388: rtt = 0.819, srtt = 0.860, rttvar = 0.068, rto = 2.000 +recv 388 +updated rto +send 389: rtt = 0.809, srtt = 0.854, rttvar = 0.064, rto = 2.000 +recv 389 +updated rto +send 390: rtt = 0.811, srtt = 0.848, rttvar = 0.058, rto = 2.000 +recv 390 +updated rto +send 391: rtt = 0.827, srtt = 0.846, rttvar = 0.049, rto = 2.000 +recv 391 +updated rto +send 392: rtt = 0.813, srtt = 0.842, rttvar = 0.045, rto = 2.000 +recv 392 +updated rto +send 393: rtt = 1.205, srtt = 0.887, rttvar = 0.125, rto = 2.000 +recv 393 +updated rto +send 394: rtt = 0.829, srtt = 0.880, rttvar = 0.108, rto = 2.000 +recv 394 +updated rto +send 395: rtt = 0.819, srtt = 0.872, rttvar = 0.096, rto = 2.000 +recv 395 +updated rto +send 396: rtt = 0.819, srtt = 0.866, rttvar = 0.085, rto = 2.000 +recv 396 +updated rto +send 397: rtt = 0.819, srtt = 0.860, rttvar = 0.076, rto = 2.000 +recv 397 +updated rto +send 398: rtt = 0.819, srtt = 0.855, rttvar = 0.067, rto = 2.000 +recv 398 +updated rto +send 399: rtt = 0.819, srtt = 0.850, rttvar = 0.059, rto = 2.000 +recv 399 +updated rto +send 400: rtt = 0.819, srtt = 0.846, rttvar = 0.052, rto = 2.000 +recv 400 +updated rto +send 401: rtt = 0.829, srtt = 0.844, rttvar = 0.043, rto = 2.000 +recv 401 +updated rto +send 402: rtt = 0.819, srtt = 0.841, rttvar = 0.039, rto = 2.000 +recv 402 +updated rto +send 403: rtt = 0.809, srtt = 0.837, rttvar = 0.037, rto = 2.000 +recv 403 +updated rto +send 404: rtt = 0.819, srtt = 0.835, rttvar = 0.032, rto = 2.000 +recv 404 +updated rto +send 405: rtt = 0.809, srtt = 0.832, rttvar = 0.031, rto = 2.000 +recv 405 +updated rto +send 406: rtt = 0.819, srtt = 0.830, rttvar = 0.026, rto = 2.000 +recv 406 +updated rto +send 407: rtt = 0.819, srtt = 0.829, rttvar = 0.022, rto = 2.000 +recv 407 +updated rto +send 408: rtt = 0.799, srtt = 0.825, rttvar = 0.024, rto = 2.000 +recv 408 +updated rto +send 409: rtt = 0.819, srtt = 0.824, rttvar = 0.020, rto = 2.000 +recv 409 +updated rto +send 410: rtt = 0.819, srtt = 0.824, rttvar = 0.016, rto = 2.000 +recv 410 +updated rto +send 411: rtt = 0.829, srtt = 0.824, rttvar = 0.013, rto = 2.000 +recv 411 +updated rto +send 412: rtt = 0.820, srtt = 0.824, rttvar = 0.011, rto = 2.000 +recv 412 +updated rto +send 413: rtt = 0.809, srtt = 0.822, rttvar = 0.012, rto = 2.000 +recv 413 +updated rto +send 414: rtt = 0.819, srtt = 0.821, rttvar = 0.010, rto = 2.000 +recv 414 +updated rto +send 415: rtt = 1.209, srtt = 0.870, rttvar = 0.104, rto = 2.000 +recv 415 +updated rto +send 416: rtt = 0.809, srtt = 0.862, rttvar = 0.093, rto = 2.000 +recv 416 +updated rto +send 417: rtt = 0.824, srtt = 0.858, rttvar = 0.080, rto = 2.000 +recv 417 +updated rto +send 418: rtt = 0.814, srtt = 0.852, rttvar = 0.071, rto = 2.000 +recv 418 +updated rto +send 419: rtt = 0.809, srtt = 0.847, rttvar = 0.064, rto = 2.000 +recv 419 +updated rto +send 420: rtt = 0.819, srtt = 0.843, rttvar = 0.055, rto = 2.000 +recv 420 +updated rto +send 421: rtt = 0.819, srtt = 0.840, rttvar = 0.047, rto = 2.000 +recv 421 +updated rto +send 422: rtt = 0.809, srtt = 0.836, rttvar = 0.043, rto = 2.000 +recv 422 +updated rto +send 423: rtt = 0.819, srtt = 0.834, rttvar = 0.037, rto = 2.000 +recv 423 +updated rto +send 424: rtt = 0.821, srtt = 0.832, rttvar = 0.031, rto = 2.000 +recv 424 +updated rto +send 425: rtt = 0.808, srtt = 0.829, rttvar = 0.029, rto = 2.000 +recv 425 +updated rto +send 426: rtt = 0.819, srtt = 0.828, rttvar = 0.025, rto = 2.000 +recv 426 +updated rto +send 427: rtt = 0.819, srtt = 0.827, rttvar = 0.021, rto = 2.000 +recv 427 +updated rto +send 428: rtt = 0.819, srtt = 0.826, rttvar = 0.017, rto = 2.000 +recv 428 +updated rto +send 429: rtt = 0.819, srtt = 0.825, rttvar = 0.015, rto = 2.000 +recv 429 +updated rto +send 430: rtt = 0.819, srtt = 0.824, rttvar = 0.013, rto = 2.000 +recv 430 +updated rto +send 431: rtt = 0.819, srtt = 0.824, rttvar = 0.011, rto = 2.000 +recv 431 +updated rto +send 432: rtt = 0.609, srtt = 0.797, rttvar = 0.062, rto = 2.000 +recv 432 +updated rto +send 433: rtt = 0.309, srtt = 0.736, rttvar = 0.168, rto = 2.000 +recv 433 +updated rto +send 434: rtt = 0.330, srtt = 0.685, rttvar = 0.228, rto = 2.000 +recv 434 +updated rto +send 435: rtt = 0.300, srtt = 0.637, rttvar = 0.267, rto = 2.000 +recv 435 +updated rto +send 436: rtt = 0.319, srtt = 0.597, rttvar = 0.280, rto = 2.000 +recv 436 +updated rto +send 437: rtt = 0.310, srtt = 0.561, rttvar = 0.282, rto = 2.000 +recv 437 +updated rto +send 438: rtt = 0.320, srtt = 0.531, rttvar = 0.272, rto = 2.000 +recv 438 +updated rto +send 439: rtt = 0.350, srtt = 0.509, rttvar = 0.249, rto = 2.000 +recv 439 +updated rto +send 440: rtt = 0.290, srtt = 0.481, rttvar = 0.241, rto = 2.000 +recv 440 +updated rto +send 441: rtt = 0.290, srtt = 0.457, rttvar = 0.229, rto = 2.000 +recv 441 +updated rto +send 442: rtt = 0.300, srtt = 0.438, rttvar = 0.211, rto = 2.000 +recv 442 +updated rto +send 443: rtt = 0.360, srtt = 0.428, rttvar = 0.178, rto = 2.000 +recv 443 +updated rto +send 444: rtt = 0.310, srtt = 0.413, rttvar = 0.163, rto = 2.000 +recv 444 +updated rto +send 445: rtt = 0.360, srtt = 0.407, rttvar = 0.135, rto = 2.000 +recv 445 +updated rto +send 446: rtt = 0.319, srtt = 0.396, rttvar = 0.123, rto = 2.000 +recv 446 +updated rto +send 447: rtt = 0.320, srtt = 0.386, rttvar = 0.111, rto = 2.000 +recv 447 +updated rto +send 448: rtt = 0.330, srtt = 0.379, rttvar = 0.098, rto = 2.000 +recv 448 +updated rto +send 449: rtt = 0.329, srtt = 0.373, rttvar = 0.086, rto = 2.000 +recv 449 +updated rto +send 450: rtt = 0.370, srtt = 0.373, rttvar = 0.065, rto = 2.000 +recv 450 +updated rto +send 451: rtt = 0.340, srtt = 0.368, rttvar = 0.057, rto = 2.000 +recv 451 +updated rto +send 452: rtt = 0.340, srtt = 0.365, rttvar = 0.050, rto = 2.000 +recv 452 +updated rto +send 453: rtt = 0.719, srtt = 0.409, rttvar = 0.126, rto = 2.000 +recv 453 +updated rto +send 454: rtt = 0.339, srtt = 0.400, rttvar = 0.112, rto = 2.000 +recv 454 +updated rto +send 455: rtt = 0.320, srtt = 0.390, rttvar = 0.104, rto = 2.000 +recv 455 +updated rto +send 456: rtt = 0.310, srtt = 0.380, rttvar = 0.098, rto = 2.000 +recv 456 +updated rto +send 457: rtt = 0.320, srtt = 0.373, rttvar = 0.089, rto = 2.000 +recv 457 +updated rto +send 458: rtt = 0.330, srtt = 0.367, rttvar = 0.077, rto = 2.000 +recv 458 +updated rto +send 459: rtt = 0.313, srtt = 0.361, rttvar = 0.071, rto = 2.000 +recv 459 +updated rto +send 460: rtt = 0.377, srtt = 0.363, rttvar = 0.058, rto = 2.000 +recv 460 +updated rto +send 461: rtt = 0.440, srtt = 0.372, rttvar = 0.063, rto = 2.000 +recv 461 +updated rto +send 462: rtt = 0.340, srtt = 0.368, rttvar = 0.055, rto = 2.000 +recv 462 +updated rto +send 463: rtt = 0.330, srtt = 0.364, rttvar = 0.051, rto = 2.000 +recv 463 +updated rto +send 464: rtt = 0.360, srtt = 0.363, rttvar = 0.039, rto = 2.000 +recv 464 +updated rto +send 465: rtt = 0.380, srtt = 0.365, rttvar = 0.033, rto = 2.000 +recv 465 +updated rto +send 466: rtt = 0.320, srtt = 0.360, rttvar = 0.036, rto = 2.000 +recv 466 +updated rto +send 467: rtt = 0.309, srtt = 0.353, rttvar = 0.040, rto = 2.000 +recv 467 +updated rto +send 468: rtt = 0.360, srtt = 0.354, rttvar = 0.032, rto = 2.000 +recv 468 +updated rto +send 469: rtt = 0.330, srtt = 0.351, rttvar = 0.030, rto = 2.000 +recv 469 +updated rto +send 470: rtt = 0.290, srtt = 0.343, rttvar = 0.038, rto = 2.000 +recv 470 +updated rto +send 471: rtt = 0.329, srtt = 0.342, rttvar = 0.032, rto = 2.000 +recv 471 +updated rto +send 472: rtt = 0.319, srtt = 0.339, rttvar = 0.030, rto = 2.000 +recv 472 +updated rto +send 473: rtt = 0.320, srtt = 0.336, rttvar = 0.027, rto = 2.000 +recv 473 +updated rto +send 474: rtt = 0.349, srtt = 0.338, rttvar = 0.023, rto = 2.000 +recv 474 +updated rto +send 475: rtt = 0.330, srtt = 0.337, rttvar = 0.019, rto = 2.000 +recv 475 +updated rto +send 476: rtt = 0.360, srtt = 0.340, rttvar = 0.020, rto = 2.000 +recv 476 +updated rto +send 477: rtt = 0.310, srtt = 0.336, rttvar = 0.023, rto = 2.000 +recv 477 +updated rto +send 478: rtt = 0.320, srtt = 0.334, rttvar = 0.021, rto = 2.000 +recv 478 +updated rto +send 479: rtt = 0.320, srtt = 0.332, rttvar = 0.019, rto = 2.000 +recv 479 +updated rto +send 480: rtt = 0.410, srtt = 0.342, rttvar = 0.034, rto = 2.000 +recv 480 +updated rto +send 481: rtt = 0.340, srtt = 0.342, rttvar = 0.026, rto = 2.000 +recv 481 +updated rto +send 482: rtt = 0.409, srtt = 0.350, rttvar = 0.036, rto = 2.000 +recv 482 +updated rto +send 483: rtt = 0.330, srtt = 0.348, rttvar = 0.032, rto = 2.000 +recv 483 +updated rto +send 484: rtt = 0.280, srtt = 0.339, rttvar = 0.041, rto = 2.000 +recv 484 +updated rto +send 485: rtt = 0.320, srtt = 0.337, rttvar = 0.036, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 485: rtt = 0.320, srtt = 0.337, rttvar = 0.036, rto = 4.000 +recv 485 +updated rto +send 486: rtt = 0.339, srtt = 0.337, rttvar = 0.027, rto = 2.000 +recv 486 +updated rto +send 487: rtt = 0.360, srtt = 0.340, rttvar = 0.026, rto = 2.000 +recv 487 +updated rto +send 488: rtt = 0.300, srtt = 0.335, rttvar = 0.030, rto = 2.000 +recv 488 +updated rto +send 489: rtt = 0.320, srtt = 0.333, rttvar = 0.026, rto = 2.000 +recv 489 +updated rto +send 490: rtt = 0.410, srtt = 0.343, rttvar = 0.039, rto = 2.000 +recv 490 +updated rto +send 491: rtt = 0.320, srtt = 0.340, rttvar = 0.035, rto = 2.000 +recv 491 +updated rto +send 492: rtt = 0.320, srtt = 0.337, rttvar = 0.031, rto = 2.000 +recv 492 +updated rto +send 493: rtt = 0.319, srtt = 0.335, rttvar = 0.028, rto = 2.000 +recv 493 +updated rto +send 494: rtt = 0.330, srtt = 0.334, rttvar = 0.022, rto = 2.000 +recv 494 +updated rto +send 495: rtt = 0.320, srtt = 0.333, rttvar = 0.020, rto = 2.000 +recv 495 +updated rto +send 496: rtt = 0.314, srtt = 0.330, rttvar = 0.020, rto = 2.000 +recv 496 +updated rto +send 497: rtt = 0.325, srtt = 0.330, rttvar = 0.016, rto = 2.000 +recv 497 +updated rto +send 498: rtt = 0.330, srtt = 0.330, rttvar = 0.012, rto = 2.000 +recv 498 +updated rto +send 499: rtt = 0.290, srtt = 0.325, rttvar = 0.019, rto = 2.000 +recv 499 +updated rto +send 500: rtt = 0.340, srtt = 0.327, rttvar = 0.018, rto = 2.000 +recv 500 +updated rto diff --git a/rtt/rtt.out.kumba.2 b/rtt/rtt.out.kumba.2 new file mode 100644 index 0000000..17fe181 --- /dev/null +++ b/rtt/rtt.out.kumba.2 @@ -0,0 +1,1500 @@ +send 1: rtt = 0.000, srtt = 0.000, rttvar = 0.750, rto = 3.000 +recv 1 +updated rto +send 2: rtt = 0.369, srtt = 0.046, rttvar = 0.655, rto = 2.665 +recv 2 +updated rto +send 3: rtt = 0.318, srtt = 0.080, rttvar = 0.559, rto = 2.316 +recv 3 +updated rto +send 4: rtt = 0.300, srtt = 0.108, rttvar = 0.474, rto = 2.005 +recv 4 +updated rto +send 5: rtt = 0.360, srtt = 0.139, rttvar = 0.419, rto = 2.000 +recv 5 +updated rto +send 6: rtt = 0.298, srtt = 0.159, rttvar = 0.354, rto = 2.000 +recv 6 +updated rto +send 7: rtt = 0.300, srtt = 0.177, rttvar = 0.301, rto = 2.000 +recv 7 +updated rto +send 8: rtt = 0.315, srtt = 0.194, rttvar = 0.260, rto = 2.000 +recv 8 +updated rto +send 9: rtt = 0.285, srtt = 0.205, rttvar = 0.218, rto = 2.000 +recv 9 +updated rto +send 10: rtt = 0.349, srtt = 0.223, rttvar = 0.199, rto = 2.000 +recv 10 +updated rto +send 11: rtt = 0.309, srtt = 0.234, rttvar = 0.171, rto = 2.000 +recv 11 +updated rto +send 12: rtt = 0.330, srtt = 0.246, rttvar = 0.152, rto = 2.000 +recv 12 +updated rto +send 13: rtt = 0.350, srtt = 0.259, rttvar = 0.140, rto = 2.000 +recv 13 +updated rto +send 14: rtt = 0.320, srtt = 0.267, rttvar = 0.120, rto = 2.000 +recv 14 +updated rto +send 15: rtt = 0.320, srtt = 0.273, rttvar = 0.104, rto = 2.000 +recv 15 +updated rto +send 16: rtt = 0.340, srtt = 0.282, rttvar = 0.094, rto = 2.000 +recv 16 +updated rto +send 17: rtt = 0.439, srtt = 0.301, rttvar = 0.110, rto = 2.000 +recv 17 +updated rto +send 18: rtt = 0.340, srtt = 0.306, rttvar = 0.092, rto = 2.000 +recv 18 +updated rto +send 19: rtt = 0.350, srtt = 0.312, rttvar = 0.080, rto = 2.000 +recv 19 +updated rto +send 20: rtt = 0.300, srtt = 0.310, rttvar = 0.063, rto = 2.000 +recv 20 +updated rto +send 21: rtt = 0.320, srtt = 0.311, rttvar = 0.050, rto = 2.000 +recv 21 +updated rto +send 22: rtt = 0.319, srtt = 0.312, rttvar = 0.039, rto = 2.000 +recv 22 +updated rto +send 23: rtt = 0.349, srtt = 0.317, rttvar = 0.039, rto = 2.000 +recv 23 +updated rto +send 24: rtt = 0.320, srtt = 0.317, rttvar = 0.030, rto = 2.000 +recv 24 +updated rto +send 25: rtt = 0.330, srtt = 0.319, rttvar = 0.025, rto = 2.000 +recv 25 +updated rto +send 26: rtt = 0.299, srtt = 0.316, rttvar = 0.024, rto = 2.000 +recv 26 +updated rto +send 27: rtt = 0.310, srtt = 0.316, rttvar = 0.020, rto = 2.000 +recv 27 +updated rto +send 28: rtt = 0.320, srtt = 0.316, rttvar = 0.016, rto = 2.000 +recv 28 +updated rto +send 29: rtt = 0.320, srtt = 0.317, rttvar = 0.013, rto = 2.000 +recv 29 +updated rto +send 30: rtt = 0.329, srtt = 0.318, rttvar = 0.013, rto = 2.000 +recv 30 +updated rto +send 31: rtt = 0.340, srtt = 0.321, rttvar = 0.015, rto = 2.000 +recv 31 +updated rto +send 32: rtt = 0.320, srtt = 0.321, rttvar = 0.011, rto = 2.000 +recv 32 +updated rto +send 33: rtt = 0.320, srtt = 0.321, rttvar = 0.009, rto = 2.000 +recv 33 +updated rto +send 34: rtt = 0.310, srtt = 0.319, rttvar = 0.009, rto = 2.000 +recv 34 +updated rto +send 35: rtt = 0.300, srtt = 0.317, rttvar = 0.012, rto = 2.000 +recv 35 +updated rto +send 36: rtt = 0.330, srtt = 0.319, rttvar = 0.012, rto = 2.000 +recv 36 +updated rto +send 37: rtt = 0.429, srtt = 0.332, rttvar = 0.037, rto = 2.000 +recv 37 +updated rto +send 38: rtt = 0.330, srtt = 0.332, rttvar = 0.028, rto = 2.000 +recv 38 +updated rto +send 39: rtt = 0.310, srtt = 0.329, rttvar = 0.027, rto = 2.000 +recv 39 +updated rto +send 40: rtt = 0.310, srtt = 0.327, rttvar = 0.025, rto = 2.000 +recv 40 +updated rto +send 41: rtt = 0.390, srtt = 0.335, rttvar = 0.034, rto = 2.000 +recv 41 +updated rto +send 42: rtt = 0.319, srtt = 0.333, rttvar = 0.030, rto = 2.000 +recv 42 +updated rto +send 43: rtt = 0.300, srtt = 0.329, rttvar = 0.030, rto = 2.000 +recv 43 +updated rto +send 44: rtt = 0.270, srtt = 0.321, rttvar = 0.038, rto = 2.000 +recv 44 +updated rto +send 45: rtt = 0.370, srtt = 0.327, rttvar = 0.040, rto = 2.000 +recv 45 +updated rto +send 46: rtt = 0.329, srtt = 0.328, rttvar = 0.031, rto = 2.000 +recv 46 +updated rto +send 47: rtt = 0.329, srtt = 0.328, rttvar = 0.023, rto = 2.000 +recv 47 +updated rto +send 48: rtt = 0.320, srtt = 0.327, rttvar = 0.019, rto = 2.000 +recv 48 +updated rto +send 49: rtt = 0.330, srtt = 0.327, rttvar = 0.015, rto = 2.000 +recv 49 +updated rto +send 50: rtt = 0.319, srtt = 0.326, rttvar = 0.014, rto = 2.000 +recv 50 +updated rto +send 51: rtt = 0.320, srtt = 0.325, rttvar = 0.012, rto = 2.000 +recv 51 +updated rto +send 52: rtt = 0.300, srtt = 0.322, rttvar = 0.015, rto = 2.000 +recv 52 +updated rto +send 53: rtt = 0.340, srtt = 0.324, rttvar = 0.016, rto = 2.000 +recv 53 +updated rto +send 54: rtt = 0.330, srtt = 0.325, rttvar = 0.013, rto = 2.000 +recv 54 +updated rto +send 55: rtt = 0.339, srtt = 0.327, rttvar = 0.013, rto = 2.000 +recv 55 +updated rto +send 56: rtt = 0.340, srtt = 0.329, rttvar = 0.013, rto = 2.000 +recv 56 +updated rto +send 57: rtt = 0.359, srtt = 0.332, rttvar = 0.018, rto = 2.000 +recv 57 +updated rto +send 58: rtt = 0.309, srtt = 0.329, rttvar = 0.019, rto = 2.000 +recv 58 +updated rto +send 59: rtt = 0.340, srtt = 0.331, rttvar = 0.017, rto = 2.000 +recv 59 +updated rto +send 60: rtt = 0.300, srtt = 0.327, rttvar = 0.020, rto = 2.000 +recv 60 +updated rto +send 61: rtt = 0.300, srtt = 0.324, rttvar = 0.022, rto = 2.000 +recv 61 +updated rto +send 62: rtt = 0.330, srtt = 0.324, rttvar = 0.018, rto = 2.000 +recv 62 +updated rto +send 63: rtt = 0.329, srtt = 0.325, rttvar = 0.015, rto = 2.000 +recv 63 +updated rto +send 64: rtt = 0.290, srtt = 0.321, rttvar = 0.020, rto = 2.000 +recv 64 +updated rto +send 65: rtt = 0.300, srtt = 0.318, rttvar = 0.020, rto = 2.000 +recv 65 +updated rto +send 66: rtt = 0.290, srtt = 0.314, rttvar = 0.022, rto = 2.000 +recv 66 +updated rto +send 67: rtt = 0.350, srtt = 0.319, rttvar = 0.025, rto = 2.000 +recv 67 +updated rto +send 68: rtt = 0.320, srtt = 0.319, rttvar = 0.019, rto = 2.000 +recv 68 +updated rto +send 69: rtt = 0.340, srtt = 0.322, rttvar = 0.020, rto = 2.000 +recv 69 +updated rto +send 70: rtt = 0.299, srtt = 0.319, rttvar = 0.020, rto = 2.000 +recv 70 +updated rto +send 71: rtt = 0.320, srtt = 0.319, rttvar = 0.016, rto = 2.000 +recv 71 +updated rto +send 72: rtt = 0.359, srtt = 0.324, rttvar = 0.022, rto = 2.000 +recv 72 +updated rto +send 73: rtt = 0.330, srtt = 0.325, rttvar = 0.018, rto = 2.000 +recv 73 +updated rto +send 74: rtt = 0.300, srtt = 0.322, rttvar = 0.020, rto = 2.000 +recv 74 +updated rto +send 75: rtt = 0.370, srtt = 0.328, rttvar = 0.027, rto = 2.000 +recv 75 +updated rto +send 76: rtt = 0.300, srtt = 0.324, rttvar = 0.027, rto = 2.000 +recv 76 +updated rto +send 77: rtt = 0.330, srtt = 0.325, rttvar = 0.022, rto = 2.000 +recv 77 +updated rto +send 78: rtt = 0.270, srtt = 0.318, rttvar = 0.030, rto = 2.000 +recv 78 +updated rto +send 79: rtt = 0.350, srtt = 0.322, rttvar = 0.030, rto = 2.000 +recv 79 +updated rto +send 80: rtt = 0.329, srtt = 0.323, rttvar = 0.025, rto = 2.000 +recv 80 +updated rto +send 81: rtt = 0.320, srtt = 0.323, rttvar = 0.019, rto = 2.000 +recv 81 +updated rto +send 82: rtt = 0.329, srtt = 0.323, rttvar = 0.016, rto = 2.000 +recv 82 +updated rto +send 83: rtt = 0.330, srtt = 0.324, rttvar = 0.014, rto = 2.000 +recv 83 +updated rto +send 84: rtt = 0.309, srtt = 0.322, rttvar = 0.014, rto = 2.000 +recv 84 +updated rto +send 85: rtt = 0.350, srtt = 0.326, rttvar = 0.017, rto = 2.000 +recv 85 +updated rto +send 86: rtt = 0.350, srtt = 0.329, rttvar = 0.019, rto = 2.000 +recv 86 +updated rto +send 87: rtt = 0.330, srtt = 0.329, rttvar = 0.015, rto = 2.000 +recv 87 +updated rto +send 88: rtt = 0.310, srtt = 0.327, rttvar = 0.016, rto = 2.000 +recv 88 +updated rto +send 89: rtt = 0.330, srtt = 0.327, rttvar = 0.013, rto = 2.000 +recv 89 +updated rto +send 90: rtt = 0.350, srtt = 0.330, rttvar = 0.015, rto = 2.000 +recv 90 +updated rto +send 91: rtt = 0.300, srtt = 0.326, rttvar = 0.019, rto = 2.000 +recv 91 +updated rto +send 92: rtt = 0.310, srtt = 0.324, rttvar = 0.018, rto = 2.000 +recv 92 +updated rto +send 93: rtt = 0.290, srtt = 0.320, rttvar = 0.022, rto = 2.000 +recv 93 +updated rto +send 94: rtt = 0.319, srtt = 0.320, rttvar = 0.017, rto = 2.000 +recv 94 +updated rto +send 95: rtt = 0.319, srtt = 0.320, rttvar = 0.013, rto = 2.000 +recv 95 +updated rto +send 96: rtt = 0.330, srtt = 0.321, rttvar = 0.012, rto = 2.000 +recv 96 +updated rto +send 97: rtt = 0.310, srtt = 0.320, rttvar = 0.012, rto = 2.000 +recv 97 +updated rto +send 98: rtt = 0.289, srtt = 0.316, rttvar = 0.017, rto = 2.000 +recv 98 +updated rto +send 99: rtt = 0.310, srtt = 0.315, rttvar = 0.014, rto = 2.000 +recv 99 +updated rto +send 100: rtt = 0.340, srtt = 0.318, rttvar = 0.017, rto = 2.000 +recv 100 +updated rto +send 101: rtt = 0.340, srtt = 0.321, rttvar = 0.018, rto = 2.000 +recv 101 +updated rto +send 102: rtt = 0.320, srtt = 0.321, rttvar = 0.014, rto = 2.000 +recv 102 +updated rto +send 103: rtt = 0.310, srtt = 0.319, rttvar = 0.013, rto = 2.000 +recv 103 +updated rto +send 104: rtt = 0.430, srtt = 0.333, rttvar = 0.037, rto = 2.000 +recv 104 +updated rto +send 105: rtt = 0.329, srtt = 0.333, rttvar = 0.029, rto = 2.000 +recv 105 +updated rto +send 106: rtt = 0.330, srtt = 0.332, rttvar = 0.022, rto = 2.000 +recv 106 +updated rto +send 107: rtt = 0.430, srtt = 0.345, rttvar = 0.041, rto = 2.000 +recv 107 +updated rto +send 108: rtt = 0.350, srtt = 0.345, rttvar = 0.032, rto = 2.000 +recv 108 +updated rto +send 109: rtt = 0.339, srtt = 0.344, rttvar = 0.026, rto = 2.000 +recv 109 +updated rto +send 110: rtt = 0.350, srtt = 0.345, rttvar = 0.021, rto = 2.000 +recv 110 +updated rto +send 111: rtt = 0.370, srtt = 0.348, rttvar = 0.022, rto = 2.000 +recv 111 +updated rto +send 112: rtt = 0.329, srtt = 0.346, rttvar = 0.021, rto = 2.000 +recv 112 +updated rto +send 113: rtt = 0.340, srtt = 0.345, rttvar = 0.017, rto = 2.000 +recv 113 +updated rto +send 114: rtt = 0.330, srtt = 0.343, rttvar = 0.017, rto = 2.000 +recv 114 +updated rto +send 115: rtt = 0.290, srtt = 0.337, rttvar = 0.026, rto = 2.000 +recv 115 +updated rto +send 116: rtt = 0.329, srtt = 0.336, rttvar = 0.021, rto = 2.000 +recv 116 +updated rto +send 117: rtt = 0.300, srtt = 0.331, rttvar = 0.025, rto = 2.000 +recv 117 +updated rto +send 118: rtt = 0.339, srtt = 0.332, rttvar = 0.021, rto = 2.000 +recv 118 +updated rto +send 119: rtt = 0.350, srtt = 0.334, rttvar = 0.020, rto = 2.000 +recv 119 +updated rto +send 120: rtt = 0.330, srtt = 0.334, rttvar = 0.016, rto = 2.000 +recv 120 +updated rto +send 121: rtt = 0.329, srtt = 0.333, rttvar = 0.013, rto = 2.000 +recv 121 +updated rto +send 122: rtt = 0.310, srtt = 0.330, rttvar = 0.016, rto = 2.000 +recv 122 +updated rto +send 123: rtt = 0.320, srtt = 0.329, rttvar = 0.014, rto = 2.000 +recv 123 +updated rto +send 124: rtt = 0.289, srtt = 0.324, rttvar = 0.021, rto = 2.000 +recv 124 +updated rto +send 125: rtt = 0.320, srtt = 0.324, rttvar = 0.017, rto = 2.000 +recv 125 +updated rto +send 126: rtt = 0.300, srtt = 0.321, rttvar = 0.018, rto = 2.000 +recv 126 +updated rto +send 127: rtt = 0.336, srtt = 0.323, rttvar = 0.018, rto = 2.000 +recv 127 +updated rto +send 128: rtt = 0.334, srtt = 0.324, rttvar = 0.016, rto = 2.000 +recv 128 +updated rto +send 129: rtt = 0.290, srtt = 0.320, rttvar = 0.021, rto = 2.000 +recv 129 +updated rto +send 130: rtt = 0.319, srtt = 0.320, rttvar = 0.016, rto = 2.000 +recv 130 +updated rto +send 131: rtt = 0.410, srtt = 0.331, rttvar = 0.034, rto = 2.000 +recv 131 +updated rto +send 132: rtt = 0.320, srtt = 0.330, rttvar = 0.028, rto = 2.000 +recv 132 +updated rto +send 133: rtt = 0.349, srtt = 0.332, rttvar = 0.026, rto = 2.000 +recv 133 +updated rto +send 134: rtt = 0.370, srtt = 0.337, rttvar = 0.029, rto = 2.000 +recv 134 +updated rto +send 135: rtt = 0.359, srtt = 0.340, rttvar = 0.027, rto = 2.000 +recv 135 +updated rto +send 136: rtt = 0.320, srtt = 0.337, rttvar = 0.025, rto = 2.000 +recv 136 +updated rto +send 137: rtt = 0.290, srtt = 0.331, rttvar = 0.031, rto = 2.000 +recv 137 +updated rto +send 138: rtt = 0.330, srtt = 0.331, rttvar = 0.023, rto = 2.000 +recv 138 +updated rto +send 139: rtt = 0.330, srtt = 0.331, rttvar = 0.018, rto = 2.000 +recv 139 +updated rto +send 140: rtt = 0.310, srtt = 0.328, rttvar = 0.019, rto = 2.000 +recv 140 +updated rto +send 141: rtt = 0.320, srtt = 0.327, rttvar = 0.016, rto = 2.000 +recv 141 +updated rto +send 142: rtt = 0.289, srtt = 0.322, rttvar = 0.022, rto = 2.000 +recv 142 +updated rto +send 143: rtt = 0.299, srtt = 0.320, rttvar = 0.022, rto = 2.000 +recv 143 +updated rto +send 144: rtt = 0.329, srtt = 0.321, rttvar = 0.019, rto = 2.000 +recv 144 +updated rto +send 145: rtt = 0.310, srtt = 0.319, rttvar = 0.017, rto = 2.000 +recv 145 +updated rto +send 146: rtt = 0.290, srtt = 0.316, rttvar = 0.020, rto = 2.000 +recv 146 +updated rto +send 147: rtt = 0.310, srtt = 0.315, rttvar = 0.016, rto = 2.000 +recv 147 +updated rto +send 148: rtt = 0.310, srtt = 0.314, rttvar = 0.014, rto = 2.000 +recv 148 +updated rto +send 149: rtt = 0.319, srtt = 0.315, rttvar = 0.011, rto = 2.000 +recv 149 +updated rto +send 150: rtt = 0.339, srtt = 0.318, rttvar = 0.015, rto = 2.000 +recv 150 +updated rto +send 151: rtt = 0.309, srtt = 0.317, rttvar = 0.013, rto = 2.000 +recv 151 +updated rto +send 152: rtt = 0.299, srtt = 0.315, rttvar = 0.014, rto = 2.000 +recv 152 +updated rto +send 153: rtt = 0.410, srtt = 0.327, rttvar = 0.035, rto = 2.000 +recv 153 +updated rto +send 154: rtt = 0.340, srtt = 0.328, rttvar = 0.029, rto = 2.000 +recv 154 +updated rto +send 155: rtt = 0.330, srtt = 0.328, rttvar = 0.022, rto = 2.000 +recv 155 +updated rto +send 156: rtt = 0.369, srtt = 0.334, rttvar = 0.027, rto = 2.000 +recv 156 +updated rto +send 157: rtt = 0.320, srtt = 0.332, rttvar = 0.024, rto = 2.000 +recv 157 +updated rto +send 158: rtt = 0.350, srtt = 0.334, rttvar = 0.022, rto = 2.000 +recv 158 +updated rto +send 159: rtt = 0.360, srtt = 0.337, rttvar = 0.023, rto = 2.000 +recv 159 +updated rto +send 160: rtt = 0.290, srtt = 0.331, rttvar = 0.029, rto = 2.000 +recv 160 +updated rto +send 161: rtt = 0.360, srtt = 0.335, rttvar = 0.029, rto = 2.000 +recv 161 +updated rto +send 162: rtt = 0.310, srtt = 0.332, rttvar = 0.028, rto = 2.000 +recv 162 +updated rto +send 163: rtt = 0.309, srtt = 0.329, rttvar = 0.027, rto = 2.000 +recv 163 +updated rto +send 164: rtt = 0.320, srtt = 0.328, rttvar = 0.022, rto = 2.000 +recv 164 +updated rto +send 165: rtt = 0.319, srtt = 0.327, rttvar = 0.019, rto = 2.000 +recv 165 +updated rto +send 166: rtt = 0.309, srtt = 0.325, rttvar = 0.019, rto = 2.000 +recv 166 +updated rto +send 167: rtt = 0.329, srtt = 0.325, rttvar = 0.015, rto = 2.000 +recv 167 +updated rto +send 168: rtt = 0.688, srtt = 0.370, rttvar = 0.102, rto = 2.000 +recv 168 +updated rto +send 169: rtt = 0.322, srtt = 0.364, rttvar = 0.089, rto = 2.000 +recv 169 +updated rto +send 170: rtt = 0.310, srtt = 0.358, rttvar = 0.080, rto = 2.000 +recv 170 +updated rto +send 171: rtt = 0.299, srtt = 0.350, rttvar = 0.075, rto = 2.000 +recv 171 +updated rto +send 172: rtt = 0.339, srtt = 0.349, rttvar = 0.059, rto = 2.000 +recv 172 +updated rto +send 173: rtt = 0.329, srtt = 0.346, rttvar = 0.049, rto = 2.000 +recv 173 +updated rto +send 174: rtt = 0.309, srtt = 0.342, rttvar = 0.046, rto = 2.000 +recv 174 +updated rto +send 175: rtt = 0.308, srtt = 0.337, rttvar = 0.043, rto = 2.000 +recv 175 +updated rto +send 176: rtt = 0.299, srtt = 0.333, rttvar = 0.042, rto = 2.000 +recv 176 +updated rto +send 177: rtt = 0.349, srtt = 0.335, rttvar = 0.036, rto = 2.000 +recv 177 +updated rto +send 178: rtt = 0.346, srtt = 0.336, rttvar = 0.029, rto = 2.000 +recv 178 +updated rto +send 179: rtt = 0.333, srtt = 0.336, rttvar = 0.023, rto = 2.000 +recv 179 +updated rto +send 180: rtt = 0.370, srtt = 0.340, rttvar = 0.026, rto = 2.000 +recv 180 +updated rto +send 181: rtt = 0.300, srtt = 0.335, rttvar = 0.029, rto = 2.000 +recv 181 +updated rto +send 182: rtt = 0.329, srtt = 0.334, rttvar = 0.023, rto = 2.000 +recv 182 +updated rto +send 183: rtt = 0.309, srtt = 0.331, rttvar = 0.024, rto = 2.000 +recv 183 +updated rto +send 184: rtt = 0.330, srtt = 0.331, rttvar = 0.018, rto = 2.000 +recv 184 +updated rto +send 185: rtt = 0.330, srtt = 0.331, rttvar = 0.014, rto = 2.000 +recv 185 +updated rto +send 186: rtt = 0.340, srtt = 0.332, rttvar = 0.013, rto = 2.000 +recv 186 +updated rto +send 187: rtt = 0.353, srtt = 0.335, rttvar = 0.015, rto = 2.000 +recv 187 +updated rto +send 188: rtt = 0.415, srtt = 0.345, rttvar = 0.031, rto = 2.000 +recv 188 +updated rto +send 189: rtt = 0.329, srtt = 0.343, rttvar = 0.027, rto = 2.000 +recv 189 +updated rto +send 190: rtt = 0.334, srtt = 0.342, rttvar = 0.023, rto = 2.000 +recv 190 +updated rto +send 191: rtt = 0.335, srtt = 0.341, rttvar = 0.019, rto = 2.000 +recv 191 +updated rto +send 192: rtt = 0.310, srtt = 0.337, rttvar = 0.022, rto = 2.000 +recv 192 +updated rto +send 193: rtt = 0.350, srtt = 0.339, rttvar = 0.020, rto = 2.000 +recv 193 +updated rto +send 194: rtt = 0.320, srtt = 0.336, rttvar = 0.019, rto = 2.000 +recv 194 +updated rto +send 195: rtt = 0.360, srtt = 0.339, rttvar = 0.020, rto = 2.000 +recv 195 +updated rto +send 196: rtt = 0.320, srtt = 0.337, rttvar = 0.020, rto = 2.000 +recv 196 +updated rto +send 197: rtt = 0.310, srtt = 0.333, rttvar = 0.022, rto = 2.000 +recv 197 +updated rto +send 198: rtt = 0.350, srtt = 0.336, rttvar = 0.020, rto = 2.000 +recv 198 +updated rto +send 199: rtt = 0.370, srtt = 0.340, rttvar = 0.024, rto = 2.000 +recv 199 +updated rto +send 200: rtt = 0.309, srtt = 0.336, rttvar = 0.026, rto = 2.000 +recv 200 +updated rto +send 201: rtt = 0.329, srtt = 0.335, rttvar = 0.021, rto = 2.000 +recv 201 +updated rto +send 202: rtt = 0.322, srtt = 0.333, rttvar = 0.019, rto = 2.000 +recv 202 +updated rto +send 203: rtt = 0.287, srtt = 0.328, rttvar = 0.026, rto = 2.000 +recv 203 +updated rto +send 204: rtt = 0.290, srtt = 0.323, rttvar = 0.029, rto = 2.000 +recv 204 +updated rto +send 205: rtt = 0.284, srtt = 0.318, rttvar = 0.031, rto = 2.000 +recv 205 +updated rto +send 206: rtt = 0.335, srtt = 0.320, rttvar = 0.028, rto = 2.000 +recv 206 +updated rto +send 207: rtt = 0.331, srtt = 0.322, rttvar = 0.024, rto = 2.000 +recv 207 +updated rto +send 208: rtt = 0.338, srtt = 0.324, rttvar = 0.022, rto = 2.000 +recv 208 +updated rto +send 209: rtt = 0.320, srtt = 0.323, rttvar = 0.017, rto = 2.000 +recv 209 +updated rto +send 210: rtt = 0.349, srtt = 0.326, rttvar = 0.019, rto = 2.000 +recv 210 +updated rto +send 211: rtt = 0.339, srtt = 0.328, rttvar = 0.018, rto = 2.000 +recv 211 +updated rto +send 212: rtt = 0.379, srtt = 0.334, rttvar = 0.026, rto = 2.000 +recv 212 +updated rto +send 213: rtt = 0.380, srtt = 0.340, rttvar = 0.031, rto = 2.000 +recv 213 +updated rto +send 214: rtt = 0.400, srtt = 0.348, rttvar = 0.038, rto = 2.000 +recv 214 +updated rto +send 215: rtt = 0.329, srtt = 0.345, rttvar = 0.033, rto = 2.000 +recv 215 +updated rto +send 216: rtt = 0.360, srtt = 0.347, rttvar = 0.029, rto = 2.000 +recv 216 +updated rto +send 217: rtt = 0.329, srtt = 0.345, rttvar = 0.026, rto = 2.000 +recv 217 +updated rto +send 218: rtt = 0.350, srtt = 0.345, rttvar = 0.021, rto = 2.000 +recv 218 +updated rto +send 219: rtt = 0.352, srtt = 0.346, rttvar = 0.017, rto = 2.000 +recv 219 +updated rto +send 220: rtt = 0.321, srtt = 0.343, rttvar = 0.019, rto = 2.000 +recv 220 +updated rto +send 221: rtt = 0.306, srtt = 0.338, rttvar = 0.024, rto = 2.000 +recv 221 +updated rto +send 222: rtt = 0.339, srtt = 0.339, rttvar = 0.018, rto = 2.000 +recv 222 +updated rto +send 223: rtt = 0.319, srtt = 0.336, rttvar = 0.018, rto = 2.000 +recv 223 +updated rto +send 224: rtt = 0.320, srtt = 0.334, rttvar = 0.018, rto = 2.000 +recv 224 +updated rto +send 225: rtt = 0.320, srtt = 0.332, rttvar = 0.017, rto = 2.000 +recv 225 +updated rto +send 226: rtt = 0.339, srtt = 0.333, rttvar = 0.014, rto = 2.000 +recv 226 +updated rto +send 227: rtt = 0.380, srtt = 0.339, rttvar = 0.022, rto = 2.000 +recv 227 +updated rto +send 228: rtt = 0.309, srtt = 0.335, rttvar = 0.024, rto = 2.000 +recv 228 +updated rto +send 229: rtt = 0.319, srtt = 0.333, rttvar = 0.022, rto = 2.000 +recv 229 +updated rto +send 230: rtt = 0.342, srtt = 0.334, rttvar = 0.019, rto = 2.000 +recv 230 +updated rto +send 231: rtt = 0.346, srtt = 0.336, rttvar = 0.017, rto = 2.000 +recv 231 +updated rto +send 232: rtt = 0.339, srtt = 0.336, rttvar = 0.014, rto = 2.000 +recv 232 +updated rto +send 233: rtt = 0.350, srtt = 0.338, rttvar = 0.014, rto = 2.000 +recv 233 +updated rto +send 234: rtt = 0.292, srtt = 0.332, rttvar = 0.022, rto = 2.000 +recv 234 +updated rto +send 235: rtt = 0.336, srtt = 0.333, rttvar = 0.017, rto = 2.000 +recv 235 +updated rto +send 236: rtt = 0.310, srtt = 0.330, rttvar = 0.019, rto = 2.000 +recv 236 +updated rto +send 237: rtt = 0.319, srtt = 0.328, rttvar = 0.017, rto = 2.000 +recv 237 +updated rto +send 238: rtt = 0.323, srtt = 0.328, rttvar = 0.014, rto = 2.000 +recv 238 +updated rto +send 239: rtt = 0.286, srtt = 0.323, rttvar = 0.021, rto = 2.000 +recv 239 +updated rto +send 240: rtt = 0.290, srtt = 0.318, rttvar = 0.024, rto = 2.000 +recv 240 +updated rto +send 241: rtt = 0.280, srtt = 0.314, rttvar = 0.027, rto = 2.000 +recv 241 +updated rto +send 242: rtt = 0.330, srtt = 0.316, rttvar = 0.025, rto = 2.000 +recv 242 +updated rto +send 243: rtt = 0.354, srtt = 0.321, rttvar = 0.028, rto = 2.000 +recv 243 +updated rto +send 244: rtt = 0.315, srtt = 0.320, rttvar = 0.022, rto = 2.000 +recv 244 +updated rto +send 245: rtt = 0.349, srtt = 0.323, rttvar = 0.024, rto = 2.000 +recv 245 +updated rto +send 246: rtt = 0.420, srtt = 0.336, rttvar = 0.042, rto = 2.000 +recv 246 +updated rto +send 247: rtt = 0.309, srtt = 0.332, rttvar = 0.038, rto = 2.000 +recv 247 +updated rto +send 248: rtt = 0.309, srtt = 0.329, rttvar = 0.035, rto = 2.000 +recv 248 +updated rto +send 249: rtt = 0.322, srtt = 0.328, rttvar = 0.028, rto = 2.000 +recv 249 +updated rto +send 250: rtt = 0.327, srtt = 0.328, rttvar = 0.021, rto = 2.000 +recv 250 +updated rto +send 251: rtt = 0.309, srtt = 0.326, rttvar = 0.021, rto = 2.000 +recv 251 +updated rto +send 252: rtt = 0.300, srtt = 0.323, rttvar = 0.022, rto = 2.000 +recv 252 +updated rto +send 253: rtt = 0.309, srtt = 0.321, rttvar = 0.020, rto = 2.000 +recv 253 +updated rto +send 254: rtt = 0.310, srtt = 0.320, rttvar = 0.018, rto = 2.000 +recv 254 +updated rto +send 255: rtt = 0.310, srtt = 0.318, rttvar = 0.016, rto = 2.000 +recv 255 +updated rto +send 256: rtt = 0.309, srtt = 0.317, rttvar = 0.014, rto = 2.000 +recv 256 +updated rto +send 257: rtt = 0.340, srtt = 0.320, rttvar = 0.016, rto = 2.000 +recv 257 +updated rto +send 258: rtt = 0.322, srtt = 0.320, rttvar = 0.013, rto = 2.000 +recv 258 +updated rto +send 259: rtt = 0.377, srtt = 0.327, rttvar = 0.024, rto = 2.000 +recv 259 +updated rto +send 260: rtt = 0.363, srtt = 0.332, rttvar = 0.027, rto = 2.000 +recv 260 +updated rto +send 261: rtt = 0.367, srtt = 0.336, rttvar = 0.029, rto = 2.000 +recv 261 +updated rto +send 262: rtt = 0.360, srtt = 0.339, rttvar = 0.028, rto = 2.000 +recv 262 +updated rto +send 263: rtt = 0.321, srtt = 0.337, rttvar = 0.025, rto = 2.000 +recv 263 +updated rto +send 264: rtt = 0.308, srtt = 0.333, rttvar = 0.026, rto = 2.000 +recv 264 +updated rto +send 265: rtt = 0.280, srtt = 0.327, rttvar = 0.033, rto = 2.000 +recv 265 +updated rto +send 266: rtt = 0.319, srtt = 0.326, rttvar = 0.027, rto = 2.000 +recv 266 +updated rto +send 267: rtt = 0.322, srtt = 0.325, rttvar = 0.021, rto = 2.000 +recv 267 +updated rto +send 268: rtt = 0.297, srtt = 0.322, rttvar = 0.023, rto = 2.000 +recv 268 +updated rto +send 269: rtt = 0.319, srtt = 0.321, rttvar = 0.018, rto = 2.000 +recv 269 +updated rto +send 270: rtt = 0.340, srtt = 0.324, rttvar = 0.018, rto = 2.000 +recv 270 +updated rto +send 271: rtt = 0.370, srtt = 0.329, rttvar = 0.025, rto = 2.000 +recv 271 +updated rto +send 272: rtt = 0.310, srtt = 0.327, rttvar = 0.024, rto = 2.000 +recv 272 +updated rto +send 273: rtt = 0.310, srtt = 0.325, rttvar = 0.022, rto = 2.000 +recv 273 +updated rto +send 274: rtt = 0.309, srtt = 0.323, rttvar = 0.020, rto = 2.000 +recv 274 +updated rto +send 275: rtt = 0.370, srtt = 0.329, rttvar = 0.027, rto = 2.000 +recv 275 +updated rto +send 276: rtt = 0.320, srtt = 0.328, rttvar = 0.023, rto = 2.000 +recv 276 +updated rto +send 277: rtt = 0.332, srtt = 0.328, rttvar = 0.018, rto = 2.000 +recv 277 +updated rto +send 278: rtt = 0.337, srtt = 0.329, rttvar = 0.016, rto = 2.000 +recv 278 +updated rto +send 279: rtt = 0.309, srtt = 0.327, rttvar = 0.017, rto = 2.000 +recv 279 +updated rto +send 280: rtt = 0.310, srtt = 0.325, rttvar = 0.017, rto = 2.000 +recv 280 +updated rto +send 281: rtt = 0.289, srtt = 0.320, rttvar = 0.022, rto = 2.000 +recv 281 +updated rto +send 282: rtt = 0.300, srtt = 0.318, rttvar = 0.021, rto = 2.000 +recv 282 +updated rto +send 283: rtt = 0.279, srtt = 0.313, rttvar = 0.026, rto = 2.000 +recv 283 +updated rto +send 284: rtt = 0.339, srtt = 0.316, rttvar = 0.026, rto = 2.000 +recv 284 +updated rto +send 285: rtt = 0.303, srtt = 0.314, rttvar = 0.023, rto = 2.000 +recv 285 +updated rto +send 286: rtt = 0.335, srtt = 0.317, rttvar = 0.022, rto = 2.000 +recv 286 +updated rto +send 287: rtt = 0.322, srtt = 0.318, rttvar = 0.018, rto = 2.000 +recv 287 +updated rto +send 288: rtt = 0.327, srtt = 0.319, rttvar = 0.016, rto = 2.000 +recv 288 +updated rto +send 289: rtt = 0.309, srtt = 0.318, rttvar = 0.014, rto = 2.000 +recv 289 +updated rto +send 290: rtt = 0.320, srtt = 0.318, rttvar = 0.011, rto = 2.000 +recv 290 +updated rto +send 291: rtt = 0.329, srtt = 0.319, rttvar = 0.011, rto = 2.000 +recv 291 +updated rto +send 292: rtt = 0.320, srtt = 0.319, rttvar = 0.009, rto = 2.000 +recv 292 +updated rto +send 293: rtt = 0.309, srtt = 0.318, rttvar = 0.009, rto = 2.000 +recv 293 +updated rto +send 294: rtt = 0.314, srtt = 0.318, rttvar = 0.008, rto = 2.000 +recv 294 +updated rto +send 295: rtt = 0.315, srtt = 0.317, rttvar = 0.006, rto = 2.000 +recv 295 +updated rto +send 296: rtt = 0.300, srtt = 0.315, rttvar = 0.009, rto = 2.000 +recv 296 +updated rto +send 297: rtt = 0.314, srtt = 0.315, rttvar = 0.007, rto = 2.000 +recv 297 +updated rto +send 298: rtt = 0.327, srtt = 0.316, rttvar = 0.008, rto = 2.000 +recv 298 +updated rto +send 299: rtt = 0.307, srtt = 0.315, rttvar = 0.009, rto = 2.000 +recv 299 +updated rto +send 300: rtt = 0.370, srtt = 0.322, rttvar = 0.020, rto = 2.000 +recv 300 +updated rto +send 301: rtt = 0.368, srtt = 0.328, rttvar = 0.027, rto = 2.000 +recv 301 +updated rto +send 302: rtt = 0.330, srtt = 0.328, rttvar = 0.020, rto = 2.000 +recv 302 +updated rto +send 303: rtt = 0.310, srtt = 0.326, rttvar = 0.020, rto = 2.000 +recv 303 +updated rto +send 304: rtt = 0.319, srtt = 0.325, rttvar = 0.017, rto = 2.000 +recv 304 +updated rto +send 305: rtt = 0.339, srtt = 0.327, rttvar = 0.016, rto = 2.000 +recv 305 +updated rto +send 306: rtt = 0.320, srtt = 0.326, rttvar = 0.014, rto = 2.000 +recv 306 +updated rto +send 307: rtt = 0.330, srtt = 0.326, rttvar = 0.011, rto = 2.000 +recv 307 +updated rto +send 308: rtt = 0.350, srtt = 0.329, rttvar = 0.014, rto = 2.000 +recv 308 +updated rto +send 309: rtt = 0.320, srtt = 0.328, rttvar = 0.013, rto = 2.000 +recv 309 +updated rto +send 310: rtt = 0.340, srtt = 0.330, rttvar = 0.013, rto = 2.000 +recv 310 +updated rto +send 311: rtt = 0.320, srtt = 0.328, rttvar = 0.012, rto = 2.000 +recv 311 +updated rto +send 312: rtt = 0.310, srtt = 0.326, rttvar = 0.014, rto = 2.000 +recv 312 +updated rto +send 313: rtt = 0.320, srtt = 0.325, rttvar = 0.012, rto = 2.000 +recv 313 +updated rto +send 314: rtt = 0.340, srtt = 0.327, rttvar = 0.012, rto = 2.000 +recv 314 +updated rto +send 315: rtt = 0.304, srtt = 0.324, rttvar = 0.015, rto = 2.000 +recv 315 +updated rto +send 316: rtt = 0.324, srtt = 0.324, rttvar = 0.011, rto = 2.000 +recv 316 +updated rto +send 317: rtt = 0.330, srtt = 0.325, rttvar = 0.010, rto = 2.000 +recv 317 +updated rto +send 318: rtt = 0.344, srtt = 0.327, rttvar = 0.012, rto = 2.000 +recv 318 +updated rto +send 319: rtt = 0.305, srtt = 0.325, rttvar = 0.015, rto = 2.000 +recv 319 +updated rto +send 320: rtt = 0.299, srtt = 0.321, rttvar = 0.017, rto = 2.000 +recv 320 +updated rto +send 321: rtt = 0.320, srtt = 0.321, rttvar = 0.013, rto = 2.000 +recv 321 +updated rto +send 322: rtt = 0.319, srtt = 0.321, rttvar = 0.011, rto = 2.000 +recv 322 +updated rto +send 323: rtt = 0.320, srtt = 0.321, rttvar = 0.008, rto = 2.000 +recv 323 +updated rto +send 324: rtt = 0.320, srtt = 0.321, rttvar = 0.006, rto = 2.000 +recv 324 +updated rto +send 325: rtt = 0.320, srtt = 0.321, rttvar = 0.005, rto = 2.000 +recv 325 +updated rto +send 326: rtt = 0.329, srtt = 0.322, rttvar = 0.006, rto = 2.000 +recv 326 +updated rto +send 327: rtt = 0.340, srtt = 0.324, rttvar = 0.009, rto = 2.000 +recv 327 +updated rto +send 328: rtt = 0.289, srtt = 0.320, rttvar = 0.015, rto = 2.000 +recv 328 +updated rto +send 329: rtt = 0.329, srtt = 0.321, rttvar = 0.014, rto = 2.000 +recv 329 +updated rto +send 330: rtt = 0.310, srtt = 0.319, rttvar = 0.013, rto = 2.000 +recv 330 +updated rto +send 331: rtt = 0.330, srtt = 0.321, rttvar = 0.013, rto = 2.000 +recv 331 +updated rto +send 332: rtt = 0.290, srtt = 0.317, rttvar = 0.017, rto = 2.000 +recv 332 +updated rto +send 333: rtt = 0.293, srtt = 0.314, rttvar = 0.019, rto = 2.000 +recv 333 +updated rto +send 334: rtt = 0.317, srtt = 0.314, rttvar = 0.015, rto = 2.000 +recv 334 +updated rto +send 335: rtt = 0.332, srtt = 0.317, rttvar = 0.016, rto = 2.000 +recv 335 +updated rto +send 336: rtt = 0.307, srtt = 0.315, rttvar = 0.014, rto = 2.000 +recv 336 +updated rto +send 337: rtt = 0.299, srtt = 0.313, rttvar = 0.015, rto = 2.000 +recv 337 +updated rto +send 338: rtt = 0.313, srtt = 0.313, rttvar = 0.011, rto = 2.000 +recv 338 +updated rto +send 339: rtt = 0.326, srtt = 0.315, rttvar = 0.011, rto = 2.000 +recv 339 +updated rto +send 340: rtt = 0.303, srtt = 0.313, rttvar = 0.012, rto = 2.000 +recv 340 +updated rto +send 341: rtt = 0.297, srtt = 0.311, rttvar = 0.013, rto = 2.000 +recv 341 +updated rto +send 342: rtt = 0.309, srtt = 0.311, rttvar = 0.010, rto = 2.000 +recv 342 +updated rto +send 343: rtt = 0.310, srtt = 0.311, rttvar = 0.008, rto = 2.000 +recv 343 +updated rto +send 344: rtt = 0.329, srtt = 0.313, rttvar = 0.010, rto = 2.000 +recv 344 +updated rto +send 345: rtt = 0.310, srtt = 0.313, rttvar = 0.009, rto = 2.000 +recv 345 +updated rto +send 346: rtt = 0.299, srtt = 0.311, rttvar = 0.010, rto = 2.000 +recv 346 +updated rto +send 347: rtt = 0.350, srtt = 0.316, rttvar = 0.017, rto = 2.000 +recv 347 +updated rto +send 348: rtt = 0.299, srtt = 0.314, rttvar = 0.017, rto = 2.000 +recv 348 +updated rto +send 349: rtt = 0.329, srtt = 0.316, rttvar = 0.017, rto = 2.000 +recv 349 +updated rto +send 350: rtt = 0.430, srtt = 0.330, rttvar = 0.041, rto = 2.000 +recv 350 +updated rto +send 351: rtt = 0.319, srtt = 0.329, rttvar = 0.034, rto = 2.000 +recv 351 +updated rto +send 352: rtt = 0.340, srtt = 0.330, rttvar = 0.028, rto = 2.000 +recv 352 +updated rto +send 353: rtt = 0.300, srtt = 0.326, rttvar = 0.029, rto = 2.000 +recv 353 +updated rto +send 354: rtt = 0.323, srtt = 0.326, rttvar = 0.022, rto = 2.000 +recv 354 +updated rto +send 355: rtt = 0.295, srtt = 0.322, rttvar = 0.024, rto = 2.000 +recv 355 +updated rto +send 356: rtt = 0.346, srtt = 0.325, rttvar = 0.024, rto = 2.000 +recv 356 +updated rto +send 357: rtt = 0.366, srtt = 0.330, rttvar = 0.028, rto = 2.000 +recv 357 +updated rto +send 358: rtt = 0.400, srtt = 0.339, rttvar = 0.039, rto = 2.000 +recv 358 +updated rto +send 359: rtt = 0.316, srtt = 0.336, rttvar = 0.035, rto = 2.000 +recv 359 +updated rto +send 360: rtt = 0.341, srtt = 0.337, rttvar = 0.027, rto = 2.000 +recv 360 +updated rto +send 361: rtt = 0.305, srtt = 0.333, rttvar = 0.028, rto = 2.000 +recv 361 +updated rto +send 362: rtt = 0.310, srtt = 0.330, rttvar = 0.027, rto = 2.000 +recv 362 +updated rto +send 363: rtt = 0.319, srtt = 0.328, rttvar = 0.023, rto = 2.000 +recv 363 +updated rto +send 364: rtt = 0.320, srtt = 0.327, rttvar = 0.019, rto = 2.000 +recv 364 +updated rto +send 365: rtt = 0.340, srtt = 0.329, rttvar = 0.018, rto = 2.000 +recv 365 +updated rto +send 366: rtt = 0.318, srtt = 0.328, rttvar = 0.016, rto = 2.000 +recv 366 +updated rto +send 367: rtt = 0.330, srtt = 0.328, rttvar = 0.013, rto = 2.000 +recv 367 +updated rto +send 368: rtt = 0.319, srtt = 0.327, rttvar = 0.012, rto = 2.000 +recv 368 +updated rto +send 369: rtt = 0.329, srtt = 0.327, rttvar = 0.009, rto = 2.000 +recv 369 +updated rto +send 370: rtt = 0.320, srtt = 0.326, rttvar = 0.009, rto = 2.000 +recv 370 +updated rto +send 371: rtt = 0.288, srtt = 0.321, rttvar = 0.016, rto = 2.000 +recv 371 +updated rto +send 372: rtt = 0.340, srtt = 0.324, rttvar = 0.017, rto = 2.000 +recv 372 +updated rto +send 373: rtt = 0.290, srtt = 0.320, rttvar = 0.021, rto = 2.000 +recv 373 +updated rto +send 374: rtt = 0.324, srtt = 0.320, rttvar = 0.017, rto = 2.000 +recv 374 +updated rto +send 375: rtt = 0.294, srtt = 0.317, rttvar = 0.019, rto = 2.000 +recv 375 +updated rto +send 376: rtt = 0.329, srtt = 0.318, rttvar = 0.017, rto = 2.000 +recv 376 +updated rto +send 377: rtt = 0.339, srtt = 0.321, rttvar = 0.018, rto = 2.000 +recv 377 +updated rto +send 378: rtt = 0.329, srtt = 0.322, rttvar = 0.016, rto = 2.000 +recv 378 +updated rto +send 379: rtt = 0.309, srtt = 0.320, rttvar = 0.015, rto = 2.000 +recv 379 +updated rto +send 380: rtt = 0.320, srtt = 0.320, rttvar = 0.011, rto = 2.000 +recv 380 +updated rto +send 381: rtt = 0.310, srtt = 0.319, rttvar = 0.011, rto = 2.000 +recv 381 +updated rto +send 382: rtt = 0.340, srtt = 0.322, rttvar = 0.014, rto = 2.000 +recv 382 +updated rto +send 383: rtt = 0.329, srtt = 0.323, rttvar = 0.012, rto = 2.000 +recv 383 +updated rto +send 384: rtt = 0.320, srtt = 0.322, rttvar = 0.010, rto = 2.000 +recv 384 +updated rto +send 385: rtt = 0.330, srtt = 0.323, rttvar = 0.009, rto = 2.000 +recv 385 +updated rto +send 386: rtt = 0.320, srtt = 0.323, rttvar = 0.008, rto = 2.000 +recv 386 +updated rto +send 387: rtt = 0.339, srtt = 0.325, rttvar = 0.010, rto = 2.000 +recv 387 +updated rto +send 388: rtt = 0.306, srtt = 0.322, rttvar = 0.012, rto = 2.000 +recv 388 +updated rto +send 389: rtt = 0.313, srtt = 0.321, rttvar = 0.011, rto = 2.000 +recv 389 +updated rto +send 390: rtt = 0.289, srtt = 0.317, rttvar = 0.017, rto = 2.000 +recv 390 +updated rto +send 391: rtt = 0.360, srtt = 0.323, rttvar = 0.023, rto = 2.000 +recv 391 +updated rto +send 392: rtt = 0.329, srtt = 0.323, rttvar = 0.019, rto = 2.000 +recv 392 +updated rto +send 393: rtt = 0.402, srtt = 0.333, rttvar = 0.034, rto = 2.000 +recv 393 +updated rto +send 394: rtt = 0.327, srtt = 0.332, rttvar = 0.027, rto = 2.000 +recv 394 +updated rto +send 395: rtt = 0.340, srtt = 0.333, rttvar = 0.022, rto = 2.000 +recv 395 +updated rto +send 396: rtt = 0.330, srtt = 0.333, rttvar = 0.017, rto = 2.000 +recv 396 +updated rto +send 397: rtt = 0.344, srtt = 0.334, rttvar = 0.016, rto = 2.000 +recv 397 +updated rto +send 398: rtt = 0.345, srtt = 0.336, rttvar = 0.015, rto = 2.000 +recv 398 +updated rto +send 399: rtt = 0.379, srtt = 0.341, rttvar = 0.022, rto = 2.000 +recv 399 +updated rto +send 400: rtt = 0.349, srtt = 0.342, rttvar = 0.018, rto = 2.000 +recv 400 +updated rto +send 401: rtt = 0.339, srtt = 0.342, rttvar = 0.014, rto = 2.000 +recv 401 +updated rto +send 402: rtt = 0.329, srtt = 0.340, rttvar = 0.014, rto = 2.000 +recv 402 +updated rto +send 403: rtt = 0.320, srtt = 0.338, rttvar = 0.016, rto = 2.000 +recv 403 +updated rto +send 404: rtt = 0.374, srtt = 0.342, rttvar = 0.021, rto = 2.000 +recv 404 +updated rto +send 405: rtt = 0.337, srtt = 0.342, rttvar = 0.017, rto = 2.000 +recv 405 +updated rto +send 406: rtt = 0.347, srtt = 0.342, rttvar = 0.014, rto = 2.000 +recv 406 +updated rto +send 407: rtt = 0.339, srtt = 0.342, rttvar = 0.011, rto = 2.000 +recv 407 +updated rto +send 408: rtt = 0.340, srtt = 0.342, rttvar = 0.009, rto = 2.000 +recv 408 +updated rto +send 409: rtt = 0.410, srtt = 0.350, rttvar = 0.024, rto = 2.000 +recv 409 +updated rto +send 410: rtt = 0.339, srtt = 0.349, rttvar = 0.021, rto = 2.000 +recv 410 +updated rto +send 411: rtt = 0.430, srtt = 0.359, rttvar = 0.036, rto = 2.000 +recv 411 +updated rto +send 412: rtt = 0.380, srtt = 0.362, rttvar = 0.032, rto = 2.000 +recv 412 +updated rto +send 413: rtt = 0.310, srtt = 0.355, rttvar = 0.037, rto = 2.000 +recv 413 +updated rto +send 414: rtt = 0.319, srtt = 0.351, rttvar = 0.037, rto = 2.000 +recv 414 +updated rto +send 415: rtt = 0.319, srtt = 0.347, rttvar = 0.035, rto = 2.000 +recv 415 +updated rto +send 416: rtt = 0.309, srtt = 0.342, rttvar = 0.036, rto = 2.000 +recv 416 +updated rto +send 417: rtt = 0.320, srtt = 0.339, rttvar = 0.032, rto = 2.000 +recv 417 +updated rto +send 418: rtt = 0.320, srtt = 0.337, rttvar = 0.029, rto = 2.000 +recv 418 +updated rto +send 419: rtt = 0.329, srtt = 0.336, rttvar = 0.024, rto = 2.000 +recv 419 +updated rto +send 420: rtt = 0.349, srtt = 0.337, rttvar = 0.021, rto = 2.000 +recv 420 +updated rto +send 421: rtt = 0.309, srtt = 0.334, rttvar = 0.023, rto = 2.000 +recv 421 +updated rto +send 422: rtt = 0.309, srtt = 0.331, rttvar = 0.023, rto = 2.000 +recv 422 +updated rto +send 423: rtt = 0.319, srtt = 0.329, rttvar = 0.021, rto = 2.000 +recv 423 +updated rto +send 424: rtt = 0.380, srtt = 0.336, rttvar = 0.028, rto = 2.000 +recv 424 +updated rto +send 425: rtt = 0.302, srtt = 0.331, rttvar = 0.029, rto = 2.000 +recv 425 +updated rto +send 426: rtt = 0.347, srtt = 0.333, rttvar = 0.026, rto = 2.000 +recv 426 +updated rto +send 427: rtt = 0.340, srtt = 0.334, rttvar = 0.021, rto = 2.000 +recv 427 +updated rto +send 428: rtt = 0.350, srtt = 0.336, rttvar = 0.020, rto = 2.000 +recv 428 +updated rto +send 429: rtt = 0.336, srtt = 0.336, rttvar = 0.015, rto = 2.000 +recv 429 +updated rto +send 430: rtt = 0.324, srtt = 0.335, rttvar = 0.014, rto = 2.000 +recv 430 +updated rto +send 431: rtt = 0.328, srtt = 0.334, rttvar = 0.012, rto = 2.000 +recv 431 +updated rto +send 432: rtt = 0.320, srtt = 0.332, rttvar = 0.013, rto = 2.000 +recv 432 +updated rto +send 433: rtt = 0.301, srtt = 0.328, rttvar = 0.017, rto = 2.000 +recv 433 +updated rto +send 434: rtt = 0.317, srtt = 0.327, rttvar = 0.016, rto = 2.000 +recv 434 +updated rto +send 435: rtt = 0.309, srtt = 0.325, rttvar = 0.016, rto = 2.000 +recv 435 +updated rto +send 436: rtt = 0.330, srtt = 0.325, rttvar = 0.014, rto = 2.000 +recv 436 +updated rto +send 437: rtt = 0.300, srtt = 0.322, rttvar = 0.016, rto = 2.000 +recv 437 +updated rto +send 438: rtt = 0.320, srtt = 0.322, rttvar = 0.013, rto = 2.000 +recv 438 +updated rto +send 439: rtt = 0.319, srtt = 0.321, rttvar = 0.010, rto = 2.000 +recv 439 +updated rto +send 440: rtt = 0.323, srtt = 0.322, rttvar = 0.008, rto = 2.000 +recv 440 +updated rto +send 441: rtt = 0.295, srtt = 0.318, rttvar = 0.013, rto = 2.000 +recv 441 +updated rto +send 442: rtt = 0.340, srtt = 0.321, rttvar = 0.015, rto = 2.000 +recv 442 +updated rto +send 443: rtt = 0.340, srtt = 0.323, rttvar = 0.016, rto = 2.000 +recv 443 +updated rto +send 444: rtt = 0.310, srtt = 0.322, rttvar = 0.015, rto = 2.000 +recv 444 +updated rto +send 445: rtt = 0.300, srtt = 0.319, rttvar = 0.017, rto = 2.000 +recv 445 +updated rto +send 446: rtt = 0.349, srtt = 0.323, rttvar = 0.020, rto = 2.000 +recv 446 +updated rto +send 447: rtt = 0.409, srtt = 0.334, rttvar = 0.037, rto = 2.000 +recv 447 +updated rto +send 448: rtt = 0.360, srtt = 0.337, rttvar = 0.034, rto = 2.000 +recv 448 +updated rto +send 449: rtt = 0.300, srtt = 0.332, rttvar = 0.035, rto = 2.000 +recv 449 +updated rto +send 450: rtt = 0.323, srtt = 0.331, rttvar = 0.028, rto = 2.000 +recv 450 +updated rto +send 451: rtt = 0.326, srtt = 0.330, rttvar = 0.023, rto = 2.000 +recv 451 +updated rto +send 452: rtt = 0.348, srtt = 0.333, rttvar = 0.021, rto = 2.000 +recv 452 +updated rto +send 453: rtt = 0.672, srtt = 0.375, rttvar = 0.101, rto = 2.000 +recv 453 +updated rto +send 454: rtt = 0.337, srtt = 0.370, rttvar = 0.085, rto = 2.000 +recv 454 +updated rto +send 455: rtt = 0.298, srtt = 0.361, rttvar = 0.082, rto = 2.000 +recv 455 +updated rto +send 456: rtt = 0.335, srtt = 0.358, rttvar = 0.068, rto = 2.000 +recv 456 +updated rto +send 457: rtt = 0.334, srtt = 0.355, rttvar = 0.057, rto = 2.000 +recv 457 +updated rto +send 458: rtt = 0.329, srtt = 0.352, rttvar = 0.049, rto = 2.000 +recv 458 +updated rto +send 459: rtt = 0.343, srtt = 0.351, rttvar = 0.039, rto = 2.000 +recv 459 +updated rto +send 460: rtt = 0.325, srtt = 0.347, rttvar = 0.036, rto = 2.000 +recv 460 +updated rto +send 461: rtt = 0.309, srtt = 0.343, rttvar = 0.036, rto = 2.000 +recv 461 +updated rto +send 462: rtt = 0.459, srtt = 0.357, rttvar = 0.056, rto = 2.000 +recv 462 +updated rto +send 463: rtt = 0.350, srtt = 0.356, rttvar = 0.044, rto = 2.000 +recv 463 +updated rto +send 464: rtt = 0.350, srtt = 0.355, rttvar = 0.035, rto = 2.000 +recv 464 +updated rto +send 465: rtt = 0.352, srtt = 0.355, rttvar = 0.027, rto = 2.000 +recv 465 +updated rto +send 466: rtt = 0.327, srtt = 0.352, rttvar = 0.027, rto = 2.000 +recv 466 +updated rto +send 467: rtt = 0.320, srtt = 0.348, rttvar = 0.028, rto = 2.000 +recv 467 +updated rto +send 468: rtt = 0.340, srtt = 0.347, rttvar = 0.023, rto = 2.000 +recv 468 +updated rto +send 469: rtt = 0.357, srtt = 0.348, rttvar = 0.020, rto = 2.000 +recv 469 +updated rto +send 470: rtt = 0.301, srtt = 0.342, rttvar = 0.027, rto = 2.000 +recv 470 +updated rto +send 471: rtt = 0.410, srtt = 0.351, rttvar = 0.037, rto = 2.000 +recv 471 +updated rto +send 472: rtt = 0.360, srtt = 0.352, rttvar = 0.030, rto = 2.000 +recv 472 +updated rto +send 473: rtt = 0.350, srtt = 0.352, rttvar = 0.023, rto = 2.000 +recv 473 +updated rto +send 474: rtt = 0.329, srtt = 0.349, rttvar = 0.023, rto = 2.000 +recv 474 +updated rto +send 475: rtt = 0.359, srtt = 0.350, rttvar = 0.020, rto = 2.000 +recv 475 +updated rto +send 476: rtt = 0.330, srtt = 0.348, rttvar = 0.020, rto = 2.000 +recv 476 +updated rto +send 477: rtt = 0.300, srtt = 0.342, rttvar = 0.027, rto = 2.000 +recv 477 +updated rto +send 478: rtt = 0.339, srtt = 0.341, rttvar = 0.021, rto = 2.000 +recv 478 +updated rto +send 479: rtt = 0.319, srtt = 0.338, rttvar = 0.021, rto = 2.000 +recv 479 +updated rto +send 480: rtt = 0.310, srtt = 0.335, rttvar = 0.023, rto = 2.000 +recv 480 +updated rto +send 481: rtt = 0.330, srtt = 0.334, rttvar = 0.018, rto = 2.000 +recv 481 +updated rto +send 482: rtt = 0.379, srtt = 0.340, rttvar = 0.025, rto = 2.000 +recv 482 +updated rto +send 483: rtt = 0.360, srtt = 0.342, rttvar = 0.024, rto = 2.000 +recv 483 +updated rto +send 484: rtt = 0.310, srtt = 0.338, rttvar = 0.026, rto = 2.000 +recv 484 +updated rto +send 485: rtt = 0.330, srtt = 0.337, rttvar = 0.022, rto = 2.000 +recv 485 +updated rto +send 486: rtt = 0.340, srtt = 0.338, rttvar = 0.017, rto = 2.000 +recv 486 +updated rto +send 487: rtt = 0.311, srtt = 0.334, rttvar = 0.019, rto = 2.000 +recv 487 +updated rto +send 488: rtt = 0.308, srtt = 0.331, rttvar = 0.021, rto = 2.000 +recv 488 +updated rto +send 489: rtt = 0.390, srtt = 0.338, rttvar = 0.031, rto = 2.000 +recv 489 +updated rto +send 490: rtt = 0.389, srtt = 0.345, rttvar = 0.036, rto = 2.000 +recv 490 +updated rto +send 491: rtt = 0.300, srtt = 0.339, rttvar = 0.038, rto = 2.000 +recv 491 +updated rto +send 492: rtt = 0.300, srtt = 0.334, rttvar = 0.038, rto = 2.000 +recv 492 +updated rto +send 493: rtt = 0.319, srtt = 0.332, rttvar = 0.032, rto = 2.000 +recv 493 +updated rto +send 494: rtt = 0.323, srtt = 0.331, rttvar = 0.027, rto = 2.000 +recv 494 +updated rto +send 495: rtt = 0.337, srtt = 0.332, rttvar = 0.021, rto = 2.000 +recv 495 +updated rto +send 496: rtt = 0.320, srtt = 0.330, rttvar = 0.019, rto = 2.000 +recv 496 +updated rto +send 497: rtt = 0.320, srtt = 0.329, rttvar = 0.017, rto = 2.000 +recv 497 +updated rto +send 498: rtt = 0.319, srtt = 0.328, rttvar = 0.015, rto = 2.000 +recv 498 +updated rto +send 499: rtt = 0.300, srtt = 0.324, rttvar = 0.018, rto = 2.000 +recv 499 +updated rto +send 500: rtt = 0.339, srtt = 0.326, rttvar = 0.017, rto = 2.000 +recv 500 +updated rto diff --git a/rtt/rtt.out.vangogh.1 b/rtt/rtt.out.vangogh.1 new file mode 100644 index 0000000..b2f830a --- /dev/null +++ b/rtt/rtt.out.vangogh.1 @@ -0,0 +1,1532 @@ +send 1: rtt = 0.000, srtt = 0.000, rttvar = 0.750, rto = 3.000 +recv 1 +updated rto +send 2: rtt = 0.316, srtt = 0.040, rttvar = 0.641, rto = 2.605 +recv 2 +updated rto +send 3: rtt = 0.218, srtt = 0.062, rttvar = 0.526, rto = 2.165 +recv 3 +updated rto +send 4: rtt = 0.225, srtt = 0.082, rttvar = 0.435, rto = 2.000 +recv 4 +updated rto +send 5: rtt = 0.264, srtt = 0.105, rttvar = 0.372, rto = 2.000 +recv 5 +updated rto +send 6: rtt = 0.228, srtt = 0.120, rttvar = 0.310, rto = 2.000 +recv 6 +updated rto +send 7: rtt = 0.221, srtt = 0.133, rttvar = 0.257, rto = 2.000 +recv 7 +updated rto +send 8: rtt = 0.228, srtt = 0.145, rttvar = 0.217, rto = 2.000 +recv 8 +updated rto +send 9: rtt = 0.200, srtt = 0.152, rttvar = 0.176, rto = 2.000 +recv 9 +updated rto +send 10: rtt = 0.240, srtt = 0.163, rttvar = 0.154, rto = 2.000 +recv 10 +updated rto +send 11: rtt = 0.210, srtt = 0.169, rttvar = 0.128, rto = 2.000 +recv 11 +updated rto +send 12: rtt = 0.249, srtt = 0.179, rttvar = 0.116, rto = 2.000 +recv 12 +updated rto +send 13: rtt = 0.240, srtt = 0.186, rttvar = 0.102, rto = 2.000 +recv 13 +updated rto +send 14: rtt = 0.260, srtt = 0.196, rttvar = 0.095, rto = 2.000 +recv 14 +updated rto +send 15: rtt = 0.201, srtt = 0.196, rttvar = 0.073, rto = 2.000 +recv 15 +updated rto +send 16: rtt = 0.248, srtt = 0.203, rttvar = 0.067, rto = 2.000 +recv 16 +updated rto +send 17: rtt = 0.261, srtt = 0.210, rttvar = 0.065, rto = 2.000 +recv 17 +updated rto +send 18: rtt = 0.248, srtt = 0.215, rttvar = 0.058, rto = 2.000 +recv 18 +updated rto +send 19: rtt = 0.260, srtt = 0.220, rttvar = 0.055, rto = 2.000 +recv 19 +updated rto +send 20: rtt = 0.210, srtt = 0.219, rttvar = 0.044, rto = 2.000 +recv 20 +updated rto +send 21: rtt = 0.240, srtt = 0.222, rttvar = 0.038, rto = 2.000 +recv 21 +updated rto +send 22: rtt = 0.240, srtt = 0.224, rttvar = 0.033, rto = 2.000 +recv 22 +updated rto +send 23: rtt = 0.249, srtt = 0.227, rttvar = 0.031, rto = 2.000 +recv 23 +updated rto +send 24: rtt = 0.230, srtt = 0.227, rttvar = 0.024, rto = 2.000 +recv 24 +updated rto +send 25: rtt = 0.240, srtt = 0.229, rttvar = 0.021, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 25: rtt = 0.240, srtt = 0.229, rttvar = 0.021, rto = 4.000 +recv 25 +updated rto +send 26: rtt = 0.190, srtt = 0.224, rttvar = 0.026, rto = 2.000 +recv 26 +updated rto +send 27: rtt = 0.220, srtt = 0.224, rttvar = 0.020, rto = 2.000 +recv 27 +updated rto +send 28: rtt = 0.259, srtt = 0.228, rttvar = 0.024, rto = 2.000 +recv 28 +updated rto +send 29: rtt = 0.243, srtt = 0.230, rttvar = 0.022, rto = 2.000 +recv 29 +updated rto +send 30: rtt = 0.257, srtt = 0.233, rttvar = 0.023, rto = 2.000 +recv 30 +updated rto +send 31: rtt = 0.260, srtt = 0.237, rttvar = 0.024, rto = 2.000 +recv 31 +updated rto +send 32: rtt = 0.240, srtt = 0.237, rttvar = 0.019, rto = 2.000 +recv 32 +updated rto +send 33: rtt = 0.240, srtt = 0.237, rttvar = 0.015, rto = 2.000 +recv 33 +updated rto +send 34: rtt = 0.249, srtt = 0.239, rttvar = 0.014, rto = 2.000 +recv 34 +updated rto +send 35: rtt = 0.210, srtt = 0.235, rttvar = 0.018, rto = 2.000 +recv 35 +updated rto +send 36: rtt = 0.239, srtt = 0.236, rttvar = 0.014, rto = 2.000 +recv 36 +updated rto +send 37: rtt = 0.240, srtt = 0.236, rttvar = 0.012, rto = 2.000 +recv 37 +updated rto +send 38: rtt = 0.260, srtt = 0.239, rttvar = 0.015, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 38: rtt = 0.260, srtt = 0.239, rttvar = 0.015, rto = 4.000 +recv 38 +updated rto +send 39: rtt = 0.220, srtt = 0.237, rttvar = 0.016, rto = 2.000 +recv 39 +updated rto +send 40: rtt = 0.230, srtt = 0.236, rttvar = 0.014, rto = 2.000 +recv 40 +updated rto +send 41: rtt = 0.250, srtt = 0.238, rttvar = 0.014, rto = 2.000 +recv 41 +updated rto +send 42: rtt = 0.240, srtt = 0.238, rttvar = 0.011, rto = 2.000 +recv 42 +updated rto +send 43: rtt = 0.240, srtt = 0.238, rttvar = 0.009, rto = 2.000 +recv 43 +updated rto +send 44: rtt = 0.210, srtt = 0.235, rttvar = 0.014, rto = 2.000 +recv 44 +updated rto +send 45: rtt = 0.240, srtt = 0.235, rttvar = 0.011, rto = 2.000 +recv 45 +updated rto +send 46: rtt = 0.239, srtt = 0.236, rttvar = 0.010, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 46: rtt = 0.239, srtt = 0.236, rttvar = 0.010, rto = 4.000 +recv 46 +updated rto +send 47: rtt = 0.240, srtt = 0.236, rttvar = 0.008, rto = 2.000 +recv 47 +updated rto +send 48: rtt = 0.250, srtt = 0.238, rttvar = 0.010, rto = 2.000 +recv 48 +updated rto +send 49: rtt = 0.239, srtt = 0.238, rttvar = 0.007, rto = 2.000 +recv 49 +updated rto +send 50: rtt = 0.220, srtt = 0.236, rttvar = 0.010, rto = 2.000 +recv 50 +updated rto +send 51: rtt = 0.229, srtt = 0.235, rttvar = 0.009, rto = 2.000 +recv 51 +updated rto +send 52: rtt = 0.210, srtt = 0.232, rttvar = 0.013, rto = 2.000 +recv 52 +updated rto +send 53: rtt = 0.259, srtt = 0.235, rttvar = 0.017, rto = 2.000 +recv 53 +updated rto +send 54: rtt = 0.240, srtt = 0.236, rttvar = 0.014, rto = 2.000 +recv 54 +updated rto +send 55: rtt = 0.260, srtt = 0.239, rttvar = 0.016, rto = 2.000 +recv 55 +updated rto +send 56: rtt = 0.249, srtt = 0.240, rttvar = 0.015, rto = 2.000 +recv 56 +updated rto +send 57: rtt = 0.249, srtt = 0.241, rttvar = 0.013, rto = 2.000 +recv 57 +updated rto +send 58: rtt = 0.240, srtt = 0.241, rttvar = 0.010, rto = 2.000 +recv 58 +updated rto +send 59: rtt = 0.209, srtt = 0.237, rttvar = 0.016, rto = 2.000 +recv 59 +updated rto +send 60: rtt = 0.190, srtt = 0.231, rttvar = 0.024, rto = 2.000 +recv 60 +updated rto +send 61: rtt = 0.230, srtt = 0.231, rttvar = 0.018, rto = 2.000 +recv 61 +updated rto +send 62: rtt = 0.229, srtt = 0.231, rttvar = 0.014, rto = 2.000 +recv 62 +updated rto +send 63: rtt = 0.229, srtt = 0.231, rttvar = 0.011, rto = 2.000 +recv 63 +updated rto +send 64: rtt = 0.210, srtt = 0.228, rttvar = 0.013, rto = 2.000 +recv 64 +updated rto +send 65: rtt = 0.230, srtt = 0.228, rttvar = 0.011, rto = 2.000 +recv 65 +updated rto +send 66: rtt = 0.200, srtt = 0.225, rttvar = 0.015, rto = 2.000 +recv 66 +updated rto +send 67: rtt = 0.240, srtt = 0.227, rttvar = 0.015, rto = 2.000 +recv 67 +updated rto +send 68: rtt = 0.260, srtt = 0.231, rttvar = 0.020, rto = 2.000 +recv 68 +updated rto +send 69: rtt = 0.240, srtt = 0.232, rttvar = 0.017, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 69: rtt = 0.240, srtt = 0.232, rttvar = 0.017, rto = 4.000 +recv 69 +updated rto +send 70: rtt = 0.200, srtt = 0.228, rttvar = 0.021, rto = 2.000 +recv 70 +updated rto +send 71: rtt = 0.250, srtt = 0.231, rttvar = 0.021, rto = 2.000 +recv 71 +updated rto +send 72: rtt = 0.220, srtt = 0.229, rttvar = 0.018, rto = 2.000 +recv 72 +updated rto +send 73: rtt = 0.239, srtt = 0.231, rttvar = 0.016, rto = 2.000 +recv 73 +updated rto +send 74: rtt = 0.229, srtt = 0.230, rttvar = 0.013, rto = 2.000 +recv 74 +updated rto +send 75: rtt = 0.210, srtt = 0.228, rttvar = 0.015, rto = 2.000 +recv 75 +updated rto +send 76: rtt = 0.199, srtt = 0.224, rttvar = 0.018, rto = 2.000 +recv 76 +updated rto +send 77: rtt = 0.250, srtt = 0.227, rttvar = 0.020, rto = 2.000 +recv 77 +updated rto +send 78: rtt = 0.199, srtt = 0.224, rttvar = 0.022, rto = 2.000 +recv 78 +updated rto +send 79: rtt = 0.249, srtt = 0.227, rttvar = 0.023, rto = 2.000 +recv 79 +updated rto +send 80: rtt = 0.239, srtt = 0.229, rttvar = 0.020, rto = 2.000 +recv 80 +updated rto +send 81: rtt = 0.230, srtt = 0.229, rttvar = 0.015, rto = 2.000 +recv 81 +updated rto +send 82: rtt = 0.259, srtt = 0.232, rttvar = 0.019, rto = 2.000 +recv 82 +updated rto +send 83: rtt = 0.240, srtt = 0.233, rttvar = 0.016, rto = 2.000 +recv 83 +updated rto +send 84: rtt = 0.240, srtt = 0.234, rttvar = 0.014, rto = 2.000 +recv 84 +updated rto +send 85: rtt = 0.250, srtt = 0.236, rttvar = 0.014, rto = 2.000 +recv 85 +updated rto +send 86: rtt = 0.230, srtt = 0.235, rttvar = 0.012, rto = 2.000 +recv 86 +updated rto +send 87: rtt = 0.259, srtt = 0.238, rttvar = 0.015, rto = 2.000 +recv 87 +updated rto +send 88: rtt = 0.220, srtt = 0.236, rttvar = 0.016, rto = 2.000 +recv 88 +updated rto +send 89: rtt = 0.239, srtt = 0.236, rttvar = 0.013, rto = 2.000 +recv 89 +updated rto +send 90: rtt = 0.250, srtt = 0.238, rttvar = 0.013, rto = 2.000 +recv 90 +updated rto +send 91: rtt = 0.230, srtt = 0.237, rttvar = 0.012, rto = 2.000 +recv 91 +updated rto +send 92: rtt = 0.219, srtt = 0.235, rttvar = 0.013, rto = 2.000 +recv 92 +updated rto +send 93: rtt = 0.220, srtt = 0.233, rttvar = 0.014, rto = 2.000 +recv 93 +updated rto +send 94: rtt = 0.229, srtt = 0.233, rttvar = 0.011, rto = 2.000 +recv 94 +updated rto +send 95: rtt = 0.239, srtt = 0.233, rttvar = 0.010, rto = 2.000 +recv 95 +updated rto +send 96: rtt = 0.250, srtt = 0.235, rttvar = 0.012, rto = 2.000 +recv 96 +updated rto +send 97: rtt = 0.250, srtt = 0.237, rttvar = 0.012, rto = 2.000 +recv 97 +updated rto +send 98: rtt = 0.220, srtt = 0.235, rttvar = 0.014, rto = 2.000 +recv 98 +updated rto +send 99: rtt = 0.230, srtt = 0.234, rttvar = 0.012, rto = 2.000 +recv 99 +updated rto +send 100: rtt = 0.249, srtt = 0.236, rttvar = 0.012, rto = 2.000 +recv 100 +updated rto +send 101: rtt = 0.240, srtt = 0.237, rttvar = 0.010, rto = 2.000 +recv 101 +updated rto +send 102: rtt = 0.239, srtt = 0.237, rttvar = 0.008, rto = 2.000 +recv 102 +updated rto +send 103: rtt = 0.249, srtt = 0.239, rttvar = 0.009, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 103: rtt = 0.249, srtt = 0.239, rttvar = 0.009, rto = 4.000 +recv 103 +updated rto +send 104: rtt = 0.250, srtt = 0.240, rttvar = 0.010, rto = 2.000 +recv 104 +updated rto +send 105: rtt = 0.260, srtt = 0.242, rttvar = 0.012, rto = 2.000 +recv 105 +updated rto +send 106: rtt = 0.250, srtt = 0.243, rttvar = 0.011, rto = 2.000 +recv 106 +updated rto +send 107: rtt = 0.241, srtt = 0.243, rttvar = 0.009, rto = 2.000 +recv 107 +updated rto +send 108: rtt = 0.248, srtt = 0.244, rttvar = 0.008, rto = 2.000 +recv 108 +updated rto +send 109: rtt = 0.249, srtt = 0.244, rttvar = 0.007, rto = 2.000 +recv 109 +updated rto +send 110: rtt = 0.240, srtt = 0.244, rttvar = 0.007, rto = 2.000 +recv 110 +updated rto +send 111: rtt = 0.259, srtt = 0.246, rttvar = 0.009, rto = 2.000 +recv 111 +updated rto +send 112: rtt = 0.310, srtt = 0.254, rttvar = 0.023, rto = 2.000 +recv 112 +updated rto +send 113: rtt = 0.250, srtt = 0.253, rttvar = 0.018, rto = 2.000 +recv 113 +updated rto +send 114: rtt = 0.250, srtt = 0.253, rttvar = 0.014, rto = 2.000 +recv 114 +updated rto +send 115: rtt = 0.230, srtt = 0.250, rttvar = 0.016, rto = 2.000 +recv 115 +updated rto +send 116: rtt = 0.220, srtt = 0.246, rttvar = 0.020, rto = 2.000 +recv 116 +updated rto +send 117: rtt = 0.230, srtt = 0.244, rttvar = 0.019, rto = 2.000 +recv 117 +updated rto +send 118: rtt = 0.240, srtt = 0.244, rttvar = 0.015, rto = 2.000 +recv 118 +updated rto +send 119: rtt = 0.240, srtt = 0.243, rttvar = 0.012, rto = 2.000 +recv 119 +updated rto +send 120: rtt = 0.250, srtt = 0.244, rttvar = 0.011, rto = 2.000 +recv 120 +updated rto +send 121: rtt = 0.250, srtt = 0.245, rttvar = 0.010, rto = 2.000 +recv 121 +updated rto +send 122: rtt = 0.220, srtt = 0.242, rttvar = 0.013, rto = 2.000 +recv 122 +updated rto +send 123: rtt = 0.219, srtt = 0.239, rttvar = 0.016, rto = 2.000 +recv 123 +updated rto +send 124: rtt = 0.219, srtt = 0.236, rttvar = 0.017, rto = 2.000 +recv 124 +updated rto +send 125: rtt = 0.240, srtt = 0.237, rttvar = 0.014, rto = 2.000 +recv 125 +updated rto +send 126: rtt = 0.220, srtt = 0.235, rttvar = 0.014, rto = 2.000 +recv 126 +updated rto +send 127: rtt = 0.230, srtt = 0.234, rttvar = 0.012, rto = 2.000 +recv 127 +updated rto +send 128: rtt = 0.229, srtt = 0.234, rttvar = 0.010, rto = 2.000 +recv 128 +updated rto +send 129: rtt = 0.239, srtt = 0.234, rttvar = 0.009, rto = 2.000 +recv 129 +updated rto +send 130: rtt = 0.230, srtt = 0.234, rttvar = 0.008, rto = 2.000 +recv 130 +updated rto +send 131: rtt = 0.259, srtt = 0.237, rttvar = 0.012, rto = 2.000 +recv 131 +updated rto +send 132: rtt = 0.230, srtt = 0.236, rttvar = 0.011, rto = 2.000 +recv 132 +updated rto +send 133: rtt = 0.249, srtt = 0.238, rttvar = 0.011, rto = 2.000 +recv 133 +updated rto +send 134: rtt = 0.250, srtt = 0.239, rttvar = 0.012, rto = 2.000 +recv 134 +updated rto +send 135: rtt = 0.240, srtt = 0.239, rttvar = 0.009, rto = 2.000 +recv 135 +updated rto +send 136: rtt = 0.248, srtt = 0.240, rttvar = 0.009, rto = 2.000 +recv 136 +updated rto +send 137: rtt = 0.200, srtt = 0.235, rttvar = 0.017, rto = 2.000 +recv 137 +updated rto +send 138: rtt = 0.260, srtt = 0.238, rttvar = 0.019, rto = 2.000 +recv 138 +updated rto +send 139: rtt = 0.230, srtt = 0.237, rttvar = 0.016, rto = 2.000 +recv 139 +updated rto +send 140: rtt = 0.230, srtt = 0.236, rttvar = 0.014, rto = 2.000 +recv 140 +updated rto +send 141: rtt = 0.230, srtt = 0.236, rttvar = 0.012, rto = 2.000 +recv 141 +updated rto +send 142: rtt = 0.349, srtt = 0.250, rttvar = 0.037, rto = 2.000 +recv 142 +updated rto +send 143: rtt = 0.230, srtt = 0.247, rttvar = 0.033, rto = 2.000 +recv 143 +updated rto +send 144: rtt = 0.230, srtt = 0.245, rttvar = 0.029, rto = 2.000 +recv 144 +updated rto +send 145: rtt = 0.250, srtt = 0.246, rttvar = 0.023, rto = 2.000 +recv 145 +updated rto +send 146: rtt = 0.239, srtt = 0.245, rttvar = 0.019, rto = 2.000 +recv 146 +updated rto +send 147: rtt = 0.220, srtt = 0.242, rttvar = 0.020, rto = 2.000 +recv 147 +updated rto +send 148: rtt = 0.240, srtt = 0.242, rttvar = 0.016, rto = 2.000 +recv 148 +updated rto +send 149: rtt = 0.240, srtt = 0.241, rttvar = 0.012, rto = 2.000 +recv 149 +updated rto +send 150: rtt = 0.249, srtt = 0.242, rttvar = 0.011, rto = 2.000 +recv 150 +updated rto +send 151: rtt = 0.219, srtt = 0.239, rttvar = 0.014, rto = 2.000 +recv 151 +updated rto +send 152: rtt = 0.220, srtt = 0.237, rttvar = 0.015, rto = 2.000 +recv 152 +updated rto +send 153: rtt = 0.229, srtt = 0.236, rttvar = 0.014, rto = 2.000 +recv 153 +updated rto +send 154: rtt = 0.260, srtt = 0.239, rttvar = 0.016, rto = 2.000 +recv 154 +updated rto +send 155: rtt = 0.259, srtt = 0.241, rttvar = 0.017, rto = 2.000 +recv 155 +updated rto +send 156: rtt = 0.260, srtt = 0.244, rttvar = 0.017, rto = 2.000 +recv 156 +updated rto +send 157: rtt = 0.239, srtt = 0.243, rttvar = 0.014, rto = 2.000 +recv 157 +updated rto +send 158: rtt = 0.249, srtt = 0.244, rttvar = 0.012, rto = 2.000 +recv 158 +updated rto +send 159: rtt = 0.229, srtt = 0.242, rttvar = 0.013, rto = 2.000 +recv 159 +updated rto +send 160: rtt = 0.220, srtt = 0.239, rttvar = 0.015, rto = 2.000 +recv 160 +updated rto +send 161: rtt = 0.240, srtt = 0.239, rttvar = 0.012, rto = 2.000 +recv 161 +updated rto +send 162: rtt = 0.230, srtt = 0.238, rttvar = 0.011, rto = 2.000 +recv 162 +updated rto +send 163: rtt = 0.230, srtt = 0.237, rttvar = 0.010, rto = 2.000 +recv 163 +updated rto +send 164: rtt = 0.239, srtt = 0.237, rttvar = 0.008, rto = 2.000 +recv 164 +updated rto +send 165: rtt = 0.269, srtt = 0.241, rttvar = 0.014, rto = 2.000 +recv 165 +updated rto +send 166: rtt = 0.220, srtt = 0.239, rttvar = 0.016, rto = 2.000 +recv 166 +updated rto +send 167: rtt = 0.219, srtt = 0.236, rttvar = 0.017, rto = 2.000 +recv 167 +updated rto +send 168: rtt = 0.220, srtt = 0.234, rttvar = 0.017, rto = 2.000 +recv 168 +updated rto +send 169: rtt = 0.220, srtt = 0.232, rttvar = 0.016, rto = 2.000 +recv 169 +updated rto +send 170: rtt = 0.240, srtt = 0.233, rttvar = 0.014, rto = 2.000 +recv 170 +updated rto +send 171: rtt = 0.239, srtt = 0.234, rttvar = 0.012, rto = 2.000 +recv 171 +updated rto +send 172: rtt = 0.240, srtt = 0.235, rttvar = 0.010, rto = 2.000 +recv 172 +updated rto +send 173: rtt = 0.240, srtt = 0.235, rttvar = 0.009, rto = 2.000 +recv 173 +updated rto +send 174: rtt = 0.240, srtt = 0.236, rttvar = 0.008, rto = 2.000 +recv 174 +updated rto +send 175: rtt = 0.229, srtt = 0.235, rttvar = 0.008, rto = 2.000 +recv 175 +updated rto +send 176: rtt = 0.199, srtt = 0.231, rttvar = 0.015, rto = 2.000 +recv 176 +updated rto +send 177: rtt = 0.249, srtt = 0.233, rttvar = 0.016, rto = 2.000 +recv 177 +updated rto +send 178: rtt = 0.239, srtt = 0.234, rttvar = 0.013, rto = 2.000 +recv 178 +updated rto +send 179: rtt = 0.220, srtt = 0.232, rttvar = 0.013, rto = 2.000 +recv 179 +updated rto +send 180: rtt = 0.240, srtt = 0.233, rttvar = 0.012, rto = 2.000 +recv 180 +updated rto +send 181: rtt = 0.219, srtt = 0.231, rttvar = 0.013, rto = 2.000 +recv 181 +updated rto +send 182: rtt = 0.240, srtt = 0.232, rttvar = 0.012, rto = 2.000 +recv 182 +updated rto +send 183: rtt = 0.240, srtt = 0.233, rttvar = 0.011, rto = 2.000 +recv 183 +updated rto +send 184: rtt = 0.230, srtt = 0.233, rttvar = 0.009, rto = 2.000 +recv 184 +updated rto +send 185: rtt = 0.240, srtt = 0.234, rttvar = 0.008, rto = 2.000 +recv 185 +updated rto +send 186: rtt = 0.230, srtt = 0.233, rttvar = 0.007, rto = 2.000 +recv 186 +updated rto +send 187: rtt = 0.240, srtt = 0.234, rttvar = 0.007, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 187: rtt = 0.240, srtt = 0.234, rttvar = 0.007, rto = 4.000 +recv 187 +updated rto +send 188: rtt = 0.229, srtt = 0.233, rttvar = 0.007, rto = 2.000 +recv 188 +updated rto +send 189: rtt = 0.250, srtt = 0.236, rttvar = 0.009, rto = 2.000 +recv 189 +updated rto +send 190: rtt = 0.248, srtt = 0.237, rttvar = 0.010, rto = 2.000 +recv 190 +updated rto +send 191: rtt = 0.230, srtt = 0.236, rttvar = 0.009, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 191: rtt = 0.230, srtt = 0.236, rttvar = 0.009, rto = 4.000 +recv 191 +updated rto +send 192: rtt = 0.230, srtt = 0.235, rttvar = 0.008, rto = 2.000 +recv 192 +updated rto +send 193: rtt = 0.230, srtt = 0.235, rttvar = 0.008, rto = 2.000 +recv 193 +updated rto +send 194: rtt = 0.200, srtt = 0.230, rttvar = 0.014, rto = 2.000 +recv 194 +updated rto +send 195: rtt = 0.210, srtt = 0.228, rttvar = 0.016, rto = 2.000 +recv 195 +updated rto +send 196: rtt = 0.200, srtt = 0.224, rttvar = 0.019, rto = 2.000 +recv 196 +updated rto +send 197: rtt = 0.209, srtt = 0.222, rttvar = 0.018, rto = 2.000 +recv 197 +updated rto +send 198: rtt = 0.200, srtt = 0.220, rttvar = 0.019, rto = 2.000 +recv 198 +updated rto +send 199: rtt = 0.231, srtt = 0.221, rttvar = 0.017, rto = 2.000 +recv 199 +updated rto +send 200: rtt = 0.247, srtt = 0.224, rttvar = 0.019, rto = 2.000 +recv 200 +updated rto +send 201: rtt = 0.240, srtt = 0.226, rttvar = 0.018, rto = 2.000 +recv 201 +updated rto +send 202: rtt = 0.220, srtt = 0.225, rttvar = 0.015, rto = 2.000 +recv 202 +updated rto +send 203: rtt = 0.200, srtt = 0.222, rttvar = 0.018, rto = 2.000 +recv 203 +updated rto +send 204: rtt = 0.210, srtt = 0.221, rttvar = 0.017, rto = 2.000 +recv 204 +updated rto +send 205: rtt = 0.200, srtt = 0.218, rttvar = 0.018, rto = 2.000 +recv 205 +updated rto +send 206: rtt = 0.230, srtt = 0.220, rttvar = 0.016, rto = 2.000 +recv 206 +updated rto +send 207: rtt = 0.250, srtt = 0.223, rttvar = 0.020, rto = 2.000 +recv 207 +updated rto +send 208: rtt = 0.239, srtt = 0.225, rttvar = 0.019, rto = 2.000 +recv 208 +updated rto +send 209: rtt = 0.230, srtt = 0.226, rttvar = 0.015, rto = 2.000 +recv 209 +updated rto +send 210: rtt = 0.249, srtt = 0.229, rttvar = 0.017, rto = 2.000 +recv 210 +updated rto +send 211: rtt = 0.230, srtt = 0.229, rttvar = 0.013, rto = 2.000 +recv 211 +updated rto +send 212: rtt = 0.240, srtt = 0.230, rttvar = 0.013, rto = 2.000 +recv 212 +updated rto +send 213: rtt = 0.240, srtt = 0.232, rttvar = 0.012, rto = 2.000 +recv 213 +updated rto +send 214: rtt = 0.218, srtt = 0.230, rttvar = 0.012, rto = 2.000 +recv 214 +updated rto +send 215: rtt = 0.229, srtt = 0.230, rttvar = 0.009, rto = 2.000 +recv 215 +updated rto +send 216: rtt = 0.230, srtt = 0.230, rttvar = 0.007, rto = 2.000 +recv 216 +updated rto +send 217: rtt = 0.250, srtt = 0.232, rttvar = 0.010, rto = 2.000 +recv 217 +updated rto +send 218: rtt = 0.229, srtt = 0.232, rttvar = 0.009, rto = 2.000 +recv 218 +updated rto +send 219: rtt = 0.229, srtt = 0.232, rttvar = 0.007, rto = 2.000 +recv 219 +updated rto +send 220: rtt = 0.220, srtt = 0.230, rttvar = 0.008, rto = 2.000 +recv 220 +updated rto +send 221: rtt = 0.220, srtt = 0.229, rttvar = 0.009, rto = 2.000 +recv 221 +updated rto +send 222: rtt = 0.240, srtt = 0.230, rttvar = 0.009, rto = 2.000 +recv 222 +updated rto +send 223: rtt = 0.240, srtt = 0.231, rttvar = 0.009, rto = 2.000 +recv 223 +updated rto +send 224: rtt = 0.249, srtt = 0.234, rttvar = 0.011, rto = 2.000 +recv 224 +updated rto +send 225: rtt = 0.239, srtt = 0.234, rttvar = 0.010, rto = 2.000 +recv 225 +updated rto +send 226: rtt = 0.240, srtt = 0.235, rttvar = 0.009, rto = 2.000 +recv 226 +updated rto +send 227: rtt = 0.279, srtt = 0.241, rttvar = 0.018, rto = 2.000 +recv 227 +updated rto +send 228: rtt = 0.229, srtt = 0.239, rttvar = 0.016, rto = 2.000 +recv 228 +updated rto +send 229: rtt = 0.229, srtt = 0.238, rttvar = 0.015, rto = 2.000 +recv 229 +updated rto +send 230: rtt = 0.239, srtt = 0.238, rttvar = 0.011, rto = 2.000 +recv 230 +updated rto +send 231: rtt = 0.239, srtt = 0.238, rttvar = 0.009, rto = 2.000 +recv 231 +updated rto +send 232: rtt = 0.250, srtt = 0.240, rttvar = 0.009, rto = 2.000 +recv 232 +updated rto +send 233: rtt = 0.249, srtt = 0.241, rttvar = 0.009, rto = 2.000 +recv 233 +updated rto +send 234: rtt = 0.239, srtt = 0.241, rttvar = 0.008, rto = 2.000 +recv 234 +updated rto +send 235: rtt = 0.240, srtt = 0.240, rttvar = 0.006, rto = 2.000 +recv 235 +updated rto +send 236: rtt = 0.230, srtt = 0.239, rttvar = 0.007, rto = 2.000 +recv 236 +updated rto +send 237: rtt = 0.240, srtt = 0.239, rttvar = 0.005, rto = 2.000 +recv 237 +updated rto +send 238: rtt = 0.219, srtt = 0.237, rttvar = 0.009, rto = 2.000 +recv 238 +updated rto +send 239: rtt = 0.199, srtt = 0.232, rttvar = 0.016, rto = 2.000 +recv 239 +updated rto +send 240: rtt = 0.220, srtt = 0.231, rttvar = 0.015, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 240: rtt = 0.220, srtt = 0.231, rttvar = 0.015, rto = 4.000 +dgsendrecv: timeout, retransmitting +send 240: rtt = 0.220, srtt = 0.231, rttvar = 0.015, rto = 8.000 +recv 240 +updated rto +send 241: rtt = 0.210, srtt = 0.228, rttvar = 0.017, rto = 2.000 +recv 241 +updated rto +send 242: rtt = 0.250, srtt = 0.231, rttvar = 0.018, rto = 2.000 +recv 242 +updated rto +send 243: rtt = 0.240, srtt = 0.232, rttvar = 0.016, rto = 2.000 +recv 243 +updated rto +send 244: rtt = 0.242, srtt = 0.233, rttvar = 0.014, rto = 2.000 +recv 244 +updated rto +send 245: rtt = 0.237, srtt = 0.234, rttvar = 0.012, rto = 2.000 +recv 245 +updated rto +send 246: rtt = 0.250, srtt = 0.236, rttvar = 0.013, rto = 2.000 +recv 246 +updated rto +send 247: rtt = 0.221, srtt = 0.234, rttvar = 0.013, rto = 2.000 +recv 247 +updated rto +send 248: rtt = 0.229, srtt = 0.233, rttvar = 0.011, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 248: rtt = 0.229, srtt = 0.233, rttvar = 0.011, rto = 4.000 +recv 248 +updated rto +send 249: rtt = 0.270, srtt = 0.238, rttvar = 0.018, rto = 2.000 +recv 249 +updated rto +send 250: rtt = 0.260, srtt = 0.241, rttvar = 0.019, rto = 2.000 +recv 250 +updated rto +send 251: rtt = 0.240, srtt = 0.241, rttvar = 0.014, rto = 2.000 +recv 251 +updated rto +send 252: rtt = 0.229, srtt = 0.239, rttvar = 0.014, rto = 2.000 +recv 252 +updated rto +send 253: rtt = 0.230, srtt = 0.238, rttvar = 0.012, rto = 2.000 +recv 253 +updated rto +send 254: rtt = 0.240, srtt = 0.238, rttvar = 0.010, rto = 2.000 +recv 254 +updated rto +send 255: rtt = 0.229, srtt = 0.237, rttvar = 0.010, rto = 2.000 +recv 255 +updated rto +send 256: rtt = 0.230, srtt = 0.236, rttvar = 0.009, rto = 2.000 +recv 256 +updated rto +send 257: rtt = 0.269, srtt = 0.240, rttvar = 0.015, rto = 2.000 +recv 257 +updated rto +send 258: rtt = 0.219, srtt = 0.238, rttvar = 0.017, rto = 2.000 +recv 258 +updated rto +send 259: rtt = 0.239, srtt = 0.238, rttvar = 0.013, rto = 2.000 +recv 259 +updated rto +send 260: rtt = 0.229, srtt = 0.237, rttvar = 0.012, rto = 2.000 +recv 260 +updated rto +send 261: rtt = 0.219, srtt = 0.234, rttvar = 0.013, rto = 2.000 +recv 261 +updated rto +send 262: rtt = 0.260, srtt = 0.238, rttvar = 0.016, rto = 2.000 +recv 262 +updated rto +send 263: rtt = 0.260, srtt = 0.240, rttvar = 0.018, rto = 2.000 +recv 263 +updated rto +send 264: rtt = 0.240, srtt = 0.240, rttvar = 0.013, rto = 2.000 +recv 264 +updated rto +send 265: rtt = 0.220, srtt = 0.238, rttvar = 0.015, rto = 2.000 +recv 265 +updated rto +send 266: rtt = 0.250, srtt = 0.239, rttvar = 0.014, rto = 2.000 +recv 266 +updated rto +send 267: rtt = 0.250, srtt = 0.241, rttvar = 0.013, rto = 2.000 +recv 267 +updated rto +send 268: rtt = 0.230, srtt = 0.239, rttvar = 0.013, rto = 2.000 +recv 268 +updated rto +send 269: rtt = 0.249, srtt = 0.241, rttvar = 0.012, rto = 2.000 +recv 269 +updated rto +send 270: rtt = 0.250, srtt = 0.242, rttvar = 0.011, rto = 2.000 +recv 270 +updated rto +send 271: rtt = 0.279, srtt = 0.246, rttvar = 0.018, rto = 2.000 +recv 271 +updated rto +send 272: rtt = 0.220, srtt = 0.243, rttvar = 0.020, rto = 2.000 +recv 272 +updated rto +send 273: rtt = 0.230, srtt = 0.241, rttvar = 0.018, rto = 2.000 +recv 273 +updated rto +send 274: rtt = 0.229, srtt = 0.240, rttvar = 0.017, rto = 2.000 +recv 274 +updated rto +send 275: rtt = 0.270, srtt = 0.244, rttvar = 0.020, rto = 2.000 +recv 275 +updated rto +send 276: rtt = 0.260, srtt = 0.246, rttvar = 0.019, rto = 2.000 +recv 276 +updated rto +send 277: rtt = 0.220, srtt = 0.242, rttvar = 0.021, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 277: rtt = 0.220, srtt = 0.242, rttvar = 0.021, rto = 4.000 +recv 277 +updated rto +send 278: rtt = 0.250, srtt = 0.243, rttvar = 0.017, rto = 2.000 +recv 278 +updated rto +send 279: rtt = 0.240, srtt = 0.243, rttvar = 0.014, rto = 2.000 +recv 279 +updated rto +send 280: rtt = 0.249, srtt = 0.244, rttvar = 0.012, rto = 2.000 +recv 280 +updated rto +send 281: rtt = 0.211, srtt = 0.240, rttvar = 0.017, rto = 2.000 +recv 281 +updated rto +send 282: rtt = 0.240, srtt = 0.240, rttvar = 0.013, rto = 2.000 +recv 282 +updated rto +send 283: rtt = 0.210, srtt = 0.236, rttvar = 0.017, rto = 2.000 +recv 283 +updated rto +send 284: rtt = 0.240, srtt = 0.236, rttvar = 0.014, rto = 2.000 +recv 284 +updated rto +send 285: rtt = 0.199, srtt = 0.232, rttvar = 0.020, rto = 2.000 +recv 285 +updated rto +send 286: rtt = 0.239, srtt = 0.233, rttvar = 0.017, rto = 2.000 +recv 286 +updated rto +send 287: rtt = 0.230, srtt = 0.232, rttvar = 0.013, rto = 2.000 +recv 287 +updated rto +send 288: rtt = 0.229, srtt = 0.232, rttvar = 0.011, rto = 2.000 +recv 288 +updated rto +send 289: rtt = 0.250, srtt = 0.234, rttvar = 0.013, rto = 2.000 +recv 289 +updated rto +send 290: rtt = 0.239, srtt = 0.235, rttvar = 0.011, rto = 2.000 +recv 290 +updated rto +send 291: rtt = 0.230, srtt = 0.234, rttvar = 0.009, rto = 2.000 +recv 291 +updated rto +send 292: rtt = 0.239, srtt = 0.235, rttvar = 0.008, rto = 2.000 +recv 292 +updated rto +send 293: rtt = 0.240, srtt = 0.235, rttvar = 0.007, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 293: rtt = 0.240, srtt = 0.235, rttvar = 0.007, rto = 4.000 +recv 293 +updated rto +send 294: rtt = 0.220, srtt = 0.234, rttvar = 0.009, rto = 2.000 +recv 294 +updated rto +send 295: rtt = 0.240, srtt = 0.234, rttvar = 0.009, rto = 2.000 +recv 295 +updated rto +send 296: rtt = 0.219, srtt = 0.232, rttvar = 0.010, rto = 2.000 +recv 296 +updated rto +send 297: rtt = 0.230, srtt = 0.232, rttvar = 0.008, rto = 2.000 +recv 297 +updated rto +send 298: rtt = 0.240, srtt = 0.233, rttvar = 0.008, rto = 2.000 +recv 298 +updated rto +send 299: rtt = 0.240, srtt = 0.234, rttvar = 0.008, rto = 2.000 +recv 299 +updated rto +send 300: rtt = 0.259, srtt = 0.237, rttvar = 0.012, rto = 2.000 +recv 300 +updated rto +send 301: rtt = 0.230, srtt = 0.236, rttvar = 0.011, rto = 2.000 +recv 301 +updated rto +send 302: rtt = 0.230, srtt = 0.235, rttvar = 0.010, rto = 2.000 +recv 302 +updated rto +send 303: rtt = 0.240, srtt = 0.236, rttvar = 0.008, rto = 2.000 +recv 303 +updated rto +send 304: rtt = 0.250, srtt = 0.238, rttvar = 0.010, rto = 2.000 +recv 304 +updated rto +send 305: rtt = 0.230, srtt = 0.237, rttvar = 0.009, rto = 2.000 +recv 305 +updated rto +send 306: rtt = 0.230, srtt = 0.236, rttvar = 0.009, rto = 2.000 +recv 306 +updated rto +send 307: rtt = 0.209, srtt = 0.233, rttvar = 0.013, rto = 2.000 +recv 307 +updated rto +send 308: rtt = 0.232, srtt = 0.232, rttvar = 0.010, rto = 2.000 +recv 308 +updated rto +send 309: rtt = 0.247, srtt = 0.234, rttvar = 0.011, rto = 2.000 +recv 309 +updated rto +send 310: rtt = 0.250, srtt = 0.236, rttvar = 0.012, rto = 2.000 +recv 310 +updated rto +send 311: rtt = 0.229, srtt = 0.235, rttvar = 0.011, rto = 2.000 +recv 311 +updated rto +send 312: rtt = 0.230, srtt = 0.235, rttvar = 0.010, rto = 2.000 +recv 312 +updated rto +send 313: rtt = 0.210, srtt = 0.232, rttvar = 0.013, rto = 2.000 +recv 313 +updated rto +send 314: rtt = 0.249, srtt = 0.234, rttvar = 0.014, rto = 2.000 +recv 314 +updated rto +send 315: rtt = 0.220, srtt = 0.232, rttvar = 0.014, rto = 2.000 +recv 315 +updated rto +send 316: rtt = 0.249, srtt = 0.234, rttvar = 0.015, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 316: rtt = 0.249, srtt = 0.234, rttvar = 0.015, rto = 4.000 +recv 316 +updated rto +send 317: rtt = 0.230, srtt = 0.234, rttvar = 0.012, rto = 2.000 +recv 317 +updated rto +send 318: rtt = 0.229, srtt = 0.233, rttvar = 0.010, rto = 2.000 +recv 318 +updated rto +send 319: rtt = 0.229, srtt = 0.233, rttvar = 0.009, rto = 2.000 +recv 319 +updated rto +send 320: rtt = 0.230, srtt = 0.232, rttvar = 0.007, rto = 2.000 +recv 320 +updated rto +send 321: rtt = 0.250, srtt = 0.234, rttvar = 0.010, rto = 2.000 +recv 321 +updated rto +send 322: rtt = 0.249, srtt = 0.236, rttvar = 0.011, rto = 2.000 +recv 322 +updated rto +send 323: rtt = 0.230, srtt = 0.235, rttvar = 0.010, rto = 2.000 +recv 323 +updated rto +send 324: rtt = 0.220, srtt = 0.234, rttvar = 0.011, rto = 2.000 +recv 324 +updated rto +send 325: rtt = 0.229, srtt = 0.233, rttvar = 0.010, rto = 2.000 +recv 325 +updated rto +send 326: rtt = 0.250, srtt = 0.235, rttvar = 0.011, rto = 2.000 +recv 326 +updated rto +send 327: rtt = 0.220, srtt = 0.233, rttvar = 0.012, rto = 2.000 +recv 327 +updated rto +send 328: rtt = 0.210, srtt = 0.230, rttvar = 0.015, rto = 2.000 +recv 328 +updated rto +send 329: rtt = 0.229, srtt = 0.230, rttvar = 0.012, rto = 2.000 +recv 329 +updated rto +send 330: rtt = 0.210, srtt = 0.228, rttvar = 0.014, rto = 2.000 +recv 330 +updated rto +send 331: rtt = 0.220, srtt = 0.227, rttvar = 0.012, rto = 2.000 +recv 331 +updated rto +send 332: rtt = 0.220, srtt = 0.226, rttvar = 0.011, rto = 2.000 +recv 332 +updated rto +send 333: rtt = 0.220, srtt = 0.225, rttvar = 0.010, rto = 2.000 +recv 333 +updated rto +send 334: rtt = 0.250, srtt = 0.228, rttvar = 0.013, rto = 2.000 +recv 334 +updated rto +send 335: rtt = 0.250, srtt = 0.231, rttvar = 0.016, rto = 2.000 +recv 335 +updated rto +send 336: rtt = 0.229, srtt = 0.231, rttvar = 0.012, rto = 2.000 +recv 336 +updated rto +send 337: rtt = 0.239, srtt = 0.232, rttvar = 0.011, rto = 2.000 +recv 337 +updated rto +send 338: rtt = 0.230, srtt = 0.232, rttvar = 0.009, rto = 2.000 +recv 338 +updated rto +send 339: rtt = 0.230, srtt = 0.231, rttvar = 0.007, rto = 2.000 +recv 339 +updated rto +send 340: rtt = 0.219, srtt = 0.230, rttvar = 0.008, rto = 2.000 +recv 340 +updated rto +send 341: rtt = 0.240, srtt = 0.231, rttvar = 0.009, rto = 2.000 +recv 341 +updated rto +send 342: rtt = 0.229, srtt = 0.231, rttvar = 0.007, rto = 2.000 +recv 342 +updated rto +send 343: rtt = 0.220, srtt = 0.229, rttvar = 0.008, rto = 2.000 +recv 343 +updated rto +send 344: rtt = 0.259, srtt = 0.233, rttvar = 0.013, rto = 2.000 +recv 344 +updated rto +send 345: rtt = 0.230, srtt = 0.233, rttvar = 0.011, rto = 2.000 +recv 345 +updated rto +send 346: rtt = 0.219, srtt = 0.231, rttvar = 0.012, rto = 2.000 +recv 346 +updated rto +send 347: rtt = 0.219, srtt = 0.230, rttvar = 0.012, rto = 2.000 +recv 347 +updated rto +send 348: rtt = 0.230, srtt = 0.230, rttvar = 0.009, rto = 2.000 +recv 348 +updated rto +send 349: rtt = 0.240, srtt = 0.231, rttvar = 0.009, rto = 2.000 +recv 349 +updated rto +send 350: rtt = 0.239, srtt = 0.232, rttvar = 0.009, rto = 2.000 +recv 350 +updated rto +send 351: rtt = 0.250, srtt = 0.234, rttvar = 0.011, rto = 2.000 +recv 351 +updated rto +send 352: rtt = 0.250, srtt = 0.236, rttvar = 0.012, rto = 2.000 +recv 352 +updated rto +send 353: rtt = 0.220, srtt = 0.234, rttvar = 0.013, rto = 2.000 +recv 353 +updated rto +send 354: rtt = 0.239, srtt = 0.235, rttvar = 0.011, rto = 2.000 +recv 354 +updated rto +send 355: rtt = 0.230, srtt = 0.234, rttvar = 0.010, rto = 2.000 +recv 355 +updated rto +send 356: rtt = 0.240, srtt = 0.235, rttvar = 0.009, rto = 2.000 +recv 356 +updated rto +send 357: rtt = 0.230, srtt = 0.234, rttvar = 0.008, rto = 2.000 +recv 357 +updated rto +send 358: rtt = 0.270, srtt = 0.239, rttvar = 0.015, rto = 2.000 +recv 358 +updated rto +send 359: rtt = 0.240, srtt = 0.239, rttvar = 0.011, rto = 2.000 +recv 359 +updated rto +send 360: rtt = 0.249, srtt = 0.240, rttvar = 0.011, rto = 2.000 +recv 360 +updated rto +send 361: rtt = 0.240, srtt = 0.240, rttvar = 0.008, rto = 2.000 +recv 361 +updated rto +send 362: rtt = 0.220, srtt = 0.238, rttvar = 0.011, rto = 2.000 +recv 362 +updated rto +send 363: rtt = 0.239, srtt = 0.238, rttvar = 0.009, rto = 2.000 +recv 363 +updated rto +send 364: rtt = 0.240, srtt = 0.238, rttvar = 0.007, rto = 2.000 +recv 364 +updated rto +send 365: rtt = 0.259, srtt = 0.241, rttvar = 0.011, rto = 2.000 +recv 365 +updated rto +send 366: rtt = 0.240, srtt = 0.241, rttvar = 0.008, rto = 2.000 +recv 366 +updated rto +send 367: rtt = 0.239, srtt = 0.240, rttvar = 0.006, rto = 2.000 +recv 367 +updated rto +send 368: rtt = 0.249, srtt = 0.241, rttvar = 0.007, rto = 2.000 +recv 368 +updated rto +send 369: rtt = 0.240, srtt = 0.241, rttvar = 0.006, rto = 2.000 +recv 369 +updated rto +send 370: rtt = 0.239, srtt = 0.241, rttvar = 0.005, rto = 2.000 +recv 370 +updated rto +send 371: rtt = 0.229, srtt = 0.240, rttvar = 0.007, rto = 2.000 +recv 371 +updated rto +send 372: rtt = 0.240, srtt = 0.240, rttvar = 0.005, rto = 2.000 +recv 372 +updated rto +send 373: rtt = 0.259, srtt = 0.242, rttvar = 0.009, rto = 2.000 +recv 373 +updated rto +send 374: rtt = 0.229, srtt = 0.240, rttvar = 0.010, rto = 2.000 +recv 374 +updated rto +send 375: rtt = 0.230, srtt = 0.239, rttvar = 0.010, rto = 2.000 +recv 375 +updated rto +send 376: rtt = 0.239, srtt = 0.239, rttvar = 0.007, rto = 2.000 +recv 376 +updated rto +send 377: rtt = 0.259, srtt = 0.242, rttvar = 0.011, rto = 2.000 +recv 377 +updated rto +send 378: rtt = 0.250, srtt = 0.243, rttvar = 0.010, rto = 2.000 +recv 378 +updated rto +send 379: rtt = 0.250, srtt = 0.244, rttvar = 0.009, rto = 2.000 +recv 379 +updated rto +send 380: rtt = 0.230, srtt = 0.242, rttvar = 0.010, rto = 2.000 +recv 380 +updated rto +send 381: rtt = 0.239, srtt = 0.241, rttvar = 0.009, rto = 2.000 +recv 381 +updated rto +send 382: rtt = 0.279, srtt = 0.246, rttvar = 0.016, rto = 2.000 +recv 382 +updated rto +send 383: rtt = 0.259, srtt = 0.248, rttvar = 0.015, rto = 2.000 +recv 383 +updated rto +send 384: rtt = 0.220, srtt = 0.244, rttvar = 0.018, rto = 2.000 +recv 384 +updated rto +send 385: rtt = 0.249, srtt = 0.245, rttvar = 0.015, rto = 2.000 +recv 385 +updated rto +send 386: rtt = 0.249, srtt = 0.245, rttvar = 0.012, rto = 2.000 +recv 386 +updated rto +send 387: rtt = 0.220, srtt = 0.242, rttvar = 0.015, rto = 2.000 +recv 387 +updated rto +send 388: rtt = 0.210, srtt = 0.238, rttvar = 0.020, rto = 2.000 +recv 388 +updated rto +send 389: rtt = 0.230, srtt = 0.237, rttvar = 0.017, rto = 2.000 +recv 389 +updated rto +send 390: rtt = 0.219, srtt = 0.235, rttvar = 0.017, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 390: rtt = 0.219, srtt = 0.235, rttvar = 0.017, rto = 4.000 +recv 390 +updated rto +send 391: rtt = 0.229, srtt = 0.234, rttvar = 0.014, rto = 2.000 +recv 391 +updated rto +send 392: rtt = 0.229, srtt = 0.234, rttvar = 0.012, rto = 2.000 +recv 392 +updated rto +send 393: rtt = 0.239, srtt = 0.234, rttvar = 0.010, rto = 2.000 +recv 393 +updated rto +send 394: rtt = 0.240, srtt = 0.235, rttvar = 0.009, rto = 2.000 +recv 394 +updated rto +send 395: rtt = 0.249, srtt = 0.237, rttvar = 0.010, rto = 2.000 +recv 395 +updated rto +send 396: rtt = 0.250, srtt = 0.238, rttvar = 0.011, rto = 2.000 +recv 396 +updated rto +send 397: rtt = 0.230, srtt = 0.237, rttvar = 0.010, rto = 2.000 +recv 397 +updated rto +send 398: rtt = 0.260, srtt = 0.240, rttvar = 0.014, rto = 2.000 +recv 398 +updated rto +send 399: rtt = 0.270, srtt = 0.244, rttvar = 0.018, rto = 2.000 +recv 399 +updated rto +send 400: rtt = 0.240, srtt = 0.243, rttvar = 0.014, rto = 2.000 +recv 400 +updated rto +send 401: rtt = 0.250, srtt = 0.244, rttvar = 0.012, rto = 2.000 +recv 401 +updated rto +send 402: rtt = 0.259, srtt = 0.246, rttvar = 0.013, rto = 2.000 +recv 402 +updated rto +send 403: rtt = 0.229, srtt = 0.244, rttvar = 0.014, rto = 2.000 +recv 403 +updated rto +send 404: rtt = 0.249, srtt = 0.245, rttvar = 0.012, rto = 2.000 +recv 404 +updated rto +send 405: rtt = 0.229, srtt = 0.243, rttvar = 0.013, rto = 2.000 +recv 405 +updated rto +send 406: rtt = 0.250, srtt = 0.244, rttvar = 0.011, rto = 2.000 +recv 406 +updated rto +send 407: rtt = 0.230, srtt = 0.242, rttvar = 0.012, rto = 2.000 +recv 407 +updated rto +send 408: rtt = 0.230, srtt = 0.240, rttvar = 0.012, rto = 2.000 +recv 408 +updated rto +send 409: rtt = 0.220, srtt = 0.238, rttvar = 0.014, rto = 2.000 +recv 409 +updated rto +send 410: rtt = 0.229, srtt = 0.237, rttvar = 0.013, rto = 2.000 +recv 410 +updated rto +send 411: rtt = 0.249, srtt = 0.238, rttvar = 0.013, rto = 2.000 +recv 411 +updated rto +send 412: rtt = 0.249, srtt = 0.240, rttvar = 0.012, rto = 2.000 +recv 412 +updated rto +send 413: rtt = 0.210, srtt = 0.236, rttvar = 0.017, rto = 2.000 +recv 413 +updated rto +send 414: rtt = 0.220, srtt = 0.234, rttvar = 0.016, rto = 2.000 +recv 414 +updated rto +send 415: rtt = 0.220, srtt = 0.232, rttvar = 0.016, rto = 2.000 +recv 415 +updated rto +send 416: rtt = 0.219, srtt = 0.231, rttvar = 0.015, rto = 2.000 +recv 416 +updated rto +send 417: rtt = 0.239, srtt = 0.232, rttvar = 0.013, rto = 2.000 +recv 417 +updated rto +send 418: rtt = 0.260, srtt = 0.235, rttvar = 0.017, rto = 2.000 +recv 418 +updated rto +send 419: rtt = 0.240, srtt = 0.236, rttvar = 0.014, rto = 2.000 +recv 419 +updated rto +send 420: rtt = 0.229, srtt = 0.235, rttvar = 0.012, rto = 2.000 +recv 420 +updated rto +send 421: rtt = 0.220, srtt = 0.233, rttvar = 0.013, rto = 2.000 +recv 421 +updated rto +send 422: rtt = 0.229, srtt = 0.233, rttvar = 0.011, rto = 2.000 +recv 422 +updated rto +send 423: rtt = 0.249, srtt = 0.235, rttvar = 0.012, rto = 2.000 +recv 423 +updated rto +send 424: rtt = 0.260, srtt = 0.238, rttvar = 0.015, rto = 2.000 +recv 424 +updated rto +send 425: rtt = 0.239, srtt = 0.238, rttvar = 0.012, rto = 2.000 +recv 425 +updated rto +send 426: rtt = 0.240, srtt = 0.238, rttvar = 0.009, rto = 2.000 +recv 426 +updated rto +send 427: rtt = 0.230, srtt = 0.237, rttvar = 0.009, rto = 2.000 +recv 427 +updated rto +send 428: rtt = 0.279, srtt = 0.242, rttvar = 0.017, rto = 2.000 +recv 428 +updated rto +send 429: rtt = 0.240, srtt = 0.242, rttvar = 0.014, rto = 2.000 +recv 429 +updated rto +send 430: rtt = 0.249, srtt = 0.243, rttvar = 0.012, rto = 2.000 +recv 430 +updated rto +send 431: rtt = 0.259, srtt = 0.245, rttvar = 0.013, rto = 2.000 +recv 431 +updated rto +send 432: rtt = 0.250, srtt = 0.246, rttvar = 0.011, rto = 2.000 +recv 432 +updated rto +send 433: rtt = 0.229, srtt = 0.244, rttvar = 0.012, rto = 2.000 +recv 433 +updated rto +send 434: rtt = 0.240, srtt = 0.243, rttvar = 0.010, rto = 2.000 +recv 434 +updated rto +send 435: rtt = 0.230, srtt = 0.241, rttvar = 0.011, rto = 2.000 +recv 435 +updated rto +send 436: rtt = 0.249, srtt = 0.242, rttvar = 0.010, rto = 2.000 +recv 436 +updated rto +send 437: rtt = 0.240, srtt = 0.242, rttvar = 0.008, rto = 2.000 +recv 437 +updated rto +send 438: rtt = 0.240, srtt = 0.242, rttvar = 0.007, rto = 2.000 +recv 438 +updated rto +send 439: rtt = 0.249, srtt = 0.243, rttvar = 0.007, rto = 2.000 +recv 439 +updated rto +send 440: rtt = 0.220, srtt = 0.240, rttvar = 0.011, rto = 2.000 +recv 440 +updated rto +send 441: rtt = 0.219, srtt = 0.237, rttvar = 0.013, rto = 2.000 +recv 441 +updated rto +send 442: rtt = 0.239, srtt = 0.237, rttvar = 0.010, rto = 2.000 +recv 442 +updated rto +send 443: rtt = 0.250, srtt = 0.239, rttvar = 0.011, rto = 2.000 +recv 443 +updated rto +send 444: rtt = 0.240, srtt = 0.239, rttvar = 0.008, rto = 2.000 +recv 444 +updated rto +send 445: rtt = 0.230, srtt = 0.238, rttvar = 0.009, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 445: rtt = 0.230, srtt = 0.238, rttvar = 0.009, rto = 4.000 +recv 445 +updated rto +send 446: rtt = 0.489, srtt = 0.269, rttvar = 0.069, rto = 2.000 +recv 446 +updated rto +send 447: rtt = 0.230, srtt = 0.264, rttvar = 0.062, rto = 2.000 +recv 447 +updated rto +send 448: rtt = 0.240, srtt = 0.261, rttvar = 0.052, rto = 2.000 +recv 448 +updated rto +send 449: rtt = 0.250, srtt = 0.260, rttvar = 0.042, rto = 2.000 +recv 449 +updated rto +send 450: rtt = 0.239, srtt = 0.257, rttvar = 0.037, rto = 2.000 +recv 450 +updated rto +send 451: rtt = 0.260, srtt = 0.258, rttvar = 0.028, rto = 2.000 +recv 451 +updated rto +send 452: rtt = 0.240, srtt = 0.255, rttvar = 0.026, rto = 2.000 +recv 452 +updated rto +send 453: rtt = 0.599, srtt = 0.298, rttvar = 0.105, rto = 2.000 +recv 453 +updated rto +send 454: rtt = 0.249, srtt = 0.292, rttvar = 0.091, rto = 2.000 +recv 454 +updated rto +send 455: rtt = 0.220, srtt = 0.283, rttvar = 0.086, rto = 2.000 +recv 455 +updated rto +send 456: rtt = 0.230, srtt = 0.277, rttvar = 0.078, rto = 2.000 +recv 456 +updated rto +send 457: rtt = 0.220, srtt = 0.269, rttvar = 0.073, rto = 2.000 +recv 457 +updated rto +send 458: rtt = 0.239, srtt = 0.266, rttvar = 0.062, rto = 2.000 +recv 458 +updated rto +send 459: rtt = 0.230, srtt = 0.261, rttvar = 0.056, rto = 2.000 +recv 459 +updated rto +send 460: rtt = 0.249, srtt = 0.260, rttvar = 0.045, rto = 2.000 +recv 460 +updated rto +send 461: rtt = 0.240, srtt = 0.257, rttvar = 0.038, rto = 2.000 +recv 461 +updated rto +send 462: rtt = 0.230, srtt = 0.254, rttvar = 0.036, rto = 2.000 +recv 462 +updated rto +send 463: rtt = 0.230, srtt = 0.251, rttvar = 0.033, rto = 2.000 +recv 463 +updated rto +send 464: rtt = 0.240, srtt = 0.249, rttvar = 0.027, rto = 2.000 +recv 464 +updated rto +send 465: rtt = 0.249, srtt = 0.249, rttvar = 0.021, rto = 2.000 +recv 465 +updated rto +send 466: rtt = 0.240, srtt = 0.248, rttvar = 0.018, rto = 2.000 +recv 466 +updated rto +send 467: rtt = 0.229, srtt = 0.246, rttvar = 0.018, rto = 2.000 +recv 467 +updated rto +send 468: rtt = 0.249, srtt = 0.246, rttvar = 0.014, rto = 2.000 +recv 468 +updated rto +send 469: rtt = 0.249, srtt = 0.247, rttvar = 0.011, rto = 2.000 +recv 469 +updated rto +send 470: rtt = 0.230, srtt = 0.245, rttvar = 0.013, rto = 2.000 +recv 470 +updated rto +send 471: rtt = 0.250, srtt = 0.245, rttvar = 0.011, rto = 2.000 +recv 471 +updated rto +send 472: rtt = 0.240, srtt = 0.245, rttvar = 0.010, rto = 2.000 +recv 472 +updated rto +send 473: rtt = 0.250, srtt = 0.245, rttvar = 0.008, rto = 2.000 +recv 473 +updated rto +send 474: rtt = 0.250, srtt = 0.246, rttvar = 0.008, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 474: rtt = 0.250, srtt = 0.246, rttvar = 0.008, rto = 4.000 +recv 474 +updated rto +send 475: rtt = 0.240, srtt = 0.245, rttvar = 0.007, rto = 2.000 +recv 475 +updated rto +send 476: rtt = 0.250, srtt = 0.246, rttvar = 0.007, rto = 2.000 +recv 476 +updated rto +send 477: rtt = 0.220, srtt = 0.242, rttvar = 0.011, rto = 2.000 +recv 477 +updated rto +send 478: rtt = 0.250, srtt = 0.243, rttvar = 0.010, rto = 2.000 +recv 478 +updated rto +send 479: rtt = 0.250, srtt = 0.244, rttvar = 0.009, rto = 2.000 +recv 479 +updated rto +send 480: rtt = 0.240, srtt = 0.244, rttvar = 0.008, rto = 2.000 +recv 480 +updated rto +send 481: rtt = 0.229, srtt = 0.242, rttvar = 0.010, rto = 2.000 +recv 481 +updated rto +send 482: rtt = 0.279, srtt = 0.247, rttvar = 0.017, rto = 2.000 +recv 482 +updated rto +send 483: rtt = 0.260, srtt = 0.248, rttvar = 0.016, rto = 2.000 +recv 483 +updated rto +send 484: rtt = 0.209, srtt = 0.243, rttvar = 0.022, rto = 2.000 +recv 484 +updated rto +send 485: rtt = 0.229, srtt = 0.242, rttvar = 0.020, rto = 2.000 +recv 485 +updated rto +send 486: rtt = 0.230, srtt = 0.240, rttvar = 0.018, rto = 2.000 +recv 486 +updated rto +send 487: rtt = 0.240, srtt = 0.240, rttvar = 0.013, rto = 2.000 +recv 487 +updated rto +send 488: rtt = 0.220, srtt = 0.238, rttvar = 0.015, rto = 2.000 +recv 488 +updated rto +send 489: rtt = 0.229, srtt = 0.236, rttvar = 0.013, rto = 2.000 +recv 489 +updated rto +send 490: rtt = 0.309, srtt = 0.246, rttvar = 0.028, rto = 2.000 +recv 490 +updated rto +send 491: rtt = 0.219, srtt = 0.242, rttvar = 0.028, rto = 2.000 +recv 491 +updated rto +send 492: rtt = 0.240, srtt = 0.242, rttvar = 0.021, rto = 2.000 +recv 492 +updated rto +send 493: rtt = 0.220, srtt = 0.239, rttvar = 0.022, rto = 2.000 +recv 493 +updated rto +send 494: rtt = 0.239, srtt = 0.239, rttvar = 0.016, rto = 2.000 +recv 494 +updated rto +send 495: rtt = 0.239, srtt = 0.239, rttvar = 0.012, rto = 2.000 +recv 495 +updated rto +send 496: rtt = 0.239, srtt = 0.239, rttvar = 0.009, rto = 2.000 +recv 496 +updated rto +send 497: rtt = 0.240, srtt = 0.239, rttvar = 0.007, rto = 2.000 +recv 497 +updated rto +send 498: rtt = 0.240, srtt = 0.239, rttvar = 0.006, rto = 2.000 +recv 498 +updated rto +send 499: rtt = 0.230, srtt = 0.238, rttvar = 0.006, rto = 2.000 +recv 499 +updated rto +send 500: rtt = 0.250, srtt = 0.240, rttvar = 0.008, rto = 2.000 +recv 500 +updated rto diff --git a/rtt/rtt.out.vangogh.2 b/rtt/rtt.out.vangogh.2 new file mode 100644 index 0000000..07a6c98 --- /dev/null +++ b/rtt/rtt.out.vangogh.2 @@ -0,0 +1,1568 @@ +send 1: rtt = 0.000, srtt = 0.000, rttvar = 0.750, rto = 3.000 +recv 1 +updated rto +send 2: rtt = 0.279, srtt = 0.035, rttvar = 0.632, rto = 2.564 +recv 2 +updated rto +send 3: rtt = 0.238, srtt = 0.060, rttvar = 0.525, rto = 2.160 +recv 3 +updated rto +send 4: rtt = 0.229, srtt = 0.081, rttvar = 0.436, rto = 2.000 +recv 4 +updated rto +send 5: rtt = 0.298, srtt = 0.108, rttvar = 0.381, rto = 2.000 +recv 5 +updated rto +send 6: rtt = 0.280, srtt = 0.130, rttvar = 0.329, rto = 2.000 +recv 6 +updated rto +send 7: rtt = 0.230, srtt = 0.142, rttvar = 0.272, rto = 2.000 +recv 7 +updated rto +send 8: rtt = 0.230, srtt = 0.153, rttvar = 0.226, rto = 2.000 +recv 8 +updated rto +send 9: rtt = 0.219, srtt = 0.162, rttvar = 0.186, rto = 2.000 +recv 9 +updated rto +send 10: rtt = 0.255, srtt = 0.173, rttvar = 0.163, rto = 2.000 +recv 10 +updated rto +send 11: rtt = 0.224, srtt = 0.180, rttvar = 0.135, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 11: rtt = 0.224, srtt = 0.180, rttvar = 0.135, rto = 4.000 +recv 11 +updated rto +send 12: rtt = 0.259, srtt = 0.190, rttvar = 0.121, rto = 2.000 +recv 12 +updated rto +send 13: rtt = 0.249, srtt = 0.197, rttvar = 0.105, rto = 2.000 +recv 13 +updated rto +send 14: rtt = 0.273, srtt = 0.206, rttvar = 0.098, rto = 2.000 +recv 14 +updated rto +send 15: rtt = 0.217, srtt = 0.208, rttvar = 0.076, rto = 2.000 +recv 15 +updated rto +send 16: rtt = 0.260, srtt = 0.214, rttvar = 0.070, rto = 2.000 +recv 16 +updated rto +send 17: rtt = 0.270, srtt = 0.221, rttvar = 0.067, rto = 2.000 +recv 17 +updated rto +send 18: rtt = 0.240, srtt = 0.224, rttvar = 0.055, rto = 2.000 +recv 18 +updated rto +send 19: rtt = 0.250, srtt = 0.227, rttvar = 0.048, rto = 2.000 +recv 19 +updated rto +send 20: rtt = 0.210, srtt = 0.225, rttvar = 0.040, rto = 2.000 +recv 20 +updated rto +send 21: rtt = 0.269, srtt = 0.230, rttvar = 0.041, rto = 2.000 +recv 21 +updated rto +send 22: rtt = 0.260, srtt = 0.234, rttvar = 0.038, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 22: rtt = 0.260, srtt = 0.234, rttvar = 0.038, rto = 4.000 +recv 22 +updated rto +send 23: rtt = 0.250, srtt = 0.236, rttvar = 0.033, rto = 2.000 +recv 23 +updated rto +send 24: rtt = 0.280, srtt = 0.242, rttvar = 0.035, rto = 2.000 +recv 24 +updated rto +send 25: rtt = 0.250, srtt = 0.243, rttvar = 0.029, rto = 2.000 +recv 25 +updated rto +send 26: rtt = 0.219, srtt = 0.240, rttvar = 0.027, rto = 2.000 +recv 26 +updated rto +send 27: rtt = 0.230, srtt = 0.238, rttvar = 0.023, rto = 2.000 +recv 27 +updated rto +send 28: rtt = 0.249, srtt = 0.240, rttvar = 0.020, rto = 2.000 +recv 28 +updated rto +send 29: rtt = 0.250, srtt = 0.241, rttvar = 0.017, rto = 2.000 +recv 29 +updated rto +send 30: rtt = 0.250, srtt = 0.242, rttvar = 0.015, rto = 2.000 +recv 30 +updated rto +send 31: rtt = 0.271, srtt = 0.246, rttvar = 0.019, rto = 2.000 +recv 31 +updated rto +send 32: rtt = 0.247, srtt = 0.246, rttvar = 0.014, rto = 2.000 +recv 32 +updated rto +send 33: rtt = 0.282, srtt = 0.250, rttvar = 0.020, rto = 2.000 +recv 33 +updated rto +send 34: rtt = 0.249, srtt = 0.250, rttvar = 0.015, rto = 2.000 +recv 34 +updated rto +send 35: rtt = 0.228, srtt = 0.247, rttvar = 0.017, rto = 2.000 +recv 35 +updated rto +send 36: rtt = 0.220, srtt = 0.244, rttvar = 0.020, rto = 2.000 +recv 36 +updated rto +send 37: rtt = 0.239, srtt = 0.243, rttvar = 0.016, rto = 2.000 +recv 37 +updated rto +send 38: rtt = 0.240, srtt = 0.243, rttvar = 0.013, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 38: rtt = 0.240, srtt = 0.243, rttvar = 0.013, rto = 4.000 +recv 38 +updated rto +send 39: rtt = 0.220, srtt = 0.240, rttvar = 0.015, rto = 2.000 +recv 39 +updated rto +send 40: rtt = 0.230, srtt = 0.239, rttvar = 0.014, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 40: rtt = 0.230, srtt = 0.239, rttvar = 0.014, rto = 4.000 +recv 40 +updated rto +send 41: rtt = 0.250, srtt = 0.240, rttvar = 0.013, rto = 2.000 +recv 41 +updated rto +send 42: rtt = 0.249, srtt = 0.241, rttvar = 0.012, rto = 2.000 +recv 42 +updated rto +send 43: rtt = 0.230, srtt = 0.240, rttvar = 0.012, rto = 2.000 +recv 43 +updated rto +send 44: rtt = 0.219, srtt = 0.237, rttvar = 0.014, rto = 2.000 +recv 44 +updated rto +send 45: rtt = 0.250, srtt = 0.239, rttvar = 0.014, rto = 2.000 +recv 45 +updated rto +send 46: rtt = 0.250, srtt = 0.240, rttvar = 0.013, rto = 2.000 +recv 46 +updated rto +send 47: rtt = 0.240, srtt = 0.240, rttvar = 0.010, rto = 2.000 +recv 47 +updated rto +send 48: rtt = 0.270, srtt = 0.244, rttvar = 0.015, rto = 2.000 +recv 48 +updated rto +send 49: rtt = 0.249, srtt = 0.245, rttvar = 0.012, rto = 2.000 +recv 49 +updated rto +send 50: rtt = 0.240, srtt = 0.244, rttvar = 0.010, rto = 2.000 +recv 50 +updated rto +send 51: rtt = 0.240, srtt = 0.244, rttvar = 0.009, rto = 2.000 +recv 51 +updated rto +send 52: rtt = 0.230, srtt = 0.242, rttvar = 0.010, rto = 2.000 +recv 52 +updated rto +send 53: rtt = 0.260, srtt = 0.244, rttvar = 0.012, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 53: rtt = 0.260, srtt = 0.244, rttvar = 0.012, rto = 4.000 +recv 53 +updated rto +send 54: rtt = 0.290, srtt = 0.250, rttvar = 0.021, rto = 2.000 +recv 54 +updated rto +send 55: rtt = 0.260, srtt = 0.251, rttvar = 0.018, rto = 2.000 +recv 55 +updated rto +send 56: rtt = 0.250, srtt = 0.251, rttvar = 0.014, rto = 2.000 +recv 56 +updated rto +send 57: rtt = 0.250, srtt = 0.251, rttvar = 0.011, rto = 2.000 +recv 57 +updated rto +send 58: rtt = 0.339, srtt = 0.262, rttvar = 0.030, rto = 2.000 +recv 58 +updated rto +send 59: rtt = 0.210, srtt = 0.255, rttvar = 0.035, rto = 2.000 +recv 59 +updated rto +send 60: rtt = 0.210, srtt = 0.250, rttvar = 0.038, rto = 2.000 +recv 60 +updated rto +send 61: rtt = 0.240, srtt = 0.248, rttvar = 0.031, rto = 2.000 +recv 61 +updated rto +send 62: rtt = 0.230, srtt = 0.246, rttvar = 0.028, rto = 2.000 +recv 62 +updated rto +send 63: rtt = 0.219, srtt = 0.243, rttvar = 0.028, rto = 2.000 +recv 63 +updated rto +send 64: rtt = 0.230, srtt = 0.241, rttvar = 0.024, rto = 2.000 +recv 64 +updated rto +send 65: rtt = 0.250, srtt = 0.242, rttvar = 0.020, rto = 2.000 +recv 65 +updated rto +send 66: rtt = 0.234, srtt = 0.241, rttvar = 0.017, rto = 2.000 +recv 66 +updated rto +send 67: rtt = 0.255, srtt = 0.243, rttvar = 0.016, rto = 2.000 +recv 67 +updated rto +send 68: rtt = 0.280, srtt = 0.248, rttvar = 0.021, rto = 2.000 +recv 68 +updated rto +send 69: rtt = 0.270, srtt = 0.250, rttvar = 0.022, rto = 2.000 +recv 69 +updated rto +send 70: rtt = 0.210, srtt = 0.245, rttvar = 0.026, rto = 2.000 +recv 70 +updated rto +send 71: rtt = 0.240, srtt = 0.245, rttvar = 0.021, rto = 2.000 +recv 71 +updated rto +send 72: rtt = 0.250, srtt = 0.245, rttvar = 0.017, rto = 2.000 +recv 72 +updated rto +send 73: rtt = 0.260, srtt = 0.247, rttvar = 0.017, rto = 2.000 +recv 73 +updated rto +send 74: rtt = 0.250, srtt = 0.248, rttvar = 0.013, rto = 2.000 +recv 74 +updated rto +send 75: rtt = 0.240, srtt = 0.247, rttvar = 0.012, rto = 2.000 +recv 75 +updated rto +send 76: rtt = 0.210, srtt = 0.242, rttvar = 0.018, rto = 2.000 +recv 76 +updated rto +send 77: rtt = 0.260, srtt = 0.244, rttvar = 0.018, rto = 2.000 +recv 77 +updated rto +send 78: rtt = 0.210, srtt = 0.240, rttvar = 0.022, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 78: rtt = 0.210, srtt = 0.240, rttvar = 0.022, rto = 4.000 +recv 78 +updated rto +send 79: rtt = 0.259, srtt = 0.242, rttvar = 0.021, rto = 2.000 +recv 79 +updated rto +send 80: rtt = 0.240, srtt = 0.242, rttvar = 0.017, rto = 2.000 +recv 80 +updated rto +send 81: rtt = 0.239, srtt = 0.242, rttvar = 0.013, rto = 2.000 +recv 81 +updated rto +send 82: rtt = 0.250, srtt = 0.243, rttvar = 0.012, rto = 2.000 +recv 82 +updated rto +send 83: rtt = 0.250, srtt = 0.244, rttvar = 0.011, rto = 2.000 +recv 83 +updated rto +send 84: rtt = 0.230, srtt = 0.242, rttvar = 0.012, rto = 2.000 +recv 84 +updated rto +send 85: rtt = 0.239, srtt = 0.242, rttvar = 0.009, rto = 2.000 +recv 85 +updated rto +send 86: rtt = 0.230, srtt = 0.240, rttvar = 0.010, rto = 2.000 +recv 86 +updated rto +send 87: rtt = 0.270, srtt = 0.244, rttvar = 0.015, rto = 2.000 +recv 87 +updated rto +send 88: rtt = 0.240, srtt = 0.243, rttvar = 0.012, rto = 2.000 +recv 88 +updated rto +send 89: rtt = 0.240, srtt = 0.243, rttvar = 0.010, rto = 2.000 +recv 89 +updated rto +send 90: rtt = 0.250, srtt = 0.244, rttvar = 0.009, rto = 2.000 +recv 90 +updated rto +send 91: rtt = 0.250, srtt = 0.245, rttvar = 0.008, rto = 2.000 +recv 91 +updated rto +send 92: rtt = 0.230, srtt = 0.243, rttvar = 0.010, rto = 2.000 +recv 92 +updated rto +send 93: rtt = 0.220, srtt = 0.240, rttvar = 0.013, rto = 2.000 +recv 93 +updated rto +send 94: rtt = 0.240, srtt = 0.240, rttvar = 0.010, rto = 2.000 +recv 94 +updated rto +send 95: rtt = 0.249, srtt = 0.241, rttvar = 0.010, rto = 2.000 +recv 95 +updated rto +send 96: rtt = 0.230, srtt = 0.240, rttvar = 0.010, rto = 2.000 +recv 96 +updated rto +send 97: rtt = 0.253, srtt = 0.241, rttvar = 0.011, rto = 2.000 +recv 97 +updated rto +send 98: rtt = 0.227, srtt = 0.240, rttvar = 0.012, rto = 2.000 +recv 98 +updated rto +send 99: rtt = 0.229, srtt = 0.238, rttvar = 0.011, rto = 2.000 +recv 99 +updated rto +send 100: rtt = 0.259, srtt = 0.241, rttvar = 0.014, rto = 2.000 +recv 100 +updated rto +send 101: rtt = 0.240, srtt = 0.241, rttvar = 0.011, rto = 2.000 +recv 101 +updated rto +send 102: rtt = 0.240, srtt = 0.241, rttvar = 0.008, rto = 2.000 +recv 102 +updated rto +send 103: rtt = 0.240, srtt = 0.241, rttvar = 0.006, rto = 2.000 +recv 103 +updated rto +send 104: rtt = 0.255, srtt = 0.242, rttvar = 0.008, rto = 2.000 +recv 104 +updated rto +send 105: rtt = 0.273, srtt = 0.246, rttvar = 0.014, rto = 2.000 +recv 105 +updated rto +send 106: rtt = 0.260, srtt = 0.248, rttvar = 0.014, rto = 2.000 +recv 106 +updated rto +send 107: rtt = 0.250, srtt = 0.248, rttvar = 0.011, rto = 2.000 +recv 107 +updated rto +send 108: rtt = 0.254, srtt = 0.249, rttvar = 0.010, rto = 2.000 +recv 108 +updated rto +send 109: rtt = 0.269, srtt = 0.251, rttvar = 0.012, rto = 2.000 +recv 109 +updated rto +send 110: rtt = 0.277, srtt = 0.255, rttvar = 0.016, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 110: rtt = 0.277, srtt = 0.255, rttvar = 0.016, rto = 4.000 +recv 110 +updated rto +send 111: rtt = 0.250, srtt = 0.254, rttvar = 0.013, rto = 2.000 +recv 111 +updated rto +send 112: rtt = 0.249, srtt = 0.253, rttvar = 0.011, rto = 2.000 +recv 112 +updated rto +send 113: rtt = 0.260, srtt = 0.254, rttvar = 0.010, rto = 2.000 +recv 113 +updated rto +send 114: rtt = 0.260, srtt = 0.255, rttvar = 0.009, rto = 2.000 +recv 114 +updated rto +send 115: rtt = 0.239, srtt = 0.253, rttvar = 0.011, rto = 2.000 +recv 115 +updated rto +send 116: rtt = 0.230, srtt = 0.250, rttvar = 0.014, rto = 2.000 +recv 116 +updated rto +send 117: rtt = 0.230, srtt = 0.248, rttvar = 0.015, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 117: rtt = 0.230, srtt = 0.248, rttvar = 0.015, rto = 4.000 +recv 117 +updated rto +send 118: rtt = 0.240, srtt = 0.247, rttvar = 0.013, rto = 2.000 +recv 118 +updated rto +send 119: rtt = 0.260, srtt = 0.248, rttvar = 0.013, rto = 2.000 +recv 119 +updated rto +send 120: rtt = 0.270, srtt = 0.251, rttvar = 0.015, rto = 2.000 +recv 120 +updated rto +send 121: rtt = 0.260, srtt = 0.252, rttvar = 0.014, rto = 2.000 +recv 121 +updated rto +send 122: rtt = 0.230, srtt = 0.249, rttvar = 0.016, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 122: rtt = 0.230, srtt = 0.249, rttvar = 0.016, rto = 4.000 +recv 122 +updated rto +send 123: rtt = 0.220, srtt = 0.246, rttvar = 0.019, rto = 2.000 +recv 123 +updated rto +send 124: rtt = 0.220, srtt = 0.242, rttvar = 0.021, rto = 2.000 +recv 124 +updated rto +send 125: rtt = 0.250, srtt = 0.243, rttvar = 0.018, rto = 2.000 +recv 125 +updated rto +send 126: rtt = 0.220, srtt = 0.240, rttvar = 0.019, rto = 2.000 +recv 126 +updated rto +send 127: rtt = 0.229, srtt = 0.239, rttvar = 0.017, rto = 2.000 +recv 127 +updated rto +send 128: rtt = 0.240, srtt = 0.239, rttvar = 0.013, rto = 2.000 +recv 128 +updated rto +send 129: rtt = 0.229, srtt = 0.238, rttvar = 0.012, rto = 2.000 +recv 129 +updated rto +send 130: rtt = 0.233, srtt = 0.237, rttvar = 0.010, rto = 2.000 +recv 130 +updated rto +send 131: rtt = 0.256, srtt = 0.240, rttvar = 0.013, rto = 2.000 +recv 131 +updated rto +send 132: rtt = 0.229, srtt = 0.238, rttvar = 0.012, rto = 2.000 +recv 132 +updated rto +send 133: rtt = 0.229, srtt = 0.237, rttvar = 0.011, rto = 2.000 +recv 133 +updated rto +send 134: rtt = 0.234, srtt = 0.237, rttvar = 0.009, rto = 2.000 +recv 134 +updated rto +send 135: rtt = 0.250, srtt = 0.238, rttvar = 0.010, rto = 2.000 +recv 135 +updated rto +send 136: rtt = 0.216, srtt = 0.236, rttvar = 0.013, rto = 2.000 +recv 136 +updated rto +send 137: rtt = 0.220, srtt = 0.234, rttvar = 0.014, rto = 2.000 +recv 137 +updated rto +send 138: rtt = 0.249, srtt = 0.236, rttvar = 0.014, rto = 2.000 +recv 138 +updated rto +send 139: rtt = 0.229, srtt = 0.235, rttvar = 0.012, rto = 2.000 +recv 139 +updated rto +send 140: rtt = 0.230, srtt = 0.234, rttvar = 0.010, rto = 2.000 +recv 140 +updated rto +send 141: rtt = 0.250, srtt = 0.236, rttvar = 0.012, rto = 2.000 +recv 141 +updated rto +send 142: rtt = 0.230, srtt = 0.235, rttvar = 0.010, rto = 2.000 +recv 142 +updated rto +send 143: rtt = 0.259, srtt = 0.238, rttvar = 0.014, rto = 2.000 +recv 143 +updated rto +send 144: rtt = 0.240, srtt = 0.239, rttvar = 0.011, rto = 2.000 +recv 144 +updated rto +send 145: rtt = 0.250, srtt = 0.240, rttvar = 0.011, rto = 2.000 +recv 145 +updated rto +send 146: rtt = 0.230, srtt = 0.239, rttvar = 0.011, rto = 2.000 +recv 146 +updated rto +send 147: rtt = 0.220, srtt = 0.236, rttvar = 0.013, rto = 2.000 +recv 147 +updated rto +send 148: rtt = 0.239, srtt = 0.237, rttvar = 0.010, rto = 2.000 +recv 148 +updated rto +send 149: rtt = 0.230, srtt = 0.236, rttvar = 0.009, rto = 2.000 +recv 149 +updated rto +send 150: rtt = 0.260, srtt = 0.239, rttvar = 0.013, rto = 2.000 +recv 150 +updated rto +send 151: rtt = 0.230, srtt = 0.238, rttvar = 0.012, rto = 2.000 +recv 151 +updated rto +send 152: rtt = 0.250, srtt = 0.239, rttvar = 0.012, rto = 2.000 +recv 152 +updated rto +send 153: rtt = 0.230, srtt = 0.238, rttvar = 0.011, rto = 2.000 +recv 153 +updated rto +send 154: rtt = 0.280, srtt = 0.243, rttvar = 0.019, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 154: rtt = 0.280, srtt = 0.243, rttvar = 0.019, rto = 4.000 +recv 154 +updated rto +send 155: rtt = 0.270, srtt = 0.247, rttvar = 0.021, rto = 2.000 +recv 155 +updated rto +send 156: rtt = 0.260, srtt = 0.248, rttvar = 0.019, rto = 2.000 +recv 156 +updated rto +send 157: rtt = 0.229, srtt = 0.246, rttvar = 0.019, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 157: rtt = 0.229, srtt = 0.246, rttvar = 0.019, rto = 4.000 +recv 157 +updated rto +send 158: rtt = 0.250, srtt = 0.246, rttvar = 0.015, rto = 2.000 +recv 158 +updated rto +send 159: rtt = 0.240, srtt = 0.246, rttvar = 0.013, rto = 2.000 +recv 159 +updated rto +send 160: rtt = 0.230, srtt = 0.244, rttvar = 0.014, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 160: rtt = 0.230, srtt = 0.244, rttvar = 0.014, rto = 4.000 +recv 160 +updated rto +send 161: rtt = 0.240, srtt = 0.243, rttvar = 0.011, rto = 2.000 +recv 161 +updated rto +send 162: rtt = 0.230, srtt = 0.242, rttvar = 0.012, rto = 2.000 +recv 162 +updated rto +send 163: rtt = 0.239, srtt = 0.241, rttvar = 0.009, rto = 2.000 +recv 163 +updated rto +send 164: rtt = 0.250, srtt = 0.242, rttvar = 0.009, rto = 2.000 +recv 164 +updated rto +send 165: rtt = 0.249, srtt = 0.243, rttvar = 0.009, rto = 2.000 +recv 165 +updated rto +send 166: rtt = 0.245, srtt = 0.243, rttvar = 0.007, rto = 2.000 +recv 166 +updated rto +send 167: rtt = 0.224, srtt = 0.241, rttvar = 0.010, rto = 2.000 +recv 167 +updated rto +send 168: rtt = 0.240, srtt = 0.241, rttvar = 0.008, rto = 2.000 +recv 168 +updated rto +send 169: rtt = 0.230, srtt = 0.240, rttvar = 0.009, rto = 2.000 +recv 169 +updated rto +send 170: rtt = 0.230, srtt = 0.238, rttvar = 0.009, rto = 2.000 +recv 170 +updated rto +send 171: rtt = 0.239, srtt = 0.238, rttvar = 0.007, rto = 2.000 +recv 171 +updated rto +send 172: rtt = 0.260, srtt = 0.241, rttvar = 0.010, rto = 2.000 +recv 172 +updated rto +send 173: rtt = 0.260, srtt = 0.243, rttvar = 0.013, rto = 2.000 +recv 173 +updated rto +send 174: rtt = 0.250, srtt = 0.244, rttvar = 0.011, rto = 2.000 +recv 174 +updated rto +send 175: rtt = 0.239, srtt = 0.244, rttvar = 0.010, rto = 2.000 +recv 175 +updated rto +send 176: rtt = 0.220, srtt = 0.241, rttvar = 0.013, rto = 2.000 +recv 176 +updated rto +send 177: rtt = 0.280, srtt = 0.246, rttvar = 0.020, rto = 2.000 +recv 177 +updated rto +send 178: rtt = 0.230, srtt = 0.244, rttvar = 0.019, rto = 2.000 +recv 178 +updated rto +send 179: rtt = 0.230, srtt = 0.242, rttvar = 0.017, rto = 2.000 +recv 179 +updated rto +send 180: rtt = 0.240, srtt = 0.242, rttvar = 0.014, rto = 2.000 +recv 180 +updated rto +send 181: rtt = 0.230, srtt = 0.240, rttvar = 0.013, rto = 2.000 +recv 181 +updated rto +send 182: rtt = 0.250, srtt = 0.241, rttvar = 0.012, rto = 2.000 +recv 182 +updated rto +send 183: rtt = 0.239, srtt = 0.241, rttvar = 0.010, rto = 2.000 +recv 183 +updated rto +send 184: rtt = 0.260, srtt = 0.244, rttvar = 0.012, rto = 2.000 +recv 184 +updated rto +send 185: rtt = 0.240, srtt = 0.243, rttvar = 0.010, rto = 2.000 +recv 185 +updated rto +send 186: rtt = 0.239, srtt = 0.243, rttvar = 0.008, rto = 2.000 +recv 186 +updated rto +send 187: rtt = 0.245, srtt = 0.243, rttvar = 0.007, rto = 2.000 +recv 187 +updated rto +send 188: rtt = 0.274, srtt = 0.247, rttvar = 0.013, rto = 2.000 +recv 188 +updated rto +send 189: rtt = 0.240, srtt = 0.246, rttvar = 0.011, rto = 2.000 +recv 189 +updated rto +send 190: rtt = 0.239, srtt = 0.245, rttvar = 0.010, rto = 2.000 +recv 190 +updated rto +send 191: rtt = 0.230, srtt = 0.243, rttvar = 0.011, rto = 2.000 +recv 191 +updated rto +send 192: rtt = 0.260, srtt = 0.245, rttvar = 0.013, rto = 2.000 +recv 192 +updated rto +send 193: rtt = 0.240, srtt = 0.245, rttvar = 0.011, rto = 2.000 +recv 193 +updated rto +send 194: rtt = 0.210, srtt = 0.240, rttvar = 0.017, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 194: rtt = 0.210, srtt = 0.240, rttvar = 0.017, rto = 4.000 +recv 194 +updated rto +send 195: rtt = 0.230, srtt = 0.239, rttvar = 0.015, rto = 2.000 +recv 195 +updated rto +send 196: rtt = 0.210, srtt = 0.235, rttvar = 0.019, rto = 2.000 +recv 196 +updated rto +send 197: rtt = 0.240, srtt = 0.236, rttvar = 0.015, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 197: rtt = 0.240, srtt = 0.236, rttvar = 0.015, rto = 4.000 +recv 197 +updated rto +send 198: rtt = 0.250, srtt = 0.238, rttvar = 0.015, rto = 2.000 +recv 198 +updated rto +send 199: rtt = 0.250, srtt = 0.239, rttvar = 0.014, rto = 2.000 +recv 199 +updated rto +send 200: rtt = 0.210, srtt = 0.236, rttvar = 0.018, rto = 2.000 +recv 200 +updated rto +send 201: rtt = 0.250, srtt = 0.237, rttvar = 0.017, rto = 2.000 +recv 201 +updated rto +send 202: rtt = 0.230, srtt = 0.236, rttvar = 0.015, rto = 2.000 +recv 202 +updated rto +send 203: rtt = 0.220, srtt = 0.234, rttvar = 0.015, rto = 2.000 +recv 203 +updated rto +send 204: rtt = 0.230, srtt = 0.234, rttvar = 0.012, rto = 2.000 +recv 204 +updated rto +send 205: rtt = 0.240, srtt = 0.235, rttvar = 0.011, rto = 2.000 +recv 205 +updated rto +send 206: rtt = 0.240, srtt = 0.235, rttvar = 0.009, rto = 2.000 +recv 206 +updated rto +send 207: rtt = 0.249, srtt = 0.237, rttvar = 0.011, rto = 2.000 +recv 207 +updated rto +send 208: rtt = 0.230, srtt = 0.236, rttvar = 0.010, rto = 2.000 +recv 208 +updated rto +send 209: rtt = 0.250, srtt = 0.238, rttvar = 0.011, rto = 2.000 +recv 209 +updated rto +send 210: rtt = 0.229, srtt = 0.237, rttvar = 0.010, rto = 2.000 +recv 210 +updated rto +send 211: rtt = 0.230, srtt = 0.236, rttvar = 0.009, rto = 2.000 +recv 211 +updated rto +send 212: rtt = 0.230, srtt = 0.235, rttvar = 0.009, rto = 2.000 +recv 212 +updated rto +send 213: rtt = 0.249, srtt = 0.237, rttvar = 0.010, rto = 2.000 +recv 213 +updated rto +send 214: rtt = 0.240, srtt = 0.237, rttvar = 0.008, rto = 2.000 +recv 214 +updated rto +send 215: rtt = 0.230, srtt = 0.236, rttvar = 0.008, rto = 2.000 +recv 215 +updated rto +send 216: rtt = 0.229, srtt = 0.235, rttvar = 0.008, rto = 2.000 +recv 216 +updated rto +send 217: rtt = 0.245, srtt = 0.237, rttvar = 0.008, rto = 2.000 +recv 217 +updated rto +send 218: rtt = 0.254, srtt = 0.239, rttvar = 0.011, rto = 2.000 +recv 218 +updated rto +send 219: rtt = 0.229, srtt = 0.238, rttvar = 0.010, rto = 2.000 +recv 219 +updated rto +send 220: rtt = 0.230, srtt = 0.237, rttvar = 0.010, rto = 2.000 +recv 220 +updated rto +send 221: rtt = 0.220, srtt = 0.235, rttvar = 0.011, rto = 2.000 +recv 221 +updated rto +send 222: rtt = 0.230, srtt = 0.234, rttvar = 0.010, rto = 2.000 +recv 222 +updated rto +send 223: rtt = 0.229, srtt = 0.233, rttvar = 0.009, rto = 2.000 +recv 223 +updated rto +send 224: rtt = 0.240, srtt = 0.234, rttvar = 0.008, rto = 2.000 +recv 224 +updated rto +send 225: rtt = 0.240, srtt = 0.235, rttvar = 0.007, rto = 2.000 +recv 225 +updated rto +send 226: rtt = 0.260, srtt = 0.238, rttvar = 0.012, rto = 2.000 +recv 226 +updated rto +send 227: rtt = 0.280, srtt = 0.243, rttvar = 0.019, rto = 2.000 +recv 227 +updated rto +send 228: rtt = 0.240, srtt = 0.243, rttvar = 0.015, rto = 2.000 +recv 228 +updated rto +send 229: rtt = 0.240, srtt = 0.243, rttvar = 0.012, rto = 2.000 +recv 229 +updated rto +send 230: rtt = 0.250, srtt = 0.243, rttvar = 0.011, rto = 2.000 +recv 230 +updated rto +send 231: rtt = 0.239, srtt = 0.243, rttvar = 0.009, rto = 2.000 +recv 231 +updated rto +send 232: rtt = 0.250, srtt = 0.244, rttvar = 0.009, rto = 2.000 +recv 232 +updated rto +send 233: rtt = 0.260, srtt = 0.246, rttvar = 0.011, rto = 2.000 +recv 233 +updated rto +send 234: rtt = 0.230, srtt = 0.244, rttvar = 0.012, rto = 2.000 +recv 234 +updated rto +send 235: rtt = 0.240, srtt = 0.243, rttvar = 0.010, rto = 2.000 +recv 235 +updated rto +send 236: rtt = 0.230, srtt = 0.242, rttvar = 0.011, rto = 2.000 +recv 236 +updated rto +send 237: rtt = 0.240, srtt = 0.241, rttvar = 0.009, rto = 2.000 +recv 237 +updated rto +send 238: rtt = 0.230, srtt = 0.240, rttvar = 0.009, rto = 2.000 +recv 238 +updated rto +send 239: rtt = 0.199, srtt = 0.235, rttvar = 0.017, rto = 2.000 +recv 239 +updated rto +send 240: rtt = 0.219, srtt = 0.233, rttvar = 0.017, rto = 2.000 +recv 240 +updated rto +send 241: rtt = 0.190, srtt = 0.228, rttvar = 0.023, rto = 2.000 +recv 241 +updated rto +send 242: rtt = 0.239, srtt = 0.229, rttvar = 0.020, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 242: rtt = 0.239, srtt = 0.229, rttvar = 0.020, rto = 4.000 +recv 242 +updated rto +send 243: rtt = 0.300, srtt = 0.238, rttvar = 0.033, rto = 2.000 +recv 243 +updated rto +send 244: rtt = 0.320, srtt = 0.248, rttvar = 0.045, rto = 2.000 +recv 244 +updated rto +send 245: rtt = 0.250, srtt = 0.248, rttvar = 0.034, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 245: rtt = 0.250, srtt = 0.248, rttvar = 0.034, rto = 4.000 +recv 245 +updated rto +send 246: rtt = 0.240, srtt = 0.247, rttvar = 0.028, rto = 2.000 +recv 246 +updated rto +send 247: rtt = 0.230, srtt = 0.245, rttvar = 0.025, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 247: rtt = 0.230, srtt = 0.245, rttvar = 0.025, rto = 4.000 +recv 247 +updated rto +send 248: rtt = 0.267, srtt = 0.248, rttvar = 0.024, rto = 2.000 +recv 248 +updated rto +send 249: rtt = 0.253, srtt = 0.249, rttvar = 0.020, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 249: rtt = 0.253, srtt = 0.249, rttvar = 0.020, rto = 4.000 +recv 249 +updated rto +send 250: rtt = 0.260, srtt = 0.250, rttvar = 0.018, rto = 2.000 +recv 250 +updated rto +send 251: rtt = 0.230, srtt = 0.247, rttvar = 0.018, rto = 2.000 +recv 251 +updated rto +send 252: rtt = 0.210, srtt = 0.243, rttvar = 0.023, rto = 2.000 +recv 252 +updated rto +send 253: rtt = 0.239, srtt = 0.242, rttvar = 0.018, rto = 2.000 +recv 253 +updated rto +send 254: rtt = 0.240, srtt = 0.242, rttvar = 0.014, rto = 2.000 +recv 254 +updated rto +send 255: rtt = 0.243, srtt = 0.242, rttvar = 0.011, rto = 2.000 +recv 255 +updated rto +send 256: rtt = 0.217, srtt = 0.239, rttvar = 0.014, rto = 2.000 +recv 256 +updated rto +send 257: rtt = 0.271, srtt = 0.243, rttvar = 0.019, rto = 2.000 +recv 257 +updated rto +send 258: rtt = 0.228, srtt = 0.241, rttvar = 0.018, rto = 2.000 +recv 258 +updated rto +send 259: rtt = 0.250, srtt = 0.242, rttvar = 0.016, rto = 2.000 +recv 259 +updated rto +send 260: rtt = 0.249, srtt = 0.243, rttvar = 0.013, rto = 2.000 +recv 260 +updated rto +send 261: rtt = 0.220, srtt = 0.240, rttvar = 0.016, rto = 2.000 +recv 261 +updated rto +send 262: rtt = 0.279, srtt = 0.245, rttvar = 0.022, rto = 2.000 +recv 262 +updated rto +send 263: rtt = 0.230, srtt = 0.243, rttvar = 0.020, rto = 2.000 +recv 263 +updated rto +send 264: rtt = 0.566, srtt = 0.284, rttvar = 0.096, rto = 2.000 +recv 264 +updated rto +send 265: rtt = 0.223, srtt = 0.276, rttvar = 0.087, rto = 2.000 +recv 265 +updated rto +send 266: rtt = 0.250, srtt = 0.273, rttvar = 0.072, rto = 2.000 +recv 266 +updated rto +send 267: rtt = 0.263, srtt = 0.271, rttvar = 0.056, rto = 2.000 +recv 267 +updated rto +send 268: rtt = 0.217, srtt = 0.265, rttvar = 0.056, rto = 2.000 +recv 268 +updated rto +send 269: rtt = 0.269, srtt = 0.265, rttvar = 0.043, rto = 2.000 +recv 269 +updated rto +send 270: rtt = 0.261, srtt = 0.265, rttvar = 0.033, rto = 2.000 +recv 270 +updated rto +send 271: rtt = 0.258, srtt = 0.264, rttvar = 0.027, rto = 2.000 +recv 271 +updated rto +send 272: rtt = 0.249, srtt = 0.262, rttvar = 0.024, rto = 2.000 +recv 272 +updated rto +send 273: rtt = 0.244, srtt = 0.260, rttvar = 0.022, rto = 2.000 +recv 273 +updated rto +send 274: rtt = 0.225, srtt = 0.255, rttvar = 0.025, rto = 2.000 +recv 274 +updated rto +send 275: rtt = 0.270, srtt = 0.257, rttvar = 0.023, rto = 2.000 +recv 275 +updated rto +send 276: rtt = 0.250, srtt = 0.256, rttvar = 0.019, rto = 2.000 +recv 276 +updated rto +send 277: rtt = 0.219, srtt = 0.252, rttvar = 0.023, rto = 2.000 +recv 277 +updated rto +send 278: rtt = 0.260, srtt = 0.253, rttvar = 0.020, rto = 2.000 +recv 278 +updated rto +send 279: rtt = 0.259, srtt = 0.253, rttvar = 0.016, rto = 2.000 +recv 279 +updated rto +send 280: rtt = 0.249, srtt = 0.253, rttvar = 0.013, rto = 2.000 +recv 280 +updated rto +send 281: rtt = 0.230, srtt = 0.250, rttvar = 0.016, rto = 2.000 +recv 281 +updated rto +send 282: rtt = 0.228, srtt = 0.247, rttvar = 0.017, rto = 2.000 +recv 282 +updated rto +send 283: rtt = 0.209, srtt = 0.243, rttvar = 0.023, rto = 2.000 +recv 283 +updated rto +send 284: rtt = 0.249, srtt = 0.243, rttvar = 0.019, rto = 2.000 +recv 284 +updated rto +send 285: rtt = 0.219, srtt = 0.240, rttvar = 0.020, rto = 2.000 +recv 285 +updated rto +send 286: rtt = 0.250, srtt = 0.242, rttvar = 0.017, rto = 2.000 +recv 286 +updated rto +send 287: rtt = 0.250, srtt = 0.243, rttvar = 0.015, rto = 2.000 +recv 287 +updated rto +send 288: rtt = 0.250, srtt = 0.243, rttvar = 0.013, rto = 2.000 +recv 288 +updated rto +send 289: rtt = 0.250, srtt = 0.244, rttvar = 0.012, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 289: rtt = 0.250, srtt = 0.244, rttvar = 0.012, rto = 4.000 +recv 289 +updated rto +send 290: rtt = 0.259, srtt = 0.246, rttvar = 0.012, rto = 2.000 +recv 290 +updated rto +send 291: rtt = 0.250, srtt = 0.247, rttvar = 0.010, rto = 2.000 +recv 291 +updated rto +send 292: rtt = 0.249, srtt = 0.247, rttvar = 0.008, rto = 2.000 +recv 292 +updated rto +send 293: rtt = 0.240, srtt = 0.246, rttvar = 0.008, rto = 2.000 +recv 293 +updated rto +send 294: rtt = 0.229, srtt = 0.244, rttvar = 0.010, rto = 2.000 +recv 294 +updated rto +send 295: rtt = 0.292, srtt = 0.250, rttvar = 0.020, rto = 2.000 +recv 295 +updated rto +send 296: rtt = 0.216, srtt = 0.246, rttvar = 0.023, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 296: rtt = 0.216, srtt = 0.246, rttvar = 0.023, rto = 4.000 +recv 296 +updated rto +send 297: rtt = 0.230, srtt = 0.244, rttvar = 0.021, rto = 2.000 +recv 297 +updated rto +send 298: rtt = 0.230, srtt = 0.242, rttvar = 0.019, rto = 2.000 +recv 298 +updated rto +send 299: rtt = 0.219, srtt = 0.239, rttvar = 0.020, rto = 2.000 +recv 299 +updated rto +send 300: rtt = 0.254, srtt = 0.241, rttvar = 0.019, rto = 2.000 +recv 300 +updated rto +send 301: rtt = 0.278, srtt = 0.246, rttvar = 0.023, rto = 2.000 +recv 301 +updated rto +send 302: rtt = 0.256, srtt = 0.247, rttvar = 0.020, rto = 2.000 +recv 302 +updated rto +send 303: rtt = 0.240, srtt = 0.246, rttvar = 0.017, rto = 2.000 +recv 303 +updated rto +send 304: rtt = 0.240, srtt = 0.245, rttvar = 0.014, rto = 2.000 +recv 304 +updated rto +send 305: rtt = 0.250, srtt = 0.246, rttvar = 0.012, rto = 2.000 +recv 305 +updated rto +send 306: rtt = 0.240, srtt = 0.245, rttvar = 0.010, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 306: rtt = 0.240, srtt = 0.245, rttvar = 0.010, rto = 4.000 +recv 306 +updated rto +send 307: rtt = 0.220, srtt = 0.242, rttvar = 0.014, rto = 2.000 +recv 307 +updated rto +send 308: rtt = 0.220, srtt = 0.239, rttvar = 0.016, rto = 2.000 +recv 308 +updated rto +send 309: rtt = 0.240, srtt = 0.239, rttvar = 0.012, rto = 2.000 +recv 309 +updated rto +send 310: rtt = 0.249, srtt = 0.241, rttvar = 0.012, rto = 2.000 +recv 310 +updated rto +send 311: rtt = 0.250, srtt = 0.242, rttvar = 0.011, rto = 2.000 +recv 311 +updated rto +send 312: rtt = 0.260, srtt = 0.244, rttvar = 0.013, rto = 2.000 +recv 312 +updated rto +send 313: rtt = 0.230, srtt = 0.242, rttvar = 0.013, rto = 2.000 +recv 313 +updated rto +send 314: rtt = 0.230, srtt = 0.241, rttvar = 0.013, rto = 2.000 +recv 314 +updated rto +send 315: rtt = 0.199, srtt = 0.236, rttvar = 0.020, rto = 2.000 +recv 315 +updated rto +send 316: rtt = 0.230, srtt = 0.235, rttvar = 0.016, rto = 2.000 +recv 316 +updated rto +send 317: rtt = 0.228, srtt = 0.234, rttvar = 0.014, rto = 2.000 +recv 317 +updated rto +send 318: rtt = 0.239, srtt = 0.235, rttvar = 0.012, rto = 2.000 +recv 318 +updated rto +send 319: rtt = 0.230, srtt = 0.234, rttvar = 0.010, rto = 2.000 +recv 319 +updated rto +send 320: rtt = 0.240, srtt = 0.235, rttvar = 0.009, rto = 2.000 +recv 320 +updated rto +send 321: rtt = 0.249, srtt = 0.237, rttvar = 0.010, rto = 2.000 +recv 321 +updated rto +send 322: rtt = 0.250, srtt = 0.238, rttvar = 0.011, rto = 2.000 +recv 322 +updated rto +send 323: rtt = 0.220, srtt = 0.236, rttvar = 0.013, rto = 2.000 +recv 323 +updated rto +send 324: rtt = 0.226, srtt = 0.235, rttvar = 0.012, rto = 2.000 +recv 324 +updated rto +send 325: rtt = 0.234, srtt = 0.235, rttvar = 0.009, rto = 2.000 +recv 325 +updated rto +send 326: rtt = 0.260, srtt = 0.238, rttvar = 0.013, rto = 2.000 +recv 326 +updated rto +send 327: rtt = 0.309, srtt = 0.247, rttvar = 0.028, rto = 2.000 +recv 327 +updated rto +send 328: rtt = 0.220, srtt = 0.243, rttvar = 0.028, rto = 2.000 +recv 328 +updated rto +send 329: rtt = 0.229, srtt = 0.242, rttvar = 0.024, rto = 2.000 +recv 329 +updated rto +send 330: rtt = 0.230, srtt = 0.240, rttvar = 0.021, rto = 2.000 +recv 330 +updated rto +send 331: rtt = 0.240, srtt = 0.240, rttvar = 0.016, rto = 2.000 +recv 331 +updated rto +send 332: rtt = 0.276, srtt = 0.245, rttvar = 0.021, rto = 2.000 +recv 332 +updated rto +send 333: rtt = 0.213, srtt = 0.241, rttvar = 0.024, rto = 2.000 +recv 333 +updated rto +send 334: rtt = 0.251, srtt = 0.242, rttvar = 0.020, rto = 2.000 +recv 334 +updated rto +send 335: rtt = 0.238, srtt = 0.241, rttvar = 0.016, rto = 2.000 +recv 335 +updated rto +send 336: rtt = 0.240, srtt = 0.241, rttvar = 0.012, rto = 2.000 +recv 336 +updated rto +send 337: rtt = 0.230, srtt = 0.240, rttvar = 0.012, rto = 2.000 +recv 337 +updated rto +send 338: rtt = 0.229, srtt = 0.238, rttvar = 0.012, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 338: rtt = 0.229, srtt = 0.238, rttvar = 0.012, rto = 4.000 +recv 338 +updated rto +send 339: rtt = 0.250, srtt = 0.240, rttvar = 0.012, rto = 2.000 +recv 339 +updated rto +send 340: rtt = 0.230, srtt = 0.239, rttvar = 0.011, rto = 2.000 +recv 340 +updated rto +send 341: rtt = 0.230, srtt = 0.238, rttvar = 0.011, rto = 2.000 +recv 341 +updated rto +send 342: rtt = 0.290, srtt = 0.244, rttvar = 0.021, rto = 2.000 +recv 342 +updated rto +send 343: rtt = 0.240, srtt = 0.244, rttvar = 0.017, rto = 2.000 +recv 343 +updated rto +send 344: rtt = 0.260, srtt = 0.246, rttvar = 0.017, rto = 2.000 +recv 344 +updated rto +send 345: rtt = 0.230, srtt = 0.244, rttvar = 0.016, rto = 2.000 +recv 345 +updated rto +send 346: rtt = 0.268, srtt = 0.247, rttvar = 0.018, rto = 2.000 +recv 346 +updated rto +send 347: rtt = 0.303, srtt = 0.254, rttvar = 0.028, rto = 2.000 +recv 347 +updated rto +send 348: rtt = 0.237, srtt = 0.252, rttvar = 0.025, rto = 2.000 +recv 348 +updated rto +send 349: rtt = 0.219, srtt = 0.248, rttvar = 0.027, rto = 2.000 +recv 349 +updated rto +send 350: rtt = 0.229, srtt = 0.245, rttvar = 0.025, rto = 2.000 +recv 350 +updated rto +send 351: rtt = 0.250, srtt = 0.246, rttvar = 0.020, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 351: rtt = 0.250, srtt = 0.246, rttvar = 0.020, rto = 4.000 +recv 351 +updated rto +send 352: rtt = 0.240, srtt = 0.245, rttvar = 0.016, rto = 2.000 +recv 352 +updated rto +send 353: rtt = 0.230, srtt = 0.243, rttvar = 0.016, rto = 2.000 +recv 353 +updated rto +send 354: rtt = 0.260, srtt = 0.245, rttvar = 0.016, rto = 2.000 +recv 354 +updated rto +send 355: rtt = 0.219, srtt = 0.242, rttvar = 0.019, rto = 2.000 +recv 355 +updated rto +send 356: rtt = 0.240, srtt = 0.242, rttvar = 0.015, rto = 2.000 +recv 356 +updated rto +send 357: rtt = 0.230, srtt = 0.240, rttvar = 0.014, rto = 2.000 +recv 357 +updated rto +send 358: rtt = 0.260, srtt = 0.243, rttvar = 0.015, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 358: rtt = 0.260, srtt = 0.243, rttvar = 0.015, rto = 4.000 +recv 358 +updated rto +send 359: rtt = 0.240, srtt = 0.242, rttvar = 0.012, rto = 2.000 +recv 359 +updated rto +send 360: rtt = 0.239, srtt = 0.242, rttvar = 0.010, rto = 2.000 +recv 360 +updated rto +send 361: rtt = 0.240, srtt = 0.242, rttvar = 0.008, rto = 2.000 +recv 361 +updated rto +send 362: rtt = 0.250, srtt = 0.243, rttvar = 0.008, rto = 2.000 +recv 362 +updated rto +send 363: rtt = 0.250, srtt = 0.244, rttvar = 0.008, rto = 2.000 +recv 363 +updated rto +send 364: rtt = 0.299, srtt = 0.251, rttvar = 0.020, rto = 2.000 +recv 364 +updated rto +send 365: rtt = 0.259, srtt = 0.252, rttvar = 0.017, rto = 2.000 +recv 365 +updated rto +send 366: rtt = 0.240, srtt = 0.250, rttvar = 0.016, rto = 2.000 +recv 366 +updated rto +send 367: rtt = 0.260, srtt = 0.251, rttvar = 0.014, rto = 2.000 +recv 367 +updated rto +send 368: rtt = 0.250, srtt = 0.251, rttvar = 0.011, rto = 2.000 +recv 368 +updated rto +send 369: rtt = 0.239, srtt = 0.250, rttvar = 0.011, rto = 2.000 +recv 369 +updated rto +send 370: rtt = 0.249, srtt = 0.250, rttvar = 0.009, rto = 2.000 +recv 370 +updated rto +send 371: rtt = 0.264, srtt = 0.251, rttvar = 0.010, rto = 2.000 +recv 371 +updated rto +send 372: rtt = 0.465, srtt = 0.278, rttvar = 0.061, rto = 2.000 +recv 372 +updated rto +send 373: rtt = 0.259, srtt = 0.276, rttvar = 0.050, rto = 2.000 +recv 373 +updated rto +send 374: rtt = 0.230, srtt = 0.270, rttvar = 0.049, rto = 2.000 +recv 374 +updated rto +send 375: rtt = 0.240, srtt = 0.266, rttvar = 0.044, rto = 2.000 +recv 375 +updated rto +send 376: rtt = 0.250, srtt = 0.264, rttvar = 0.037, rto = 2.000 +recv 376 +updated rto +send 377: rtt = 0.260, srtt = 0.264, rttvar = 0.029, rto = 2.000 +recv 377 +updated rto +send 378: rtt = 0.239, srtt = 0.261, rttvar = 0.028, rto = 2.000 +recv 378 +updated rto +send 379: rtt = 0.229, srtt = 0.257, rttvar = 0.029, rto = 2.000 +recv 379 +updated rto +send 380: rtt = 0.240, srtt = 0.255, rttvar = 0.026, rto = 2.000 +recv 380 +updated rto +send 381: rtt = 0.230, srtt = 0.252, rttvar = 0.026, rto = 2.000 +recv 381 +updated rto +send 382: rtt = 0.250, srtt = 0.251, rttvar = 0.020, rto = 2.000 +recv 382 +updated rto +send 383: rtt = 0.280, srtt = 0.255, rttvar = 0.022, rto = 2.000 +recv 383 +updated rto +send 384: rtt = 0.240, srtt = 0.253, rttvar = 0.020, rto = 2.000 +recv 384 +updated rto +send 385: rtt = 0.250, srtt = 0.253, rttvar = 0.016, rto = 2.000 +recv 385 +updated rto +send 386: rtt = 0.220, srtt = 0.249, rttvar = 0.020, rto = 2.000 +recv 386 +updated rto +send 387: rtt = 0.239, srtt = 0.247, rttvar = 0.017, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 387: rtt = 0.239, srtt = 0.247, rttvar = 0.017, rto = 4.000 +recv 387 +updated rto +send 388: rtt = 0.220, srtt = 0.244, rttvar = 0.020, rto = 2.000 +recv 388 +updated rto +send 389: rtt = 0.230, srtt = 0.242, rttvar = 0.018, rto = 2.000 +recv 389 +updated rto +send 390: rtt = 0.220, srtt = 0.239, rttvar = 0.019, rto = 2.000 +recv 390 +updated rto +send 391: rtt = 0.240, srtt = 0.240, rttvar = 0.015, rto = 2.000 +recv 391 +updated rto +send 392: rtt = 0.249, srtt = 0.241, rttvar = 0.013, rto = 2.000 +recv 392 +updated rto +send 393: rtt = 0.260, srtt = 0.243, rttvar = 0.015, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 393: rtt = 0.260, srtt = 0.243, rttvar = 0.015, rto = 4.000 +recv 393 +updated rto +send 394: rtt = 0.270, srtt = 0.246, rttvar = 0.018, rto = 2.000 +recv 394 +updated rto +send 395: rtt = 0.250, srtt = 0.247, rttvar = 0.014, rto = 2.000 +recv 395 +updated rto +send 396: rtt = 0.250, srtt = 0.247, rttvar = 0.011, rto = 2.000 +recv 396 +updated rto +send 397: rtt = 0.230, srtt = 0.245, rttvar = 0.013, rto = 2.000 +recv 397 +updated rto +send 398: rtt = 0.259, srtt = 0.247, rttvar = 0.013, rto = 2.000 +recv 398 +updated rto +send 399: rtt = 0.249, srtt = 0.247, rttvar = 0.010, rto = 2.000 +recv 399 +updated rto +send 400: rtt = 0.240, srtt = 0.246, rttvar = 0.010, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 400: rtt = 0.240, srtt = 0.246, rttvar = 0.010, rto = 4.000 +recv 400 +updated rto +send 401: rtt = 0.250, srtt = 0.247, rttvar = 0.008, rto = 2.000 +recv 401 +updated rto +send 402: rtt = 0.250, srtt = 0.247, rttvar = 0.007, rto = 2.000 +recv 402 +updated rto +send 403: rtt = 0.230, srtt = 0.245, rttvar = 0.009, rto = 2.000 +recv 403 +updated rto +send 404: rtt = 0.240, srtt = 0.244, rttvar = 0.008, rto = 2.000 +recv 404 +updated rto +send 405: rtt = 0.240, srtt = 0.244, rttvar = 0.007, rto = 2.000 +recv 405 +updated rto +send 406: rtt = 0.260, srtt = 0.246, rttvar = 0.010, rto = 2.000 +recv 406 +updated rto +send 407: rtt = 0.239, srtt = 0.245, rttvar = 0.009, rto = 2.000 +recv 407 +updated rto +send 408: rtt = 0.229, srtt = 0.243, rttvar = 0.011, rto = 2.000 +recv 408 +updated rto +send 409: rtt = 0.240, srtt = 0.243, rttvar = 0.009, rto = 2.000 +recv 409 +updated rto +send 410: rtt = 0.250, srtt = 0.244, rttvar = 0.008, rto = 2.000 +recv 410 +updated rto +send 411: rtt = 0.249, srtt = 0.244, rttvar = 0.008, rto = 2.000 +recv 411 +updated rto +send 412: rtt = 0.270, srtt = 0.247, rttvar = 0.012, rto = 2.000 +recv 412 +updated rto +send 413: rtt = 0.209, srtt = 0.243, rttvar = 0.019, rto = 2.000 +recv 413 +updated rto +send 414: rtt = 0.230, srtt = 0.241, rttvar = 0.017, rto = 2.000 +recv 414 +updated rto +send 415: rtt = 0.229, srtt = 0.240, rttvar = 0.016, rto = 2.000 +recv 415 +updated rto +send 416: rtt = 0.230, srtt = 0.238, rttvar = 0.014, rto = 2.000 +recv 416 +updated rto +send 417: rtt = 0.267, srtt = 0.242, rttvar = 0.018, rto = 2.000 +recv 417 +updated rto +send 418: rtt = 0.262, srtt = 0.244, rttvar = 0.018, rto = 2.000 +recv 418 +updated rto +send 419: rtt = 0.240, srtt = 0.244, rttvar = 0.015, rto = 2.000 +recv 419 +updated rto +send 420: rtt = 0.239, srtt = 0.243, rttvar = 0.012, rto = 2.000 +recv 420 +updated rto +send 421: rtt = 0.242, srtt = 0.243, rttvar = 0.010, rto = 2.000 +recv 421 +updated rto +send 422: rtt = 0.237, srtt = 0.242, rttvar = 0.009, rto = 2.000 +recv 422 +updated rto +send 423: rtt = 0.240, srtt = 0.242, rttvar = 0.007, rto = 2.000 +recv 423 +updated rto +send 424: rtt = 0.250, srtt = 0.243, rttvar = 0.007, rto = 2.000 +recv 424 +updated rto +send 425: rtt = 0.269, srtt = 0.246, rttvar = 0.012, rto = 2.000 +recv 425 +updated rto +send 426: rtt = 0.250, srtt = 0.247, rttvar = 0.010, rto = 2.000 +recv 426 +updated rto +send 427: rtt = 0.230, srtt = 0.245, rttvar = 0.012, rto = 2.000 +recv 427 +updated rto +send 428: rtt = 0.269, srtt = 0.248, rttvar = 0.015, rto = 2.000 +recv 428 +updated rto +send 429: rtt = 0.259, srtt = 0.249, rttvar = 0.014, rto = 2.000 +recv 429 +updated rto +send 430: rtt = 0.270, srtt = 0.252, rttvar = 0.016, rto = 2.000 +recv 430 +updated rto +send 431: rtt = 0.249, srtt = 0.251, rttvar = 0.012, rto = 2.000 +recv 431 +updated rto +send 432: rtt = 0.220, srtt = 0.247, rttvar = 0.017, rto = 2.000 +recv 432 +updated rto +send 433: rtt = 0.260, srtt = 0.249, rttvar = 0.016, rto = 2.000 +recv 433 +updated rto +send 434: rtt = 0.250, srtt = 0.249, rttvar = 0.012, rto = 2.000 +recv 434 +updated rto +send 435: rtt = 0.220, srtt = 0.246, rttvar = 0.016, rto = 2.000 +recv 435 +updated rto +send 436: rtt = 0.230, srtt = 0.244, rttvar = 0.016, rto = 2.000 +recv 436 +updated rto +send 437: rtt = 0.240, srtt = 0.243, rttvar = 0.013, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 437: rtt = 0.240, srtt = 0.243, rttvar = 0.013, rto = 4.000 +recv 437 +updated rto +send 438: rtt = 0.250, srtt = 0.244, rttvar = 0.012, rto = 2.000 +recv 438 +updated rto +send 439: rtt = 0.260, srtt = 0.246, rttvar = 0.013, rto = 2.000 +recv 439 +updated rto +send 440: rtt = 0.220, srtt = 0.243, rttvar = 0.016, rto = 2.000 +recv 440 +updated rto +send 441: rtt = 0.210, srtt = 0.239, rttvar = 0.020, rto = 2.000 +recv 441 +updated rto +send 442: rtt = 0.240, srtt = 0.239, rttvar = 0.015, rto = 2.000 +recv 442 +updated rto +send 443: rtt = 0.250, srtt = 0.240, rttvar = 0.014, rto = 2.000 +recv 443 +updated rto +send 444: rtt = 0.241, srtt = 0.240, rttvar = 0.011, rto = 2.000 +recv 444 +updated rto +send 445: rtt = 0.228, srtt = 0.239, rttvar = 0.011, rto = 2.000 +recv 445 +updated rto +send 446: rtt = 0.240, srtt = 0.239, rttvar = 0.009, rto = 2.000 +recv 446 +updated rto +send 447: rtt = 0.230, srtt = 0.238, rttvar = 0.009, rto = 2.000 +recv 447 +updated rto +send 448: rtt = 0.240, srtt = 0.238, rttvar = 0.007, rto = 2.000 +recv 448 +updated rto +send 449: rtt = 0.220, srtt = 0.236, rttvar = 0.010, rto = 2.000 +recv 449 +updated rto +send 450: rtt = 0.260, srtt = 0.239, rttvar = 0.013, rto = 2.000 +recv 450 +updated rto +send 451: rtt = 0.250, srtt = 0.240, rttvar = 0.013, rto = 2.000 +recv 451 +updated rto +send 452: rtt = 0.240, srtt = 0.240, rttvar = 0.010, rto = 2.000 +recv 452 +updated rto +send 453: rtt = 0.589, srtt = 0.284, rttvar = 0.094, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 453: rtt = 0.589, srtt = 0.284, rttvar = 0.094, rto = 4.000 +recv 453 +updated rto +send 454: rtt = 0.257, srtt = 0.280, rttvar = 0.078, rto = 2.000 +recv 454 +updated rto +send 455: rtt = 0.230, srtt = 0.274, rttvar = 0.071, rto = 2.000 +recv 455 +updated rto +send 456: rtt = 0.230, srtt = 0.269, rttvar = 0.064, rto = 2.000 +recv 456 +updated rto +send 457: rtt = 0.239, srtt = 0.265, rttvar = 0.056, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 457: rtt = 0.239, srtt = 0.265, rttvar = 0.056, rto = 4.000 +recv 457 +updated rto +send 458: rtt = 0.260, srtt = 0.264, rttvar = 0.043, rto = 2.000 +recv 458 +updated rto +send 459: rtt = 0.240, srtt = 0.261, rttvar = 0.038, rto = 2.000 +recv 459 +updated rto +send 460: rtt = 0.260, srtt = 0.261, rttvar = 0.029, rto = 2.000 +recv 460 +updated rto +send 461: rtt = 0.280, srtt = 0.263, rttvar = 0.026, rto = 2.000 +recv 461 +updated rto +send 462: rtt = 0.249, srtt = 0.262, rttvar = 0.023, rto = 2.000 +recv 462 +updated rto +send 463: rtt = 0.240, srtt = 0.259, rttvar = 0.023, rto = 2.000 +recv 463 +updated rto +send 464: rtt = 0.250, srtt = 0.258, rttvar = 0.020, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 464: rtt = 0.250, srtt = 0.258, rttvar = 0.020, rto = 4.000 +dgsendrecv: timeout, retransmitting +send 464: rtt = 0.250, srtt = 0.258, rttvar = 0.020, rto = 8.000 +recv 464 +updated rto +send 465: rtt = 0.260, srtt = 0.258, rttvar = 0.015, rto = 2.000 +recv 465 +updated rto +send 466: rtt = 0.230, srtt = 0.255, rttvar = 0.018, rto = 2.000 +recv 466 +updated rto +send 467: rtt = 0.239, srtt = 0.253, rttvar = 0.018, rto = 2.000 +recv 467 +updated rto +send 468: rtt = 0.280, srtt = 0.256, rttvar = 0.020, rto = 2.000 +recv 468 +updated rto +send 469: rtt = 0.240, srtt = 0.254, rttvar = 0.019, rto = 2.000 +recv 469 +updated rto +send 470: rtt = 0.230, srtt = 0.251, rttvar = 0.020, rto = 2.000 +recv 470 +updated rto +send 471: rtt = 0.250, srtt = 0.251, rttvar = 0.016, rto = 2.000 +recv 471 +updated rto +send 472: rtt = 0.280, srtt = 0.255, rttvar = 0.019, rto = 2.000 +recv 472 +updated rto +send 473: rtt = 0.250, srtt = 0.254, rttvar = 0.015, rto = 2.000 +recv 473 +updated rto +send 474: rtt = 0.270, srtt = 0.256, rttvar = 0.015, rto = 2.000 +recv 474 +updated rto +send 475: rtt = 0.269, srtt = 0.258, rttvar = 0.015, rto = 2.000 +recv 475 +updated rto +send 476: rtt = 0.260, srtt = 0.258, rttvar = 0.012, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 476: rtt = 0.260, srtt = 0.258, rttvar = 0.012, rto = 4.000 +recv 476 +updated rto +send 477: rtt = 0.230, srtt = 0.254, rttvar = 0.016, rto = 2.000 +recv 477 +updated rto +send 478: rtt = 0.260, srtt = 0.255, rttvar = 0.013, rto = 2.000 +recv 478 +updated rto +send 479: rtt = 0.240, srtt = 0.253, rttvar = 0.014, rto = 2.000 +recv 479 +updated rto +send 480: rtt = 0.289, srtt = 0.258, rttvar = 0.019, rto = 2.000 +recv 480 +updated rto +send 481: rtt = 0.250, srtt = 0.257, rttvar = 0.016, rto = 2.000 +recv 481 +updated rto +send 482: rtt = 0.290, srtt = 0.261, rttvar = 0.021, rto = 2.000 +dgsendrecv: timeout, retransmitting +send 482: rtt = 0.290, srtt = 0.261, rttvar = 0.021, rto = 4.000 +recv 482 +updated rto +send 483: rtt = 0.270, srtt = 0.262, rttvar = 0.018, rto = 2.000 +recv 483 +updated rto +send 484: rtt = 0.248, srtt = 0.260, rttvar = 0.017, rto = 2.000 +recv 484 +updated rto +send 485: rtt = 0.291, srtt = 0.264, rttvar = 0.020, rto = 2.000 +recv 485 +updated rto +send 486: rtt = 0.250, srtt = 0.262, rttvar = 0.019, rto = 2.000 +recv 486 +updated rto +send 487: rtt = 0.250, srtt = 0.261, rttvar = 0.017, rto = 2.000 +recv 487 +updated rto +send 488: rtt = 0.230, srtt = 0.257, rttvar = 0.021, rto = 2.000 +recv 488 +updated rto +send 489: rtt = 0.240, srtt = 0.255, rttvar = 0.020, rto = 2.000 +recv 489 +updated rto +send 490: rtt = 0.310, srtt = 0.262, rttvar = 0.029, rto = 2.000 +recv 490 +updated rto +send 491: rtt = 0.220, srtt = 0.257, rttvar = 0.032, rto = 2.000 +recv 491 +updated rto +send 492: rtt = 0.250, srtt = 0.256, rttvar = 0.026, rto = 2.000 +recv 492 +updated rto +send 493: rtt = 0.220, srtt = 0.251, rttvar = 0.028, rto = 2.000 +recv 493 +updated rto +send 494: rtt = 0.260, srtt = 0.252, rttvar = 0.023, rto = 2.000 +recv 494 +updated rto +send 495: rtt = 0.270, srtt = 0.255, rttvar = 0.022, rto = 2.000 +recv 495 +updated rto +send 496: rtt = 0.240, srtt = 0.253, rttvar = 0.020, rto = 2.000 +recv 496 +updated rto +send 497: rtt = 0.239, srtt = 0.251, rttvar = 0.018, rto = 2.000 +recv 497 +updated rto +send 498: rtt = 0.239, srtt = 0.250, rttvar = 0.017, rto = 2.000 +recv 498 +updated rto +send 499: rtt = 0.210, srtt = 0.245, rttvar = 0.023, rto = 2.000 +recv 499 +updated rto +send 500: rtt = 0.278, srtt = 0.249, rttvar = 0.025, rto = 2.000 +recv 500 +updated rto diff --git a/rtt/rtt.vals.kumba.1 b/rtt/rtt.vals.kumba.1 new file mode 100644 index 0000000..6f2bd4e --- /dev/null +++ b/rtt/rtt.vals.kumba.1 @@ -0,0 +1,508 @@ +1 0.000 +2 0.366 +3 0.309 +4 0.298 +5 0.360 +6 0.360 +7 0.320 +8 0.340 +9 0.330 +10 0.350 +11 0.349 +12 0.380 +13 0.349 +14 0.340 +15 0.280 +16 0.330 +17 0.340 +18 0.340 +19 0.349 +20 0.310 +21 0.350 +21 0.350 +22 0.340 +23 0.350 +24 0.319 +25 0.360 +26 0.290 +27 0.310 +28 0.340 +29 0.371 +30 0.368 +31 0.350 +32 0.364 +33 0.335 +33 0.335 +34 0.330 +35 0.290 +36 0.390 +37 0.355 +38 0.334 +39 0.320 +40 0.344 +41 0.345 +42 0.349 +43 0.305 +44 0.284 +45 0.320 +46 0.320 +47 0.340 +48 0.309 +49 0.310 +50 0.320 +51 0.320 +52 0.300 +53 0.320 +54 0.350 +55 0.349 +56 0.339 +57 0.350 +58 0.319 +59 0.309 +60 0.310 +61 0.320 +62 0.300 +63 0.309 +64 0.290 +65 0.320 +66 0.280 +67 0.339 +68 0.330 +69 0.320 +70 0.280 +71 0.319 +72 0.339 +73 0.309 +74 0.340 +75 0.330 +76 0.280 +77 0.320 +78 0.280 +79 0.330 +80 0.349 +81 0.320 +82 0.320 +83 0.329 +84 0.320 +85 0.329 +86 0.330 +87 0.339 +88 0.360 +89 0.320 +90 0.319 +91 0.330 +92 0.304 +93 0.316 +94 0.319 +95 0.360 +96 0.316 +97 0.314 +98 0.330 +99 0.330 +100 0.360 +101 0.330 +102 0.350 +103 0.320 +103 0.320 +104 0.340 +105 0.340 +106 0.320 +107 0.340 +108 0.340 +109 0.340 +110 0.369 +111 0.350 +112 0.369 +113 0.339 +114 0.349 +115 0.319 +116 0.340 +117 0.319 +118 0.340 +119 0.380 +120 0.340 +121 0.320 +122 0.340 +123 0.360 +124 0.359 +125 0.330 +126 0.329 +127 0.340 +128 0.360 +129 0.320 +130 0.340 +131 0.350 +132 0.340 +133 0.370 +134 0.339 +135 0.330 +136 0.340 +137 0.300 +138 0.340 +139 0.340 +140 0.380 +141 0.450 +142 0.370 +143 0.309 +144 0.290 +145 0.390 +146 0.329 +147 0.330 +148 0.320 +149 0.340 +150 0.359 +151 0.350 +152 0.349 +153 0.400 +154 0.350 +155 0.370 +156 0.359 +157 0.349 +158 0.360 +159 0.319 +160 0.320 +161 0.330 +162 0.340 +163 0.350 +164 0.350 +165 0.339 +166 0.339 +167 0.330 +168 0.310 +169 0.310 +170 0.320 +171 0.339 +172 0.320 +173 0.319 +174 0.320 +175 0.319 +176 0.309 +177 0.340 +178 0.334 +179 0.315 +180 0.309 +181 0.309 +182 0.330 +183 0.370 +184 0.320 +185 0.380 +186 0.350 +187 0.309 +188 0.330 +189 0.320 +189 0.320 +190 0.329 +191 0.310 +192 0.319 +193 0.310 +194 0.300 +195 0.309 +196 0.319 +197 0.310 +198 0.309 +199 0.330 +200 0.299 +201 0.310 +202 0.354 +203 0.312 +204 0.303 +205 0.329 +206 0.319 +207 0.339 +208 0.310 +209 0.321 +210 0.308 +211 0.350 +212 0.359 +213 0.310 +214 0.329 +215 0.310 +216 0.772 +217 0.317 +218 0.379 +219 0.310 +220 0.304 +221 0.315 +222 0.340 +223 0.329 +224 0.349 +225 0.350 +226 0.360 +227 0.380 +228 0.320 +229 0.319 +230 0.370 +231 0.358 +232 0.340 +233 0.360 +234 0.289 +235 0.350 +236 0.310 +237 0.319 +238 0.330 +239 0.308 +240 0.320 +241 0.290 +242 0.360 +243 0.330 +244 0.339 +245 0.350 +246 0.330 +247 0.309 +248 0.329 +249 0.360 +250 0.350 +251 0.340 +252 0.410 +253 0.339 +254 0.335 +255 0.335 +256 0.319 +257 0.350 +258 0.310 +259 0.320 +260 0.319 +261 0.300 +262 0.389 +263 1.259 +264 0.819 +265 0.809 +266 0.809 +267 0.819 +267 0.819 +268 0.748 +269 0.819 +270 0.819 +271 0.819 +272 0.799 +273 1.059 +274 0.370 +275 0.370 +276 0.380 +277 0.340 +278 0.400 +279 0.350 +280 0.320 +281 0.390 +282 0.329 +283 0.280 +284 0.330 +285 0.310 +286 0.370 +287 0.379 +288 0.329 +289 0.320 +290 0.410 +291 0.340 +292 0.360 +293 0.349 +294 0.360 +295 0.360 +296 0.329 +297 0.360 +298 0.340 +299 0.359 +300 0.369 +301 0.330 +302 0.320 +303 0.320 +304 0.313 +305 0.337 +306 0.320 +307 0.319 +308 0.680 +309 0.380 +310 0.319 +311 0.330 +312 0.330 +313 0.310 +314 0.300 +315 0.340 +316 0.350 +317 0.350 +318 0.340 +319 0.309 +320 0.343 +321 0.326 +322 0.319 +323 1.178 +324 0.320 +325 0.309 +326 0.330 +327 0.300 +328 0.300 +329 0.310 +330 0.290 +331 0.310 +332 0.300 +333 0.300 +334 0.340 +335 0.339 +336 0.310 +337 0.320 +338 0.330 +339 0.320 +340 0.315 +340 0.315 +341 0.338 +342 0.320 +343 0.309 +344 0.320 +345 0.349 +346 0.339 +347 0.300 +348 0.300 +349 0.289 +350 0.329 +351 0.340 +352 0.329 +353 0.320 +354 0.410 +355 0.300 +356 0.389 +357 0.299 +358 1.280 +359 0.809 +360 0.818 +361 0.819 +362 0.829 +363 0.819 +364 0.809 +365 0.819 +366 0.999 +367 0.999 +368 1.479 +369 1.010 +370 0.998 +371 0.999 +372 0.999 +373 0.999 +374 0.989 +375 0.989 +376 1.009 +377 0.999 +378 1.009 +379 0.939 +380 0.809 +381 0.821 +382 0.827 +382 0.827 +383 0.809 +384 0.839 +385 0.819 +386 0.809 +387 0.819 +388 0.819 +389 0.809 +390 0.811 +391 0.827 +392 0.813 +393 1.205 +394 0.829 +395 0.819 +396 0.819 +397 0.819 +398 0.819 +399 0.819 +400 0.819 +401 0.829 +402 0.819 +403 0.809 +404 0.819 +405 0.809 +406 0.819 +407 0.819 +408 0.799 +409 0.819 +410 0.819 +411 0.829 +412 0.820 +413 0.809 +414 0.819 +415 1.209 +416 0.809 +417 0.824 +418 0.814 +419 0.809 +420 0.819 +421 0.819 +422 0.809 +423 0.819 +424 0.821 +425 0.808 +426 0.819 +427 0.819 +428 0.819 +429 0.819 +430 0.819 +431 0.819 +432 0.609 +433 0.309 +434 0.330 +435 0.300 +436 0.319 +437 0.310 +438 0.320 +439 0.350 +440 0.290 +441 0.290 +442 0.300 +443 0.360 +444 0.310 +445 0.360 +446 0.319 +447 0.320 +448 0.330 +449 0.329 +450 0.370 +451 0.340 +452 0.340 +453 0.719 +454 0.339 +455 0.320 +456 0.310 +457 0.320 +458 0.330 +459 0.313 +460 0.377 +461 0.440 +462 0.340 +463 0.330 +464 0.360 +465 0.380 +466 0.320 +467 0.309 +468 0.360 +469 0.330 +470 0.290 +471 0.329 +472 0.319 +473 0.320 +474 0.349 +475 0.330 +476 0.360 +477 0.310 +478 0.320 +479 0.320 +480 0.410 +481 0.340 +482 0.409 +483 0.330 +484 0.280 +485 0.320 +485 0.320 +486 0.339 +487 0.360 +488 0.300 +489 0.320 +490 0.410 +491 0.320 +492 0.320 +493 0.319 +494 0.330 +495 0.320 +496 0.314 +497 0.325 +498 0.330 +499 0.290 +500 0.340 diff --git a/rtt/rtt.vals.vangogh.1 b/rtt/rtt.vals.vangogh.1 new file mode 100644 index 0000000..bdb0402 --- /dev/null +++ b/rtt/rtt.vals.vangogh.1 @@ -0,0 +1,516 @@ +1 0.000 +2 0.316 +3 0.218 +4 0.225 +5 0.264 +6 0.228 +7 0.221 +8 0.228 +9 0.200 +10 0.240 +11 0.210 +12 0.249 +13 0.240 +14 0.260 +15 0.201 +16 0.248 +17 0.261 +18 0.248 +19 0.260 +20 0.210 +21 0.240 +22 0.240 +23 0.249 +24 0.230 +25 0.240 +25 0.240 +26 0.190 +27 0.220 +28 0.259 +29 0.243 +30 0.257 +31 0.260 +32 0.240 +33 0.240 +34 0.249 +35 0.210 +36 0.239 +37 0.240 +38 0.260 +38 0.260 +39 0.220 +40 0.230 +41 0.250 +42 0.240 +43 0.240 +44 0.210 +45 0.240 +46 0.239 +46 0.239 +47 0.240 +48 0.250 +49 0.239 +50 0.220 +51 0.229 +52 0.210 +53 0.259 +54 0.240 +55 0.260 +56 0.249 +57 0.249 +58 0.240 +59 0.209 +60 0.190 +61 0.230 +62 0.229 +63 0.229 +64 0.210 +65 0.230 +66 0.200 +67 0.240 +68 0.260 +69 0.240 +69 0.240 +70 0.200 +71 0.250 +72 0.220 +73 0.239 +74 0.229 +75 0.210 +76 0.199 +77 0.250 +78 0.199 +79 0.249 +80 0.239 +81 0.230 +82 0.259 +83 0.240 +84 0.240 +85 0.250 +86 0.230 +87 0.259 +88 0.220 +89 0.239 +90 0.250 +91 0.230 +92 0.219 +93 0.220 +94 0.229 +95 0.239 +96 0.250 +97 0.250 +98 0.220 +99 0.230 +100 0.249 +101 0.240 +102 0.239 +103 0.249 +103 0.249 +104 0.250 +105 0.260 +106 0.250 +107 0.241 +108 0.248 +109 0.249 +110 0.240 +111 0.259 +112 0.310 +113 0.250 +114 0.250 +115 0.230 +116 0.220 +117 0.230 +118 0.240 +119 0.240 +120 0.250 +121 0.250 +122 0.220 +123 0.219 +124 0.219 +125 0.240 +126 0.220 +127 0.230 +128 0.229 +129 0.239 +130 0.230 +131 0.259 +132 0.230 +133 0.249 +134 0.250 +135 0.240 +136 0.248 +137 0.200 +138 0.260 +139 0.230 +140 0.230 +141 0.230 +142 0.349 +143 0.230 +144 0.230 +145 0.250 +146 0.239 +147 0.220 +148 0.240 +149 0.240 +150 0.249 +151 0.219 +152 0.220 +153 0.229 +154 0.260 +155 0.259 +156 0.260 +157 0.239 +158 0.249 +159 0.229 +160 0.220 +161 0.240 +162 0.230 +163 0.230 +164 0.239 +165 0.269 +166 0.220 +167 0.219 +168 0.220 +169 0.220 +170 0.240 +171 0.239 +172 0.240 +173 0.240 +174 0.240 +175 0.229 +176 0.199 +177 0.249 +178 0.239 +179 0.220 +180 0.240 +181 0.219 +182 0.240 +183 0.240 +184 0.230 +185 0.240 +186 0.230 +187 0.240 +187 0.240 +188 0.229 +189 0.250 +190 0.248 +191 0.230 +191 0.230 +192 0.230 +193 0.230 +194 0.200 +195 0.210 +196 0.200 +197 0.209 +198 0.200 +199 0.231 +200 0.247 +201 0.240 +202 0.220 +203 0.200 +204 0.210 +205 0.200 +206 0.230 +207 0.250 +208 0.239 +209 0.230 +210 0.249 +211 0.230 +212 0.240 +213 0.240 +214 0.218 +215 0.229 +216 0.230 +217 0.250 +218 0.229 +219 0.229 +220 0.220 +221 0.220 +222 0.240 +223 0.240 +224 0.249 +225 0.239 +226 0.240 +227 0.279 +228 0.229 +229 0.229 +230 0.239 +231 0.239 +232 0.250 +233 0.249 +234 0.239 +235 0.240 +236 0.230 +237 0.240 +238 0.219 +239 0.199 +240 0.220 +240 0.220 +240 0.220 +241 0.210 +242 0.250 +243 0.240 +244 0.242 +245 0.237 +246 0.250 +247 0.221 +248 0.229 +248 0.229 +249 0.270 +250 0.260 +251 0.240 +252 0.229 +253 0.230 +254 0.240 +255 0.229 +256 0.230 +257 0.269 +258 0.219 +259 0.239 +260 0.229 +261 0.219 +262 0.260 +263 0.260 +264 0.240 +265 0.220 +266 0.250 +267 0.250 +268 0.230 +269 0.249 +270 0.250 +271 0.279 +272 0.220 +273 0.230 +274 0.229 +275 0.270 +276 0.260 +277 0.220 +277 0.220 +278 0.250 +279 0.240 +280 0.249 +281 0.211 +282 0.240 +283 0.210 +284 0.240 +285 0.199 +286 0.239 +287 0.230 +288 0.229 +289 0.250 +290 0.239 +291 0.230 +292 0.239 +293 0.240 +293 0.240 +294 0.220 +295 0.240 +296 0.219 +297 0.230 +298 0.240 +299 0.240 +300 0.259 +301 0.230 +302 0.230 +303 0.240 +304 0.250 +305 0.230 +306 0.230 +307 0.209 +308 0.232 +309 0.247 +310 0.250 +311 0.229 +312 0.230 +313 0.210 +314 0.249 +315 0.220 +316 0.249 +316 0.249 +317 0.230 +318 0.229 +319 0.229 +320 0.230 +321 0.250 +322 0.249 +323 0.230 +324 0.220 +325 0.229 +326 0.250 +327 0.220 +328 0.210 +329 0.229 +330 0.210 +331 0.220 +332 0.220 +333 0.220 +334 0.250 +335 0.250 +336 0.229 +337 0.239 +338 0.230 +339 0.230 +340 0.219 +341 0.240 +342 0.229 +343 0.220 +344 0.259 +345 0.230 +346 0.219 +347 0.219 +348 0.230 +349 0.240 +350 0.239 +351 0.250 +352 0.250 +353 0.220 +354 0.239 +355 0.230 +356 0.240 +357 0.230 +358 0.270 +359 0.240 +360 0.249 +361 0.240 +362 0.220 +363 0.239 +364 0.240 +365 0.259 +366 0.240 +367 0.239 +368 0.249 +369 0.240 +370 0.239 +371 0.229 +372 0.240 +373 0.259 +374 0.229 +375 0.230 +376 0.239 +377 0.259 +378 0.250 +379 0.250 +380 0.230 +381 0.239 +382 0.279 +383 0.259 +384 0.220 +385 0.249 +386 0.249 +387 0.220 +388 0.210 +389 0.230 +390 0.219 +390 0.219 +391 0.229 +392 0.229 +393 0.239 +394 0.240 +395 0.249 +396 0.250 +397 0.230 +398 0.260 +399 0.270 +400 0.240 +401 0.250 +402 0.259 +403 0.229 +404 0.249 +405 0.229 +406 0.250 +407 0.230 +408 0.230 +409 0.220 +410 0.229 +411 0.249 +412 0.249 +413 0.210 +414 0.220 +415 0.220 +416 0.219 +417 0.239 +418 0.260 +419 0.240 +420 0.229 +421 0.220 +422 0.229 +423 0.249 +424 0.260 +425 0.239 +426 0.240 +427 0.230 +428 0.279 +429 0.240 +430 0.249 +431 0.259 +432 0.250 +433 0.229 +434 0.240 +435 0.230 +436 0.249 +437 0.240 +438 0.240 +439 0.249 +440 0.220 +441 0.219 +442 0.239 +443 0.250 +444 0.240 +445 0.230 +445 0.230 +446 0.489 +447 0.230 +448 0.240 +449 0.250 +450 0.239 +451 0.260 +452 0.240 +453 0.599 +454 0.249 +455 0.220 +456 0.230 +457 0.220 +458 0.239 +459 0.230 +460 0.249 +461 0.240 +462 0.230 +463 0.230 +464 0.240 +465 0.249 +466 0.240 +467 0.229 +468 0.249 +469 0.249 +470 0.230 +471 0.250 +472 0.240 +473 0.250 +474 0.250 +474 0.250 +475 0.240 +476 0.250 +477 0.220 +478 0.250 +479 0.250 +480 0.240 +481 0.229 +482 0.279 +483 0.260 +484 0.209 +485 0.229 +486 0.230 +487 0.240 +488 0.220 +489 0.229 +490 0.309 +491 0.219 +492 0.240 +493 0.220 +494 0.239 +495 0.239 +496 0.239 +497 0.240 +498 0.240 +499 0.230 +500 0.250 diff --git a/rtt/udpcli01.c b/rtt/udpcli01.c new file mode 100644 index 0000000..01beb88 --- /dev/null +++ b/rtt/udpcli01.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(7); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/rtt/unprtt.h b/rtt/unprtt.h new file mode 100644 index 0000000..6d4fdce --- /dev/null +++ b/rtt/unprtt.h @@ -0,0 +1,30 @@ +#ifndef __unp_rtt_h +#define __unp_rtt_h + +#include "unp.h" + +struct rtt_info { + float rtt_rtt; /* most recent measured RTT, seconds */ + float rtt_srtt; /* smoothed RTT estimator, seconds */ + float rtt_rttvar; /* smoothed mean deviation, seconds */ + float rtt_rto; /* current RTO to use, seconds */ + int rtt_nrexmt; /* #times retransmitted: 0, 1, 2, ... */ + uint32_t rtt_base; /* #sec since 1/1/1970 at start */ +}; + +#define RTT_RXTMIN 2 /* min retransmit timeout value, seconds */ +#define RTT_RXTMAX 60 /* max retransmit timeout value, seconds */ +#define RTT_MAXNREXMT 3 /* max #times to retransmit */ + + /* function prototypes */ +void rtt_debug(struct rtt_info *); +void rtt_init(struct rtt_info *); +void rtt_newpack(struct rtt_info *); +int rtt_start(struct rtt_info *); +void rtt_stop(struct rtt_info *, uint32_t); +int rtt_timeout(struct rtt_info *); +uint32_t rtt_ts(struct rtt_info *); + +extern int rtt_d_flag; /* can be set nonzero for addl info */ + +#endif /* __unp_rtt_h */ diff --git a/sctp/Makefile b/sctp/Makefile new file mode 100644 index 0000000..b6a2339 --- /dev/null +++ b/sctp/Makefile @@ -0,0 +1,56 @@ +include ../Make.defines + +PROGS = sctpserv01 sctpclient01 sctpserv02 sctpserv03 sctpclient02 sctpserv04 \ +sctpserv05 sctpclient03 sctpserv06 sctpserv07 sctpclient04 sctpserv_fork + +LIBS+= -L/usr/local/v6/lib -lm -lsctp + +.c.lc: + ../../troff/fixcode.sh $< > $@ +.h.lh: + ../../troff/fixcode.sh $< > $@ + +CFLAGS+= -g +all: ${PROGS} + +sctpserv01: sctpserv01.o + ${CC} ${CFLAGS} -o $@ sctpserv01.o ${LIBS} + + +sctpclient01: sctpclient01.o sctp_strcli.o sctp_strcliecho.o + ${CC} ${CFLAGS} -o $@ sctpclient01.o sctp_strcli.o sctp_strcliecho.o ${LIBS} + + +sctpserv02: sctpserv02.o + ${CC} ${CFLAGS} -o $@ sctpserv02.o ${LIBS} + +sctpserv03: sctpserv03.o + ${CC} ${CFLAGS} -o $@ sctpserv03.o ${LIBS} + +sctpserv04: sctpserv04.o + ${CC} ${CFLAGS} -o $@ sctpserv04.o ${LIBS} + +sctpserv05: sctpserv05.o sctp_pdapircv.o + ${CC} ${CFLAGS} -o $@ sctpserv05.o sctp_pdapircv.o ${LIBS} + +sctpserv06: sctpserv06.o sctp_displayevents.o + ${CC} ${CFLAGS} -o $@ sctpserv06.o sctp_displayevents.o ${LIBS} + +sctpclient02: sctpclient02.o sctp_strcli.o sctp_strcliecho.o + ${CC} ${CFLAGS} -o $@ sctpclient02.o sctp_strcli.o sctp_strcliecho.o ${LIBS} + +sctpclient03: sctpclient01.o sctp_strcli_un.o sctp_strcliecho.o + ${CC} ${CFLAGS} -o $@ sctpclient01.o sctp_strcli_un.o sctp_strcliecho.o ${LIBS} + +sctpserv07: sctpserv07.o sctp_displayevents.o sctp_bindargs.o + ${CC} ${CFLAGS} -o $@ sctpserv07.o sctp_displayevents.o sctp_bindargs.o ${LIBS} + + +sctpclient04: sctpclient04.o sctp_strcli1.o sctp_check_notify.o sctp_print_addrs.o sctp_modify_hb.o + ${CC} ${CFLAGS} -o $@ sctpclient04.o sctp_strcli1.o sctp_check_notify.o sctp_print_addrs.o ${LIBS} + +sctpserv_fork: sctpserv_fork.o sctp_addr_to_associd.o + ${CC} ${CFLAGS} -o $@ sctpserv_fork.o sctp_addr_to_associd.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/sctp/sctp_addr_to_associd.c b/sctp/sctp_addr_to_associd.c new file mode 100644 index 0000000..3428a39 --- /dev/null +++ b/sctp/sctp_addr_to_associd.c @@ -0,0 +1,15 @@ +#include "unp.h" + +sctp_assoc_t +sctp_address_to_associd(int sock_fd, struct sockaddr *sa, socklen_t salen) +{ + struct sctp_paddrparams sp; + int siz; + + siz = sizeof(struct sctp_paddrparams); + bzero(&sp,siz); + memcpy(&sp.spp_address,sa,salen); + sctp_opt_info(sock_fd,0, + SCTP_PEER_ADDR_PARAMS, &sp, &siz); + return(sp.spp_assoc_id); +} diff --git a/sctp/sctp_addr_to_associd.lc b/sctp/sctp_addr_to_associd.lc new file mode 100644 index 0000000..d401ea3 --- /dev/null +++ b/sctp/sctp_addr_to_associd.lc @@ -0,0 +1,13 @@ + +sctp_assoc_t## 1 ##src/sctp/sctp_addr_to_associd.c## +sctp_address_to_associd(int sock_fd, struct sockaddr *sa, socklen_t salen)## 2 ##src/sctp/sctp_addr_to_associd.c## +{## 3 ##src/sctp/sctp_addr_to_associd.c## + struct sctp_paddrparams sp;## 4 ##src/sctp/sctp_addr_to_associd.c## + int siz;## 5 ##src/sctp/sctp_addr_to_associd.c## + + siz = sizeof(struct sctp_paddrparams);## 6 ##src/sctp/sctp_addr_to_associd.c## + bzero(&sp, siz);## 7 ##src/sctp/sctp_addr_to_associd.c## + memcpy(&sp.spp_address, sa, salen);## 8 ##src/sctp/sctp_addr_to_associd.c## + sctp_opt_info(sock_fd, 0, SCTP_PEER_ADDR_PARAMS, &sp, &siz);## 9 ##src/sctp/sctp_addr_to_associd.c## + return (sp.spp_assoc_id);## 10 ##src/sctp/sctp_addr_to_associd.c## +}## 11 ##src/sctp/sctp_addr_to_associd.c## diff --git a/sctp/sctp_bindargs.c b/sctp/sctp_bindargs.c new file mode 100644 index 0000000..5c33342 --- /dev/null +++ b/sctp/sctp_bindargs.c @@ -0,0 +1,24 @@ +#include "unp.h" + +int +sctp_bind_arg_list(int sock_fd, char **argv, int argc) +{ + struct addrinfo *addr; + char *bindbuf, *p, portbuf[10]; + int addrcnt=0; + int i; + + bindbuf = (char *)Calloc(argc, sizeof(struct sockaddr_storage)); + p = bindbuf; + sprintf(portbuf, "%d", SERV_PORT); + for( i=0; iai_addr, addr->ai_addrlen); + freeaddrinfo(addr); + addrcnt++; + p += addr->ai_addrlen; + } + Sctp_bindx(sock_fd,(SA *)bindbuf,addrcnt,SCTP_BINDX_ADD_ADDR); + free(bindbuf); + return(0); +} diff --git a/sctp/sctp_bindargs.lc b/sctp/sctp_bindargs.lc new file mode 100644 index 0000000..c4fcd7e --- /dev/null +++ b/sctp/sctp_bindargs.lc @@ -0,0 +1,28 @@ + +int## 1 ##src/sctp/sctp_bindargs.c## +sctp_bind_arg_list(int sock_fd, char **argv, int argc)## 2 ##src/sctp/sctp_bindargs.c## +{## 3 ##src/sctp/sctp_bindargs.c## + struct addrinfo *addr;## 4 ##src/sctp/sctp_bindargs.c## + struct sockaddr_storage *at;## 5 ##src/sctp/sctp_bindargs.c## + + char *bindbuf, portbuf[10];## 6 ##src/sctp/sctp_bindargs.c## + int addrcnt = 0;## 7 ##src/sctp/sctp_bindargs.c## + int i, sz;## 8 ##src/sctp/sctp_bindargs.c## + + sz = argc * sizeof(struct sockaddr_storage);## 9 ##src/sctp/sctp_bindargs.c## + bindbuf = (char *) Malloc(sz);## 10 ##src/sctp/sctp_bindargs.c## + bzero(bindbuf, sz);## 11 ##src/sctp/sctp_bindargs.c## + at = (struct sockaddr_storage *) bindbuf;## 12 ##src/sctp/sctp_bindargs.c## + sprintf(portbuf, "%d", SERV_PORT);## 13 ##src/sctp/sctp_bindargs.c## + for (i = 0; i < argc; i++) {## 14 ##src/sctp/sctp_bindargs.c## + addr = Host_serv(argv[i], portbuf, AF_UNSPEC, SOCK_SEQPACKET);## 15 ##src/sctp/sctp_bindargs.c## + memcpy(at, addr->ai_addr, addr->ai_addrlen);## 16 ##src/sctp/sctp_bindargs.c## + freeaddrinfo(addr);## 17 ##src/sctp/sctp_bindargs.c## + addrcnt++;## 18 ##src/sctp/sctp_bindargs.c## + at++;## 19 ##src/sctp/sctp_bindargs.c## + }## 20 ##src/sctp/sctp_bindargs.c## + at = (struct sockaddr_storage *) bindbuf;## 21 ##src/sctp/sctp_bindargs.c## + Sctp_bindx(sock_fd, at, addrcnt, SCTP_BINDX_ADD_ADDR);## 22 ##src/sctp/sctp_bindargs.c## + free(bindbuf);## 23 ##src/sctp/sctp_bindargs.c## + return (0);## 24 ##src/sctp/sctp_bindargs.c## +}## 25 ##src/sctp/sctp_bindargs.c## diff --git a/sctp/sctp_check_notify.c b/sctp/sctp_check_notify.c new file mode 100644 index 0000000..0543c1c --- /dev/null +++ b/sctp/sctp_check_notify.c @@ -0,0 +1,30 @@ +#include "unp.h" + +void +check_notification(int sock_fd,char *recvline,int rd_len) +{ + union sctp_notification *snp; + struct sctp_assoc_change *sac; + struct sockaddr_storage *sal,*sar; + int num_rem, num_loc; + + snp = (union sctp_notification *)recvline; + if(snp->sn_header.sn_type == SCTP_ASSOC_CHANGE) { + sac = &snp->sn_assoc_change; + if((sac->sac_state == SCTP_COMM_UP) || + (sac->sac_state == SCTP_RESTART)) { + num_rem = sctp_getpaddrs(sock_fd,sac->sac_assoc_id,&sar); + printf("There are %d remote addresses and they are:\n", + num_rem); + sctp_print_addresses(sar,num_rem); + sctp_freepaddrs(sar); + + num_loc = sctp_getladdrs(sock_fd,sac->sac_assoc_id,&sal); + printf("There are %d local addresses and they are:\n", + num_loc); + sctp_print_addresses(sal,num_loc); + sctp_freeladdrs(sal); + } + } + +} diff --git a/sctp/sctp_check_notify.lc b/sctp/sctp_check_notify.lc new file mode 100644 index 0000000..9d6bb56 --- /dev/null +++ b/sctp/sctp_check_notify.lc @@ -0,0 +1,27 @@ + +void## 1 ##src/sctp/sctp_check_notify.c## +check_notification(int sock_fd, char *recvline, int rd_len)## 2 ##src/sctp/sctp_check_notify.c## +{## 3 ##src/sctp/sctp_check_notify.c## + union sctp_notification *snp;## 4 ##src/sctp/sctp_check_notify.c## + struct sctp_assoc_change *sac;## 5 ##src/sctp/sctp_check_notify.c## + struct sockaddr_storage *sal, *sar;## 6 ##src/sctp/sctp_check_notify.c## + int num_rem, num_loc;## 7 ##src/sctp/sctp_check_notify.c## + + snp = (union sctp_notification *) recvline;## 8 ##src/sctp/sctp_check_notify.c## + if (snp->sn_header.sn_type == SCTP_ASSOC_CHANGE) {## 9 ##src/sctp/sctp_check_notify.c## + sac = &snp->sn_assoc_change;## 10 ##src/sctp/sctp_check_notify.c## + if ((sac->sac_state == SCTP_COMM_UP) ||## 11 ##src/sctp/sctp_check_notify.c## + (sac->sac_state == SCTP_RESTART)) {## 12 ##src/sctp/sctp_check_notify.c## + num_rem = sctp_getpaddrs(sock_fd, sac->sac_assoc_id, &sar);## 13 ##src/sctp/sctp_check_notify.c## + printf("There are %d remote addresses and they are:\n", num_rem);## 14 ##src/sctp/sctp_check_notify.c## + sctp_print_addresses(sar, num_rem);## 15 ##src/sctp/sctp_check_notify.c## + sctp_freepaddrs(sar);## 16 ##src/sctp/sctp_check_notify.c## + + num_loc = sctp_getladdrs(sock_fd, sac->sac_assoc_id, &sal);## 17 ##src/sctp/sctp_check_notify.c## + printf("There are %d local addresses and they are:\n", num_loc);## 18 ##src/sctp/sctp_check_notify.c## + sctp_print_addresses(sal, num_loc);## 19 ##src/sctp/sctp_check_notify.c## + sctp_freeladdrs(sal);## 20 ##src/sctp/sctp_check_notify.c## + }## 21 ##src/sctp/sctp_check_notify.c## + }## 22 ##src/sctp/sctp_check_notify.c## + +}## 23 ##src/sctp/sctp_check_notify.c## diff --git a/sctp/sctp_displayevents.c b/sctp/sctp_displayevents.c new file mode 100644 index 0000000..8a816ee --- /dev/null +++ b/sctp/sctp_displayevents.c @@ -0,0 +1,101 @@ +#include "unp.h" + +void +print_notification(char *notify_buf) +{ + union sctp_notification *snp; + struct sctp_assoc_change *sac; + struct sctp_paddr_change *spc; + struct sctp_remote_error *sre; + struct sctp_send_failed *ssf; + struct sctp_shutdown_event *sse; + struct sctp_adaption_event *ae; + struct sctp_pdapi_event *pdapi; + const char *str; + + snp = (union sctp_notification *)notify_buf; + switch(snp->sn_header.sn_type) { + case SCTP_ASSOC_CHANGE: + sac = &snp->sn_assoc_change; + switch(sac->sac_state) { + case SCTP_COMM_UP: + str = "COMMUNICATION UP"; + break; + case SCTP_COMM_LOST: + str = "COMMUNICATION LOST"; + break; + case SCTP_RESTART: + str = "RESTART"; + break; + case SCTP_SHUTDOWN_COMP: + str = "SHUTDOWN COMPLETE"; + break; + case SCTP_CANT_STR_ASSOC: + str = "CAN'T START ASSOC"; + break; + default: + str = "UNKNOWN"; + break; + } /* end switch(sac->sac_state) */ + printf("SCTP_ASSOC_CHANGE: %s, assoc=0x%x\n", str, + (uint32_t)sac->sac_assoc_id); + break; + case SCTP_PEER_ADDR_CHANGE: + spc = &snp->sn_paddr_change; + switch(spc->spc_state) { + case SCTP_ADDR_AVAILABLE: + str = "ADDRESS AVAILABLE"; + break; + case SCTP_ADDR_UNREACHABLE: + str = "ADDRESS UNREACHABLE"; + break; + case SCTP_ADDR_REMOVED: + str = "ADDRESS REMOVED"; + break; + case SCTP_ADDR_ADDED: + str = "ADDRESS ADDED"; + break; + case SCTP_ADDR_MADE_PRIM: + str = "ADDRESS MADE PRIMARY"; + break; + default: + str = "UNKNOWN"; + break; + } /* end switch(spc->spc_state) */ + printf("SCTP_PEER_ADDR_CHANGE: %s, addr=%s, assoc=0x%x\n", str, + Sock_ntop((SA *)&spc->spc_aaddr, sizeof(spc->spc_aaddr)), + (uint32_t)spc->spc_assoc_id); + break; + case SCTP_REMOTE_ERROR: + sre = &snp->sn_remote_error; + printf("SCTP_REMOTE_ERROR: assoc=0x%x error=%d\n", + (uint32_t)sre->sre_assoc_id, sre->sre_error); + break; + case SCTP_SEND_FAILED: + ssf = &snp->sn_send_failed; + printf("SCTP_SEND_FAILED: assoc=0x%x error=%d\n", + (uint32_t)ssf->ssf_assoc_id, ssf->ssf_error); + break; + case SCTP_ADAPTION_INDICATION: + ae = &snp->sn_adaption_event; + printf("SCTP_ADAPTION_INDICATION: 0x%x\n", + (u_int)ae->sai_adaption_ind); + break; + case SCTP_PARTIAL_DELIVERY_EVENT: + pdapi = &snp->sn_pdapi_event; + if(pdapi->pdapi_indication == SCTP_PARTIAL_DELIVERY_ABORTED) + printf("SCTP_PARTIAL_DELIEVERY_ABORTED\n"); + else + printf("Unknown SCTP_PARTIAL_DELIVERY_EVENT 0x%x\n", + pdapi->pdapi_indication); + break; + case SCTP_SHUTDOWN_EVENT: + sse = &snp->sn_shutdown_event; + printf("SCTP_SHUTDOWN_EVENT: assoc=0x%x\n", + (uint32_t)sse->sse_assoc_id); + break; + default: + printf("Unknown notification event type=0x%x\n", + snp->sn_header.sn_type); + } +} diff --git a/sctp/sctp_displayevents.lc b/sctp/sctp_displayevents.lc new file mode 100644 index 0000000..0c7235e --- /dev/null +++ b/sctp/sctp_displayevents.lc @@ -0,0 +1,100 @@ + +void## 1 ##src/sctp/sctp_displayevents.c## +print_notification(char *notify_buf)## 2 ##src/sctp/sctp_displayevents.c## +{## 3 ##src/sctp/sctp_displayevents.c## + union sctp_notification *snp;## 4 ##src/sctp/sctp_displayevents.c## + struct sctp_assoc_change *sac;## 5 ##src/sctp/sctp_displayevents.c## + struct sctp_paddr_change *spc;## 6 ##src/sctp/sctp_displayevents.c## + struct sctp_remote_error *sre;## 7 ##src/sctp/sctp_displayevents.c## + struct sctp_send_failed *ssf;## 8 ##src/sctp/sctp_displayevents.c## + struct sctp_shutdown_event *sse;## 9 ##src/sctp/sctp_displayevents.c## + struct sctp_adaption_event *ae;## 10 ##src/sctp/sctp_displayevents.c## + struct sctp_pdapi_event *pdapi;## 11 ##src/sctp/sctp_displayevents.c## + const char *str;## 12 ##src/sctp/sctp_displayevents.c## + + snp = (union sctp_notification *) notify_buf;## 13 ##src/sctp/sctp_displayevents.c## + switch (snp->sn_header.sn_type) {## 14 ##src/sctp/sctp_displayevents.c## + case SCTP_ASSOC_CHANGE:## 15 ##src/sctp/sctp_displayevents.c## + sac = &snp->sn_assoc_change;## 16 ##src/sctp/sctp_displayevents.c## + switch (sac->sac_state) {## 17 ##src/sctp/sctp_displayevents.c## + case SCTP_COMM_UP:## 18 ##src/sctp/sctp_displayevents.c## + str = "COMMUNICATION UP";## 19 ##src/sctp/sctp_displayevents.c## + break;## 20 ##src/sctp/sctp_displayevents.c## + case SCTP_COMM_LOST:## 21 ##src/sctp/sctp_displayevents.c## + str = "COMMUNICATION LOST";## 22 ##src/sctp/sctp_displayevents.c## + break;## 23 ##src/sctp/sctp_displayevents.c## + case SCTP_RESTART:## 24 ##src/sctp/sctp_displayevents.c## + str = "RESTART";## 25 ##src/sctp/sctp_displayevents.c## + break;## 26 ##src/sctp/sctp_displayevents.c## + case SCTP_SHUTDOWN_COMP:## 27 ##src/sctp/sctp_displayevents.c## + str = "SHUTDOWN COMPLETE";## 28 ##src/sctp/sctp_displayevents.c## + break;## 29 ##src/sctp/sctp_displayevents.c## + case SCTP_CANT_STR_ASSOC:## 30 ##src/sctp/sctp_displayevents.c## + str = "CANT START ASSOC";## 31 ##src/sctp/sctp_displayevents.c## + break;## 32 ##src/sctp/sctp_displayevents.c## + default:## 33 ##src/sctp/sctp_displayevents.c## + str = "UNKNOWN";## 34 ##src/sctp/sctp_displayevents.c## + break;## 35 ##src/sctp/sctp_displayevents.c## + } /* end switch(sac->sac_state) */## 36 ##src/sctp/sctp_displayevents.c## + printf("SCTP_ASSOC_CHANGE: %s, assoc=0x%x\n", str,## 37 ##src/sctp/sctp_displayevents.c## + (uint32_t) sac->sac_assoc_id);## 38 ##src/sctp/sctp_displayevents.c## + break;## 39 ##src/sctp/sctp_displayevents.c## + case SCTP_PEER_ADDR_CHANGE:## 40 ##src/sctp/sctp_displayevents.c## + spc = &snp->sn_paddr_change;## 41 ##src/sctp/sctp_displayevents.c## + switch (spc->spc_state) {## 42 ##src/sctp/sctp_displayevents.c## + case SCTP_ADDR_AVAILABLE:## 43 ##src/sctp/sctp_displayevents.c## + str = "ADDRESS AVAILABLE";## 44 ##src/sctp/sctp_displayevents.c## + break;## 45 ##src/sctp/sctp_displayevents.c## + case SCTP_ADDR_UNREACHABLE:## 46 ##src/sctp/sctp_displayevents.c## + str = "ADDRESS UNAVAILABLE";## 47 ##src/sctp/sctp_displayevents.c## + break;## 48 ##src/sctp/sctp_displayevents.c## + case SCTP_ADDR_REMOVED:## 49 ##src/sctp/sctp_displayevents.c## + str = "ADDRESS REMOVED";## 50 ##src/sctp/sctp_displayevents.c## + break;## 51 ##src/sctp/sctp_displayevents.c## + case SCTP_ADDR_ADDED:## 52 ##src/sctp/sctp_displayevents.c## + str = "ADDRESS ADDED";## 53 ##src/sctp/sctp_displayevents.c## + break;## 54 ##src/sctp/sctp_displayevents.c## + case SCTP_ADDR_MADE_PRIM:## 55 ##src/sctp/sctp_displayevents.c## + str = "ADDRESS MADE PRIMARY";## 56 ##src/sctp/sctp_displayevents.c## + break;## 57 ##src/sctp/sctp_displayevents.c## + default:## 58 ##src/sctp/sctp_displayevents.c## + str = "UNKNOWN";## 59 ##src/sctp/sctp_displayevents.c## + break;## 60 ##src/sctp/sctp_displayevents.c## + } /* end switch(spc->spc_state) */## 61 ##src/sctp/sctp_displayevents.c## + printf("SCTP_PEER_ADDR_CHANGE: %s, addr=%s, assoc=0x%x\n", str,## 62 ##src/sctp/sctp_displayevents.c## + Sock_ntop((SA *) &spc->spc_aaddr, sizeof(spc->spc_aaddr)),## 63 ##src/sctp/sctp_displayevents.c## + (uint32_t) spc->spc_assoc_id);## 64 ##src/sctp/sctp_displayevents.c## + break;## 65 ##src/sctp/sctp_displayevents.c## + case SCTP_REMOTE_ERROR:## 66 ##src/sctp/sctp_displayevents.c## + sre = &snp->sn_remote_error;## 67 ##src/sctp/sctp_displayevents.c## + printf("SCTP_REMOTE_ERROR: assoc=0x%x\n",## 68 ##src/sctp/sctp_displayevents.c## + (uint32_t) sre->sre_assoc_id);## 69 ##src/sctp/sctp_displayevents.c## + break;## 70 ##src/sctp/sctp_displayevents.c## + case SCTP_SEND_FAILED:## 71 ##src/sctp/sctp_displayevents.c## + ssf = &snp->sn_send_failed;## 72 ##src/sctp/sctp_displayevents.c## + printf("SCTP_SEND_FAILED: assoc=0x%x\n",## 73 ##src/sctp/sctp_displayevents.c## + (uint32_t) ssf->ssf_assoc_id);## 74 ##src/sctp/sctp_displayevents.c## + break;## 75 ##src/sctp/sctp_displayevents.c## + case SCTP_ADAPTION_INDICATION:## 76 ##src/sctp/sctp_displayevents.c## + ae = &snp->sn_adaption_event;## 77 ##src/sctp/sctp_displayevents.c## + printf("SCTP_adaption_indication:0x%x\n",## 78 ##src/sctp/sctp_displayevents.c## + (u_int) ae->sai_adaption_ind);## 79 ##src/sctp/sctp_displayevents.c## + break;## 80 ##src/sctp/sctp_displayevents.c## + case SCTP_PARTIAL_DELIVERY_EVENT:## 81 ##src/sctp/sctp_displayevents.c## + pdapi = &snp->sn_pdapi_event;## 82 ##src/sctp/sctp_displayevents.c## + if (pdapi->pdapi_indication == SCTP_PARTIAL_DELIVERY_ABORTED)## 83 ##src/sctp/sctp_displayevents.c## + printf("SCTP_PD-API ABORTED\n");## 84 ##src/sctp/sctp_displayevents.c## + else## 85 ##src/sctp/sctp_displayevents.c## + printf("Unknown SCTP_PD-API EVENT 0x%x\n",## 86 ##src/sctp/sctp_displayevents.c## + pdapi->pdapi_indication);## 87 ##src/sctp/sctp_displayevents.c## + break;## 88 ##src/sctp/sctp_displayevents.c## + case SCTP_SHUTDOWN_EVENT:## 89 ##src/sctp/sctp_displayevents.c## + sse = &snp->sn_shutdown_event;## 90 ##src/sctp/sctp_displayevents.c## + printf("SCTP_SHUTDOWN_EVENT: assoc=0x%x\n",## 91 ##src/sctp/sctp_displayevents.c## + (uint32_t) sse->sse_assoc_id);## 92 ##src/sctp/sctp_displayevents.c## + break;## 93 ##src/sctp/sctp_displayevents.c## + default:## 94 ##src/sctp/sctp_displayevents.c## + printf("Unknown notification event type=0x%x\n",## 95 ##src/sctp/sctp_displayevents.c## + snp->sn_header.sn_type);## 96 ##src/sctp/sctp_displayevents.c## + }## 97 ##src/sctp/sctp_displayevents.c## +}## 98 ##src/sctp/sctp_displayevents.c## diff --git a/sctp/sctp_getnostrm.c b/sctp/sctp_getnostrm.c new file mode 100644 index 0000000..afb045f --- /dev/null +++ b/sctp/sctp_getnostrm.c @@ -0,0 +1,15 @@ +#include "unp.h" + +int +sctp_get_no_strms(int sock_fd,struct sockaddr *to, socklen_t tolen) +{ + int retsz; + struct sctp_status status; + retsz = sizeof(status); + bzero(&status,sizeof(status)); + + status.sstat_assoc_id = sctp_address_to_associd(sock_fd,to,tolen); + Getsockopt(sock_fd,IPPROTO_SCTP, SCTP_STATUS, + &status, &retsz); + return(status.sstat_outstrms); +} diff --git a/sctp/sctp_modify_hb.c b/sctp/sctp_modify_hb.c new file mode 100644 index 0000000..5a424d5 --- /dev/null +++ b/sctp/sctp_modify_hb.c @@ -0,0 +1,15 @@ +#include "unp.h" + +int heartbeat_action(int sock_fd, struct sockaddr *sa, socklen_t salen, + u_int value) +{ + struct sctp_paddrparams sp; + int siz; + + bzero(&sp,sizeof(sp)); + sp.spp_hbinterval = value; + memcpy((caddr_t)&sp.spp_address,sa,salen); + Setsockopt(sock_fd,IPPROTO_SCTP, + SCTP_PEER_ADDR_PARAMS, &sp, sizeof(sp)); + return(0); +} diff --git a/sctp/sctp_modify_hb.lc b/sctp/sctp_modify_hb.lc new file mode 100644 index 0000000..ff8d2fa --- /dev/null +++ b/sctp/sctp_modify_hb.lc @@ -0,0 +1,27 @@ + +int## 1 ##src/sctp/sctp_modify_hb.c## +heartbeat_action(int sock_fd, struct sockaddr *sa, socklen_t salen,## 2 ##src/sctp/sctp_modify_hb.c## + int action, u_int value)## 3 ##src/sctp/sctp_modify_hb.c## +{## 4 ##src/sctp/sctp_modify_hb.c## + struct sctp_paddrparams sp;## 5 ##src/sctp/sctp_modify_hb.c## + int siz;## 6 ##src/sctp/sctp_modify_hb.c## + bzero(&sp, sizeof(sp));## 7 ##src/sctp/sctp_modify_hb.c## + if (action == SCTP_ON_DEMAND_HB) {## 8 ##src/sctp/sctp_modify_hb.c## + sp.spp_hbinterval = SCTP_ISSUE_HB;## 9 ##src/sctp/sctp_modify_hb.c## + } else if (action == SCTP_SET_HB_INTERVAL) {## 10 ##src/sctp/sctp_modify_hb.c## + if ((value == SCTP_NO_HB) || (value == SCTP_ISSUE_HB)) {## 11 ##src/sctp/sctp_modify_hb.c## + errno = EINVAL;## 12 ##src/sctp/sctp_modify_hb.c## + return (-1);## 13 ##src/sctp/sctp_modify_hb.c## + }## 14 ##src/sctp/sctp_modify_hb.c## + sp.spp_hbinterval = value;## 15 ##src/sctp/sctp_modify_hb.c## + } else if (action == SCTP_DISABLE_HB) {## 16 ##src/sctp/sctp_modify_hb.c## + sp.spp_hbinterval = SCTP_NO_HB;## 17 ##src/sctp/sctp_modify_hb.c## + } else {## 18 ##src/sctp/sctp_modify_hb.c## + errno = EINVAL;## 19 ##src/sctp/sctp_modify_hb.c## + return (-1);## 20 ##src/sctp/sctp_modify_hb.c## + }## 21 ##src/sctp/sctp_modify_hb.c## + siz = sizeof(struct sctp_paddrparams);## 22 ##src/sctp/sctp_modify_hb.c## + memcpy((caddr_t) & sp.spp_address, sa, salen);## 23 ##src/sctp/sctp_modify_hb.c## + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &sp, siz);## 24 ##src/sctp/sctp_modify_hb.c## + return (0);## 25 ##src/sctp/sctp_modify_hb.c## +}## 26 ##src/sctp/sctp_modify_hb.c## diff --git a/sctp/sctp_pdapircv.c b/sctp/sctp_pdapircv.c new file mode 100644 index 0000000..2344f03 --- /dev/null +++ b/sctp/sctp_pdapircv.c @@ -0,0 +1,45 @@ +#include "unp.h" + +static uint8_t *sctp_pdapi_readbuf=NULL; +static int sctp_pdapi_rdbuf_sz=0; + + +uint8_t * +pdapi_recvmsg(int sock_fd, + int *rdlen, + SA *from, + int *from_len, + struct sctp_sndrcvinfo *sri, + int *msg_flags) +{ + int rdsz,left,at_in_buf; + int frmlen=0; + + if (sctp_pdapi_readbuf == NULL) { + sctp_pdapi_readbuf = (uint8_t *)Malloc(SCTP_PDAPI_INCR_SZ); + sctp_pdapi_rdbuf_sz = SCTP_PDAPI_INCR_SZ; + } + at_in_buf = Sctp_recvmsg(sock_fd, sctp_pdapi_readbuf, sctp_pdapi_rdbuf_sz, + from, from_len, + sri,msg_flags); + if(at_in_buf < 1){ + *rdlen = at_in_buf; + return(NULL); + } + while((*msg_flags & MSG_EOR) == 0) { + left = sctp_pdapi_rdbuf_sz - at_in_buf; + if(left < SCTP_PDAPI_NEED_MORE_THRESHOLD) { + sctp_pdapi_readbuf = realloc(sctp_pdapi_readbuf, sctp_pdapi_rdbuf_sz+SCTP_PDAPI_INCR_SZ); + if(sctp_pdapi_readbuf == NULL) { + err_quit("sctp_pdapi ran out of memory"); + } + sctp_pdapi_rdbuf_sz += SCTP_PDAPI_INCR_SZ; + left = sctp_pdapi_rdbuf_sz - at_in_buf; + } + rdsz = Sctp_recvmsg(sock_fd, &sctp_pdapi_readbuf[at_in_buf], + left, NULL, &frmlen, NULL, msg_flags); + at_in_buf += rdsz; + } + *rdlen = at_in_buf; + return(sctp_pdapi_readbuf); +} diff --git a/sctp/sctp_pdapircv.lc b/sctp/sctp_pdapircv.lc new file mode 100644 index 0000000..b874172 --- /dev/null +++ b/sctp/sctp_pdapircv.lc @@ -0,0 +1,49 @@ + +static uint8_t *sctp_pdapi_readbuf = NULL;## 1 ##src/sctp/sctp_pdapircv.c## +static int sctp_pdapi_rdbuf_sz = 0;## 2 ##src/sctp/sctp_pdapircv.c## + +uint8_t *## 3 ##src/sctp/sctp_pdapircv.c## +pdapi_recvmsg(int sock_fd,## 4 ##src/sctp/sctp_pdapircv.c## + int *rdlen,## 5 ##src/sctp/sctp_pdapircv.c## + SA *from,## 6 ##src/sctp/sctp_pdapircv.c## + int *from_len, struct sctp_sndrcvinfo *sri, int *msg_flags)## 7 ##src/sctp/sctp_pdapircv.c## +{## 8 ##src/sctp/sctp_pdapircv.c## + int rdsz, left, at_in_buf;## 9 ##src/sctp/sctp_pdapircv.c## + int frmlen = 0;## 10 ##src/sctp/sctp_pdapircv.c## + + if (sctp_pdapi_readbuf == NULL) {## 11 ##src/sctp/sctp_pdapircv.c## + sctp_pdapi_readbuf = (uint8_t *) Malloc(SCTP_PDAPI_INCR_SZ);## 12 ##src/sctp/sctp_pdapircv.c## + sctp_pdapi_rdbuf_sz = SCTP_PDAPI_INCR_SZ;## 13 ##src/sctp/sctp_pdapircv.c## + }## 14 ##src/sctp/sctp_pdapircv.c## + at_in_buf =## 15 ##src/sctp/sctp_pdapircv.c## + Sctp_recvmsg(sock_fd, sctp_pdapi_readbuf, sctp_pdapi_rdbuf_sz, from,## 16 ##src/sctp/sctp_pdapircv.c## + from_len, sri, msg_flags);## 17 ##src/sctp/sctp_pdapircv.c## + if (at_in_buf < 1) {## 18 ##src/sctp/sctp_pdapircv.c## + *rdlen = at_in_buf;## 19 ##src/sctp/sctp_pdapircv.c## + return (NULL);## 20 ##src/sctp/sctp_pdapircv.c## + }## 21 ##src/sctp/sctp_pdapircv.c## + while ((*msg_flags & MSG_EOR) == 0) {## 22 ##src/sctp/sctp_pdapircv.c## + left = sctp_pdapi_rdbuf_sz - at_in_buf;## 23 ##src/sctp/sctp_pdapircv.c## + if (left < SCTP_PDAPI_NEED_MORE_THRESHOLD) {## 24 ##src/sctp/sctp_pdapircv.c## + uint8_t *more;## 25 ##src/sctp/sctp_pdapircv.c## + more =## 26 ##src/sctp/sctp_pdapircv.c## + (uint8_t *) malloc(sctp_pdapi_rdbuf_sz + SCTP_PDAPI_INCR_SZ);## 27 ##src/sctp/sctp_pdapircv.c## + if (more == NULL) {## 28 ##src/sctp/sctp_pdapircv.c## + printf("Warning:memory exhausted - partial message loss\n");## 29 ##src/sctp/sctp_pdapircv.c## + left = sctp_pdapi_rdbuf_sz;## 30 ##src/sctp/sctp_pdapircv.c## + at_in_buf = 0;## 31 ##src/sctp/sctp_pdapircv.c## + } else {## 32 ##src/sctp/sctp_pdapircv.c## + memcpy(more, sctp_pdapi_readbuf, at_in_buf);## 33 ##src/sctp/sctp_pdapircv.c## + free(sctp_pdapi_readbuf);## 34 ##src/sctp/sctp_pdapircv.c## + sctp_pdapi_readbuf = more;## 35 ##src/sctp/sctp_pdapircv.c## + sctp_pdapi_rdbuf_sz += SCTP_PDAPI_INCR_SZ;## 36 ##src/sctp/sctp_pdapircv.c## + left = sctp_pdapi_rdbuf_sz - at_in_buf;## 37 ##src/sctp/sctp_pdapircv.c## + }## 38 ##src/sctp/sctp_pdapircv.c## + }## 39 ##src/sctp/sctp_pdapircv.c## + rdsz = Sctp_recvmsg(sock_fd, &sctp_pdapi_readbuf[at_in_buf],## 40 ##src/sctp/sctp_pdapircv.c## + left, NULL, &frmlen, NULL, msg_flags);## 41 ##src/sctp/sctp_pdapircv.c## + at_in_buf += rdsz;## 42 ##src/sctp/sctp_pdapircv.c## + }## 43 ##src/sctp/sctp_pdapircv.c## + *rdlen = at_in_buf;## 44 ##src/sctp/sctp_pdapircv.c## + return (sctp_pdapi_readbuf);## 45 ##src/sctp/sctp_pdapircv.c## +}## 46 ##src/sctp/sctp_pdapircv.c## diff --git a/sctp/sctp_print_addrs.c b/sctp/sctp_print_addrs.c new file mode 100644 index 0000000..6454ca1 --- /dev/null +++ b/sctp/sctp_print_addrs.c @@ -0,0 +1,31 @@ +#include "unp.h" + +void +sctp_print_addresses(struct sockaddr_storage *addrs, int num) +{ + struct sockaddr_storage *ss; + int i,salen; + + ss = addrs; + for(i=0; iss_len; +#else + switch(ss->ss_family) { + case AF_INET: + salen = sizeof(struct sockaddr_in); + break; +#ifdef IPV6 + case AF_INET6: + salen = sizeof(struct sockaddr_in6); + break; +#endif + default: + err_quit("sctp_print_addresses: unknown AF"); + break; + } +#endif + ss = (struct sockaddr_storage *)((char *)ss + salen); + } +} diff --git a/sctp/sctp_print_addrs.lc b/sctp/sctp_print_addrs.lc new file mode 100644 index 0000000..d8aef0e --- /dev/null +++ b/sctp/sctp_print_addrs.lc @@ -0,0 +1,31 @@ +#include "unp.h"## 1 ##src/sctp/sctp_print_addrs.c## + +void## 2 ##src/sctp/sctp_print_addrs.c## +sctp_print_addresses(struct sockaddr_storage *addrs, int num)## 3 ##src/sctp/sctp_print_addrs.c## +{## 4 ##src/sctp/sctp_print_addrs.c## + struct sockaddr_storage *ss;## 5 ##src/sctp/sctp_print_addrs.c## + int i, salen;## 6 ##src/sctp/sctp_print_addrs.c## + + ss = addrs;## 7 ##src/sctp/sctp_print_addrs.c## + for (i = 0; i < num; i++) {## 8 ##src/sctp/sctp_print_addrs.c## + printf("%s\n", Sock_ntop((SA *) ss, salen));## 9 ##src/sctp/sctp_print_addrs.c## +#ifdef HAVE_SOCKADDR_SA_LEN## 10 ##src/sctp/sctp_print_addrs.c## + salen = ss->ss_len;## 11 ##src/sctp/sctp_print_addrs.c## +#else## 12 ##src/sctp/sctp_print_addrs.c## + switch (ss->ss_family) {## 13 ##src/sctp/sctp_print_addrs.c## + case AF_INET:## 14 ##src/sctp/sctp_print_addrs.c## + salen = sizeof(struct sockaddr_in);## 15 ##src/sctp/sctp_print_addrs.c## + break;## 16 ##src/sctp/sctp_print_addrs.c## +#ifdef IPV6## 17 ##src/sctp/sctp_print_addrs.c## + case AF_INET6:## 18 ##src/sctp/sctp_print_addrs.c## + salen = sizeof(struct sockaddr_in6);## 19 ##src/sctp/sctp_print_addrs.c## + break;## 20 ##src/sctp/sctp_print_addrs.c## +#endif## 21 ##src/sctp/sctp_print_addrs.c## + default:## 22 ##src/sctp/sctp_print_addrs.c## + err_quit("sctp_print_addresses: unknown AF");## 23 ##src/sctp/sctp_print_addrs.c## + break;## 24 ##src/sctp/sctp_print_addrs.c## + }## 25 ##src/sctp/sctp_print_addrs.c## +#endif## 26 ##src/sctp/sctp_print_addrs.c## + ss = (struct sockaddr_storage *) ((char *) ss + salen);## 27 ##src/sctp/sctp_print_addrs.c## + }## 28 ##src/sctp/sctp_print_addrs.c## +}## 29 ##src/sctp/sctp_print_addrs.c## diff --git a/sctp/sctp_strcli.c b/sctp/sctp_strcli.c new file mode 100644 index 0000000..b3ecfe0 --- /dev/null +++ b/sctp/sctp_strcli.c @@ -0,0 +1,36 @@ +#include "unp.h" + +void +sctpstr_cli(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen) +{ + struct sockaddr_in peeraddr; + struct sctp_sndrcvinfo sri; + char sendline[MAXLINE], recvline[MAXLINE]; + socklen_t len; + int out_sz,rd_sz; + int msg_flags; + + bzero(&sri,sizeof(sri)); + while (fgets(sendline, MAXLINE, fp) != NULL) { + if(sendline[0] != '[') { + printf("Error, line must be of the form '[streamnum]text'\n"); + continue; + } + sri.sinfo_stream = strtol(&sendline[1],NULL,0); + out_sz = strlen(sendline); + Sctp_sendmsg(sock_fd, sendline, out_sz, + to, tolen, + 0, 0, + sri.sinfo_stream, + 0, 0); + + len = sizeof(peeraddr); + rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline), + (SA *)&peeraddr, &len, + &sri,&msg_flags); + printf("From str:%d seq:%d (assoc:0x%x):", + sri.sinfo_stream,sri.sinfo_ssn, + (u_int)sri.sinfo_assoc_id); + printf("%.*s",rd_sz,recvline); + } +} diff --git a/sctp/sctp_strcli.lc b/sctp/sctp_strcli.lc new file mode 100644 index 0000000..f2c7a63 --- /dev/null +++ b/sctp/sctp_strcli.lc @@ -0,0 +1,31 @@ +#include "unp.h"## 1 ##src/sctp/sctp_strcli.c## + +void## 2 ##src/sctp/sctp_strcli.c## +sctpstr_cli(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen)## 3 ##src/sctp/sctp_strcli.c## +{## 4 ##src/sctp/sctp_strcli.c## + struct sockaddr_in peeraddr;## 5 ##src/sctp/sctp_strcli.c## + struct sctp_sndrcvinfo sri;## 6 ##src/sctp/sctp_strcli.c## + char sendline[MAXLINE], recvline[MAXLINE];## 7 ##src/sctp/sctp_strcli.c## + socklen_t len;## 8 ##src/sctp/sctp_strcli.c## + int out_sz, rd_sz;## 9 ##src/sctp/sctp_strcli.c## + int msg_flags;## 10 ##src/sctp/sctp_strcli.c## + + bzero(&sri, sizeof(sri));## 11 ##src/sctp/sctp_strcli.c## + while (fgets(sendline, MAXLINE, fp) != NULL) {## 12 ##src/sctp/sctp_strcli.c## + if (sendline[0] != '[') {## 13 ##src/sctp/sctp_strcli.c## + printf("Error, line must be of the form '[streamnum]text'\n");## 14 ##src/sctp/sctp_strcli.c## + continue;## 15 ##src/sctp/sctp_strcli.c## + }## 16 ##src/sctp/sctp_strcli.c## + sri.sinfo_stream = strtol(&sendline[1], NULL, 0);## 17 ##src/sctp/sctp_strcli.c## + out_sz = strlen(sendline);## 18 ##src/sctp/sctp_strcli.c## + Sctp_sendmsg(sock_fd, sendline, out_sz,## 19 ##src/sctp/sctp_strcli.c## + to, tolen, 0, 0, sri.sinfo_stream, 0, 0);## 20 ##src/sctp/sctp_strcli.c## + + len = sizeof(peeraddr);## 21 ##src/sctp/sctp_strcli.c## + rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline),## 22 ##src/sctp/sctp_strcli.c## + (SA *) &peeraddr, &len, &sri, &msg_flags);## 23 ##src/sctp/sctp_strcli.c## + printf("From str:%d seq:%d (assoc:0x%x):",## 24 ##src/sctp/sctp_strcli.c## + sri.sinfo_stream, sri.sinfo_ssn, (u_int) sri.sinfo_assoc_id);## 25 ##src/sctp/sctp_strcli.c## + printf("%.*s", rd_sz, recvline);## 26 ##src/sctp/sctp_strcli.c## + }## 27 ##src/sctp/sctp_strcli.c## +}## 28 ##src/sctp/sctp_strcli.c## diff --git a/sctp/sctp_strcli1.c b/sctp/sctp_strcli1.c new file mode 100644 index 0000000..fd6c56c --- /dev/null +++ b/sctp/sctp_strcli1.c @@ -0,0 +1,41 @@ +#include "unp.h" + +void +sctpstr_cli(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen) +{ + struct sockaddr_in peeraddr; + struct sctp_sndrcvinfo sri; + char sendline[MAXLINE], recvline[MAXLINE]; + socklen_t len; + int out_sz,rd_sz; + int msg_flags; + + bzero(&sri,sizeof(sri)); + while (fgets(sendline, MAXLINE, fp) != NULL) { + if(sendline[0] != '[') { + printf("Error, line must be of the form '[streamnum]text'\n"); + continue; + } + sri.sinfo_stream = strtol(&sendline[1],NULL,0); + out_sz = strlen(sendline); + Sctp_sendmsg(sock_fd, sendline, out_sz, + to, tolen, + 0, 0, + sri.sinfo_stream, + 0, 0); +/* include mod_strcli1 */ + do { + len = sizeof(peeraddr); + rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline), + (SA *)&peeraddr, &len, + &sri,&msg_flags); + if(msg_flags & MSG_NOTIFICATION) + check_notification(sock_fd,recvline,rd_sz); + } while (msg_flags & MSG_NOTIFICATION); + printf("From str:%d seq:%d (assoc:0x%x):", + sri.sinfo_stream,sri.sinfo_ssn, + (u_int)sri.sinfo_assoc_id); + printf("%.*s",rd_sz,recvline); +/* end mod_strcli1 */ + } +} diff --git a/sctp/sctp_strcli1.lc b/sctp/sctp_strcli1.lc new file mode 100644 index 0000000..d6269e1 --- /dev/null +++ b/sctp/sctp_strcli1.lc @@ -0,0 +1,36 @@ +#include "unp.h"## 1 ##src/sctp/sctp_strcli1.c## + +void## 2 ##src/sctp/sctp_strcli1.c## +sctpstr_cli(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen)## 3 ##src/sctp/sctp_strcli1.c## +{## 4 ##src/sctp/sctp_strcli1.c## + struct sockaddr_in peeraddr;## 5 ##src/sctp/sctp_strcli1.c## + struct sctp_sndrcvinfo sri;## 6 ##src/sctp/sctp_strcli1.c## + char sendline[MAXLINE], recvline[MAXLINE];## 7 ##src/sctp/sctp_strcli1.c## + socklen_t len;## 8 ##src/sctp/sctp_strcli1.c## + int out_sz, rd_sz;## 9 ##src/sctp/sctp_strcli1.c## + int msg_flags;## 10 ##src/sctp/sctp_strcli1.c## + + bzero(&sri, sizeof(sri));## 11 ##src/sctp/sctp_strcli1.c## + while (fgets(sendline, MAXLINE, fp) != NULL) {## 12 ##src/sctp/sctp_strcli1.c## + if (sendline[0] != '[') {## 13 ##src/sctp/sctp_strcli1.c## + printf("Error, line must be of the form '[streamnum]text'\n");## 14 ##src/sctp/sctp_strcli1.c## + continue;## 15 ##src/sctp/sctp_strcli1.c## + }## 16 ##src/sctp/sctp_strcli1.c## + sri.sinfo_stream = strtol(&sendline[1], NULL, 0);## 17 ##src/sctp/sctp_strcli1.c## + out_sz = strlen(sendline);## 18 ##src/sctp/sctp_strcli1.c## + Sctp_sendmsg(sock_fd, sendline, out_sz,## 19 ##src/sctp/sctp_strcli1.c## + to, tolen, 0, 0, sri.sinfo_stream, 0, 0);## 20 ##src/sctp/sctp_strcli1.c## + /* include mod_strcli1 */## 21 ##src/sctp/sctp_strcli1.c## + do {## 22 ##src/sctp/sctp_strcli1.c## + len = sizeof(peeraddr);## 23 ##src/sctp/sctp_strcli1.c## + rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline),## 24 ##src/sctp/sctp_strcli1.c## + (SA *) &peeraddr, &len, &sri, &msg_flags);## 25 ##src/sctp/sctp_strcli1.c## + if (msg_flags & MSG_NOTIFICATION)## 26 ##src/sctp/sctp_strcli1.c## + check_notification(sock_fd, recvline, rd_sz);## 27 ##src/sctp/sctp_strcli1.c## + } while (msg_flags & MSG_NOTIFICATION);## 28 ##src/sctp/sctp_strcli1.c## + printf("From str:%d seq:%d (assoc:0x%x):",## 29 ##src/sctp/sctp_strcli1.c## + sri.sinfo_stream, sri.sinfo_ssn, (u_int) sri.sinfo_assoc_id);## 30 ##src/sctp/sctp_strcli1.c## + printf("%.*s", rd_sz, recvline);## 31 ##src/sctp/sctp_strcli1.c## + /* end mod_strcli1 */## 32 ##src/sctp/sctp_strcli1.c## + }## 33 ##src/sctp/sctp_strcli1.c## +}## 34 ##src/sctp/sctp_strcli1.c## diff --git a/sctp/sctp_strcli_un.c b/sctp/sctp_strcli_un.c new file mode 100644 index 0000000..21d685f --- /dev/null +++ b/sctp/sctp_strcli_un.c @@ -0,0 +1,38 @@ +#include "unp.h" + +void +sctpstr_cli(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen) +{ + struct sockaddr_in peeraddr; + struct sctp_sndrcvinfo sri; + char sendline[MAXLINE], recvline[MAXLINE]; + socklen_t len; + int out_sz,rd_sz; + int msg_flags; + + bzero(&sri,sizeof(sri)); + while (fgets(sendline, MAXLINE, fp) != NULL) { + if(sendline[0] != '[') { + printf("Error, line must be of the form '[streamnum]text'\n"); + continue; + } + sri.sinfo_stream = strtol(&sendline[1],NULL,0); +/* include mod_unordered */ + out_sz = strlen(sendline); + Sctp_sendmsg(sock_fd, sendline, out_sz, + to, tolen, + 0, + MSG_UNORDERED, + sri.sinfo_stream, + 0, 0); +/* end mod_unordered */ + len = sizeof(peeraddr); + rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline), + (SA *)&peeraddr, &len, + &sri,&msg_flags); + printf("From str:%d seq:%d (assoc:0x%x):", + sri.sinfo_stream,sri.sinfo_ssn, + (u_int)sri.sinfo_assoc_id); + printf("%.*s",rd_sz,recvline); + } +} diff --git a/sctp/sctp_strcli_un.lc b/sctp/sctp_strcli_un.lc new file mode 100644 index 0000000..b30e016 --- /dev/null +++ b/sctp/sctp_strcli_un.lc @@ -0,0 +1,32 @@ +#include "unp.h"## 1 ##src/sctp/sctp_strcli_un.c## + +void## 2 ##src/sctp/sctp_strcli_un.c## +sctpstr_cli(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen)## 3 ##src/sctp/sctp_strcli_un.c## +{## 4 ##src/sctp/sctp_strcli_un.c## + struct sockaddr_in peeraddr;## 5 ##src/sctp/sctp_strcli_un.c## + struct sctp_sndrcvinfo sri;## 6 ##src/sctp/sctp_strcli_un.c## + char sendline[MAXLINE], recvline[MAXLINE];## 7 ##src/sctp/sctp_strcli_un.c## + socklen_t len;## 8 ##src/sctp/sctp_strcli_un.c## + int out_sz, rd_sz;## 9 ##src/sctp/sctp_strcli_un.c## + int msg_flags;## 10 ##src/sctp/sctp_strcli_un.c## + + bzero(&sri, sizeof(sri));## 11 ##src/sctp/sctp_strcli_un.c## + while (fgets(sendline, MAXLINE, fp) != NULL) {## 12 ##src/sctp/sctp_strcli_un.c## + if (sendline[0] != '[') {## 13 ##src/sctp/sctp_strcli_un.c## + printf("Error, line must be of the form '[streamnum]text'\n");## 14 ##src/sctp/sctp_strcli_un.c## + continue;## 15 ##src/sctp/sctp_strcli_un.c## + }## 16 ##src/sctp/sctp_strcli_un.c## + sri.sinfo_stream = strtol(&sendline[1], NULL, 0);## 17 ##src/sctp/sctp_strcli_un.c## + /* include mod_unordered */## 18 ##src/sctp/sctp_strcli_un.c## + out_sz = strlen(sendline);## 19 ##src/sctp/sctp_strcli_un.c## + Sctp_sendmsg(sock_fd, sendline, out_sz,## 20 ##src/sctp/sctp_strcli_un.c## + to, tolen, 0, MSG_UNORDERED, sri.sinfo_stream, 0, 0);## 21 ##src/sctp/sctp_strcli_un.c## + /* end mod_unordered */## 22 ##src/sctp/sctp_strcli_un.c## + len = sizeof(peeraddr);## 23 ##src/sctp/sctp_strcli_un.c## + rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline),## 24 ##src/sctp/sctp_strcli_un.c## + (SA *) &peeraddr, &len, &sri, &msg_flags);## 25 ##src/sctp/sctp_strcli_un.c## + printf("From str:%d seq:%d (assoc:0x%x):",## 26 ##src/sctp/sctp_strcli_un.c## + sri.sinfo_stream, sri.sinfo_ssn, (u_int) sri.sinfo_assoc_id);## 27 ##src/sctp/sctp_strcli_un.c## + printf("%.*s", rd_sz, recvline);## 28 ##src/sctp/sctp_strcli_un.c## + }## 29 ##src/sctp/sctp_strcli_un.c## +}## 30 ##src/sctp/sctp_strcli_un.c## diff --git a/sctp/sctp_strcliecho.c b/sctp/sctp_strcliecho.c new file mode 100644 index 0000000..fa015f5 --- /dev/null +++ b/sctp/sctp_strcliecho.c @@ -0,0 +1,43 @@ +#include "unp.h" + +#define SCTP_MAXLINE 800 + +void +sctpstr_cli_echoall(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen) +{ + struct sockaddr_in peeraddr; + struct sctp_sndrcvinfo sri; + char sendline[SCTP_MAXLINE], recvline[SCTP_MAXLINE]; + socklen_t len; + int rd_sz,i,strsz; + int msg_flags; + + bzero(sendline,sizeof(sendline)); + bzero(&sri,sizeof(sri)); + while (fgets(sendline, SCTP_MAXLINE - 9, fp) != NULL) { + strsz = strlen(sendline); + if(sendline[strsz-1] == '\n') { + sendline[strsz-1] = '\0'; + strsz--; + } + for(i=0;i 2) { + printf("Echoing messages to all streams\n"); + echo_to_all = 1; + } + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + bzero(&evnts, sizeof(evnts)); + evnts.sctp_data_io_event = 1; + Setsockopt(sock_fd,IPPROTO_SCTP, SCTP_EVENTS, + &evnts, sizeof(evnts)); + if(echo_to_all == 0) + sctpstr_cli(stdin,sock_fd,(SA *)&servaddr,sizeof(servaddr)); + else + sctpstr_cli_echoall(stdin,sock_fd,(SA *)&servaddr,sizeof(servaddr)); + Close(sock_fd); + return(0); +} diff --git a/sctp/sctpclient01.lc b/sctp/sctpclient01.lc new file mode 100644 index 0000000..80c4b99 --- /dev/null +++ b/sctp/sctpclient01.lc @@ -0,0 +1,37 @@ +#include "unp.h"## 1 ##src/sctp/sctpclient01.c## + +int## 2 ##src/sctp/sctpclient01.c## +main(int argc, char **argv)## 3 ##src/sctp/sctpclient01.c## +{## 4 ##src/sctp/sctpclient01.c## + int sock_fd;## 5 ##src/sctp/sctpclient01.c## + struct sockaddr_in servaddr;## 6 ##src/sctp/sctpclient01.c## + struct sctp_event_subscribe evnts;## 7 ##src/sctp/sctpclient01.c## + int echo_to_all = 0;## 8 ##src/sctp/sctpclient01.c## + + if (argc < 2)## 9 ##src/sctp/sctpclient01.c## + err_quit("Missing host argument - use '%s host [echo]'\n", argv[0]);## 10 ##src/sctp/sctpclient01.c## + if (argc > 2) {## 11 ##src/sctp/sctpclient01.c## + printf("Echoing messages to all streams\n");## 12 ##src/sctp/sctpclient01.c## + echo_to_all = 1;## 13 ##src/sctp/sctpclient01.c## + }## 14 ##src/sctp/sctpclient01.c## + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 15 ##src/sctp/sctpclient01.c## + bzero(&servaddr, sizeof(servaddr));## 16 ##src/sctp/sctpclient01.c## + servaddr.sin_family = AF_INET;## 17 ##src/sctp/sctpclient01.c## +#ifdef HAVE_SOCKADDR_SA_LEN## 18 ##src/sctp/sctpclient01.c## + servaddr.sin_len = sizeof(servaddr);## 19 ##src/sctp/sctpclient01.c## +#endif## 20 ##src/sctp/sctpclient01.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 21 ##src/sctp/sctpclient01.c## + servaddr.sin_port = htons(SERV_PORT);## 22 ##src/sctp/sctpclient01.c## + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);## 23 ##src/sctp/sctpclient01.c## + + bzero(&evnts, sizeof(evnts));## 24 ##src/sctp/sctpclient01.c## + evnts.sctp_data_io_event = 1;## 25 ##src/sctp/sctpclient01.c## + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 26 ##src/sctp/sctpclient01.c## + if (echo_to_all == 0)## 27 ##src/sctp/sctpclient01.c## + sctpstr_cli(stdin, sock_fd, (SA *) &servaddr, sizeof(servaddr));## 28 ##src/sctp/sctpclient01.c## + else## 29 ##src/sctp/sctpclient01.c## + sctpstr_cli_echoall(stdin, sock_fd, (SA *) &servaddr,## 30 ##src/sctp/sctpclient01.c## + sizeof(servaddr));## 31 ##src/sctp/sctpclient01.c## + Close(sock_fd);## 32 ##src/sctp/sctpclient01.c## + return (0);## 33 ##src/sctp/sctpclient01.c## +}## 34 ##src/sctp/sctpclient01.c## diff --git a/sctp/sctpclient02.c b/sctp/sctpclient02.c new file mode 100644 index 0000000..b55cd9d --- /dev/null +++ b/sctp/sctpclient02.c @@ -0,0 +1,44 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sock_fd; + struct sockaddr_in servaddr; + struct sctp_event_subscribe evnts; + int echo_to_all=0; + char byemsg[10]; + + if(argc < 2) + err_quit("Missing host argument - use '%s host [echo]'\n", + argv[0]); + if(argc > 2) { + printf("Echoing messages to all streams\n"); + echo_to_all = 1; + } + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + bzero(&evnts, sizeof(evnts)); + evnts.sctp_data_io_event = 1; + Setsockopt(sock_fd,IPPROTO_SCTP, SCTP_EVENTS, + &evnts, sizeof(evnts)); +/* include modified_client02 */ + if(echo_to_all == 0) + sctpstr_cli(stdin,sock_fd,(SA *)&servaddr,sizeof(servaddr)); + else + sctpstr_cli_echoall(stdin,sock_fd,(SA *)&servaddr,sizeof(servaddr)); + strcpy(byemsg,"goodbye"); + Sctp_sendmsg(sock_fd, byemsg, strlen(byemsg), + (SA *)&servaddr, sizeof(servaddr), + 0, + MSG_ABORT, + 0, 0, 0); + Close(sock_fd); +/* end modified_client02 */ + return(0); +} diff --git a/sctp/sctpclient02.lc b/sctp/sctpclient02.lc new file mode 100644 index 0000000..1f50b06 --- /dev/null +++ b/sctp/sctpclient02.lc @@ -0,0 +1,42 @@ + +int## 1 ##src/sctp/sctpclient02.c## +main(int argc, char **argv)## 2 ##src/sctp/sctpclient02.c## +{## 3 ##src/sctp/sctpclient02.c## + int sock_fd;## 4 ##src/sctp/sctpclient02.c## + struct sockaddr_in servaddr;## 5 ##src/sctp/sctpclient02.c## + struct sctp_event_subscribe evnts;## 6 ##src/sctp/sctpclient02.c## + int echo_to_all = 0;## 7 ##src/sctp/sctpclient02.c## + char byemsg[10];## 8 ##src/sctp/sctpclient02.c## + + if (argc < 2)## 9 ##src/sctp/sctpclient02.c## + err_quit("Missing host argument - use '%s host [echo]'\n", argv[0]);## 10 ##src/sctp/sctpclient02.c## + if (argc > 2) {## 11 ##src/sctp/sctpclient02.c## + printf("Echoing messages to all streams\n");## 12 ##src/sctp/sctpclient02.c## + echo_to_all = 1;## 13 ##src/sctp/sctpclient02.c## + }## 14 ##src/sctp/sctpclient02.c## + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 15 ##src/sctp/sctpclient02.c## + bzero(&servaddr, sizeof(servaddr));## 16 ##src/sctp/sctpclient02.c## + servaddr.sin_family = AF_INET;## 17 ##src/sctp/sctpclient02.c## +#ifdef HAVE_SOCKADDR_SA_LEN## 18 ##src/sctp/sctpclient02.c## + servaddr.sin_len = sizeof(servaddr);## 19 ##src/sctp/sctpclient02.c## +#endif## 20 ##src/sctp/sctpclient02.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 21 ##src/sctp/sctpclient02.c## + servaddr.sin_port = htons(SERV_PORT);## 22 ##src/sctp/sctpclient02.c## + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);## 23 ##src/sctp/sctpclient02.c## + + bzero(&evnts, sizeof(evnts));## 24 ##src/sctp/sctpclient02.c## + evnts.sctp_data_io_event = 1;## 25 ##src/sctp/sctpclient02.c## + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 26 ##src/sctp/sctpclient02.c## + /* include modified_client02 */## 27 ##src/sctp/sctpclient02.c## + if (echo_to_all == 0)## 28 ##src/sctp/sctpclient02.c## + sctpstr_cli(stdin, sock_fd, (SA *) &servaddr, sizeof(servaddr));## 29 ##src/sctp/sctpclient02.c## + else## 30 ##src/sctp/sctpclient02.c## + sctpstr_cli_echoall(stdin, sock_fd, (SA *) &servaddr,## 31 ##src/sctp/sctpclient02.c## + sizeof(servaddr));## 32 ##src/sctp/sctpclient02.c## + strcpy(byemsg, "goodbye");## 33 ##src/sctp/sctpclient02.c## + Sctp_sendmsg(sock_fd, byemsg, strlen(byemsg),## 34 ##src/sctp/sctpclient02.c## + (SA *) &servaddr, sizeof(servaddr), 0, MSG_ABORT, 0, 0, 0);## 35 ##src/sctp/sctpclient02.c## + Close(sock_fd);## 36 ##src/sctp/sctpclient02.c## + /* end modified_client02 */## 37 ##src/sctp/sctpclient02.c## + return (0);## 38 ##src/sctp/sctpclient02.c## +}## 39 ##src/sctp/sctpclient02.c## diff --git a/sctp/sctpclient04.c b/sctp/sctpclient04.c new file mode 100644 index 0000000..205475f --- /dev/null +++ b/sctp/sctpclient04.c @@ -0,0 +1,30 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sock_fd; + struct sockaddr_in servaddr; + struct sctp_event_subscribe evnts; + + if(argc != 2) + err_quit("Missing host argument - use '%s host'\n", + argv[0]); + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); +/* include mod_client04 */ + bzero(&evnts, sizeof(evnts)); + evnts.sctp_data_io_event = 1; + evnts.sctp_association_event = 1; + Setsockopt(sock_fd,IPPROTO_SCTP, SCTP_EVENTS, + &evnts, sizeof(evnts)); + + sctpstr_cli(stdin,sock_fd,(SA *)&servaddr,sizeof(servaddr)); +/* end mod_client04 */ + close(sock_fd); + return(0); +} diff --git a/sctp/sctpclient04.lc b/sctp/sctpclient04.lc new file mode 100644 index 0000000..282e765 --- /dev/null +++ b/sctp/sctpclient04.lc @@ -0,0 +1,31 @@ +#include "unp.h"## 1 ##src/sctp/sctpclient04.c## + +int## 2 ##src/sctp/sctpclient04.c## +main(int argc, char **argv)## 3 ##src/sctp/sctpclient04.c## +{## 4 ##src/sctp/sctpclient04.c## + int sock_fd;## 5 ##src/sctp/sctpclient04.c## + struct sockaddr_in servaddr;## 6 ##src/sctp/sctpclient04.c## + struct sctp_event_subscribe evnts;## 7 ##src/sctp/sctpclient04.c## + + if (argc != 2)## 8 ##src/sctp/sctpclient04.c## + err_quit("Missing host argument - use '%s host'\n", argv[0]);## 9 ##src/sctp/sctpclient04.c## + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 10 ##src/sctp/sctpclient04.c## + bzero(&servaddr, sizeof(servaddr));## 11 ##src/sctp/sctpclient04.c## + servaddr.sin_family = AF_INET;## 12 ##src/sctp/sctpclient04.c## +#ifdef HAVE_SOCKADDR_SA_LEN## 13 ##src/sctp/sctpclient04.c## + servaddr.sin_len = sizeof(servaddr);## 14 ##src/sctp/sctpclient04.c## +#endif## 15 ##src/sctp/sctpclient04.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 16 ##src/sctp/sctpclient04.c## + servaddr.sin_port = htons(SERV_PORT);## 17 ##src/sctp/sctpclient04.c## + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);## 18 ##src/sctp/sctpclient04.c## + /* include mod_client04 */## 19 ##src/sctp/sctpclient04.c## + bzero(&evnts, sizeof(evnts));## 20 ##src/sctp/sctpclient04.c## + evnts.sctp_data_io_event = 1;## 21 ##src/sctp/sctpclient04.c## + evnts.sctp_association_event = 1;## 22 ##src/sctp/sctpclient04.c## + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 23 ##src/sctp/sctpclient04.c## + + sctpstr_cli(stdin, sock_fd, (SA *) &servaddr, sizeof(servaddr));## 24 ##src/sctp/sctpclient04.c## + /* end mod_client04 */## 25 ##src/sctp/sctpclient04.c## + close(sock_fd);## 26 ##src/sctp/sctpclient04.c## + return (0);## 27 ##src/sctp/sctpclient04.c## +}## 28 ##src/sctp/sctpclient04.c## diff --git a/sctp/sctpserv01.c b/sctp/sctpserv01.c new file mode 100644 index 0000000..54634e9 --- /dev/null +++ b/sctp/sctpserv01.c @@ -0,0 +1,48 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sock_fd,msg_flags; + char readbuf[BUFFSIZE]; + struct sockaddr_in servaddr, cliaddr; + struct sctp_sndrcvinfo sri; + struct sctp_event_subscribe evnts; + int stream_increment=1; + socklen_t len; + size_t rd_sz; + + if (argc == 2) + stream_increment = atoi(argv[1]); + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr)); + + bzero(&evnts, sizeof(evnts)); + evnts.sctp_data_io_event = 1; + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, + &evnts, sizeof(evnts)); + + Listen(sock_fd, LISTENQ); + for ( ; ; ) { + len = sizeof(struct sockaddr_in); + rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf), + (SA *)&cliaddr, &len, + &sri,&msg_flags); + if(stream_increment) { + sri.sinfo_stream++; + if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd,(SA *)&cliaddr, len)) + sri.sinfo_stream = 0; + } + Sctp_sendmsg(sock_fd, readbuf, rd_sz, + (SA *)&cliaddr, len, + sri.sinfo_ppid, + sri.sinfo_flags, + sri.sinfo_stream, + 0, 0); + } +} diff --git a/sctp/sctpserv01.lc b/sctp/sctpserv01.lc new file mode 100644 index 0000000..9c5a189 --- /dev/null +++ b/sctp/sctpserv01.lc @@ -0,0 +1,48 @@ +#include "unp.h"## 1 ##src/sctp/sctpserv01.c## + +int## 2 ##src/sctp/sctpserv01.c## +main(int argc, char **argv)## 3 ##src/sctp/sctpserv01.c## +{## 4 ##src/sctp/sctpserv01.c## + int sock_fd, msg_flags;## 5 ##src/sctp/sctpserv01.c## + char readbuf[BUFFSIZE];## 6 ##src/sctp/sctpserv01.c## + struct sockaddr_in servaddr, cliaddr;## 7 ##src/sctp/sctpserv01.c## + struct sctp_sndrcvinfo sri;## 8 ##src/sctp/sctpserv01.c## + struct sctp_event_subscribe evnts;## 9 ##src/sctp/sctpserv01.c## + int stream_increment = 1;## 10 ##src/sctp/sctpserv01.c## + socklen_t len;## 11 ##src/sctp/sctpserv01.c## + size_t rd_sz;## 12 ##src/sctp/sctpserv01.c## + + if (argc == 2)## 13 ##src/sctp/sctpserv01.c## + stream_increment = atoi(argv[1]);## 14 ##src/sctp/sctpserv01.c## + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 15 ##src/sctp/sctpserv01.c## + bzero(&servaddr, sizeof(servaddr));## 16 ##src/sctp/sctpserv01.c## + servaddr.sin_family = AF_INET;## 17 ##src/sctp/sctpserv01.c## +#ifdef HAVE_SOCKADDR_SA_LEN## 18 ##src/sctp/sctpserv01.c## + servaddr.sin_len = sizeof(servaddr);## 19 ##src/sctp/sctpserv01.c## +#endif## 20 ##src/sctp/sctpserv01.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 21 ##src/sctp/sctpserv01.c## + servaddr.sin_port = htons(SERV_PORT);## 22 ##src/sctp/sctpserv01.c## + + Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));## 23 ##src/sctp/sctpserv01.c## + + bzero(&evnts, sizeof(evnts));## 24 ##src/sctp/sctpserv01.c## + evnts.sctp_data_io_event = 1;## 25 ##src/sctp/sctpserv01.c## + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 26 ##src/sctp/sctpserv01.c## + + Listen(sock_fd, LISTENQ);## 27 ##src/sctp/sctpserv01.c## + for (;;) {## 28 ##src/sctp/sctpserv01.c## + len = sizeof(struct sockaddr_in);## 29 ##src/sctp/sctpserv01.c## + rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),## 30 ##src/sctp/sctpserv01.c## + (SA *) &cliaddr, &len, &sri, &msg_flags);## 31 ##src/sctp/sctpserv01.c## + if (stream_increment) {## 32 ##src/sctp/sctpserv01.c## + sri.sinfo_stream++;## 33 ##src/sctp/sctpserv01.c## + if (sri.sinfo_stream >=## 34 ##src/sctp/sctpserv01.c## + sctp_get_no_strms(sock_fd, (SA *) &cliaddr, len))## 35 ##src/sctp/sctpserv01.c## + sri.sinfo_stream = 0;## 36 ##src/sctp/sctpserv01.c## + }## 37 ##src/sctp/sctpserv01.c## + Sctp_sendmsg(sock_fd, readbuf, rd_sz,## 38 ##src/sctp/sctpserv01.c## + (SA *) &cliaddr, len,## 39 ##src/sctp/sctpserv01.c## + sri.sinfo_ppid,## 40 ##src/sctp/sctpserv01.c## + sri.sinfo_flags, sri.sinfo_stream, 0, 0);## 41 ##src/sctp/sctpserv01.c## + }## 42 ##src/sctp/sctpserv01.c## +}## 43 ##src/sctp/sctpserv01.c## diff --git a/sctp/sctpserv02.c b/sctp/sctpserv02.c new file mode 100644 index 0000000..94b9f90 --- /dev/null +++ b/sctp/sctpserv02.c @@ -0,0 +1,55 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sock_fd,msg_flags; + char readbuf[BUFFSIZE]; + struct sockaddr_in servaddr, cliaddr; + struct sctp_sndrcvinfo sri; + struct sctp_event_subscribe evnts; + int stream_increment=1; + socklen_t len; + size_t rd_sz; + struct sctp_initmsg initm; + +/* include modified_sctpserv02 */ + if (argc == 2) + stream_increment = atoi(argv[1]); + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + bzero(&initm,sizeof(initm)); + initm.sinit_num_ostreams = SERV_MORE_STRMS_SCTP; + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_INITMSG, + &initm, sizeof(initm)); +/* end modified_sctpserv02 */ + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr)); + + bzero(&evnts, sizeof(evnts)); + evnts.sctp_data_io_event = 1; + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, + &evnts, sizeof(evnts)); + + Listen(sock_fd, LISTENQ); + for ( ; ; ) { + len = sizeof(struct sockaddr_in); + rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf), + (SA *)&cliaddr, &len, + &sri,&msg_flags); + if(stream_increment) { + sri.sinfo_stream++; + if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd,(SA *)&cliaddr, len)) + sri.sinfo_stream = 0; + } + Sctp_sendmsg(sock_fd, readbuf, rd_sz, + (SA *)&cliaddr, len, + sri.sinfo_ppid, + sri.sinfo_flags, + sri.sinfo_stream, + 0, 0); + } +} diff --git a/sctp/sctpserv02.lc b/sctp/sctpserv02.lc new file mode 100644 index 0000000..a758cb8 --- /dev/null +++ b/sctp/sctpserv02.lc @@ -0,0 +1,54 @@ +#include "unp.h"## 1 ##src/sctp/sctpserv02.c## + +int## 2 ##src/sctp/sctpserv02.c## +main(int argc, char **argv)## 3 ##src/sctp/sctpserv02.c## +{## 4 ##src/sctp/sctpserv02.c## + int sock_fd, msg_flags;## 5 ##src/sctp/sctpserv02.c## + char readbuf[BUFFSIZE];## 6 ##src/sctp/sctpserv02.c## + struct sockaddr_in servaddr, cliaddr;## 7 ##src/sctp/sctpserv02.c## + struct sctp_sndrcvinfo sri;## 8 ##src/sctp/sctpserv02.c## + struct sctp_event_subscribe evnts;## 9 ##src/sctp/sctpserv02.c## + int stream_increment = 1;## 10 ##src/sctp/sctpserv02.c## + socklen_t len;## 11 ##src/sctp/sctpserv02.c## + size_t rd_sz;## 12 ##src/sctp/sctpserv02.c## + struct sctp_initmsg initm;## 13 ##src/sctp/sctpserv02.c## + + /* include modified_sctpserv02 */## 14 ##src/sctp/sctpserv02.c## + if (argc == 2)## 15 ##src/sctp/sctpserv02.c## + stream_increment = atoi(argv[1]);## 16 ##src/sctp/sctpserv02.c## + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 17 ##src/sctp/sctpserv02.c## + bzero(&initm, sizeof(initm));## 18 ##src/sctp/sctpserv02.c## + initm.sinit_num_ostreams = SERV_MORE_STRMS_SCTP;## 19 ##src/sctp/sctpserv02.c## + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_INITMSG, &initm, sizeof(initm));## 20 ##src/sctp/sctpserv02.c## + /* end modified_sctpserv02 */## 21 ##src/sctp/sctpserv02.c## + bzero(&servaddr, sizeof(servaddr));## 22 ##src/sctp/sctpserv02.c## + servaddr.sin_family = AF_INET;## 23 ##src/sctp/sctpserv02.c## +#ifdef HAVE_SOCKADDR_SA_LEN## 24 ##src/sctp/sctpserv02.c## + servaddr.sin_len = sizeof(servaddr);## 25 ##src/sctp/sctpserv02.c## +#endif## 26 ##src/sctp/sctpserv02.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 27 ##src/sctp/sctpserv02.c## + servaddr.sin_port = htons(SERV_PORT);## 28 ##src/sctp/sctpserv02.c## + + Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));## 29 ##src/sctp/sctpserv02.c## + + bzero(&evnts, sizeof(evnts));## 30 ##src/sctp/sctpserv02.c## + evnts.sctp_data_io_event = 1;## 31 ##src/sctp/sctpserv02.c## + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 32 ##src/sctp/sctpserv02.c## + + Listen(sock_fd, LISTENQ);## 33 ##src/sctp/sctpserv02.c## + for (;;) {## 34 ##src/sctp/sctpserv02.c## + len = sizeof(struct sockaddr_in);## 35 ##src/sctp/sctpserv02.c## + rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),## 36 ##src/sctp/sctpserv02.c## + (SA *) &cliaddr, &len, &sri, &msg_flags);## 37 ##src/sctp/sctpserv02.c## + if (stream_increment) {## 38 ##src/sctp/sctpserv02.c## + sri.sinfo_stream++;## 39 ##src/sctp/sctpserv02.c## + if (sri.sinfo_stream >=## 40 ##src/sctp/sctpserv02.c## + sctp_get_no_strms(sock_fd, (SA *) &cliaddr, len))## 41 ##src/sctp/sctpserv02.c## + sri.sinfo_stream = 0;## 42 ##src/sctp/sctpserv02.c## + }## 43 ##src/sctp/sctpserv02.c## + Sctp_sendmsg(sock_fd, readbuf, rd_sz,## 44 ##src/sctp/sctpserv02.c## + (SA *) &cliaddr, len,## 45 ##src/sctp/sctpserv02.c## + sri.sinfo_ppid,## 46 ##src/sctp/sctpserv02.c## + sri.sinfo_flags, sri.sinfo_stream, 0, 0);## 47 ##src/sctp/sctpserv02.c## + }## 48 ##src/sctp/sctpserv02.c## +}## 49 ##src/sctp/sctpserv02.c## diff --git a/sctp/sctpserv03.c b/sctp/sctpserv03.c new file mode 100644 index 0000000..f799af4 --- /dev/null +++ b/sctp/sctpserv03.c @@ -0,0 +1,50 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sock_fd,msg_flags; + char readbuf[BUFFSIZE]; + struct sockaddr_in servaddr, cliaddr; + struct sctp_sndrcvinfo sri; + struct sctp_event_subscribe evnts; + int stream_increment=1; + socklen_t len; + size_t rd_sz; + + if (argc == 2) + stream_increment = atoi(argv[1]); + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr)); + + bzero(&evnts, sizeof(evnts)); + evnts.sctp_data_io_event = 1; + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, + &evnts, sizeof(evnts)); + + Listen(sock_fd, LISTENQ); +/* include modified_sctpserv03 */ + for ( ; ; ) { + len = sizeof(struct sockaddr_in); + rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf), + (SA *)&cliaddr, &len, + &sri,&msg_flags); + if(stream_increment) { + sri.sinfo_stream++; + if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd,(SA *)&cliaddr, len)) + sri.sinfo_stream = 0; + } + Sctp_sendmsg(sock_fd, readbuf, rd_sz, + (SA *)&cliaddr, len, + sri.sinfo_ppid, + (sri.sinfo_flags|MSG_EOF), + sri.sinfo_stream, + 0, 0); + } +/* end modified_sctpserv03 */ +} diff --git a/sctp/sctpserv03.lc b/sctp/sctpserv03.lc new file mode 100644 index 0000000..e791db1 --- /dev/null +++ b/sctp/sctpserv03.lc @@ -0,0 +1,50 @@ +#include "unp.h"## 1 ##src/sctp/sctpserv03.c## + +int## 2 ##src/sctp/sctpserv03.c## +main(int argc, char **argv)## 3 ##src/sctp/sctpserv03.c## +{## 4 ##src/sctp/sctpserv03.c## + int sock_fd, msg_flags;## 5 ##src/sctp/sctpserv03.c## + char readbuf[BUFFSIZE];## 6 ##src/sctp/sctpserv03.c## + struct sockaddr_in servaddr, cliaddr;## 7 ##src/sctp/sctpserv03.c## + struct sctp_sndrcvinfo sri;## 8 ##src/sctp/sctpserv03.c## + struct sctp_event_subscribe evnts;## 9 ##src/sctp/sctpserv03.c## + int stream_increment = 1;## 10 ##src/sctp/sctpserv03.c## + socklen_t len;## 11 ##src/sctp/sctpserv03.c## + size_t rd_sz;## 12 ##src/sctp/sctpserv03.c## + + if (argc == 2)## 13 ##src/sctp/sctpserv03.c## + stream_increment = atoi(argv[1]);## 14 ##src/sctp/sctpserv03.c## + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 15 ##src/sctp/sctpserv03.c## + bzero(&servaddr, sizeof(servaddr));## 16 ##src/sctp/sctpserv03.c## + servaddr.sin_family = AF_INET;## 17 ##src/sctp/sctpserv03.c## +#ifdef HAVE_SOCKADDR_SA_LEN## 18 ##src/sctp/sctpserv03.c## + servaddr.sin_len = sizeof(servaddr);## 19 ##src/sctp/sctpserv03.c## +#endif## 20 ##src/sctp/sctpserv03.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 21 ##src/sctp/sctpserv03.c## + servaddr.sin_port = htons(SERV_PORT);## 22 ##src/sctp/sctpserv03.c## + + Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));## 23 ##src/sctp/sctpserv03.c## + + bzero(&evnts, sizeof(evnts));## 24 ##src/sctp/sctpserv03.c## + evnts.sctp_data_io_event = 1;## 25 ##src/sctp/sctpserv03.c## + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 26 ##src/sctp/sctpserv03.c## + + Listen(sock_fd, LISTENQ);## 27 ##src/sctp/sctpserv03.c## + /* include modified_sctpserv03 */## 28 ##src/sctp/sctpserv03.c## + for (;;) {## 29 ##src/sctp/sctpserv03.c## + len = sizeof(struct sockaddr_in);## 30 ##src/sctp/sctpserv03.c## + rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),## 31 ##src/sctp/sctpserv03.c## + (SA *) &cliaddr, &len, &sri, &msg_flags);## 32 ##src/sctp/sctpserv03.c## + if (stream_increment) {## 33 ##src/sctp/sctpserv03.c## + sri.sinfo_stream++;## 34 ##src/sctp/sctpserv03.c## + if (sri.sinfo_stream >=## 35 ##src/sctp/sctpserv03.c## + sctp_get_no_strms(sock_fd, (SA *) &cliaddr, len))## 36 ##src/sctp/sctpserv03.c## + sri.sinfo_stream = 0;## 37 ##src/sctp/sctpserv03.c## + }## 38 ##src/sctp/sctpserv03.c## + Sctp_sendmsg(sock_fd, readbuf, rd_sz,## 39 ##src/sctp/sctpserv03.c## + (SA *) &cliaddr, len,## 40 ##src/sctp/sctpserv03.c## + sri.sinfo_ppid,## 41 ##src/sctp/sctpserv03.c## + (sri.sinfo_flags | MSG_EOF), sri.sinfo_stream, 0, 0);## 42 ##src/sctp/sctpserv03.c## + }## 43 ##src/sctp/sctpserv03.c## + /* end modified_sctpserv03 */## 44 ##src/sctp/sctpserv03.c## +}## 45 ##src/sctp/sctpserv03.c## diff --git a/sctp/sctpserv04.c b/sctp/sctpserv04.c new file mode 100644 index 0000000..0439595 --- /dev/null +++ b/sctp/sctpserv04.c @@ -0,0 +1,54 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sock_fd,msg_flags; + char readbuf[BUFFSIZE]; + struct sockaddr_in servaddr, cliaddr; + struct sctp_sndrcvinfo sri; + struct sctp_event_subscribe evnts; + int stream_increment=1; + int close_time; + socklen_t len; + size_t rd_sz; + +/* include mod_serv04 */ + if (argc == 2) + stream_increment = atoi(argv[1]); + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + close_time = 120; + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_AUTOCLOSE, + &close_time, sizeof(close_time)); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); +/* end mod_serv04 */ + Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr)); + + bzero(&evnts, sizeof(evnts)); + evnts.sctp_data_io_event = 1; + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, + &evnts, sizeof(evnts)); + + Listen(sock_fd, LISTENQ); + for ( ; ; ) { + len = sizeof(struct sockaddr_in); + rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf), + (SA *)&cliaddr, &len, + &sri,&msg_flags); + if(stream_increment) { + sri.sinfo_stream++; + if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd,(SA *)&cliaddr, len)) + sri.sinfo_stream = 0; + } + Sctp_sendmsg(sock_fd, readbuf, rd_sz, + (SA *)&cliaddr, len, + sri.sinfo_ppid, + sri.sinfo_flags, + sri.sinfo_stream, + 0, 0); + } +} diff --git a/sctp/sctpserv04.lc b/sctp/sctpserv04.lc new file mode 100644 index 0000000..72a5359 --- /dev/null +++ b/sctp/sctpserv04.lc @@ -0,0 +1,54 @@ +#include "unp.h"## 1 ##src/sctp/sctpserv04.c## + +int## 2 ##src/sctp/sctpserv04.c## +main(int argc, char **argv)## 3 ##src/sctp/sctpserv04.c## +{## 4 ##src/sctp/sctpserv04.c## + int sock_fd, msg_flags;## 5 ##src/sctp/sctpserv04.c## + char readbuf[BUFFSIZE];## 6 ##src/sctp/sctpserv04.c## + struct sockaddr_in servaddr, cliaddr;## 7 ##src/sctp/sctpserv04.c## + struct sctp_sndrcvinfo sri;## 8 ##src/sctp/sctpserv04.c## + struct sctp_event_subscribe evnts;## 9 ##src/sctp/sctpserv04.c## + int stream_increment = 1;## 10 ##src/sctp/sctpserv04.c## + int close_time;## 11 ##src/sctp/sctpserv04.c## + socklen_t len;## 12 ##src/sctp/sctpserv04.c## + size_t rd_sz;## 13 ##src/sctp/sctpserv04.c## + + /* include mod_serv04 */## 14 ##src/sctp/sctpserv04.c## + if (argc == 2)## 15 ##src/sctp/sctpserv04.c## + stream_increment = atoi(argv[1]);## 16 ##src/sctp/sctpserv04.c## + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 17 ##src/sctp/sctpserv04.c## + close_time = 120;## 18 ##src/sctp/sctpserv04.c## + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_AUTOCLOSE,## 19 ##src/sctp/sctpserv04.c## + &close_time, sizeof(close_time));## 20 ##src/sctp/sctpserv04.c## + + bzero(&servaddr, sizeof(servaddr));## 21 ##src/sctp/sctpserv04.c## + servaddr.sin_family = AF_INET;## 22 ##src/sctp/sctpserv04.c## +#ifdef HAVE_SOCKADDR_SA_LEN## 23 ##src/sctp/sctpserv04.c## + servaddr.sin_len = sizeof(servaddr);## 24 ##src/sctp/sctpserv04.c## +#endif## 25 ##src/sctp/sctpserv04.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 26 ##src/sctp/sctpserv04.c## + servaddr.sin_port = htons(SERV_PORT);## 27 ##src/sctp/sctpserv04.c## + /* end mod_serv04 */## 28 ##src/sctp/sctpserv04.c## + Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));## 29 ##src/sctp/sctpserv04.c## + + bzero(&evnts, sizeof(evnts));## 30 ##src/sctp/sctpserv04.c## + evnts.sctp_data_io_event = 1;## 31 ##src/sctp/sctpserv04.c## + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 32 ##src/sctp/sctpserv04.c## + + Listen(sock_fd, LISTENQ);## 33 ##src/sctp/sctpserv04.c## + for (;;) {## 34 ##src/sctp/sctpserv04.c## + len = sizeof(struct sockaddr_in);## 35 ##src/sctp/sctpserv04.c## + rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),## 36 ##src/sctp/sctpserv04.c## + (SA *) &cliaddr, &len, &sri, &msg_flags);## 37 ##src/sctp/sctpserv04.c## + if (stream_increment) {## 38 ##src/sctp/sctpserv04.c## + sri.sinfo_stream++;## 39 ##src/sctp/sctpserv04.c## + if (sri.sinfo_stream >=## 40 ##src/sctp/sctpserv04.c## + sctp_get_no_strms(sock_fd, (SA *) &cliaddr, len))## 41 ##src/sctp/sctpserv04.c## + sri.sinfo_stream = 0;## 42 ##src/sctp/sctpserv04.c## + }## 43 ##src/sctp/sctpserv04.c## + Sctp_sendmsg(sock_fd, readbuf, rd_sz,## 44 ##src/sctp/sctpserv04.c## + (SA *) &cliaddr, len,## 45 ##src/sctp/sctpserv04.c## + sri.sinfo_ppid,## 46 ##src/sctp/sctpserv04.c## + sri.sinfo_flags, sri.sinfo_stream, 0, 0);## 47 ##src/sctp/sctpserv04.c## + }## 48 ##src/sctp/sctpserv04.c## +}## 49 ##src/sctp/sctpserv04.c## diff --git a/sctp/sctpserv05.c b/sctp/sctpserv05.c new file mode 100644 index 0000000..9ad38b2 --- /dev/null +++ b/sctp/sctpserv05.c @@ -0,0 +1,54 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + uint8_t *readbuf; + int sock_fd,msg_flags; + struct sockaddr_in servaddr, cliaddr; + struct sctp_sndrcvinfo sri; + struct sctp_event_subscribe evnts; + int stream_increment=1; + socklen_t len; + size_t rd_sz; + + if (argc == 2) + stream_increment = atoi(argv[1]); + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr)); + + bzero(&evnts, sizeof(evnts)); + evnts.sctp_data_io_event = 1; + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, + &evnts, sizeof(evnts)); + + Listen(sock_fd, LISTENQ); + rd_sz = 0; +/* include mod_serv05 */ + for ( ; ; ) { + len = sizeof(struct sockaddr_in); + bzero(&sri,sizeof(sri)); + readbuf = pdapi_recvmsg(sock_fd, &rd_sz, + (SA *)&cliaddr, &len, + &sri,&msg_flags); + if(readbuf == NULL) + continue; +/* end mod_serv05 */ + if(stream_increment) { + sri.sinfo_stream++; + if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd,(SA *)&cliaddr, len)) + sri.sinfo_stream = 0; + } + Sctp_sendmsg(sock_fd, readbuf, rd_sz, + (SA *)&cliaddr, len, + sri.sinfo_ppid, + sri.sinfo_flags, + sri.sinfo_stream, + 0, 0); + } +} diff --git a/sctp/sctpserv05.lc b/sctp/sctpserv05.lc new file mode 100644 index 0000000..e68f6fb --- /dev/null +++ b/sctp/sctpserv05.lc @@ -0,0 +1,54 @@ +#include "unp.h"## 1 ##src/sctp/sctpserv05.c## + +int## 2 ##src/sctp/sctpserv05.c## +main(int argc, char **argv)## 3 ##src/sctp/sctpserv05.c## +{## 4 ##src/sctp/sctpserv05.c## + uint8_t *readbuf;## 5 ##src/sctp/sctpserv05.c## + int sock_fd, msg_flags;## 6 ##src/sctp/sctpserv05.c## + struct sockaddr_in servaddr, cliaddr;## 7 ##src/sctp/sctpserv05.c## + struct sctp_sndrcvinfo sri;## 8 ##src/sctp/sctpserv05.c## + struct sctp_event_subscribe evnts;## 9 ##src/sctp/sctpserv05.c## + int stream_increment = 1;## 10 ##src/sctp/sctpserv05.c## + socklen_t len;## 11 ##src/sctp/sctpserv05.c## + size_t rd_sz;## 12 ##src/sctp/sctpserv05.c## + + if (argc == 2)## 13 ##src/sctp/sctpserv05.c## + stream_increment = atoi(argv[1]);## 14 ##src/sctp/sctpserv05.c## + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 15 ##src/sctp/sctpserv05.c## + bzero(&servaddr, sizeof(servaddr));## 16 ##src/sctp/sctpserv05.c## + servaddr.sin_family = AF_INET;## 17 ##src/sctp/sctpserv05.c## +#ifdef HAVE_SOCKADDR_SA_LEN## 18 ##src/sctp/sctpserv05.c## + servaddr.sin_len = sizeof(servaddr);## 19 ##src/sctp/sctpserv05.c## +#endif## 20 ##src/sctp/sctpserv05.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 21 ##src/sctp/sctpserv05.c## + servaddr.sin_port = htons(SERV_PORT);## 22 ##src/sctp/sctpserv05.c## + + Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));## 23 ##src/sctp/sctpserv05.c## + + bzero(&evnts, sizeof(evnts));## 24 ##src/sctp/sctpserv05.c## + evnts.sctp_data_io_event = 1;## 25 ##src/sctp/sctpserv05.c## + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 26 ##src/sctp/sctpserv05.c## + + Listen(sock_fd, LISTENQ);## 27 ##src/sctp/sctpserv05.c## + rd_sz = 0;## 28 ##src/sctp/sctpserv05.c## + /* include mod_serv05 */## 29 ##src/sctp/sctpserv05.c## + for (;;) {## 30 ##src/sctp/sctpserv05.c## + len = sizeof(struct sockaddr_in);## 31 ##src/sctp/sctpserv05.c## + bzero(&sri, sizeof(sri));## 32 ##src/sctp/sctpserv05.c## + readbuf = pdapi_recvmsg(sock_fd, &rd_sz,## 33 ##src/sctp/sctpserv05.c## + (SA *) &cliaddr, &len, &sri, &msg_flags);## 34 ##src/sctp/sctpserv05.c## + if (readbuf == NULL)## 35 ##src/sctp/sctpserv05.c## + continue;## 36 ##src/sctp/sctpserv05.c## + /* end mod_serv05 */## 37 ##src/sctp/sctpserv05.c## + if (stream_increment) {## 38 ##src/sctp/sctpserv05.c## + sri.sinfo_stream++;## 39 ##src/sctp/sctpserv05.c## + if (sri.sinfo_stream >=## 40 ##src/sctp/sctpserv05.c## + sctp_get_no_strms(sock_fd, (SA *) &cliaddr, len))## 41 ##src/sctp/sctpserv05.c## + sri.sinfo_stream = 0;## 42 ##src/sctp/sctpserv05.c## + }## 43 ##src/sctp/sctpserv05.c## + Sctp_sendmsg(sock_fd, readbuf, rd_sz,## 44 ##src/sctp/sctpserv05.c## + (SA *) &cliaddr, len,## 45 ##src/sctp/sctpserv05.c## + sri.sinfo_ppid,## 46 ##src/sctp/sctpserv05.c## + sri.sinfo_flags, sri.sinfo_stream, 0, 0);## 47 ##src/sctp/sctpserv05.c## + }## 48 ##src/sctp/sctpserv05.c## +}## 49 ##src/sctp/sctpserv05.c## diff --git a/sctp/sctpserv06.c b/sctp/sctpserv06.c new file mode 100644 index 0000000..6fe2660 --- /dev/null +++ b/sctp/sctpserv06.c @@ -0,0 +1,61 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sock_fd,msg_flags; + char readbuf[BUFFSIZE]; + struct sockaddr_in servaddr, cliaddr; + struct sctp_sndrcvinfo sri; + struct sctp_event_subscribe evnts; + int stream_increment=1; + socklen_t len; + size_t rd_sz; + + if (argc == 2) + stream_increment = atoi(argv[1]); + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr)); + +/* include mod_serv06 */ + bzero(&evnts, sizeof(evnts)); + evnts.sctp_data_io_event = 1; + evnts.sctp_association_event = 1; + evnts.sctp_address_event = 1; + evnts.sctp_send_failure_event = 1; + evnts.sctp_peer_error_event = 1; + evnts.sctp_shutdown_event = 1; + evnts.sctp_partial_delivery_event = 1; + evnts.sctp_adaption_layer_event = 1; + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, + &evnts, sizeof(evnts)); + + Listen(sock_fd, LISTENQ); + for ( ; ; ) { + len = sizeof(struct sockaddr_in); + rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf), + (SA *)&cliaddr, &len, + &sri,&msg_flags); + if(msg_flags & MSG_NOTIFICATION) { + print_notification(readbuf); + continue; + } +/* end mod_serv06 */ + if(stream_increment) { + sri.sinfo_stream++; + if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd,(SA *)&cliaddr, len)) + sri.sinfo_stream = 0; + } + Sctp_sendmsg(sock_fd, readbuf, rd_sz, + (SA *)&cliaddr, len, + sri.sinfo_ppid, + sri.sinfo_flags, + sri.sinfo_stream, + 0, 0); + } +} diff --git a/sctp/sctpserv06.lc b/sctp/sctpserv06.lc new file mode 100644 index 0000000..c0ec200 --- /dev/null +++ b/sctp/sctpserv06.lc @@ -0,0 +1,61 @@ +#include "unp.h"## 1 ##src/sctp/sctpserv06.c## + +int## 2 ##src/sctp/sctpserv06.c## +main(int argc, char **argv)## 3 ##src/sctp/sctpserv06.c## +{## 4 ##src/sctp/sctpserv06.c## + int sock_fd, msg_flags;## 5 ##src/sctp/sctpserv06.c## + char readbuf[BUFFSIZE];## 6 ##src/sctp/sctpserv06.c## + struct sockaddr_in servaddr, cliaddr;## 7 ##src/sctp/sctpserv06.c## + struct sctp_sndrcvinfo sri;## 8 ##src/sctp/sctpserv06.c## + struct sctp_event_subscribe evnts;## 9 ##src/sctp/sctpserv06.c## + int stream_increment = 1;## 10 ##src/sctp/sctpserv06.c## + socklen_t len;## 11 ##src/sctp/sctpserv06.c## + size_t rd_sz;## 12 ##src/sctp/sctpserv06.c## + + if (argc == 2)## 13 ##src/sctp/sctpserv06.c## + stream_increment = atoi(argv[1]);## 14 ##src/sctp/sctpserv06.c## + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 15 ##src/sctp/sctpserv06.c## + bzero(&servaddr, sizeof(servaddr));## 16 ##src/sctp/sctpserv06.c## + servaddr.sin_family = AF_INET;## 17 ##src/sctp/sctpserv06.c## +#ifdef HAVE_SOCKADDR_SA_LEN## 18 ##src/sctp/sctpserv06.c## + servaddr.sin_len = sizeof(servaddr);## 19 ##src/sctp/sctpserv06.c## +#endif## 20 ##src/sctp/sctpserv06.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 21 ##src/sctp/sctpserv06.c## + servaddr.sin_port = htons(SERV_PORT);## 22 ##src/sctp/sctpserv06.c## + + Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));## 23 ##src/sctp/sctpserv06.c## + + /* include mod_serv06 */## 24 ##src/sctp/sctpserv06.c## + bzero(&evnts, sizeof(evnts));## 25 ##src/sctp/sctpserv06.c## + evnts.sctp_data_io_event = 1;## 26 ##src/sctp/sctpserv06.c## + evnts.sctp_association_event = 1;## 27 ##src/sctp/sctpserv06.c## + evnts.sctp_address_event = 1;## 28 ##src/sctp/sctpserv06.c## + evnts.sctp_send_failure_event = 1;## 29 ##src/sctp/sctpserv06.c## + evnts.sctp_peer_error_event = 1;## 30 ##src/sctp/sctpserv06.c## + evnts.sctp_shutdown_event = 1;## 31 ##src/sctp/sctpserv06.c## + evnts.sctp_partial_delivery_event = 1;## 32 ##src/sctp/sctpserv06.c## + evnts.sctp_adaption_layer_event = 1;## 33 ##src/sctp/sctpserv06.c## + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 34 ##src/sctp/sctpserv06.c## + + Listen(sock_fd, LISTENQ);## 35 ##src/sctp/sctpserv06.c## + for (;;) {## 36 ##src/sctp/sctpserv06.c## + len = sizeof(struct sockaddr_in);## 37 ##src/sctp/sctpserv06.c## + rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),## 38 ##src/sctp/sctpserv06.c## + (SA *) &cliaddr, &len, &sri, &msg_flags);## 39 ##src/sctp/sctpserv06.c## + if (msg_flags & MSG_NOTIFICATION) {## 40 ##src/sctp/sctpserv06.c## + print_notification(readbuf);## 41 ##src/sctp/sctpserv06.c## + continue;## 42 ##src/sctp/sctpserv06.c## + }## 43 ##src/sctp/sctpserv06.c## + /* end mod_serv06 */## 44 ##src/sctp/sctpserv06.c## + if (stream_increment) {## 45 ##src/sctp/sctpserv06.c## + sri.sinfo_stream++;## 46 ##src/sctp/sctpserv06.c## + if (sri.sinfo_stream >=## 47 ##src/sctp/sctpserv06.c## + sctp_get_no_strms(sock_fd, (SA *) &cliaddr, len))## 48 ##src/sctp/sctpserv06.c## + sri.sinfo_stream = 0;## 49 ##src/sctp/sctpserv06.c## + }## 50 ##src/sctp/sctpserv06.c## + Sctp_sendmsg(sock_fd, readbuf, rd_sz,## 51 ##src/sctp/sctpserv06.c## + (SA *) &cliaddr, len,## 52 ##src/sctp/sctpserv06.c## + sri.sinfo_ppid,## 53 ##src/sctp/sctpserv06.c## + sri.sinfo_flags, sri.sinfo_stream, 0, 0);## 54 ##src/sctp/sctpserv06.c## + }## 55 ##src/sctp/sctpserv06.c## +}## 56 ##src/sctp/sctpserv06.c## diff --git a/sctp/sctpserv07.c b/sctp/sctpserv07.c new file mode 100644 index 0000000..f8bcb69 --- /dev/null +++ b/sctp/sctpserv07.c @@ -0,0 +1,54 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sock_fd,msg_flags; + char readbuf[BUFFSIZE]; + struct sockaddr_in cliaddr; + struct sctp_sndrcvinfo sri; + struct sctp_event_subscribe evnts; + socklen_t len; + size_t rd_sz; +/* include mod_serv07 */ + if(argc < 2) + err_quit("Error, use %s [list of addresses to bind]\n", + argv[0]); + sock_fd = Socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP); + + if(sctp_bind_arg_list(sock_fd, argv + 1, argc - 1)) + err_sys("Can't bind the address set"); + + bzero(&evnts, sizeof(evnts)); + evnts.sctp_data_io_event = 1; +/* end mod_serv07 */ + evnts.sctp_association_event = 1; + evnts.sctp_address_event = 1; + evnts.sctp_send_failure_event = 1; + evnts.sctp_peer_error_event = 1; + evnts.sctp_shutdown_event = 1; + evnts.sctp_partial_delivery_event = 1; + evnts.sctp_adaption_layer_event = 1; + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, + &evnts, sizeof(evnts)); + + Listen(sock_fd, LISTENQ); + + for ( ; ; ) { + len = sizeof(struct sockaddr_in); + rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf), + (SA *)&cliaddr, &len, + &sri,&msg_flags); + if(msg_flags & MSG_NOTIFICATION) { + print_notification(readbuf); + continue; + } + Sctp_sendmsg(sock_fd, readbuf, rd_sz, + (SA *)&cliaddr, len, + sri.sinfo_ppid, + sri.sinfo_flags, + sri.sinfo_stream, + 0, 0); + } + +} diff --git a/sctp/sctpserv07.lc b/sctp/sctpserv07.lc new file mode 100644 index 0000000..d636fa9 --- /dev/null +++ b/sctp/sctpserv07.lc @@ -0,0 +1,48 @@ + +int## 1 ##src/sctp/sctpserv07.c## +main(int argc, char **argv)## 2 ##src/sctp/sctpserv07.c## +{## 3 ##src/sctp/sctpserv07.c## + int sock_fd, msg_flags;## 4 ##src/sctp/sctpserv07.c## + char readbuf[BUFFSIZE];## 5 ##src/sctp/sctpserv07.c## + struct sockaddr_in cliaddr;## 6 ##src/sctp/sctpserv07.c## + struct sctp_sndrcvinfo sri;## 7 ##src/sctp/sctpserv07.c## + struct sctp_event_subscribe evnts;## 8 ##src/sctp/sctpserv07.c## + socklen_t len;## 9 ##src/sctp/sctpserv07.c## + size_t rd_sz;## 10 ##src/sctp/sctpserv07.c## + /* include mod_serv07 */## 11 ##src/sctp/sctpserv07.c## + if (argc < 2)## 12 ##src/sctp/sctpserv07.c## + err_quit("Error, use %s [list of addresses to bind]\n", argv[0]);## 13 ##src/sctp/sctpserv07.c## + sock_fd = Socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP);## 14 ##src/sctp/sctpserv07.c## + + if (sctp_bind_arg_list(sock_fd, argv + 1, argc - 1))## 15 ##src/sctp/sctpserv07.c## + err_sys("Can't bind the address set");## 16 ##src/sctp/sctpserv07.c## + + bzero(&evnts, sizeof(evnts));## 17 ##src/sctp/sctpserv07.c## + evnts.sctp_data_io_event = 1;## 18 ##src/sctp/sctpserv07.c## + /* end mod_serv07 */## 19 ##src/sctp/sctpserv07.c## + evnts.sctp_association_event = 1;## 20 ##src/sctp/sctpserv07.c## + evnts.sctp_address_event = 1;## 21 ##src/sctp/sctpserv07.c## + evnts.sctp_send_failure_event = 1;## 22 ##src/sctp/sctpserv07.c## + evnts.sctp_peer_error_event = 1;## 23 ##src/sctp/sctpserv07.c## + evnts.sctp_shutdown_event = 1;## 24 ##src/sctp/sctpserv07.c## + evnts.sctp_partial_delivery_event = 1;## 25 ##src/sctp/sctpserv07.c## + evnts.sctp_adaption_layer_event = 1;## 26 ##src/sctp/sctpserv07.c## + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 27 ##src/sctp/sctpserv07.c## + + Listen(sock_fd, LISTENQ);## 28 ##src/sctp/sctpserv07.c## + + for (;;) {## 29 ##src/sctp/sctpserv07.c## + len = sizeof(struct sockaddr_in);## 30 ##src/sctp/sctpserv07.c## + rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),## 31 ##src/sctp/sctpserv07.c## + (SA *) &cliaddr, &len, &sri, &msg_flags);## 32 ##src/sctp/sctpserv07.c## + if (msg_flags & MSG_NOTIFICATION) {## 33 ##src/sctp/sctpserv07.c## + print_notification(readbuf);## 34 ##src/sctp/sctpserv07.c## + continue;## 35 ##src/sctp/sctpserv07.c## + }## 36 ##src/sctp/sctpserv07.c## + Sctp_sendmsg(sock_fd, readbuf, rd_sz,## 37 ##src/sctp/sctpserv07.c## + (SA *) &cliaddr, len,## 38 ##src/sctp/sctpserv07.c## + sri.sinfo_ppid,## 39 ##src/sctp/sctpserv07.c## + sri.sinfo_flags, sri.sinfo_stream, 0, 0);## 40 ##src/sctp/sctpserv07.c## + }## 41 ##src/sctp/sctpserv07.c## + +}## 42 ##src/sctp/sctpserv07.c## diff --git a/sctp/sctpserv_fork.c b/sctp/sctpserv_fork.c new file mode 100644 index 0000000..58e4b19 --- /dev/null +++ b/sctp/sctpserv_fork.c @@ -0,0 +1,60 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sock_fd,msg_flags,connfd,childpid; + sctp_assoc_t assoc; + char readbuf[BUFFSIZE]; + struct sockaddr_in servaddr, cliaddr; + struct sctp_sndrcvinfo sri; + struct sctp_event_subscribe evnts; + socklen_t len; + size_t rd_sz; + + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr)); + + bzero(&evnts, sizeof(evnts)); + evnts.sctp_data_io_event = 1; + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, + &evnts, sizeof(evnts)); + + Listen(sock_fd, LISTENQ); +/* include mod_servfork */ + for ( ; ; ) { + len = sizeof(struct sockaddr_in); + rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf), + (SA *)&cliaddr, &len, + &sri,&msg_flags); + Sctp_sendmsg(sock_fd, readbuf, rd_sz, + (SA *)&cliaddr, len, + sri.sinfo_ppid, + sri.sinfo_flags, + sri.sinfo_stream, + 0, 0); + assoc = sctp_address_to_associd(sock_fd,(SA *)&cliaddr,len); + if((int)assoc == 0){ + err_ret("Can't get association id"); + continue; + } + connfd = sctp_peeloff(sock_fd,assoc); + if(connfd == -1){ + err_ret("sctp_peeloff fails"); + continue; + } + if((childpid = fork()) == 0) { + Close(sock_fd); + str_echo(connfd); + exit(0); + } else { + Close(connfd); + } + } +/* end mod_servfork */ +} diff --git a/sctp/sctpserv_fork.lc b/sctp/sctpserv_fork.lc new file mode 100644 index 0000000..0594b6e --- /dev/null +++ b/sctp/sctpserv_fork.lc @@ -0,0 +1,59 @@ +#include "unp.h"## 1 ##src/sctp/sctpserv_fork.c## + +int## 2 ##src/sctp/sctpserv_fork.c## +main(int argc, char **argv)## 3 ##src/sctp/sctpserv_fork.c## +{## 4 ##src/sctp/sctpserv_fork.c## + int sock_fd, msg_flags, connfd, childpid;## 5 ##src/sctp/sctpserv_fork.c## + sctp_assoc_t assoc;## 6 ##src/sctp/sctpserv_fork.c## + char readbuf[BUFFSIZE];## 7 ##src/sctp/sctpserv_fork.c## + struct sockaddr_in servaddr, cliaddr;## 8 ##src/sctp/sctpserv_fork.c## + struct sctp_sndrcvinfo sri;## 9 ##src/sctp/sctpserv_fork.c## + struct sctp_event_subscribe evnts;## 10 ##src/sctp/sctpserv_fork.c## + socklen_t len;## 11 ##src/sctp/sctpserv_fork.c## + size_t rd_sz;## 12 ##src/sctp/sctpserv_fork.c## + + sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 13 ##src/sctp/sctpserv_fork.c## + bzero(&servaddr, sizeof(servaddr));## 14 ##src/sctp/sctpserv_fork.c## + servaddr.sin_family = AF_INET;## 15 ##src/sctp/sctpserv_fork.c## +#ifdef HAVE_SOCKADDR_SA_LEN## 16 ##src/sctp/sctpserv_fork.c## + servaddr.sin_len = sizeof(servaddr);## 17 ##src/sctp/sctpserv_fork.c## +#endif## 18 ##src/sctp/sctpserv_fork.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 19 ##src/sctp/sctpserv_fork.c## + servaddr.sin_port = htons(SERV_PORT);## 20 ##src/sctp/sctpserv_fork.c## + + Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));## 21 ##src/sctp/sctpserv_fork.c## + + bzero(&evnts, sizeof(evnts));## 22 ##src/sctp/sctpserv_fork.c## + evnts.sctp_data_io_event = 1;## 23 ##src/sctp/sctpserv_fork.c## + Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 24 ##src/sctp/sctpserv_fork.c## + + Listen(sock_fd, LISTENQ);## 25 ##src/sctp/sctpserv_fork.c## + /* include mod_servfork */## 26 ##src/sctp/sctpserv_fork.c## + for (;;) {## 27 ##src/sctp/sctpserv_fork.c## + len = sizeof(struct sockaddr_in);## 28 ##src/sctp/sctpserv_fork.c## + rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),## 29 ##src/sctp/sctpserv_fork.c## + (SA *) &cliaddr, &len, &sri, &msg_flags);## 30 ##src/sctp/sctpserv_fork.c## + Sctp_sendmsg(sock_fd, readbuf, rd_sz,## 31 ##src/sctp/sctpserv_fork.c## + (SA *) &cliaddr, len,## 32 ##src/sctp/sctpserv_fork.c## + sri.sinfo_ppid,## 33 ##src/sctp/sctpserv_fork.c## + sri.sinfo_flags, sri.sinfo_stream, 0, 0);## 34 ##src/sctp/sctpserv_fork.c## + assoc = sctp_address_to_associd(sock_fd, (SA *) &cliaddr, len);## 35 ##src/sctp/sctpserv_fork.c## + if ((int) assoc == 0) {## 36 ##src/sctp/sctpserv_fork.c## + err_ret("Can't get association id");## 37 ##src/sctp/sctpserv_fork.c## + continue;## 38 ##src/sctp/sctpserv_fork.c## + }## 39 ##src/sctp/sctpserv_fork.c## + connfd = sctp_peeloff(sock_fd, assoc);## 40 ##src/sctp/sctpserv_fork.c## + if (connfd == -1) {## 41 ##src/sctp/sctpserv_fork.c## + err_ret("sctp_peeloff fails");## 42 ##src/sctp/sctpserv_fork.c## + continue;## 43 ##src/sctp/sctpserv_fork.c## + }## 44 ##src/sctp/sctpserv_fork.c## + if ((childpid = fork()) == 0) {## 45 ##src/sctp/sctpserv_fork.c## + Close(sock_fd);## 46 ##src/sctp/sctpserv_fork.c## + str_echo(connfd);## 47 ##src/sctp/sctpserv_fork.c## + exit(0);## 48 ##src/sctp/sctpserv_fork.c## + } else {## 49 ##src/sctp/sctpserv_fork.c## + Close(connfd);## 50 ##src/sctp/sctpserv_fork.c## + }## 51 ##src/sctp/sctpserv_fork.c## + }## 52 ##src/sctp/sctpserv_fork.c## + /* end mod_servfork */## 53 ##src/sctp/sctpserv_fork.c## +}## 54 ##src/sctp/sctpserv_fork.c## diff --git a/sctp/unp.h b/sctp/unp.h new file mode 100644 index 0000000..0e8a9cc --- /dev/null +++ b/sctp/unp.h @@ -0,0 +1,471 @@ +/* include unph */ +/* Our own header. Tabs are set for 4 spaces, not 8 */ + +#ifndef __unp_h +#define __unp_h + +#include "../config.h" /* configuration options for current OS */ + /* "../config.h" is generated by configure */ + +/* If anything changes in the following list of #includes, must change + acsite.m4 also, for configure's tests. */ + +#include /* basic system data types */ +#include /* basic socket definitions */ +#include /* timeval{} for select() */ +#include /* timespec{} for pselect() */ +#include /* sockaddr_in{} and other Internet defns */ +#include /* inet(3) functions */ +#include /* note if sctp does not exist we blow up :> */ +#include +#include /* for nonblocking */ +#include +#include +#include +#include +#include +#include /* for S_xxx file mode constants */ +#include /* for iovec{} and readv/writev */ +#include +#include +#include /* for Unix domain sockets */ + +#ifdef HAVE_SYS_SELECT_H +# include /* for convenience */ +#endif + +#ifdef HAVE_POLL_H +# include /* for convenience */ +#endif + +#ifdef HAVE_STRINGS_H +# include /* for convenience */ +#endif + +/* Three headers are normally needed for socket/file ioctl's: + * , , and . + */ +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_FILIO_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif + +#ifdef HAVE_PTHREAD_H +# include +#endif + +/* OSF/1 actually disables recv() and send() in */ +#ifdef __osf__ +#undef recv +#undef send +#define recv(a,b,c,d) recvfrom(a,b,c,d,0,0) +#define send(a,b,c,d) sendto(a,b,c,d,0,0) +#endif + +#ifndef INADDR_NONE +/* $$.Ic INADDR_NONE$$ */ +#define INADDR_NONE 0xffffffff /* should have been in */ +#endif + +#ifndef SHUT_RD /* these three Posix.1g names are quite new */ +#define SHUT_RD 0 /* shutdown for reading */ +#define SHUT_WR 1 /* shutdown for writing */ +#define SHUT_RDWR 2 /* shutdown for reading and writing */ +/* $$.Ic SHUT_RD$$ */ +/* $$.Ic SHUT_WR$$ */ +/* $$.Ic SHUT_RDWR$$ */ +#endif + +/* *INDENT-OFF* */ +#ifndef INET_ADDRSTRLEN +/* $$.Ic INET_ADDRSTRLEN$$ */ +#define INET_ADDRSTRLEN 16 /* "ddd.ddd.ddd.ddd\0" + 1234567890123456 */ +#endif + +/* Define following even if IPv6 not supported, so we can always allocate + an adequately-sized buffer, without #ifdefs in the code. */ +#ifndef INET6_ADDRSTRLEN +/* $$.Ic INET6_ADDRSTRLEN$$ */ +#define INET6_ADDRSTRLEN 46 /* max size of IPv6 address string: + "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx" or + "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd\0" + 1234567890123456789012345678901234567890123456 */ +#endif +/* *INDENT-ON* */ + +/* Define bzero() as a macro if it's not in standard C library. */ +#ifndef HAVE_BZERO +#define bzero(ptr,n) memset(ptr, 0, n) +/* $$.If bzero$$ */ +/* $$.If memset$$ */ +#endif + +/* Older resolvers do not have gethostbyname2() */ +#ifndef HAVE_GETHOSTBYNAME2 +#define gethostbyname2(host,family) gethostbyname((host)) +#endif + +/* The structure returned by recvfrom_flags() */ +struct in_pktinfo { + struct in_addr ipi_addr; /* dst IPv4 address */ + int ipi_ifindex;/* received interface index */ +}; +/* $$.It in_pktinfo$$ */ +/* $$.Ib ipi_addr$$ */ +/* $$.Ib ipi_ifindex$$ */ + +/* We need the newer CMSG_LEN() and CMSG_SPACE() macros, but few + implementations support them today. These two macros really need + an ALIGN() macro, but each implementation does this differently. */ +#ifndef CMSG_LEN +/* $$.Ic CMSG_LEN$$ */ +#define CMSG_LEN(size) (sizeof(struct cmsghdr) + (size)) +#endif +#ifndef CMSG_SPACE +/* $$.Ic CMSG_SPACE$$ */ +#define CMSG_SPACE(size) (sizeof(struct cmsghdr) + (size)) +#endif + +/* Posix.1g requires the SUN_LEN() macro but not all implementations DefinE + it (yet). Note that this 4.4BSD macro works regardless whether there is + a length field or not. */ +#ifndef SUN_LEN +/* $$.Im SUN_LEN$$ */ +# define SUN_LEN(su) \ + (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) +#endif + +/* Posix.1g renames "Unix domain" as "local IPC". + But not all systems DefinE AF_LOCAL and PF_LOCAL (yet). */ +#ifndef AF_LOCAL +#define AF_LOCAL AF_UNIX +#endif +#ifndef PF_LOCAL +#define PF_LOCAL PF_UNIX +#endif + +/* Posix.1g requires that an #include of DefinE INFTIM, but many + systems still DefinE it in . We don't want to include + all the streams stuff if it's not needed, so we just DefinE INFTIM here. + This is the standard value, but there's no guarantee it is -1. */ +#ifndef INFTIM +#define INFTIM (-1) /* infinite poll timeout */ +/* $$.Ic INFTIM$$ */ +#ifdef HAVE_POLL_H +#define INFTIM_UNPH /* tell unpxti.h we defined it */ +#endif +#endif + +/* Following could be derived from SOMAXCONN in , but many + kernels still #define it as 5, while actually supporting many more */ +#define LISTENQ 1024 /* 2nd argument to listen() */ + +/* Miscellaneous constants */ +#define MAXLINE 4096 /* max text line length */ +#define MAXSOCKADDR 128 /* max socket address structure size */ +#define BUFFSIZE 8192 /* buffer size for reads and writes */ + +/* Define some port number that can be used for client-servers */ +#define SERV_PORT 9877 /* TCP and UDP client-servers */ +#define SERV_PORT_STR "9877" /* TCP and UDP client-servers */ +/* Some things for SCTP */ +#define SCTP_PDAPI_INCR_SZ 65535 /* increment size for pdapi when adding buf space */ +#define SCTP_PDAPI_NEED_MORE_THRESHOLD 1024 /* need more space threshold */ +#define SERV_MAX_SCTP_STRM 10 /* normal maximum streams */ +#define SERV_MORE_STRMS_SCTP 20 /* larger number of streams */ + + +#define UNIXSTR_PATH "/tmp/unix.str" /* Unix domain stream cli-serv */ +#define UNIXDG_PATH "/tmp/unix.dg" /* Unix domain datagram cli-serv */ +/* $$.ix [LISTENQ]~constant,~definition~of$$ */ +/* $$.ix [MAXLINE]~constant,~definition~of$$ */ +/* $$.ix [MAXSOCKADDR]~constant,~definition~of$$ */ +/* $$.ix [BUFFSIZE]~constant,~definition~of$$ */ +/* $$.ix [SERV_PORT]~constant,~definition~of$$ */ +/* $$.ix [UNIXSTR_PATH]~constant,~definition~of$$ */ +/* $$.ix [UNIXDG_PATH]~constant,~definition~of$$ */ + +/* Following shortens all the type casts of pointer arguments */ +#define SA struct sockaddr + +#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) + /* default file access permissions for new files */ +#define DIR_MODE (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH) + /* default permissions for new directories */ + +typedef void Sigfunc(int); /* for signal handlers */ + +#define min(a,b) ((a) < (b) ? (a) : (b)) +#define max(a,b) ((a) > (b) ? (a) : (b)) + +#ifndef HAVE_ADDRINFO_STRUCT +# include "../lib/addrinfo.h" +#endif + +#ifndef HAVE_IF_NAMEINDEX_STRUCT +struct if_nameindex { + unsigned int if_index; /* 1, 2, ... */ + char *if_name; /* null terminated name: "le0", ... */ +}; +/* $$.It if_nameindex$$ */ +/* $$.Ib if_index$$ */ +/* $$.Ib if_name$$ */ +#endif + +#ifndef HAVE_TIMESPEC_STRUCT +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* and nanoseconds */ +}; +/* $$.It timespec$$ */ +/* $$.Ib tv_sec$$ */ +/* $$.Ib tv_nsec$$ */ +#endif +/* end unph */ + + /* prototypes for our own library functions */ +int connect_nonb(int, const SA *, socklen_t, int); +int connect_timeo(int, const SA *, socklen_t, int); +void daemon_init(const char *, int); +void daemon_inetd(const char *, int); +void dg_cli(FILE *, int, const SA *, socklen_t); +void dg_echo(int, SA *, socklen_t); +char *gf_time(void); +void heartbeat_cli(int, int, int); +void heartbeat_serv(int, int, int); +struct addrinfo *host_serv(const char *, const char *, int, int); +int inet_srcrt_add(char *, int); +u_char *inet_srcrt_init(void); +void inet_srcrt_print(u_char *, int); +char **my_addrs(int *); +int readable_timeo(int, int); +ssize_t readline(int, void *, size_t); +ssize_t readn(int, void *, size_t); +ssize_t read_fd(int, void *, size_t, int *); +ssize_t recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *, + struct in_pktinfo *); +Sigfunc *signal_intr(int, Sigfunc *); +int sock_bind_wild(int, int); +int sock_cmp_addr(const SA *, const SA *, socklen_t); +int sock_cmp_port(const SA *, const SA *, socklen_t); +int sock_get_port(const SA *, socklen_t); +void sock_set_addr(SA *, socklen_t, const void *); +void sock_set_port(SA *, socklen_t, int); +void sock_set_wild(SA *, socklen_t); +char *sock_ntop(const SA *, socklen_t); +char *sock_ntop_host(const SA *, socklen_t); +int sockfd_to_family(int); +void str_echo(int); +void str_cli(FILE *, int); +void sctpstr_cli(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen); +void sctpstr_cli_echoall(FILE *fp, int sock_fd, struct sockaddr *to, + socklen_t tolen); +uint8_t *sctp_pdapi_recvmsg(int sock_fd, int *rdlen, SA *from, int *from_len, + struct sctp_sndrcvinfo *sri, int *msg_flags); +int sctp_bind_arg_list(int sock_fd, char **argv, int argc); + +void sctp_print_addresses(struct sockaddr_storage *addrs, int num); + +void sctp_check_notification(int sock_fd,char *recvlin); + +#define SCTP_ON_DEMAND_HB 1 +#define SCTP_SET_HB_INTERVAL 2 +#define SCTP_DISABLE_HB 3 +int sctp_heartbeat_action(int sock_fd, struct sockaddr *sa, + int action, u_int value); + +sctp_assoc_t +sctp_address_to_associd(int sock_fd, struct sockaddr *sa, socklen_t); + + +void +sctp_print_notification(char *notify_buf); + +int tcp_connect(const char *, const char *); +int tcp_listen(const char *, const char *, socklen_t *); +void tv_sub(struct timeval *, struct timeval *); +int udp_client(const char *, const char *, void **, socklen_t *); +int udp_connect(const char *, const char *); +int udp_server(const char *, const char *, socklen_t *); +int writable_timeo(int, int); +ssize_t writen(int, const void *, size_t); +ssize_t write_fd(int, void *, size_t, int); + +#ifdef MCAST +int mcast_leave(int, const SA *, socklen_t); +int mcast_join(int, const SA *, socklen_t, const char *, u_int); +int mcast_get_if(int); +int mcast_get_loop(int); +int mcast_get_ttl(int); +int mcast_set_if(int, const char *, u_int); +int mcast_set_loop(int, int); +int mcast_set_ttl(int, int); + +void Mcast_leave(int, const SA *, socklen_t); +void Mcast_join(int, const SA *, socklen_t, const char *, u_int); +int Mcast_get_if(int); +int Mcast_get_loop(int); +int Mcast_get_ttl(int); +void Mcast_set_if(int, const char *, u_int); +void Mcast_set_loop(int, int); +void Mcast_set_ttl(int, int); +#endif + +unsigned short in_cksum(unsigned short *, int); + +#ifndef HAVE_GETADDRINFO_PROTO +int getaddrinfo(const char *, const char *, const struct addrinfo *, + struct addrinfo **); +void freeaddrinfo(struct addrinfo *); +char *gai_strerror(int); +#endif + +#ifndef HAVE_GETNAMEINFO_PROTO +int getnameinfo(const SA *, socklen_t, char *, size_t, char *, size_t, int); +#endif + +#ifndef HAVE_GETHOSTNAME_PROTO +int gethostname(char *, int); +#endif + +#ifndef HAVE_HSTRERROR_PROTO +const char *hstrerror(int); +#endif + +#ifndef HAVE_IF_NAMETOINDEX_PROTO +unsigned int if_nametoindex(const char *); +char *if_indextoname(unsigned int, char *); +void if_freenameindex(struct if_nameindex *); +struct if_nameindex *if_nameindex(void); +#endif + +#ifndef HAVE_INET_PTON_PROTO +int inet_pton(int, const char *, void *); +const char *inet_ntop(int, const void *, char *, size_t); +#endif + +#ifndef HAVE_INET_ATON_PROTO +int inet_aton(const char *, struct in_addr *); +#endif + +#ifndef HAVE_ISFDTYPE_PROTO +int isfdtype(int, int); +#endif + +#ifndef HAVE_PSELECT_PROTO +int pselect(int, fd_set *, fd_set *, fd_set *, + const struct timespec *, const sigset_t *); +#endif + +#ifndef HAVE_SOCKATMARK_PROTO +int sockatmark(int); +#endif + +#ifndef HAVE_SNPRINTF_PROTO +int snprintf(char *, size_t, const char *, ...); +#endif + + /* prototypes for our own library wrapper functions */ +void Connect_timeo(int, const SA *, socklen_t, int); +struct addrinfo *Host_serv(const char *, const char *, int, int); +const char *Inet_ntop(int, const void *, char *, size_t); +void Inet_pton(int, const char *, void *); +char *If_indextoname(unsigned int, char *); +unsigned int If_nametoindex(const char *); +struct if_nameindex *If_nameindex(void); +char **My_addrs(int *); +ssize_t Read_fd(int, void *, size_t, int *); +int Readable_timeo(int, int); +ssize_t Recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *, + struct in_pktinfo *); +Sigfunc *Signal(int, Sigfunc *); +Sigfunc *Signal_intr(int, Sigfunc *); +int Sock_bind_wild(int, int); +char *Sock_ntop(const SA *, socklen_t); +char *Sock_ntop_host(const SA *, socklen_t); +int Sockfd_to_family(int); +int Tcp_connect(const char *, const char *); +int Tcp_listen(const char *, const char *, socklen_t *); +int Udp_client(const char *, const char *, void **, socklen_t *); +int Udp_connect(const char *, const char *); +int Udp_server(const char *, const char *, socklen_t *); +ssize_t Write_fd(int, void *, size_t, int); +int Writable_timeo(int, int); + + /* prototypes for our Unix wrapper functions: see {Sec errors} */ +void *Calloc(size_t, size_t); +void Close(int); +void Dup2(int, int); +int Fcntl(int, int, int); +void Gettimeofday(struct timeval *, void *); +int Ioctl(int, int, void *); +pid_t Fork(void); +void *Malloc(size_t); +void Mktemp(char *); +void *Mmap(void *, size_t, int, int, int, off_t); +int Open(const char *, int, mode_t); +void Pipe(int *fds); +ssize_t Read(int, void *, size_t); +void Sigaddset(sigset_t *, int); +void Sigdelset(sigset_t *, int); +void Sigemptyset(sigset_t *); +void Sigfillset(sigset_t *); +int Sigismember(const sigset_t *, int); +void Sigpending(sigset_t *); +void Sigprocmask(int, const sigset_t *, sigset_t *); +char *Strdup(const char *); +long Sysconf(int); +void Sysctl(int *, u_int, void *, size_t *, void *, size_t); +void Unlink(const char *); +pid_t Wait(int *); +pid_t Waitpid(pid_t, int *, int); +void Write(int, void *, size_t); + + /* prototypes for our stdio wrapper functions: see {Sec errors} */ +void Fclose(FILE *); +FILE *Fdopen(int, const char *); +char *Fgets(char *, int, FILE *); +FILE *Fopen(const char *, const char *); +void Fputs(const char *, FILE *); + + /* prototypes for our socket wrapper functions: see {Sec errors} */ +int Accept(int, SA *, socklen_t *); +void Bind(int, const SA *, socklen_t); +void Connect(int, const SA *, socklen_t); +void Getpeername(int, SA *, socklen_t *); +void Getsockname(int, SA *, socklen_t *); +void Getsockopt(int, int, int, void *, socklen_t *); +int Isfdtype(int, int); +void Listen(int, int); +#ifdef HAVE_POLL +int Poll(struct pollfd *, unsigned long, int); +#endif +ssize_t Readline(int, void *, size_t); +ssize_t Readn(int, void *, size_t); +ssize_t Recv(int, void *, size_t, int); +ssize_t Recvfrom(int, void *, size_t, int, SA *, socklen_t *); +ssize_t Recvmsg(int, struct msghdr *, int); +int Select(int, fd_set *, fd_set *, fd_set *, struct timeval *); +void Send(int, const void *, size_t, int); +void Sendto(int, const void *, size_t, int, const SA *, socklen_t); +void Sendmsg(int, const struct msghdr *, int); +void Setsockopt(int, int, int, const void *, socklen_t); +void Shutdown(int, int); +int Sockatmark(int); +int Socket(int, int, int); +void Socketpair(int, int, int, int *); +void Writen(int, void *, size_t); + +void err_dump(const char *, ...); +void err_msg(const char *, ...); +void err_quit(const char *, ...); +void err_ret(const char *, ...); +void err_sys(const char *, ...); + +#endif /* __unp_h */ diff --git a/select/Makefile b/select/Makefile new file mode 100644 index 0000000..4ae76eb --- /dev/null +++ b/select/Makefile @@ -0,0 +1,17 @@ +include ../Make.defines + +PROGS = tcpcli01 tcpcli02 tcpcli03 + +all: ${PROGS} + +tcpcli01: tcpcli01.o strcliselect01.o + ${CC} ${CFLAGS} -o $@ tcpcli01.o strcliselect01.o ${LIBS} + +tcpcli02: tcpcli02.o strcliselect02.o + ${CC} ${CFLAGS} -o $@ tcpcli02.o strcliselect02.o ${LIBS} + +tcpcli03: tcpcli03.o + ${CC} ${CFLAGS} -o $@ tcpcli03.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/select/strcliselect01.c b/select/strcliselect01.c new file mode 100644 index 0000000..a4a1aef --- /dev/null +++ b/select/strcliselect01.c @@ -0,0 +1,29 @@ +#include "unp.h" + +void +str_cli(FILE *fp, int sockfd) +{ + int maxfdp1; + fd_set rset; + char sendline[MAXLINE], recvline[MAXLINE]; + + FD_ZERO(&rset); + for ( ; ; ) { + FD_SET(fileno(fp), &rset); + FD_SET(sockfd, &rset); + maxfdp1 = max(fileno(fp), sockfd) + 1; + Select(maxfdp1, &rset, NULL, NULL, NULL); + + if (FD_ISSET(sockfd, &rset)) { /* socket is readable */ + if (Readline(sockfd, recvline, MAXLINE) == 0) + err_quit("str_cli: server terminated prematurely"); + Fputs(recvline, stdout); + } + + if (FD_ISSET(fileno(fp), &rset)) { /* input is readable */ + if (Fgets(sendline, MAXLINE, fp) == NULL) + return; /* all done */ + Writen(sockfd, sendline, strlen(sendline)); + } + } +} diff --git a/select/strcliselect02.c b/select/strcliselect02.c new file mode 100644 index 0000000..3234fee --- /dev/null +++ b/select/strcliselect02.c @@ -0,0 +1,42 @@ +#include "unp.h" + +void +str_cli(FILE *fp, int sockfd) +{ + int maxfdp1, stdineof; + fd_set rset; + char buf[MAXLINE]; + int n; + + stdineof = 0; + FD_ZERO(&rset); + for ( ; ; ) { + if (stdineof == 0) + FD_SET(fileno(fp), &rset); + FD_SET(sockfd, &rset); + maxfdp1 = max(fileno(fp), sockfd) + 1; + Select(maxfdp1, &rset, NULL, NULL, NULL); + + if (FD_ISSET(sockfd, &rset)) { /* socket is readable */ + if ( (n = Read(sockfd, buf, MAXLINE)) == 0) { + if (stdineof == 1) + return; /* normal termination */ + else + err_quit("str_cli: server terminated prematurely"); + } + + Write(fileno(stdout), buf, n); + } + + if (FD_ISSET(fileno(fp), &rset)) { /* input is readable */ + if ( (n = Read(fileno(fp), buf, MAXLINE)) == 0) { + stdineof = 1; + Shutdown(sockfd, SHUT_WR); /* send FIN */ + FD_CLR(fileno(fp), &rset); + continue; + } + + Writen(sockfd, buf, n); + } + } +} diff --git a/select/strcliselect02.lc b/select/strcliselect02.lc new file mode 100644 index 0000000..7257daa --- /dev/null +++ b/select/strcliselect02.lc @@ -0,0 +1,41 @@ +#include "unp.h"## 1 ##src/select/strcliselect02.c## + +void## 2 ##src/select/strcliselect02.c## +str_cli(FILE *fp, int sockfd)## 3 ##src/select/strcliselect02.c## +{## 4 ##src/select/strcliselect02.c## + int maxfdp1, stdineof;## 5 ##src/select/strcliselect02.c## + fd_set rset;## 6 ##src/select/strcliselect02.c## + char sendline[MAXLINE], recvline[MAXLINE];## 7 ##src/select/strcliselect02.c## + + stdineof = 0;## 8 ##src/select/strcliselect02.c## + FD_ZERO(&rset);## 9 ##src/select/strcliselect02.c## + for (;;) {## 10 ##src/select/strcliselect02.c## + if (stdineof == 0)## 11 ##src/select/strcliselect02.c## + FD_SET(fileno(fp), &rset);## 12 ##src/select/strcliselect02.c## + FD_SET(sockfd, &rset);## 13 ##src/select/strcliselect02.c## + maxfdp1 = max(fileno(fp), sockfd) + 1;## 14 ##src/select/strcliselect02.c## + Select(maxfdp1, &rset, NULL, NULL, NULL);## 15 ##src/select/strcliselect02.c## + + if (FD_ISSET(sockfd, &rset)) { /* socket is readable */## 16 ##src/select/strcliselect02.c## + if (Readline(sockfd, recvline, MAXLINE) == 0) {## 17 ##src/select/strcliselect02.c## + if (stdineof == 1)## 18 ##src/select/strcliselect02.c## + return; /* normal termination */## 19 ##src/select/strcliselect02.c## + else## 20 ##src/select/strcliselect02.c## + err_quit("str_cli: server terminated prematurely");## 21 ##src/select/strcliselect02.c## + }## 22 ##src/select/strcliselect02.c## + + Fputs(recvline, stdout);## 23 ##src/select/strcliselect02.c## + }## 24 ##src/select/strcliselect02.c## + + if (FD_ISSET(fileno(fp), &rset)) { /* input is readable */## 25 ##src/select/strcliselect02.c## + if (Fgets(sendline, MAXLINE, fp) == NULL) {## 26 ##src/select/strcliselect02.c## + stdineof = 1;## 27 ##src/select/strcliselect02.c## + Shutdown(sockfd, SHUT_WR); /* send FIN */## 28 ##src/select/strcliselect02.c## + FD_CLR(fileno(fp), &rset);## 29 ##src/select/strcliselect02.c## + continue;## 30 ##src/select/strcliselect02.c## + }## 31 ##src/select/strcliselect02.c## + + Writen(sockfd, sendline, strlen(sendline));## 32 ##src/select/strcliselect02.c## + }## 33 ##src/select/strcliselect02.c## + }## 34 ##src/select/strcliselect02.c## +}## 35 ##src/select/strcliselect02.c## diff --git a/select/tcpcli01.c b/select/tcpcli01.c new file mode 100644 index 0000000..c9b4898 --- /dev/null +++ b/select/tcpcli01.c @@ -0,0 +1,25 @@ +/* Use standard echo server; baseline measurements for nonblocking version */ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(7); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/select/tcpcli02.c b/select/tcpcli02.c new file mode 100644 index 0000000..c9b4898 --- /dev/null +++ b/select/tcpcli02.c @@ -0,0 +1,25 @@ +/* Use standard echo server; baseline measurements for nonblocking version */ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(7); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/select/tcpcli03.c b/select/tcpcli03.c new file mode 100644 index 0000000..df9de96 --- /dev/null +++ b/select/tcpcli03.c @@ -0,0 +1,27 @@ +/* Test shutdown(fd,SHUT_RD) and see what happens */ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli03 "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(19); /* chargen server */ + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + shutdown(sockfd, SHUT_RD); + + pause(); + + exit(0); +} diff --git a/server/Makefile b/server/Makefile new file mode 100644 index 0000000..c69d6f2 --- /dev/null +++ b/server/Makefile @@ -0,0 +1,85 @@ +include ../Make.defines + +PROGS = client clientrst \ + serv01 serv02 serv03 serv04 serv05 serv06 serv07 serv08 + +all: ${PROGS} + +# The client to test the various servers. +client: client.o pr_cpu_time.o + ${CC} ${CFLAGS} -o $@ client.o pr_cpu_time.o ${LIBS} + +# A special client that sends an RST occasionally. +# Used to test the XTI server (should receive disconnect). +clientrst: clientrst.o pr_cpu_time.o + ${CC} ${CFLAGS} -o $@ clientrst.o pr_cpu_time.o ${LIBS} + +# serv00: traditional concurrent server: use as base level +serv00: serv00.o web_child.o pr_cpu_time.o + ${CC} ${CFLAGS} -o $@ serv00.o web_child.o pr_cpu_time.o ${LIBS} + +# serv01: one fork per client (traditional concurrent server). +serv01: serv01.o web_child.o sig_chld_waitpid.o pr_cpu_time.o + ${CC} ${CFLAGS} -o $@ serv01.o web_child.o sig_chld_waitpid.o \ + pr_cpu_time.o ${LIBS} + +# serv02: prefork, no locking; works on BSD-derived systems +# but not on SVR4-derived systems. +serv02: serv02.o child02.o web_child.o pr_cpu_time.o + ${CC} ${CFLAGS} -o $@ serv02.o child02.o web_child.o pr_cpu_time.o ${LIBS} + +# serv02l: prefork, no locking, block in select instead of accept to see +# select collisions; works on BSD-derived systems but not on SVR4. +serv02l:serv02.o child02l.o web_child.o pr_cpu_time.o + ${CC} ${CFLAGS} -o serv02l serv02.o child02l.o web_child.o \ + pr_cpu_time.o ${LIBS} + +# serv02m: prefork, no locking; works on BSD-derived systems. +# This version is "metered" to see #clients/child serviced. +serv02m:serv02m.o child02m.o web_child.o pr_cpu_time.o meter.o + ${CC} ${CFLAGS} -o serv02m serv02m.o child02m.o web_child.o \ + pr_cpu_time.o meter.o ${LIBS} + +# serv03: prefork, file locking using fcntl(). Similar to Apache server. +serv03: serv03.o child03.o lock_fcntl.o web_child.o pr_cpu_time.o + ${CC} ${CFLAGS} -o $@ serv03.o child03.o lock_fcntl.o web_child.o \ + pr_cpu_time.o ${LIBS} + +# serv03m: prefork, file locking using fcntl(), metered. +serv03m: serv03m.o child03m.o lock_fcntl.o web_child.o pr_cpu_time.o meter.o + ${CC} ${CFLAGS} -o $@ serv03m.o child03m.o lock_fcntl.o web_child.o \ + pr_cpu_time.o meter.o ${LIBS} + +# serv04: prefork, file locking using pthread locking. +serv04: serv04.o child04.o lock_pthread.o web_child.o pr_cpu_time.o + ${CC} ${CFLAGS} -o $@ serv04.o child04.o lock_pthread.o \ + web_child.o pr_cpu_time.o ${LIBS} + +# serv05: prefork, descrptor passing to children. Similar to NSCA server. +serv05: serv05.o child05.o lock_fcntl.o web_child.o pr_cpu_time.o + ${CC} ${CFLAGS} -o $@ serv05.o child05.o lock_fcntl.o web_child.o \ + pr_cpu_time.o ${LIBS} + +# Thread versions must call a reentrant version of readline(). +# serv06: one thread per client. +serv06: serv06.o web_child.o pr_cpu_time.o readline.o + ${CC} ${CFLAGS} -o $@ serv06.o web_child.o pr_cpu_time.o \ + readline.o ${LIBS} + +# serv07: prethread with mutex locking around accept(). +serv07: serv07.o pthread07.o web_child.o pr_cpu_time.o readline.o + ${CC} ${CFLAGS} -o $@ serv07.o pthread07.o web_child.o pr_cpu_time.o \ + readline.o ${LIBS} + +# serv08: prethread with only main thread doing accept(). +serv08: serv08.o pthread08.o web_child.o pr_cpu_time.o readline.o + ${CC} ${CFLAGS} -o $@ serv08.o pthread08.o web_child.o pr_cpu_time.o \ + readline.o ${LIBS} + +# serv09: prethread with no locking around accept(). +serv09: serv09.o pthread09.o web_child.o pr_cpu_time.o readline.o + ${CC} ${CFLAGS} -o $@ serv09.o pthread09.o web_child.o pr_cpu_time.o \ + readline.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/server/child.h b/server/child.h new file mode 100644 index 0000000..0f58b5c --- /dev/null +++ b/server/child.h @@ -0,0 +1,8 @@ +typedef struct { + pid_t child_pid; /* process ID */ + int child_pipefd; /* parent's stream pipe to/from child */ + int child_status; /* 0 = ready */ + long child_count; /* # connections handled */ +} Child; + +Child *cptr; /* array of Child structures; calloc'ed */ diff --git a/server/child.lh b/server/child.lh new file mode 100644 index 0000000..817e7dc --- /dev/null +++ b/server/child.lh @@ -0,0 +1,8 @@ +typedef struct {## 1 ##src/server/child.h## + pid_t child_pid; /* process ID */## 2 ##src/server/child.h## + int child_pipefd; /* parent's stream pipe to/from child */## 3 ##src/server/child.h## + int child_status; /* 0 = ready */## 4 ##src/server/child.h## + long child_count; /* #connections handled */## 5 ##src/server/child.h## +} Child;## 6 ##src/server/child.h## + +Child *cptr; /* array of Child structures; calloc'ed */## 7 ##src/server/child.h## diff --git a/server/child02.c b/server/child02.c new file mode 100644 index 0000000..6191c46 --- /dev/null +++ b/server/child02.c @@ -0,0 +1,37 @@ +/* include child_make */ +#include "unp.h" + +pid_t +child_make(int i, int listenfd, int addrlen) +{ + pid_t pid; + void child_main(int, int, int); + + if ( (pid = Fork()) > 0) + return(pid); /* parent */ + + child_main(i, listenfd, addrlen); /* never returns */ +} +/* end child_make */ + +/* include child_main */ +void +child_main(int i, int listenfd, int addrlen) +{ + int connfd; + void web_child(int); + socklen_t clilen; + struct sockaddr *cliaddr; + + cliaddr = Malloc(addrlen); + + printf("child %ld starting\n", (long) getpid()); + for ( ; ; ) { + clilen = addrlen; + connfd = Accept(listenfd, cliaddr, &clilen); + + web_child(connfd); /* process the request */ + Close(connfd); + } +} +/* end child_main */ diff --git a/server/child02.lc b/server/child02.lc new file mode 100644 index 0000000..9f06095 --- /dev/null +++ b/server/child02.lc @@ -0,0 +1,37 @@ +/* include child_make */ +#include "unp.h"## 1 ##src/server/child02.c## + +pid_t## 2 ##src/server/child02.c## +child_make(int i, int listenfd, int addrlen)## 3 ##src/server/child02.c## +{## 4 ##src/server/child02.c## + pid_t pid;## 5 ##src/server/child02.c## + void child_main(int, int, int);## 6 ##src/server/child02.c## + + if ((pid = Fork()) > 0)## 7 ##src/server/child02.c## + return (pid); /* parent */## 8 ##src/server/child02.c## + + child_main(i, listenfd, addrlen); /* never returns */## 9 ##src/server/child02.c## +}## 10 ##src/server/child02.c## +/* end child_make */ + +/* include child_main */ +void## 11 ##src/server/child02.c## +child_main(int i, int listenfd, int addrlen)## 12 ##src/server/child02.c## +{## 13 ##src/server/child02.c## + int connfd;## 14 ##src/server/child02.c## + void web_child(int);## 15 ##src/server/child02.c## + socklen_t clilen;## 16 ##src/server/child02.c## + struct sockaddr *cliaddr;## 17 ##src/server/child02.c## + + cliaddr = Malloc(addrlen);## 18 ##src/server/child02.c## + + printf("child %ld starting\n", (long) getpid());## 19 ##src/server/child02.c## + for (;;) {## 20 ##src/server/child02.c## + clilen = addrlen;## 21 ##src/server/child02.c## + connfd = Accept(listenfd, cliaddr, &clilen);## 22 ##src/server/child02.c## + + web_child(connfd); /* process the request */## 23 ##src/server/child02.c## + Close(connfd);## 24 ##src/server/child02.c## + }## 25 ##src/server/child02.c## +}## 26 ##src/server/child02.c## +/* end child_main */ diff --git a/server/child02l.c b/server/child02l.c new file mode 100644 index 0000000..2b92a71 --- /dev/null +++ b/server/child02l.c @@ -0,0 +1,40 @@ +#include "unp.h" + +pid_t +child_make(int i, int listenfd, int addrlen) +{ + pid_t pid; + void child_main(int, int, int); + + if ( (pid = Fork()) > 0) + return(pid); /* parent */ + + child_main(i, listenfd, addrlen); /* never returns */ +} + +void +child_main(int i, int listenfd, int addrlen) +{ + int connfd; + void web_child(int); + fd_set rset; + socklen_t clilen; + struct sockaddr *cliaddr; + + cliaddr = Malloc(addrlen); + + printf("child %ld starting\n", (long) getpid()); + FD_ZERO(&rset); + for ( ; ; ) { + FD_SET(listenfd, &rset); + Select(listenfd+1, &rset, NULL, NULL, NULL); + if (FD_ISSET(listenfd, &rset) == 0) + err_quit("listenfd readable"); + + clilen = addrlen; + connfd = Accept(listenfd, cliaddr, &clilen); + + web_child(connfd); /* process the request */ + Close(connfd); + } +} diff --git a/server/child02m.c b/server/child02m.c new file mode 100644 index 0000000..ecd7359 --- /dev/null +++ b/server/child02m.c @@ -0,0 +1,35 @@ +#include "unp.h" + +pid_t +child_make(int i, int listenfd, int addrlen) +{ + pid_t pid; + void child_main(int, int, int); + + if ( (pid = Fork()) > 0) + return(pid); /* parent */ + + child_main(i, listenfd, addrlen); /* never returns */ +} + +void +child_main(int i, int listenfd, int addrlen) +{ + int connfd; + void web_child(int); + socklen_t clilen; + struct sockaddr *cliaddr; + extern long *cptr; + + cliaddr = Malloc(addrlen); + + printf("child %ld starting\n", (long) getpid()); + for ( ; ; ) { + clilen = addrlen; + connfd = Accept(listenfd, cliaddr, &clilen); + cptr[i]++; + + web_child(connfd); /* process the request */ + Close(connfd); + } +} diff --git a/server/child03.c b/server/child03.c new file mode 100644 index 0000000..ab67dc8 --- /dev/null +++ b/server/child03.c @@ -0,0 +1,35 @@ +#include "unp.h" + +pid_t +child_make(int i, int listenfd, int addrlen) +{ + pid_t pid; + void child_main(int, int, int); + + if ( (pid = Fork()) > 0) + return(pid); /* parent */ + + child_main(i, listenfd, addrlen); /* never returns */ +} + +void +child_main(int i, int listenfd, int addrlen) +{ + int connfd; + void web_child(int); + socklen_t clilen; + struct sockaddr *cliaddr; + + cliaddr = Malloc(addrlen); + + printf("child %ld starting\n", (long) getpid()); + for ( ; ; ) { + clilen = addrlen; + my_lock_wait(); + connfd = Accept(listenfd, cliaddr, &clilen); + my_lock_release(); + + web_child(connfd); /* process the request */ + Close(connfd); + } +} diff --git a/server/child03m.c b/server/child03m.c new file mode 100644 index 0000000..f906073 --- /dev/null +++ b/server/child03m.c @@ -0,0 +1,37 @@ +#include "unp.h" + +pid_t +child_make(int i, int listenfd, int addrlen) +{ + pid_t pid; + void child_main(int, int, int); + + if ( (pid = Fork()) > 0) + return(pid); /* parent */ + + child_main(i, listenfd, addrlen); /* never returns */ +} + +void +child_main(int i, int listenfd, int addrlen) +{ + int connfd; + void web_child(int); + socklen_t clilen; + struct sockaddr *cliaddr; + extern long *cptr; + + cliaddr = Malloc(addrlen); + + printf("child %ld starting\n", (long) getpid()); + for ( ; ; ) { + clilen = addrlen; + my_lock_wait(); + connfd = Accept(listenfd, cliaddr, &clilen); + my_lock_release(); + cptr[i]++; + + web_child(connfd); /* process the request */ + Close(connfd); + } +} diff --git a/server/child04.c b/server/child04.c new file mode 100644 index 0000000..ab67dc8 --- /dev/null +++ b/server/child04.c @@ -0,0 +1,35 @@ +#include "unp.h" + +pid_t +child_make(int i, int listenfd, int addrlen) +{ + pid_t pid; + void child_main(int, int, int); + + if ( (pid = Fork()) > 0) + return(pid); /* parent */ + + child_main(i, listenfd, addrlen); /* never returns */ +} + +void +child_main(int i, int listenfd, int addrlen) +{ + int connfd; + void web_child(int); + socklen_t clilen; + struct sockaddr *cliaddr; + + cliaddr = Malloc(addrlen); + + printf("child %ld starting\n", (long) getpid()); + for ( ; ; ) { + clilen = addrlen; + my_lock_wait(); + connfd = Accept(listenfd, cliaddr, &clilen); + my_lock_release(); + + web_child(connfd); /* process the request */ + Close(connfd); + } +} diff --git a/server/child05.c b/server/child05.c new file mode 100644 index 0000000..a17bf42 --- /dev/null +++ b/server/child05.c @@ -0,0 +1,52 @@ +/* include child_make */ +#include "unp.h" +#include "child.h" + +pid_t +child_make(int i, int listenfd, int addrlen) +{ + int sockfd[2]; + pid_t pid; + void child_main(int, int, int); + + Socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd); + + if ( (pid = Fork()) > 0) { + Close(sockfd[1]); + cptr[i].child_pid = pid; + cptr[i].child_pipefd = sockfd[0]; + cptr[i].child_status = 0; + return(pid); /* parent */ + } + + Dup2(sockfd[1], STDERR_FILENO); /* child's stream pipe to parent */ + Close(sockfd[0]); + Close(sockfd[1]); + Close(listenfd); /* child does not need this open */ + child_main(i, listenfd, addrlen); /* never returns */ +} +/* end child_make */ + +/* include child_main */ +void +child_main(int i, int listenfd, int addrlen) +{ + char c; + int connfd; + ssize_t n; + void web_child(int); + + printf("child %ld starting\n", (long) getpid()); + for ( ; ; ) { + if ( (n = Read_fd(STDERR_FILENO, &c, 1, &connfd)) == 0) + err_quit("read_fd returned 0"); + if (connfd < 0) + err_quit("no descriptor from read_fd"); + + web_child(connfd); /* process request */ + Close(connfd); + + Write(STDERR_FILENO, "", 1); /* tell parent we're ready again */ + } +} +/* end child_main */ diff --git a/server/child05.lc b/server/child05.lc new file mode 100644 index 0000000..4380ee0 --- /dev/null +++ b/server/child05.lc @@ -0,0 +1,52 @@ +/* include child_make */ +#include "unp.h"## 1 ##src/server/child05.c## +#include "child.h"## 2 ##src/server/child05.c## + +pid_t## 3 ##src/server/child05.c## +child_make(int i, int listenfd, int addrlen)## 4 ##src/server/child05.c## +{## 5 ##src/server/child05.c## + int sockfd[2];## 6 ##src/server/child05.c## + pid_t pid;## 7 ##src/server/child05.c## + void child_main(int, int, int);## 8 ##src/server/child05.c## + + Socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd);## 9 ##src/server/child05.c## + + if ((pid = Fork()) > 0) {## 10 ##src/server/child05.c## + Close(sockfd[1]);## 11 ##src/server/child05.c## + cptr[i].child_pid = pid;## 12 ##src/server/child05.c## + cptr[i].child_pipefd = sockfd[0];## 13 ##src/server/child05.c## + cptr[i].child_status = 0;## 14 ##src/server/child05.c## + return (pid); /* parent */## 15 ##src/server/child05.c## + }## 16 ##src/server/child05.c## + + Dup2(sockfd[1], STDERR_FILENO); /* child's stream pipe to parent */## 17 ##src/server/child05.c## + Close(sockfd[0]);## 18 ##src/server/child05.c## + Close(sockfd[1]);## 19 ##src/server/child05.c## + Close(listenfd); /* child does not need this open */## 20 ##src/server/child05.c## + child_main(i, listenfd, addrlen); /* never returns */## 21 ##src/server/child05.c## +}## 22 ##src/server/child05.c## +/* end child_make */ + +/* include child_main */ +void## 23 ##src/server/child05.c## +child_main(int i, int listenfd, int addrlen)## 24 ##src/server/child05.c## +{## 25 ##src/server/child05.c## + char c;## 26 ##src/server/child05.c## + int connfd;## 27 ##src/server/child05.c## + ssize_t n;## 28 ##src/server/child05.c## + void web_child(int);## 29 ##src/server/child05.c## + + printf("child %ld starting\n", (long) getpid());## 30 ##src/server/child05.c## + for (;;) {## 31 ##src/server/child05.c## + if ((n = Read_fd(STDERR_FILENO, &c, 1, &connfd)) == 0)## 32 ##src/server/child05.c## + err_quit("read_fd returned 0");## 33 ##src/server/child05.c## + if (connfd < 0)## 34 ##src/server/child05.c## + err_quit("no descriptor from read_fd");## 35 ##src/server/child05.c## + + web_child(connfd); /* process the request */## 36 ##src/server/child05.c## + Close(connfd);## 37 ##src/server/child05.c## + + Write(STDERR_FILENO, "", 1); /* tell parent we're ready again */## 38 ##src/server/child05.c## + }## 39 ##src/server/child05.c## +}## 40 ##src/server/child05.c## +/* end child_main */ diff --git a/server/client.c b/server/client.c new file mode 100644 index 0000000..33fdf0b --- /dev/null +++ b/server/client.c @@ -0,0 +1,46 @@ +#include "unp.h" + +#define MAXN 16384 /* max # bytes to request from server */ + +int +main(int argc, char **argv) +{ + int i, j, fd, nchildren, nloops, nbytes; + pid_t pid; + ssize_t n; + char request[MAXLINE], reply[MAXN]; + + if (argc != 6) + err_quit("usage: client <#children> " + "<#loops/child> <#bytes/request>"); + + nchildren = atoi(argv[3]); + nloops = atoi(argv[4]); + nbytes = atoi(argv[5]); + snprintf(request, sizeof(request), "%d\n", nbytes); /* newline at end */ + + for (i = 0; i < nchildren; i++) { + if ( (pid = Fork()) == 0) { /* child */ + for (j = 0; j < nloops; j++) { + fd = Tcp_connect(argv[1], argv[2]); + + Write(fd, request, strlen(request)); + + if ( (n = Readn(fd, reply, nbytes)) != nbytes) + err_quit("server returned %d bytes", n); + + Close(fd); /* TIME_WAIT on client, not server */ + } + printf("child %d done\n", i); + exit(0); + } + /* parent loops around to fork() again */ + } + + while (wait(NULL) > 0) /* now parent waits for all children */ + ; + if (errno != ECHILD) + err_sys("wait error"); + + exit(0); +} diff --git a/server/clientrst.c b/server/clientrst.c new file mode 100644 index 0000000..9d163e4 --- /dev/null +++ b/server/clientrst.c @@ -0,0 +1,70 @@ +#include "unp.h" + +#define MAXN 16384 /* max #bytes to request from server */ + +int +main(int argc, char **argv) +{ + int i, j, fd, nchildren, nloops, nbytes; + pid_t pid; + ssize_t n; + char request[MAXLINE], reply[MAXN]; + + if (argc != 6) + err_quit("usage: client <#children> " + "<#loops/child> <#bytes/request>"); + + nchildren = atoi(argv[3]); + nloops = atoi(argv[4]); + nbytes = atoi(argv[5]); + snprintf(request, sizeof(request), "%d\n", nbytes); /* newline at end */ + + for (i = 0; i < nchildren; i++) { + if ( (pid = Fork()) == 0) { /* child */ + for (j = 0; j < nloops; j++) { + fd = Tcp_connect(argv[1], argv[2]); + + /* + * We want to see what happens to the server when it has + * connections outstanding and an RST arrives for one of + * them, before the connection is accepted. + * With the XTI server, this should generate some + * T_DISCONNECT events from t_accept(), which must be + * handled correctly. + * + * We do this for every third connection from the third + * client child. (Could add more command-line args ...) + */ + + if (i == 2 && (j % 3) == 0) { + struct linger ling; + + ling.l_onoff = 1; + ling.l_linger = 0; + Setsockopt(fd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)); + Close(fd); + + /* and just continue on for this client connection ... */ + fd = Tcp_connect(argv[1], argv[2]); + } + + Write(fd, request, strlen(request)); + + if ( (n = Readn(fd, reply, nbytes)) != nbytes) + err_quit("server returned %d bytes", n); + + Close(fd); /* TIME_WAIT on client, not server */ + } + printf("child %d done\n", i); + exit(0); + } + /* parent loops around to fork() again */ + } + + while (wait(NULL) > 0) /* now parent waits for all children */ + ; + if (errno != ECHILD) + err_sys("wait error"); + + exit(0); +} diff --git a/server/lock_fcntl.c b/server/lock_fcntl.c new file mode 100644 index 0000000..ae513d9 --- /dev/null +++ b/server/lock_fcntl.c @@ -0,0 +1,51 @@ +/* include my_lock_init */ +#include "unp.h" + +static struct flock lock_it, unlock_it; +static int lock_fd = -1; + /* fcntl() will fail if my_lock_init() not called */ + +void +my_lock_init(char *pathname) +{ + char lock_file[1024]; + + /* 4must copy caller's string, in case it's a constant */ + strncpy(lock_file, pathname, sizeof(lock_file)); + lock_fd = Mkstemp(lock_file); + + Unlink(lock_file); /* but lock_fd remains open */ + + lock_it.l_type = F_WRLCK; + lock_it.l_whence = SEEK_SET; + lock_it.l_start = 0; + lock_it.l_len = 0; + + unlock_it.l_type = F_UNLCK; + unlock_it.l_whence = SEEK_SET; + unlock_it.l_start = 0; + unlock_it.l_len = 0; +} +/* end my_lock_init */ + +/* include my_lock_wait */ +void +my_lock_wait() +{ + int rc; + + while ( (rc = fcntl(lock_fd, F_SETLKW, &lock_it)) < 0) { + if (errno == EINTR) + continue; + else + err_sys("fcntl error for my_lock_wait"); + } +} + +void +my_lock_release() +{ + if (fcntl(lock_fd, F_SETLKW, &unlock_it) < 0) + err_sys("fcntl error for my_lock_release"); +} +/* end my_lock_wait */ diff --git a/server/lock_fcntl.lc b/server/lock_fcntl.lc new file mode 100644 index 0000000..0d1c47e --- /dev/null +++ b/server/lock_fcntl.lc @@ -0,0 +1,51 @@ +/* include my_lock_init */ +#include "unp.h"## 1 ##src/server/lock_fcntl.c## + +static struct flock lock_it, unlock_it;## 2 ##src/server/lock_fcntl.c## +static int lock_fd = -1;## 3 ##src/server/lock_fcntl.c## + /* fcntl() will fail if my_lock_init() not called */## 4 ##src/server/lock_fcntl.c## + +void## 5 ##src/server/lock_fcntl.c## +my_lock_init(char *pathname)## 6 ##src/server/lock_fcntl.c## +{## 7 ##src/server/lock_fcntl.c## + char lock_file[1024];## 8 ##src/server/lock_fcntl.c## + + /* 4must copy caller's string, in case it's a constant */## 9 ##src/server/lock_fcntl.c## + strncpy(lock_file, pathname, sizeof(lock_file));## 10 ##src/server/lock_fcntl.c## + lock_fd = Mkstemp(lock_file);## 11 ##src/server/lock_fcntl.c## + + Unlink(lock_file); /* but lock_fd remains open */## 12 ##src/server/lock_fcntl.c## + + lock_it.l_type = F_WRLCK;## 13 ##src/server/lock_fcntl.c## + lock_it.l_whence = SEEK_SET;## 14 ##src/server/lock_fcntl.c## + lock_it.l_start = 0;## 15 ##src/server/lock_fcntl.c## + lock_it.l_len = 0;## 16 ##src/server/lock_fcntl.c## + + unlock_it.l_type = F_UNLCK;## 17 ##src/server/lock_fcntl.c## + unlock_it.l_whence = SEEK_SET;## 18 ##src/server/lock_fcntl.c## + unlock_it.l_start = 0;## 19 ##src/server/lock_fcntl.c## + unlock_it.l_len = 0;## 20 ##src/server/lock_fcntl.c## +}## 21 ##src/server/lock_fcntl.c## +/* end my_lock_init */ + +/* include my_lock_wait */ +void## 22 ##src/server/lock_fcntl.c## +my_lock_wait()## 23 ##src/server/lock_fcntl.c## +{## 24 ##src/server/lock_fcntl.c## + int rc;## 25 ##src/server/lock_fcntl.c## + + while ((rc = fcntl(lock_fd, F_SETLKW, &lock_it)) < 0) {## 26 ##src/server/lock_fcntl.c## + if (errno == EINTR)## 27 ##src/server/lock_fcntl.c## + continue;## 28 ##src/server/lock_fcntl.c## + else## 29 ##src/server/lock_fcntl.c## + err_sys("fcntl error for my_lock_wait");## 30 ##src/server/lock_fcntl.c## + }## 31 ##src/server/lock_fcntl.c## +}## 32 ##src/server/lock_fcntl.c## + +void## 33 ##src/server/lock_fcntl.c## +my_lock_release()## 34 ##src/server/lock_fcntl.c## +{## 35 ##src/server/lock_fcntl.c## + if (fcntl(lock_fd, F_SETLKW, &unlock_it) < 0)## 36 ##src/server/lock_fcntl.c## + err_sys("fcntl error for my_lock_release");## 37 ##src/server/lock_fcntl.c## +}## 38 ##src/server/lock_fcntl.c## +/* end my_lock_wait */ diff --git a/server/lock_pthread.c b/server/lock_pthread.c new file mode 100644 index 0000000..7c9de9e --- /dev/null +++ b/server/lock_pthread.c @@ -0,0 +1,37 @@ +/* include my_lock_init */ +#include "unpthread.h" +#include + +static pthread_mutex_t *mptr; /* actual mutex will be in shared memory */ + +void +my_lock_init(char *pathname) +{ + int fd; + pthread_mutexattr_t mattr; + + fd = Open("/dev/zero", O_RDWR, 0); + + mptr = Mmap(0, sizeof(pthread_mutex_t), PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + Close(fd); + + Pthread_mutexattr_init(&mattr); + Pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); + Pthread_mutex_init(mptr, &mattr); +} +/* end my_lock_init */ + +/* include my_lock_wait */ +void +my_lock_wait() +{ + Pthread_mutex_lock(mptr); +} + +void +my_lock_release() +{ + Pthread_mutex_unlock(mptr); +} +/* end my_lock_wait */ diff --git a/server/lock_pthread.lc b/server/lock_pthread.lc new file mode 100644 index 0000000..ac79541 --- /dev/null +++ b/server/lock_pthread.lc @@ -0,0 +1,37 @@ +/* include my_lock_init */ +#include "unpthread.h"## 1 ##src/server/lock_pthread.c## +#include ## 2 ##src/server/lock_pthread.c## + +static pthread_mutex_t *mptr; /* actual mutex will be in shared memory */## 3 ##src/server/lock_pthread.c## + +void## 4 ##src/server/lock_pthread.c## +my_lock_init(char *pathname)## 5 ##src/server/lock_pthread.c## +{## 6 ##src/server/lock_pthread.c## + int fd;## 7 ##src/server/lock_pthread.c## + pthread_mutexattr_t mattr;## 8 ##src/server/lock_pthread.c## + + fd = Open("/dev/zero", O_RDWR, 0);## 9 ##src/server/lock_pthread.c## + + mptr = Mmap(0, sizeof(pthread_mutex_t), PROT_READ | PROT_WRITE,## 10 ##src/server/lock_pthread.c## + MAP_SHARED, fd, 0);## 11 ##src/server/lock_pthread.c## + Close(fd);## 12 ##src/server/lock_pthread.c## + + Pthread_mutexattr_init(&mattr);## 13 ##src/server/lock_pthread.c## + Pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);## 14 ##src/server/lock_pthread.c## + Pthread_mutex_init(mptr, &mattr);## 15 ##src/server/lock_pthread.c## +}## 16 ##src/server/lock_pthread.c## +/* end my_lock_init */ + +/* include my_lock_wait */ +void## 17 ##src/server/lock_pthread.c## +my_lock_wait()## 18 ##src/server/lock_pthread.c## +{## 19 ##src/server/lock_pthread.c## + Pthread_mutex_lock(mptr);## 20 ##src/server/lock_pthread.c## +}## 21 ##src/server/lock_pthread.c## + +void## 22 ##src/server/lock_pthread.c## +my_lock_release()## 23 ##src/server/lock_pthread.c## +{## 24 ##src/server/lock_pthread.c## + Pthread_mutex_unlock(mptr);## 25 ##src/server/lock_pthread.c## +}## 26 ##src/server/lock_pthread.c## +/* end my_lock_wait */ diff --git a/server/meter.c b/server/meter.c new file mode 100644 index 0000000..2f11fbc --- /dev/null +++ b/server/meter.c @@ -0,0 +1,28 @@ +#include "unp.h" +#include + +/* + * Allocate an array of "nchildren" longs in shared memory that can + * be used as a counter by each child of how many clients it services. + * See pp. 467-470 of "Advanced Programming in the Unix Environment." + */ + +long * +meter(int nchildren) +{ + int fd; + long *ptr; + +#ifdef MAP_ANON + ptr = Mmap(0, nchildren*sizeof(long), PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0); +#else + fd = Open("/dev/zero", O_RDWR, 0); + + ptr = Mmap(0, nchildren*sizeof(long), PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + Close(fd); +#endif + + return(ptr); +} diff --git a/server/pr_cpu_time.c b/server/pr_cpu_time.c new file mode 100644 index 0000000..8bc8525 --- /dev/null +++ b/server/pr_cpu_time.c @@ -0,0 +1,29 @@ +#include "unp.h" +#include + +#ifndef HAVE_GETRUSAGE_PROTO +int getrusage(int, struct rusage *); +#endif + +void +pr_cpu_time(void) +{ + double user, sys; + struct rusage myusage, childusage; + + if (getrusage(RUSAGE_SELF, &myusage) < 0) + err_sys("getrusage error"); + if (getrusage(RUSAGE_CHILDREN, &childusage) < 0) + err_sys("getrusage error"); + + user = (double) myusage.ru_utime.tv_sec + + myusage.ru_utime.tv_usec/1000000.0; + user += (double) childusage.ru_utime.tv_sec + + childusage.ru_utime.tv_usec/1000000.0; + sys = (double) myusage.ru_stime.tv_sec + + myusage.ru_stime.tv_usec/1000000.0; + sys += (double) childusage.ru_stime.tv_sec + + childusage.ru_stime.tv_usec/1000000.0; + + printf("\nuser time = %g, sys time = %g\n", user, sys); +} diff --git a/server/pthread07.c b/server/pthread07.c new file mode 100644 index 0000000..6b43629 --- /dev/null +++ b/server/pthread07.c @@ -0,0 +1,34 @@ +#include "unpthread.h" +#include "pthread07.h" + +void +thread_make(int i) +{ + void *thread_main(void *); + + Pthread_create(&tptr[i].thread_tid, NULL, &thread_main, (void *) i); + return; /* main thread returns */ +} + +void * +thread_main(void *arg) +{ + int connfd; + void web_child(int); + socklen_t clilen; + struct sockaddr *cliaddr; + + cliaddr = Malloc(addrlen); + + printf("thread %d starting\n", (int) arg); + for ( ; ; ) { + clilen = addrlen; + Pthread_mutex_lock(&mlock); + connfd = Accept(listenfd, cliaddr, &clilen); + Pthread_mutex_unlock(&mlock); + tptr[(int) arg].thread_count++; + + web_child(connfd); /* process request */ + Close(connfd); + } +} diff --git a/server/pthread07.h b/server/pthread07.h new file mode 100644 index 0000000..5ac04f1 --- /dev/null +++ b/server/pthread07.h @@ -0,0 +1,9 @@ +typedef struct { + pthread_t thread_tid; /* thread ID */ + long thread_count; /* # connections handled */ +} Thread; +Thread *tptr; /* array of Thread structures; calloc'ed */ + +int listenfd, nthreads; +socklen_t addrlen; +pthread_mutex_t mlock; diff --git a/server/pthread07.lc b/server/pthread07.lc new file mode 100644 index 0000000..406fae0 --- /dev/null +++ b/server/pthread07.lc @@ -0,0 +1,34 @@ +#include "unpthread.h"## 1 ##src/server/pthread07.c## +#include "pthread07.h"## 2 ##src/server/pthread07.c## + +void## 3 ##src/server/pthread07.c## +thread_make(int i)## 4 ##src/server/pthread07.c## +{## 5 ##src/server/pthread07.c## + void *thread_main(void *);## 6 ##src/server/pthread07.c## + + Pthread_create(&tptr[i].thread_tid, NULL, &thread_main, (void *) i);## 7 ##src/server/pthread07.c## + return; /* main thread returns */## 8 ##src/server/pthread07.c## +}## 9 ##src/server/pthread07.c## + +void *## 10 ##src/server/pthread07.c## +thread_main(void *arg)## 11 ##src/server/pthread07.c## +{## 12 ##src/server/pthread07.c## + int connfd;## 13 ##src/server/pthread07.c## + void web_child(int);## 14 ##src/server/pthread07.c## + socklen_t clilen;## 15 ##src/server/pthread07.c## + struct sockaddr *cliaddr;## 16 ##src/server/pthread07.c## + + cliaddr = Malloc(addrlen);## 17 ##src/server/pthread07.c## + + printf("thread %d starting\n", (int) arg);## 18 ##src/server/pthread07.c## + for (;;) {## 19 ##src/server/pthread07.c## + clilen = addrlen;## 20 ##src/server/pthread07.c## + Pthread_mutex_lock(&mlock);## 21 ##src/server/pthread07.c## + connfd = Accept(listenfd, cliaddr, &clilen);## 22 ##src/server/pthread07.c## + Pthread_mutex_unlock(&mlock);## 23 ##src/server/pthread07.c## + tptr[(int) arg].thread_count++;## 24 ##src/server/pthread07.c## + + web_child(connfd); /* process the request */## 25 ##src/server/pthread07.c## + Close(connfd);## 26 ##src/server/pthread07.c## + }## 27 ##src/server/pthread07.c## +}## 28 ##src/server/pthread07.c## diff --git a/server/pthread08.c b/server/pthread08.c new file mode 100644 index 0000000..8177cea --- /dev/null +++ b/server/pthread08.c @@ -0,0 +1,33 @@ +#include "unpthread.h" +#include "pthread08.h" + +void +thread_make(int i) +{ + void *thread_main(void *); + + Pthread_create(&tptr[i].thread_tid, NULL, &thread_main, (void *) i); + return; /* main thread returns */ +} + +void * +thread_main(void *arg) +{ + int connfd; + void web_child(int); + + printf("thread %d starting\n", (int) arg); + for ( ; ; ) { + Pthread_mutex_lock(&clifd_mutex); + while (iget == iput) + Pthread_cond_wait(&clifd_cond, &clifd_mutex); + connfd = clifd[iget]; /* connected socket to service */ + if (++iget == MAXNCLI) + iget = 0; + Pthread_mutex_unlock(&clifd_mutex); + tptr[(int) arg].thread_count++; + + web_child(connfd); /* process request */ + Close(connfd); + } +} diff --git a/server/pthread08.h b/server/pthread08.h new file mode 100644 index 0000000..5964553 --- /dev/null +++ b/server/pthread08.h @@ -0,0 +1,10 @@ +typedef struct { + pthread_t thread_tid; /* thread ID */ + long thread_count; /* # connections handled */ +} Thread; +Thread *tptr; /* array of Thread structures; calloc'ed */ + +#define MAXNCLI 32 +int clifd[MAXNCLI], iget, iput; +pthread_mutex_t clifd_mutex; +pthread_cond_t clifd_cond; diff --git a/server/pthread08.lc b/server/pthread08.lc new file mode 100644 index 0000000..8a57aa0 --- /dev/null +++ b/server/pthread08.lc @@ -0,0 +1,33 @@ +#include "unpthread.h"## 1 ##src/server/pthread08.c## +#include "pthread08.h"## 2 ##src/server/pthread08.c## + +void## 3 ##src/server/pthread08.c## +thread_make(int i)## 4 ##src/server/pthread08.c## +{## 5 ##src/server/pthread08.c## + void *thread_main(void *);## 6 ##src/server/pthread08.c## + + Pthread_create(&tptr[i].thread_tid, NULL, &thread_main, (void *) i);## 7 ##src/server/pthread08.c## + return; /* main thread returns */## 8 ##src/server/pthread08.c## +}## 9 ##src/server/pthread08.c## + +void *## 10 ##src/server/pthread08.c## +thread_main(void *arg)## 11 ##src/server/pthread08.c## +{## 12 ##src/server/pthread08.c## + int connfd;## 13 ##src/server/pthread08.c## + void web_child(int);## 14 ##src/server/pthread08.c## + + printf("thread %d starting\n", (int) arg);## 15 ##src/server/pthread08.c## + for (;;) {## 16 ##src/server/pthread08.c## + Pthread_mutex_lock(&clifd_mutex);## 17 ##src/server/pthread08.c## + while (iget == iput)## 18 ##src/server/pthread08.c## + Pthread_cond_wait(&clifd_cond, &clifd_mutex);## 19 ##src/server/pthread08.c## + connfd = clifd[iget]; /* connected socket to service */## 20 ##src/server/pthread08.c## + if (++iget == MAXNCLI)## 21 ##src/server/pthread08.c## + iget = 0;## 22 ##src/server/pthread08.c## + Pthread_mutex_unlock(&clifd_mutex);## 23 ##src/server/pthread08.c## + tptr[(int) arg].thread_count++;## 24 ##src/server/pthread08.c## + + web_child(connfd); /* process the request */## 25 ##src/server/pthread08.c## + Close(connfd);## 26 ##src/server/pthread08.c## + }## 27 ##src/server/pthread08.c## +}## 28 ##src/server/pthread08.c## diff --git a/server/pthread09.c b/server/pthread09.c new file mode 100644 index 0000000..9a2aac1 --- /dev/null +++ b/server/pthread09.c @@ -0,0 +1,32 @@ +#include "unpthread.h" +#include "pthread09.h" + +void +thread_make(int i) +{ + void *thread_main(void *); + + Pthread_create(&tptr[i].thread_tid, NULL, &thread_main, (void *) i); + return; /* main thread returns */ +} + +void * +thread_main(void *arg) +{ + int connfd; + void web_child(int); + socklen_t clilen; + struct sockaddr *cliaddr; + + cliaddr = Malloc(addrlen); + + printf("thread %d starting\n", (int) arg); + for ( ; ; ) { + clilen = addrlen; + connfd = Accept(listenfd, cliaddr, &clilen); + tptr[(int) arg].thread_count++; + + web_child(connfd); /* process the request */ + Close(connfd); + } +} diff --git a/server/pthread09.h b/server/pthread09.h new file mode 100644 index 0000000..1256af8 --- /dev/null +++ b/server/pthread09.h @@ -0,0 +1,8 @@ +typedef struct { + pthread_t thread_tid; /* thread ID */ + long thread_count; /* #connections handled */ +} Thread; +Thread *tptr; /* array of Thread structures; calloc'ed */ + +int listenfd, nthreads; +socklen_t addrlen; diff --git a/server/readline.c b/server/readline.c new file mode 100644 index 0000000..39b5fac --- /dev/null +++ b/server/readline.c @@ -0,0 +1,38 @@ +/* include readline */ +#include "unp.h" + +ssize_t +readline(int fd, void *vptr, size_t maxlen) +{ + ssize_t n, rc; + char c, *ptr; + + ptr = vptr; + for (n = 1; n < maxlen; n++) { + if ( (rc = read(fd, &c, 1)) == 1) { + *ptr++ = c; + if (c == '\n') + break; + } else if (rc == 0) { + if (n == 1) + return(0); /* EOF, no data read */ + else + break; /* EOF, some data was read */ + } else + return(-1); /* error */ + } + + *ptr = 0; + return(n); +} +/* end readline */ + +ssize_t +Readline(int fd, void *ptr, size_t maxlen) +{ + ssize_t n; + + if ( (n = readline(fd, ptr, maxlen)) == -1) + err_sys("readline error"); + return(n); +} diff --git a/server/readline_r.c b/server/readline_r.c new file mode 100644 index 0000000..bc22039 --- /dev/null +++ b/server/readline_r.c @@ -0,0 +1,72 @@ +/* include readline */ +#include "unp.h" +#include "readline_r.h" + +static ssize_t +my_read_r(Rline *rptr, char *ptr) +{ + if (rptr->rl_cnt <= 0) { +again: + rptr->rl_cnt = read(rptr->read_fd, rptr->rl_buf, sizeof(rptr->rl_buf)); + if (rptr->rl_cnt < 0) { + if (errno == EINTR) + goto again; + else + return(-1); + } + else if (rptr->rl_cnt == 0) + return(0); + rptr->rl_bufptr = rptr->rl_buf; + } + + rptr->rl_cnt--; + *ptr = *rptr->rl_bufptr++ & 255; + return(1); +} + +void +readline_rinit(int fd, void *ptr, size_t maxlen, Rline *rptr) +{ + rptr->read_fd = fd; /* save caller's arguments */ + rptr->read_ptr = ptr; + rptr->read_maxlen = maxlen; + + rptr->rl_cnt = 0; /* and init our counter & pointer */ + rptr->rl_bufptr = rptr->rl_buf; +} + +ssize_t +readline_r(Rline *rptr) +{ + int n, rc; + char c, *ptr; + + ptr = rptr->read_ptr; + for (n = 1; n < rptr->read_maxlen; n++) { + if ( (rc = my_read_r(rptr, &c)) == 1) { + *ptr++ = c; + if (c == '\n') + break; + } else if (rc == 0) { + if (n == 1) + return(0); /* EOF, no data read */ + else + break; /* EOF, some data was read */ + } else + return(-1); /* error */ + } + + *ptr = 0; + return(n); +} +/* end readline */ + +ssize_t +Readline_r(Rline *rptr) +{ + ssize_t n; + + if ( (n = readline_r(rptr)) == -1) + err_sys("readline_r error"); + return(n); +} diff --git a/server/readline_r.h b/server/readline_r.h new file mode 100644 index 0000000..9fe1dbe --- /dev/null +++ b/server/readline_r.h @@ -0,0 +1,13 @@ +typedef struct { + int read_fd; /* caller's descriptor to read from */ + char *read_ptr; /* caller's buffer to read into */ + size_t read_maxlen; /* max #bytes to read */ + /* next three are used internally by the function */ + int rl_cnt; /* initialize to 0 */ + char *rl_bufptr; /* initialize to rl_buf */ + char rl_buf[MAXLINE]; +} Rline; + +void readline_rinit(int, void *, size_t, Rline *); +ssize_t readline_r(Rline *); +ssize_t Readline_r(Rline *); diff --git a/server/serv00.c b/server/serv00.c new file mode 100644 index 0000000..6f712ba --- /dev/null +++ b/server/serv00.c @@ -0,0 +1,42 @@ +/* include serv00 */ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + void sig_int(int), web_child(int); + socklen_t clilen, addrlen; + struct sockaddr *cliaddr; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: serv00 [ ] "); + cliaddr = Malloc(addrlen); + + Signal(SIGINT, sig_int); + + for ( ; ; ) { + clilen = addrlen; + connfd = Accept(listenfd, cliaddr, &clilen); + + web_child(connfd); /* process the request */ + + Close(connfd); /* parent closes connected socket */ + } +} +/* end serv00 */ + +/* include sigint */ +void +sig_int(int signo) +{ + void pr_cpu_time(void); + + pr_cpu_time(); + exit(0); +} +/* end sigint */ diff --git a/server/serv01.c b/server/serv01.c new file mode 100644 index 0000000..2d59aa3 --- /dev/null +++ b/server/serv01.c @@ -0,0 +1,52 @@ +/* include serv01 */ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + pid_t childpid; + void sig_chld(int), sig_int(int), web_child(int); + socklen_t clilen, addrlen; + struct sockaddr *cliaddr; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: serv01 [ ] "); + cliaddr = Malloc(addrlen); + + Signal(SIGCHLD, sig_chld); + Signal(SIGINT, sig_int); + + for ( ; ; ) { + clilen = addrlen; + if ( (connfd = accept(listenfd, cliaddr, &clilen)) < 0) { + if (errno == EINTR) + continue; /* back to for() */ + else + err_sys("accept error"); + } + + if ( (childpid = Fork()) == 0) { /* child process */ + Close(listenfd); /* close listening socket */ + web_child(connfd); /* process request */ + exit(0); + } + Close(connfd); /* parent closes connected socket */ + } +} +/* end serv01 */ + +/* include sigint */ +void +sig_int(int signo) +{ + void pr_cpu_time(void); + + pr_cpu_time(); + exit(0); +} +/* end sigint */ diff --git a/server/serv01.lc b/server/serv01.lc new file mode 100644 index 0000000..ebdf33d --- /dev/null +++ b/server/serv01.lc @@ -0,0 +1,52 @@ +/* include serv01 */ +#include "unp.h"## 1 ##src/server/serv01.c## + +int## 2 ##src/server/serv01.c## +main(int argc, char **argv)## 3 ##src/server/serv01.c## +{## 4 ##src/server/serv01.c## + int listenfd, connfd;## 5 ##src/server/serv01.c## + pid_t childpid;## 6 ##src/server/serv01.c## + void sig_chld(int), sig_int(int), web_child(int);## 7 ##src/server/serv01.c## + socklen_t clilen, addrlen;## 8 ##src/server/serv01.c## + struct sockaddr *cliaddr;## 9 ##src/server/serv01.c## + + if (argc == 2)## 10 ##src/server/serv01.c## + listenfd = Tcp_listen(NULL, argv[1], &addrlen);## 11 ##src/server/serv01.c## + else if (argc == 3)## 12 ##src/server/serv01.c## + listenfd = Tcp_listen(argv[1], argv[2], &addrlen);## 13 ##src/server/serv01.c## + else## 14 ##src/server/serv01.c## + err_quit("usage: serv01 [ ] ");## 15 ##src/server/serv01.c## + cliaddr = Malloc(addrlen);## 16 ##src/server/serv01.c## + + Signal(SIGCHLD, sig_chld);## 17 ##src/server/serv01.c## + Signal(SIGINT, sig_int);## 18 ##src/server/serv01.c## + + for (;;) {## 19 ##src/server/serv01.c## + clilen = addrlen;## 20 ##src/server/serv01.c## + if ((connfd = accept(listenfd, cliaddr, &clilen)) < 0) {## 21 ##src/server/serv01.c## + if (errno == EINTR)## 22 ##src/server/serv01.c## + continue; /* back to for() */## 23 ##src/server/serv01.c## + else## 24 ##src/server/serv01.c## + err_sys("accept error");## 25 ##src/server/serv01.c## + }## 26 ##src/server/serv01.c## + + if ((childpid = Fork()) == 0) { /* child process */## 27 ##src/server/serv01.c## + Close(listenfd); /* close listening socket */## 28 ##src/server/serv01.c## + web_child(connfd); /* process the request */## 29 ##src/server/serv01.c## + exit(0);## 30 ##src/server/serv01.c## + }## 31 ##src/server/serv01.c## + Close(connfd); /* parent closes connected socket */## 32 ##src/server/serv01.c## + }## 33 ##src/server/serv01.c## +}## 34 ##src/server/serv01.c## +/* end serv01 */ + +/* include sigint */ +void## 35 ##src/server/serv01.c## +sig_int(int signo)## 36 ##src/server/serv01.c## +{## 37 ##src/server/serv01.c## + void pr_cpu_time(void);## 38 ##src/server/serv01.c## + + pr_cpu_time();## 39 ##src/server/serv01.c## + exit(0);## 40 ##src/server/serv01.c## +}## 41 ##src/server/serv01.c## +/* end sigint */ diff --git a/server/serv02.c b/server/serv02.c new file mode 100644 index 0000000..0afd4a7 --- /dev/null +++ b/server/serv02.c @@ -0,0 +1,52 @@ +/* include serv02 */ +#include "unp.h" + +static int nchildren; +static pid_t *pids; + +int +main(int argc, char **argv) +{ + int listenfd, i; + socklen_t addrlen; + void sig_int(int); + pid_t child_make(int, int, int); + + if (argc == 3) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 4) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: serv02 [ ] <#children>"); + nchildren = atoi(argv[argc-1]); + pids = Calloc(nchildren, sizeof(pid_t)); + + for (i = 0; i < nchildren; i++) + pids[i] = child_make(i, listenfd, addrlen); /* parent returns */ + + Signal(SIGINT, sig_int); + + for ( ; ; ) + pause(); /* everything done by children */ +} +/* end serv02 */ + +/* include sigint */ +void +sig_int(int signo) +{ + int i; + void pr_cpu_time(void); + + /* 4terminate all children */ + for (i = 0; i < nchildren; i++) + kill(pids[i], SIGTERM); + while (wait(NULL) > 0) /* wait for all children */ + ; + if (errno != ECHILD) + err_sys("wait error"); + + pr_cpu_time(); + exit(0); +} +/* end sigint */ diff --git a/server/serv02.lc b/server/serv02.lc new file mode 100644 index 0000000..ae2ca82 --- /dev/null +++ b/server/serv02.lc @@ -0,0 +1,52 @@ +/* include serv02 */ +#include "unp.h"## 1 ##src/server/serv02.c## + +static int nchildren;## 2 ##src/server/serv02.c## +static pid_t *pids;## 3 ##src/server/serv02.c## + +int## 4 ##src/server/serv02.c## +main(int argc, char **argv)## 5 ##src/server/serv02.c## +{## 6 ##src/server/serv02.c## + int listenfd, i;## 7 ##src/server/serv02.c## + socklen_t addrlen;## 8 ##src/server/serv02.c## + void sig_int(int);## 9 ##src/server/serv02.c## + pid_t child_make(int, int, int);## 10 ##src/server/serv02.c## + + if (argc == 3)## 11 ##src/server/serv02.c## + listenfd = Tcp_listen(NULL, argv[1], &addrlen);## 12 ##src/server/serv02.c## + else if (argc == 4)## 13 ##src/server/serv02.c## + listenfd = Tcp_listen(argv[1], argv[2], &addrlen);## 14 ##src/server/serv02.c## + else## 15 ##src/server/serv02.c## + err_quit("usage: serv02 [ ] <#children>");## 16 ##src/server/serv02.c## + nchildren = atoi(argv[argc - 1]);## 17 ##src/server/serv02.c## + pids = Calloc(nchildren, sizeof(pid_t));## 18 ##src/server/serv02.c## + + for (i = 0; i < nchildren; i++)## 19 ##src/server/serv02.c## + pids[i] = child_make(i, listenfd, addrlen); /* parent returns */## 20 ##src/server/serv02.c## + + Signal(SIGINT, sig_int);## 21 ##src/server/serv02.c## + + for (;;)## 22 ##src/server/serv02.c## + pause(); /* everything done by children */## 23 ##src/server/serv02.c## +}## 24 ##src/server/serv02.c## +/* end serv02 */ + +/* include sigint */ +void## 25 ##src/server/serv02.c## +sig_int(int signo)## 26 ##src/server/serv02.c## +{## 27 ##src/server/serv02.c## + int i;## 28 ##src/server/serv02.c## + void pr_cpu_time(void);## 29 ##src/server/serv02.c## + + /* 4terminate all children */## 30 ##src/server/serv02.c## + for (i = 0; i < nchildren; i++)## 31 ##src/server/serv02.c## + kill(pids[i], SIGTERM);## 32 ##src/server/serv02.c## + while (wait(NULL) > 0) /* wait for all children */## 33 ##src/server/serv02.c## + ;## 34 ##src/server/serv02.c## + if (errno != ECHILD)## 35 ##src/server/serv02.c## + err_sys("wait error");## 36 ##src/server/serv02.c## + + pr_cpu_time();## 37 ##src/server/serv02.c## + exit(0);## 38 ##src/server/serv02.c## +}## 39 ##src/server/serv02.c## +/* end sigint */ diff --git a/server/serv02m.c b/server/serv02m.c new file mode 100644 index 0000000..216a1e2 --- /dev/null +++ b/server/serv02m.c @@ -0,0 +1,54 @@ +#include "unp.h" + +static int nchildren; +static pid_t *pids; +long *cptr, *meter(int); /* for counting #clients/child */ + +int +main(int argc, char **argv) +{ + int listenfd, i; + socklen_t addrlen; + void sig_int(int); + pid_t child_make(int, int, int); + + if (argc == 3) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 4) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: serv02 [ ] <#children>"); + nchildren = atoi(argv[argc-1]); + pids = Calloc(nchildren, sizeof(pid_t)); + cptr = meter(nchildren); + + for (i = 0; i < nchildren; i++) + pids[i] = child_make(i, listenfd, addrlen); /* parent returns */ + + Signal(SIGINT, sig_int); + + for ( ; ; ) + pause(); /* everything done by children */ +} + +void +sig_int(int signo) +{ + int i; + void pr_cpu_time(void); + + /* terminate all children */ + for (i = 0; i < nchildren; i++) + kill(pids[i], SIGTERM); + while (wait(NULL) > 0) /* wait for all children */ + ; + if (errno != ECHILD) + err_sys("wait error"); + + pr_cpu_time(); + + for (i = 0; i < nchildren; i++) + printf("child %d, %ld connections\n", i, cptr[i]); + + exit(0); +} diff --git a/server/serv03.c b/server/serv03.c new file mode 100644 index 0000000..6c033f2 --- /dev/null +++ b/server/serv03.c @@ -0,0 +1,49 @@ +#include "unp.h" + +static int nchildren; +static pid_t *pids; + +int +main(int argc, char **argv) +{ + int listenfd, i; + socklen_t addrlen; + void sig_int(int); + pid_t child_make(int, int, int); + + if (argc == 3) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 4) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: serv03 [ ] <#children>"); + nchildren = atoi(argv[argc-1]); + pids = Calloc(nchildren, sizeof(pid_t)); + + my_lock_init("/tmp/lock.XXXXXX"); /* one lock file for all children */ + for (i = 0; i < nchildren; i++) + pids[i] = child_make(i, listenfd, addrlen); /* parent returns */ + + Signal(SIGINT, sig_int); + + for ( ; ; ) + pause(); /* everything done by children */ +} + +void +sig_int(int signo) +{ + int i; + void pr_cpu_time(void); + + /* terminate all children */ + for (i = 0; i < nchildren; i++) + kill(pids[i], SIGTERM); + while (wait(NULL) > 0) /* wait for all children */ + ; + if (errno != ECHILD) + err_sys("wait error"); + + pr_cpu_time(); + exit(0); +} diff --git a/server/serv03m.c b/server/serv03m.c new file mode 100644 index 0000000..70ebe6b --- /dev/null +++ b/server/serv03m.c @@ -0,0 +1,55 @@ +#include "unp.h" + +static int nchildren; +static pid_t *pids; +long *cptr, *meter(int); /* for counting #clients/child */ + +int +main(int argc, char **argv) +{ + int listenfd, i; + socklen_t addrlen; + void sig_int(int); + pid_t child_make(int, int, int); + + if (argc == 3) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 4) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: serv03 [ ] <#children>"); + nchildren = atoi(argv[argc-1]); + pids = Calloc(nchildren, sizeof(pid_t)); + cptr = meter(nchildren); + + my_lock_init("/tmp/lock.XXXXXX"); /* one lock file for all children */ + for (i = 0; i < nchildren; i++) + pids[i] = child_make(i, listenfd, addrlen); /* parent returns */ + + Signal(SIGINT, sig_int); + + for ( ; ; ) + pause(); /* everything done by children */ +} + +void +sig_int(int signo) +{ + int i; + void pr_cpu_time(void); + + /* terminate all children */ + for (i = 0; i < nchildren; i++) + kill(pids[i], SIGTERM); + while (wait(NULL) > 0) /* wait for all children */ + ; + if (errno != ECHILD) + err_sys("wait error"); + + pr_cpu_time(); + + for (i = 0; i < nchildren; i++) + printf("child %d, %ld connections\n", i, cptr[i]); + + exit(0); +} diff --git a/server/serv04.c b/server/serv04.c new file mode 100644 index 0000000..04a86ba --- /dev/null +++ b/server/serv04.c @@ -0,0 +1,49 @@ +#include "unp.h" + +static int nchildren; +static pid_t *pids; + +int +main(int argc, char **argv) +{ + int listenfd, i; + socklen_t addrlen; + void sig_int(int); + pid_t child_make(int, int, int); + + if (argc == 3) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 4) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: serv04 [ ] <#children>"); + nchildren = atoi(argv[argc-1]); + pids = Calloc(nchildren, sizeof(pid_t)); + + my_lock_init(NULL); + for (i = 0; i < nchildren; i++) + pids[i] = child_make(i, listenfd, addrlen); /* parent returns */ + + Signal(SIGINT, sig_int); + + for ( ; ; ) + pause(); /* everything done by children */ +} + +void +sig_int(int signo) +{ + int i; + void pr_cpu_time(void); + + /* terminate all children */ + for (i = 0; i < nchildren; i++) + kill(pids[i], SIGTERM); + while (wait(NULL) > 0) /* wait for all children */ + ; + if (errno != ECHILD) + err_sys("wait error"); + + pr_cpu_time(); + exit(0); +} diff --git a/server/serv05.c b/server/serv05.c new file mode 100644 index 0000000..29d3e0d --- /dev/null +++ b/server/serv05.c @@ -0,0 +1,105 @@ +/* include serv05a */ +#include "unp.h" +#include "child.h" + +static int nchildren; + +int +main(int argc, char **argv) +{ + int listenfd, i, navail, maxfd, nsel, connfd, rc; + void sig_int(int); + pid_t child_make(int, int, int); + ssize_t n; + fd_set rset, masterset; + socklen_t addrlen, clilen; + struct sockaddr *cliaddr; + + if (argc == 3) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 4) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: serv05 [ ] <#children>"); + + FD_ZERO(&masterset); + FD_SET(listenfd, &masterset); + maxfd = listenfd; + cliaddr = Malloc(addrlen); + + nchildren = atoi(argv[argc-1]); + navail = nchildren; + cptr = Calloc(nchildren, sizeof(Child)); + + /* 4prefork all the children */ + for (i = 0; i < nchildren; i++) { + child_make(i, listenfd, addrlen); /* parent returns */ + FD_SET(cptr[i].child_pipefd, &masterset); + maxfd = max(maxfd, cptr[i].child_pipefd); + } + + Signal(SIGINT, sig_int); + + for ( ; ; ) { + rset = masterset; + if (navail <= 0) + FD_CLR(listenfd, &rset); /* turn off if no available children */ + nsel = Select(maxfd + 1, &rset, NULL, NULL, NULL); + + /* 4check for new connections */ + if (FD_ISSET(listenfd, &rset)) { + clilen = addrlen; + connfd = Accept(listenfd, cliaddr, &clilen); + + for (i = 0; i < nchildren; i++) + if (cptr[i].child_status == 0) + break; /* available */ + + if (i == nchildren) + err_quit("no available children"); + cptr[i].child_status = 1; /* mark child as busy */ + cptr[i].child_count++; + navail--; + + n = Write_fd(cptr[i].child_pipefd, "", 1, connfd); + Close(connfd); + if (--nsel == 0) + continue; /* all done with select() results */ + } + + /* 4find any newly-available children */ + for (i = 0; i < nchildren; i++) { + if (FD_ISSET(cptr[i].child_pipefd, &rset)) { + if ( (n = Read(cptr[i].child_pipefd, &rc, 1)) == 0) + err_quit("child %d terminated unexpectedly", i); + cptr[i].child_status = 0; + navail++; + if (--nsel == 0) + break; /* all done with select() results */ + } + } + } +} +/* end serv05a */ + +void +sig_int(int signo) +{ + int i; + void pr_cpu_time(void); + + /* 4terminate all children */ + for (i = 0; i < nchildren; i++) + kill(cptr[i].child_pid, SIGTERM); + while (wait(NULL) > 0) /* wait for all children */ + ; + if (errno != ECHILD) + err_sys("wait error"); + + pr_cpu_time(); + + for (i = 0; i < nchildren; i++) + printf("child %d, %ld connections\n", i, cptr[i].child_count); + + exit(0); +} diff --git a/server/serv05.lc b/server/serv05.lc new file mode 100644 index 0000000..ef959be --- /dev/null +++ b/server/serv05.lc @@ -0,0 +1,105 @@ +/* include serv05a */ +#include "unp.h"## 1 ##src/server/serv05.c## +#include "child.h"## 2 ##src/server/serv05.c## + +static int nchildren;## 3 ##src/server/serv05.c## + +int## 4 ##src/server/serv05.c## +main(int argc, char **argv)## 5 ##src/server/serv05.c## +{## 6 ##src/server/serv05.c## + int listenfd, i, navail, maxfd, nsel, connfd, rc;## 7 ##src/server/serv05.c## + void sig_int(int);## 8 ##src/server/serv05.c## + pid_t child_make(int, int, int);## 9 ##src/server/serv05.c## + ssize_t n;## 10 ##src/server/serv05.c## + fd_set rset, masterset;## 11 ##src/server/serv05.c## + socklen_t addrlen, clilen;## 12 ##src/server/serv05.c## + struct sockaddr *cliaddr;## 13 ##src/server/serv05.c## + + if (argc == 3)## 14 ##src/server/serv05.c## + listenfd = Tcp_listen(NULL, argv[1], &addrlen);## 15 ##src/server/serv05.c## + else if (argc == 4)## 16 ##src/server/serv05.c## + listenfd = Tcp_listen(argv[1], argv[2], &addrlen);## 17 ##src/server/serv05.c## + else## 18 ##src/server/serv05.c## + err_quit("usage: serv05 [ ] <#children>");## 19 ##src/server/serv05.c## + + FD_ZERO(&masterset);## 20 ##src/server/serv05.c## + FD_SET(listenfd, &masterset);## 21 ##src/server/serv05.c## + maxfd = listenfd;## 22 ##src/server/serv05.c## + cliaddr = Malloc(addrlen);## 23 ##src/server/serv05.c## + + nchildren = atoi(argv[argc - 1]);## 24 ##src/server/serv05.c## + navail = nchildren;## 25 ##src/server/serv05.c## + cptr = Calloc(nchildren, sizeof(Child));## 26 ##src/server/serv05.c## + + /* 4prefork all the children */## 27 ##src/server/serv05.c## + for (i = 0; i < nchildren; i++) {## 28 ##src/server/serv05.c## + child_make(i, listenfd, addrlen); /* parent returns */## 29 ##src/server/serv05.c## + FD_SET(cptr[i].child_pipefd, &masterset);## 30 ##src/server/serv05.c## + maxfd = max(maxfd, cptr[i].child_pipefd);## 31 ##src/server/serv05.c## + }## 32 ##src/server/serv05.c## + + Signal(SIGINT, sig_int);## 33 ##src/server/serv05.c## + + for (;;) {## 34 ##src/server/serv05.c## + rset = masterset;## 35 ##src/server/serv05.c## + if (navail <= 0)## 36 ##src/server/serv05.c## + FD_CLR(listenfd, &rset); /* turn off if no available children */## 37 ##src/server/serv05.c## + nsel = Select(maxfd + 1, &rset, NULL, NULL, NULL);## 38 ##src/server/serv05.c## + + /* 4check for new connections */## 39 ##src/server/serv05.c## + if (FD_ISSET(listenfd, &rset)) {## 40 ##src/server/serv05.c## + clilen = addrlen;## 41 ##src/server/serv05.c## + connfd = Accept(listenfd, cliaddr, &clilen);## 42 ##src/server/serv05.c## + + for (i = 0; i < nchildren; i++)## 43 ##src/server/serv05.c## + if (cptr[i].child_status == 0)## 44 ##src/server/serv05.c## + break; /* available */## 45 ##src/server/serv05.c## + + if (i == nchildren)## 46 ##src/server/serv05.c## + err_quit("no available children");## 47 ##src/server/serv05.c## + cptr[i].child_status = 1; /* mark child as busy */## 48 ##src/server/serv05.c## + cptr[i].child_count++;## 49 ##src/server/serv05.c## + navail--;## 50 ##src/server/serv05.c## + + n = Write_fd(cptr[i].child_pipefd, "", 1, connfd);## 51 ##src/server/serv05.c## + Close(connfd);## 52 ##src/server/serv05.c## + if (--nsel == 0)## 53 ##src/server/serv05.c## + continue; /* all done with select() results */## 54 ##src/server/serv05.c## + }## 55 ##src/server/serv05.c## + + /* 4find any newly-available children */## 56 ##src/server/serv05.c## + for (i = 0; i < nchildren; i++) {## 57 ##src/server/serv05.c## + if (FD_ISSET(cptr[i].child_pipefd, &rset)) {## 58 ##src/server/serv05.c## + if ((n = Read(cptr[i].child_pipefd, &rc, 1)) == 0)## 59 ##src/server/serv05.c## + err_quit("child %d terminated unexpectedly", i);## 60 ##src/server/serv05.c## + cptr[i].child_status = 0;## 61 ##src/server/serv05.c## + navail++;## 62 ##src/server/serv05.c## + if (--nsel == 0)## 63 ##src/server/serv05.c## + break; /* all done with select() results */## 64 ##src/server/serv05.c## + }## 65 ##src/server/serv05.c## + }## 66 ##src/server/serv05.c## + }## 67 ##src/server/serv05.c## +}## 68 ##src/server/serv05.c## +/* end serv05a */ + +void## 69 ##src/server/serv05.c## +sig_int(int signo)## 70 ##src/server/serv05.c## +{## 71 ##src/server/serv05.c## + int i;## 72 ##src/server/serv05.c## + void pr_cpu_time(void);## 73 ##src/server/serv05.c## + + /* 4terminate all children */## 74 ##src/server/serv05.c## + for (i = 0; i < nchildren; i++)## 75 ##src/server/serv05.c## + kill(cptr[i].child_pid, SIGTERM);## 76 ##src/server/serv05.c## + while (wait(NULL) > 0) /* wait for all children */## 77 ##src/server/serv05.c## + ;## 78 ##src/server/serv05.c## + if (errno != ECHILD)## 79 ##src/server/serv05.c## + err_sys("wait error");## 80 ##src/server/serv05.c## + + pr_cpu_time();## 81 ##src/server/serv05.c## + + for (i = 0; i < nchildren; i++)## 82 ##src/server/serv05.c## + printf("child %d, %ld connections\n", i, cptr[i].child_count);## 83 ##src/server/serv05.c## + + exit(0);## 84 ##src/server/serv05.c## +}## 85 ##src/server/serv05.c## diff --git a/server/serv06.c b/server/serv06.c new file mode 100644 index 0000000..d19d41f --- /dev/null +++ b/server/serv06.c @@ -0,0 +1,51 @@ +/* include serv06 */ +#include "unpthread.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + void sig_int(int); + void *doit(void *); + pthread_t tid; + socklen_t clilen, addrlen; + struct sockaddr *cliaddr; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: serv06 [ ] "); + cliaddr = Malloc(addrlen); + + Signal(SIGINT, sig_int); + + for ( ; ; ) { + clilen = addrlen; + connfd = Accept(listenfd, cliaddr, &clilen); + + Pthread_create(&tid, NULL, &doit, (void *) connfd); + } +} + +void * +doit(void *arg) +{ + void web_child(int); + + Pthread_detach(pthread_self()); + web_child((int) arg); + Close((int) arg); + return(NULL); +} +/* end serv06 */ + +void +sig_int(int signo) +{ + void pr_cpu_time(void); + + pr_cpu_time(); + exit(0); +} diff --git a/server/serv06.lc b/server/serv06.lc new file mode 100644 index 0000000..4f2b04e --- /dev/null +++ b/server/serv06.lc @@ -0,0 +1,51 @@ +/* include serv06 */ +#include "unpthread.h"## 1 ##src/server/serv06.c## + +int## 2 ##src/server/serv06.c## +main(int argc, char **argv)## 3 ##src/server/serv06.c## +{## 4 ##src/server/serv06.c## + int listenfd, connfd;## 5 ##src/server/serv06.c## + void sig_int(int);## 6 ##src/server/serv06.c## + void *doit(void *);## 7 ##src/server/serv06.c## + pthread_t tid;## 8 ##src/server/serv06.c## + socklen_t clilen, addrlen;## 9 ##src/server/serv06.c## + struct sockaddr *cliaddr;## 10 ##src/server/serv06.c## + + if (argc == 2)## 11 ##src/server/serv06.c## + listenfd = Tcp_listen(NULL, argv[1], &addrlen);## 12 ##src/server/serv06.c## + else if (argc == 3)## 13 ##src/server/serv06.c## + listenfd = Tcp_listen(argv[1], argv[2], &addrlen);## 14 ##src/server/serv06.c## + else## 15 ##src/server/serv06.c## + err_quit("usage: serv06 [ ] ");## 16 ##src/server/serv06.c## + cliaddr = Malloc(addrlen);## 17 ##src/server/serv06.c## + + Signal(SIGINT, sig_int);## 18 ##src/server/serv06.c## + + for (;;) {## 19 ##src/server/serv06.c## + clilen = addrlen;## 20 ##src/server/serv06.c## + connfd = Accept(listenfd, cliaddr, &clilen);## 21 ##src/server/serv06.c## + + Pthread_create(&tid, NULL, &doit, (void *) connfd);## 22 ##src/server/serv06.c## + }## 23 ##src/server/serv06.c## +}## 24 ##src/server/serv06.c## + +void *## 25 ##src/server/serv06.c## +doit(void *arg)## 26 ##src/server/serv06.c## +{## 27 ##src/server/serv06.c## + void web_child(int);## 28 ##src/server/serv06.c## + + Pthread_detach(pthread_self());## 29 ##src/server/serv06.c## + web_child((int) arg);## 30 ##src/server/serv06.c## + Close((int) arg);## 31 ##src/server/serv06.c## + return (NULL);## 32 ##src/server/serv06.c## +}## 33 ##src/server/serv06.c## +/* end serv06 */ + +void## 34 ##src/server/serv06.c## +sig_int(int signo)## 35 ##src/server/serv06.c## +{## 36 ##src/server/serv06.c## + void pr_cpu_time(void);## 37 ##src/server/serv06.c## + + pr_cpu_time();## 38 ##src/server/serv06.c## + exit(0);## 39 ##src/server/serv06.c## +}## 40 ##src/server/serv06.c## diff --git a/server/serv07.c b/server/serv07.c new file mode 100644 index 0000000..112738c --- /dev/null +++ b/server/serv07.c @@ -0,0 +1,44 @@ +/* include serv07 */ +#include "unpthread.h" +#include "pthread07.h" + +pthread_mutex_t mlock = PTHREAD_MUTEX_INITIALIZER; + +int +main(int argc, char **argv) +{ + int i; + void sig_int(int), thread_make(int); + + if (argc == 3) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 4) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: serv07 [ ] <#threads>"); + nthreads = atoi(argv[argc-1]); + tptr = Calloc(nthreads, sizeof(Thread)); + + for (i = 0; i < nthreads; i++) + thread_make(i); /* only main thread returns */ + + Signal(SIGINT, sig_int); + + for ( ; ; ) + pause(); /* everything done by threads */ +} +/* end serv07 */ + +void +sig_int(int signo) +{ + int i; + void pr_cpu_time(void); + + pr_cpu_time(); + + for (i = 0; i < nthreads; i++) + printf("thread %d, %ld connections\n", i, tptr[i].thread_count); + + exit(0); +} diff --git a/server/serv07.lc b/server/serv07.lc new file mode 100644 index 0000000..2e260a2 --- /dev/null +++ b/server/serv07.lc @@ -0,0 +1,44 @@ +/* include serv07 */ +#include "unpthread.h"## 1 ##src/server/serv07.c## +#include "pthread07.h"## 2 ##src/server/serv07.c## + +pthread_mutex_t mlock = PTHREAD_MUTEX_INITIALIZER;## 3 ##src/server/serv07.c## + +int## 4 ##src/server/serv07.c## +main(int argc, char **argv)## 5 ##src/server/serv07.c## +{## 6 ##src/server/serv07.c## + int i;## 7 ##src/server/serv07.c## + void sig_int(int), thread_make(int);## 8 ##src/server/serv07.c## + + if (argc == 3)## 9 ##src/server/serv07.c## + listenfd = Tcp_listen(NULL, argv[1], &addrlen);## 10 ##src/server/serv07.c## + else if (argc == 4)## 11 ##src/server/serv07.c## + listenfd = Tcp_listen(argv[1], argv[2], &addrlen);## 12 ##src/server/serv07.c## + else## 13 ##src/server/serv07.c## + err_quit("usage: serv07 [ ] <#threads>");## 14 ##src/server/serv07.c## + nthreads = atoi(argv[argc - 1]);## 15 ##src/server/serv07.c## + tptr = Calloc(nthreads, sizeof(Thread));## 16 ##src/server/serv07.c## + + for (i = 0; i < nthreads; i++)## 17 ##src/server/serv07.c## + thread_make(i); /* only main thread returns */## 18 ##src/server/serv07.c## + + Signal(SIGINT, sig_int);## 19 ##src/server/serv07.c## + + for (;;)## 20 ##src/server/serv07.c## + pause(); /* everything done by threads */## 21 ##src/server/serv07.c## +}## 22 ##src/server/serv07.c## +/* end serv07 */ + +void## 23 ##src/server/serv07.c## +sig_int(int signo)## 24 ##src/server/serv07.c## +{## 25 ##src/server/serv07.c## + int i;## 26 ##src/server/serv07.c## + void pr_cpu_time(void);## 27 ##src/server/serv07.c## + + pr_cpu_time();## 28 ##src/server/serv07.c## + + for (i = 0; i < nthreads; i++)## 29 ##src/server/serv07.c## + printf("thread %d, %ld connections\n", i, tptr[i].thread_count);## 30 ##src/server/serv07.c## + + exit(0);## 31 ##src/server/serv07.c## +}## 32 ##src/server/serv07.c## diff --git a/server/serv08.c b/server/serv08.c new file mode 100644 index 0000000..2ba4723 --- /dev/null +++ b/server/serv08.c @@ -0,0 +1,63 @@ +/* include serv08 */ +#include "unpthread.h" +#include "pthread08.h" + +static int nthreads; +pthread_mutex_t clifd_mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t clifd_cond = PTHREAD_COND_INITIALIZER; + +int +main(int argc, char **argv) +{ + int i, listenfd, connfd; + void sig_int(int), thread_make(int); + socklen_t addrlen, clilen; + struct sockaddr *cliaddr; + + if (argc == 3) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 4) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: serv08 [ ] <#threads>"); + cliaddr = Malloc(addrlen); + + nthreads = atoi(argv[argc-1]); + tptr = Calloc(nthreads, sizeof(Thread)); + iget = iput = 0; + + /* 4create all the threads */ + for (i = 0; i < nthreads; i++) + thread_make(i); /* only main thread returns */ + + Signal(SIGINT, sig_int); + + for ( ; ; ) { + clilen = addrlen; + connfd = Accept(listenfd, cliaddr, &clilen); + + Pthread_mutex_lock(&clifd_mutex); + clifd[iput] = connfd; + if (++iput == MAXNCLI) + iput = 0; + if (iput == iget) + err_quit("iput = iget = %d", iput); + Pthread_cond_signal(&clifd_cond); + Pthread_mutex_unlock(&clifd_mutex); + } +} +/* end serv08 */ + +void +sig_int(int signo) +{ + int i; + void pr_cpu_time(void); + + pr_cpu_time(); + + for (i = 0; i < nthreads; i++) + printf("thread %d, %ld connections\n", i, tptr[i].thread_count); + + exit(0); +} diff --git a/server/serv08.lc b/server/serv08.lc new file mode 100644 index 0000000..ab4390f --- /dev/null +++ b/server/serv08.lc @@ -0,0 +1,63 @@ +/* include serv08 */ +#include "unpthread.h"## 1 ##src/server/serv08.c## +#include "pthread08.h"## 2 ##src/server/serv08.c## + +static int nthreads;## 3 ##src/server/serv08.c## +pthread_mutex_t clifd_mutex = PTHREAD_MUTEX_INITIALIZER;## 4 ##src/server/serv08.c## +pthread_cond_t clifd_cond = PTHREAD_COND_INITIALIZER;## 5 ##src/server/serv08.c## + +int## 6 ##src/server/serv08.c## +main(int argc, char **argv)## 7 ##src/server/serv08.c## +{## 8 ##src/server/serv08.c## + int i, listenfd, connfd;## 9 ##src/server/serv08.c## + void sig_int(int), thread_make(int);## 10 ##src/server/serv08.c## + socklen_t addrlen, clilen;## 11 ##src/server/serv08.c## + struct sockaddr *cliaddr;## 12 ##src/server/serv08.c## + + if (argc == 3)## 13 ##src/server/serv08.c## + listenfd = Tcp_listen(NULL, argv[1], &addrlen);## 14 ##src/server/serv08.c## + else if (argc == 4)## 15 ##src/server/serv08.c## + listenfd = Tcp_listen(argv[1], argv[2], &addrlen);## 16 ##src/server/serv08.c## + else## 17 ##src/server/serv08.c## + err_quit("usage: serv08 [ ] <#threads>");## 18 ##src/server/serv08.c## + cliaddr = Malloc(addrlen);## 19 ##src/server/serv08.c## + + nthreads = atoi(argv[argc - 1]);## 20 ##src/server/serv08.c## + tptr = Calloc(nthreads, sizeof(Thread));## 21 ##src/server/serv08.c## + iget = iput = 0;## 22 ##src/server/serv08.c## + + /* 4create all the threads */## 23 ##src/server/serv08.c## + for (i = 0; i < nthreads; i++)## 24 ##src/server/serv08.c## + thread_make(i); /* only main thread returns */## 25 ##src/server/serv08.c## + + Signal(SIGINT, sig_int);## 26 ##src/server/serv08.c## + + for (;;) {## 27 ##src/server/serv08.c## + clilen = addrlen;## 28 ##src/server/serv08.c## + connfd = Accept(listenfd, cliaddr, &clilen);## 29 ##src/server/serv08.c## + + Pthread_mutex_lock(&clifd_mutex);## 30 ##src/server/serv08.c## + clifd[iput] = connfd;## 31 ##src/server/serv08.c## + if (++iput == MAXNCLI)## 32 ##src/server/serv08.c## + iput = 0;## 33 ##src/server/serv08.c## + if (iput == iget)## 34 ##src/server/serv08.c## + err_quit("iput = iget = %d", iput);## 35 ##src/server/serv08.c## + Pthread_cond_signal(&clifd_cond);## 36 ##src/server/serv08.c## + Pthread_mutex_unlock(&clifd_mutex);## 37 ##src/server/serv08.c## + }## 38 ##src/server/serv08.c## +}## 39 ##src/server/serv08.c## +/* end serv08 */ + +void## 40 ##src/server/serv08.c## +sig_int(int signo)## 41 ##src/server/serv08.c## +{## 42 ##src/server/serv08.c## + int i;## 43 ##src/server/serv08.c## + void pr_cpu_time(void);## 44 ##src/server/serv08.c## + + pr_cpu_time();## 45 ##src/server/serv08.c## + + for (i = 0; i < nthreads; i++)## 46 ##src/server/serv08.c## + printf("thread %d, %ld connections\n", i, tptr[i].thread_count);## 47 ##src/server/serv08.c## + + exit(0);## 48 ##src/server/serv08.c## +}## 49 ##src/server/serv08.c## diff --git a/server/serv09.c b/server/serv09.c new file mode 100644 index 0000000..9bc0c89 --- /dev/null +++ b/server/serv09.c @@ -0,0 +1,42 @@ +/* include serv09 */ +#include "unpthread.h" +#include "pthread09.h" + +int +main(int argc, char **argv) +{ + int i; + void sig_int(int), thread_make(int); + + if (argc == 3) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 4) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: serv09 [ ] <#threads>"); + nthreads = atoi(argv[argc-1]); + tptr = Calloc(nthreads, sizeof(Thread)); + + for (i = 0; i < nthreads; i++) + thread_make(i); /* only main thread returns */ + + Signal(SIGINT, sig_int); + + for ( ; ; ) + pause(); /* everything done by threads */ +} +/* end serv09 */ + +void +sig_int(int signo) +{ + int i; + void pr_cpu_time(void); + + pr_cpu_time(); + + for (i = 0; i < nthreads; i++) + printf("thread %d, %ld connections\n", i, tptr[i].thread_count); + + exit(0); +} diff --git a/server/sig_chld_waitpid.c b/server/sig_chld_waitpid.c new file mode 100644 index 0000000..b901f9b --- /dev/null +++ b/server/sig_chld_waitpid.c @@ -0,0 +1,13 @@ +#include "unp.h" + +void +sig_chld(int signo) +{ + pid_t pid; + int stat; + + while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) { + /* printf("child %d terminated\n", pid); */ + } + return; +} diff --git a/server/unpthread.h b/server/unpthread.h new file mode 100644 index 0000000..e79b779 --- /dev/null +++ b/server/unpthread.h @@ -0,0 +1,31 @@ +/* Our own header for the programs that use threads. + Include this file, instead of "unp.h". */ + +#ifndef __unp_pthread_h +#define __unp_pthread_h + +#include "unp.h" + +void Pthread_create(pthread_t *, const pthread_attr_t *, + void * (*)(void *), void *); +void Pthread_join(pthread_t, void **); +void Pthread_detach(pthread_t); +void Pthread_kill(pthread_t, int); + +void Pthread_mutexattr_init(pthread_mutexattr_t *); +void Pthread_mutexattr_setpshared(pthread_mutexattr_t *, int); +void Pthread_mutex_init(pthread_mutex_t *, pthread_mutexattr_t *); +void Pthread_mutex_lock(pthread_mutex_t *); +void Pthread_mutex_unlock(pthread_mutex_t *); + +void Pthread_cond_broadcast(pthread_cond_t *); +void Pthread_cond_signal(pthread_cond_t *); +void Pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); +void Pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *, + const struct timespec *); + +void Pthread_key_create(pthread_key_t *, void (*)(void *)); +void Pthread_setspecific(pthread_key_t, const void *); +void Pthread_once(pthread_once_t *, void (*)(void)); + +#endif /* __unp_pthread_h */ diff --git a/server/web_child.c b/server/web_child.c new file mode 100644 index 0000000..c5cc7e1 --- /dev/null +++ b/server/web_child.c @@ -0,0 +1,23 @@ +#include "unp.h" + +#define MAXN 16384 /* max # bytes client can request */ + +void +web_child(int sockfd) +{ + int ntowrite; + ssize_t nread; + char line[MAXLINE], result[MAXN]; + + for ( ; ; ) { + if ( (nread = Readline(sockfd, line, MAXLINE)) == 0) + return; /* connection closed by other end */ + + /* 4line from client specifies #bytes to write back */ + ntowrite = atol(line); + if ((ntowrite <= 0) || (ntowrite > MAXN)) + err_quit("client request for %d bytes", ntowrite); + + Writen(sockfd, result, ntowrite); + } +} diff --git a/server/web_child_r.c b/server/web_child_r.c new file mode 100644 index 0000000..e456fe5 --- /dev/null +++ b/server/web_child_r.c @@ -0,0 +1,26 @@ +#include "unp.h" +#include "readline_r.h" + +#define MAXN 16384 /* max #bytes that a client can request */ + +void +web_child(int sockfd) +{ + int ntowrite; + ssize_t nread; + char line[MAXLINE], result[MAXN]; + Rline rline; + + readline_rinit(sockfd, line, MAXLINE, &rline); + for ( ; ; ) { + if ( (nread = Readline_r(&rline)) == 0) + return; /* connection closed by other end */ + + /* line from client specifies #bytes to write back */ + ntowrite = atol(line); + if ((ntowrite <= 0) || (ntowrite > MAXN)) + err_quit("client request for %d bytes", ntowrite); + + Writen(sockfd, result, ntowrite); + } +} diff --git a/sigio/Makefile b/sigio/Makefile new file mode 100644 index 0000000..6e3fa56 --- /dev/null +++ b/sigio/Makefile @@ -0,0 +1,14 @@ +include ../Make.defines + +PROGS = udpcli01 udpserv01 + +all: ${PROGS} + +udpcli01: udpcli01.o dgcli01.o + ${CC} ${CFLAGS} -o $@ udpcli01.o dgcli01.o ${LIBS} + +udpserv01: udpserv01.o dgecho01.o + ${CC} ${CFLAGS} -o $@ udpserv01.o dgecho01.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/sigio/dgcli01.c b/sigio/dgcli01.c new file mode 100644 index 0000000..b3e9fbd --- /dev/null +++ b/sigio/dgcli01.c @@ -0,0 +1,18 @@ +#include "unp.h" + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL); + + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } +} diff --git a/sigio/dgecho01.c b/sigio/dgecho01.c new file mode 100644 index 0000000..0dd88c6 --- /dev/null +++ b/sigio/dgecho01.c @@ -0,0 +1,120 @@ +/* include dgecho1 */ +#include "unp.h" + +static int sockfd; + +#define QSIZE 8 /* size of input queue */ +#define MAXDG 4096 /* max datagram size */ + +typedef struct { + void *dg_data; /* ptr to actual datagram */ + size_t dg_len; /* length of datagram */ + struct sockaddr *dg_sa; /* ptr to sockaddr{} w/client's address */ + socklen_t dg_salen; /* length of sockaddr{} */ +} DG; +static DG dg[QSIZE]; /* queue of datagrams to process */ +static long cntread[QSIZE+1]; /* diagnostic counter */ + +static int iget; /* next one for main loop to process */ +static int iput; /* next one for signal handler to read into */ +static int nqueue; /* # on queue for main loop to process */ +static socklen_t clilen;/* max length of sockaddr{} */ + +static void sig_io(int); +static void sig_hup(int); +/* end dgecho1 */ + +/* include dgecho2 */ +void +dg_echo(int sockfd_arg, SA *pcliaddr, socklen_t clilen_arg) +{ + int i; + const int on = 1; + sigset_t zeromask, newmask, oldmask; + + sockfd = sockfd_arg; + clilen = clilen_arg; + + for (i = 0; i < QSIZE; i++) { /* init queue of buffers */ + dg[i].dg_data = Malloc(MAXDG); + dg[i].dg_sa = Malloc(clilen); + dg[i].dg_salen = clilen; + } + iget = iput = nqueue = 0; + + Signal(SIGHUP, sig_hup); + Signal(SIGIO, sig_io); + Fcntl(sockfd, F_SETOWN, getpid()); + Ioctl(sockfd, FIOASYNC, &on); + Ioctl(sockfd, FIONBIO, &on); + + Sigemptyset(&zeromask); /* init three signal sets */ + Sigemptyset(&oldmask); + Sigemptyset(&newmask); + Sigaddset(&newmask, SIGIO); /* signal we want to block */ + + Sigprocmask(SIG_BLOCK, &newmask, &oldmask); + for ( ; ; ) { + while (nqueue == 0) + sigsuspend(&zeromask); /* wait for datagram to process */ + + /* 4unblock SIGIO */ + Sigprocmask(SIG_SETMASK, &oldmask, NULL); + + Sendto(sockfd, dg[iget].dg_data, dg[iget].dg_len, 0, + dg[iget].dg_sa, dg[iget].dg_salen); + + if (++iget >= QSIZE) + iget = 0; + + /* 4block SIGIO */ + Sigprocmask(SIG_BLOCK, &newmask, &oldmask); + nqueue--; + } +} +/* end dgecho2 */ + +/* include sig_io */ +static void +sig_io(int signo) +{ + ssize_t len; + int nread; + DG *ptr; + + for (nread = 0; ; ) { + if (nqueue >= QSIZE) + err_quit("receive overflow"); + + ptr = &dg[iput]; + ptr->dg_salen = clilen; + len = recvfrom(sockfd, ptr->dg_data, MAXDG, 0, + ptr->dg_sa, &ptr->dg_salen); + if (len < 0) { + if (errno == EWOULDBLOCK) + break; /* all done; no more queued to read */ + else + err_sys("recvfrom error"); + } + ptr->dg_len = len; + + nread++; + nqueue++; + if (++iput >= QSIZE) + iput = 0; + + } + cntread[nread]++; /* histogram of # datagrams read per signal */ +} +/* end sig_io */ + +/* include sig_hup */ +static void +sig_hup(int signo) +{ + int i; + + for (i = 0; i <= QSIZE; i++) + printf("cntread[%d] = %ld\n", i, cntread[i]); +} +/* end sig_hup */ diff --git a/sigio/dgecho01.lc b/sigio/dgecho01.lc new file mode 100644 index 0000000..22a2ccf --- /dev/null +++ b/sigio/dgecho01.lc @@ -0,0 +1,120 @@ +/* include dgecho1 */ +#include "unp.h"## 1 ##src/sigio/dgecho01.c## + +static int sockfd;## 2 ##src/sigio/dgecho01.c## + +#define QSIZE 8 /* size of input queue */## 3 ##src/sigio/dgecho01.c## +#define MAXDG 4096 /* maximum datagram size */## 4 ##src/sigio/dgecho01.c## + +typedef struct {## 5 ##src/sigio/dgecho01.c## + void *dg_data; /* ptr to actual datagram */## 6 ##src/sigio/dgecho01.c## + size_t dg_len; /* length of datagram */## 7 ##src/sigio/dgecho01.c## + struct sockaddr *dg_sa; /* ptr to sockaddr{} w/client's address */## 8 ##src/sigio/dgecho01.c## + socklen_t dg_salen; /* length of sockaddr{} */## 9 ##src/sigio/dgecho01.c## +} DG;## 10 ##src/sigio/dgecho01.c## +static DG dg[QSIZE]; /* the queue of datagrams to process */## 11 ##src/sigio/dgecho01.c## +static long cntread[QSIZE + 1]; /* diagnostic counter */## 12 ##src/sigio/dgecho01.c## + +static int iget; /* next one for main loop to process */## 13 ##src/sigio/dgecho01.c## +static int iput; /* next one for signal handler to read into */## 14 ##src/sigio/dgecho01.c## +static int nqueue; /* #on queue for main loop to process */## 15 ##src/sigio/dgecho01.c## +static socklen_t clilen; /* max length of sockaddr{} */## 16 ##src/sigio/dgecho01.c## + +static void sig_io(int);## 17 ##src/sigio/dgecho01.c## +static void sig_hup(int);## 18 ##src/sigio/dgecho01.c## +/* end dgecho1 */ + +/* include dgecho2 */ +void## 19 ##src/sigio/dgecho01.c## +dg_echo(int sockfd_arg, SA *pcliaddr, socklen_t clilen_arg)## 20 ##src/sigio/dgecho01.c## +{## 21 ##src/sigio/dgecho01.c## + int i;## 22 ##src/sigio/dgecho01.c## + const int on = 1;## 23 ##src/sigio/dgecho01.c## + sigset_t zeromask, newmask, oldmask;## 24 ##src/sigio/dgecho01.c## + + sockfd = sockfd_arg;## 25 ##src/sigio/dgecho01.c## + clilen = clilen_arg;## 26 ##src/sigio/dgecho01.c## + + for (i = 0; i < QSIZE; i++) { /* init queue of buffers */## 27 ##src/sigio/dgecho01.c## + dg[i].dg_data = Malloc(MAXDG);## 28 ##src/sigio/dgecho01.c## + dg[i].dg_sa = Malloc(clilen);## 29 ##src/sigio/dgecho01.c## + dg[i].dg_salen = clilen;## 30 ##src/sigio/dgecho01.c## + }## 31 ##src/sigio/dgecho01.c## + iget = iput = nqueue = 0;## 32 ##src/sigio/dgecho01.c## + + Signal(SIGHUP, sig_hup);## 33 ##src/sigio/dgecho01.c## + Signal(SIGIO, sig_io);## 34 ##src/sigio/dgecho01.c## + Fcntl(sockfd, F_SETOWN, getpid());## 35 ##src/sigio/dgecho01.c## + Ioctl(sockfd, FIOASYNC, &on);## 36 ##src/sigio/dgecho01.c## + Ioctl(sockfd, FIONBIO, &on);## 37 ##src/sigio/dgecho01.c## + + Sigemptyset(&zeromask); /* init three signal sets */## 38 ##src/sigio/dgecho01.c## + Sigemptyset(&oldmask);## 39 ##src/sigio/dgecho01.c## + Sigemptyset(&newmask);## 40 ##src/sigio/dgecho01.c## + Sigaddset(&newmask, SIGIO); /* the signal we want to block */## 41 ##src/sigio/dgecho01.c## + + Sigprocmask(SIG_BLOCK, &newmask, &oldmask);## 42 ##src/sigio/dgecho01.c## + for (;;) {## 43 ##src/sigio/dgecho01.c## + while (nqueue == 0)## 44 ##src/sigio/dgecho01.c## + sigsuspend(&zeromask); /* wait for a datagram to process */## 45 ##src/sigio/dgecho01.c## + + /* 4unblock SIGIO */## 46 ##src/sigio/dgecho01.c## + Sigprocmask(SIG_SETMASK, &oldmask, NULL);## 47 ##src/sigio/dgecho01.c## + + Sendto(sockfd, dg[iget].dg_data, dg[iget].dg_len, 0,## 48 ##src/sigio/dgecho01.c## + dg[iget].dg_sa, dg[iget].dg_salen);## 49 ##src/sigio/dgecho01.c## + + if (++iget >= QSIZE)## 50 ##src/sigio/dgecho01.c## + iget = 0;## 51 ##src/sigio/dgecho01.c## + + /* 4block SIGIO */## 52 ##src/sigio/dgecho01.c## + Sigprocmask(SIG_BLOCK, &newmask, &oldmask);## 53 ##src/sigio/dgecho01.c## + nqueue--;## 54 ##src/sigio/dgecho01.c## + }## 55 ##src/sigio/dgecho01.c## +}## 56 ##src/sigio/dgecho01.c## +/* end dgecho2 */ + +/* include sig_io */ +static void## 57 ##src/sigio/dgecho01.c## +sig_io(int signo)## 58 ##src/sigio/dgecho01.c## +{## 59 ##src/sigio/dgecho01.c## + ssize_t len;## 60 ##src/sigio/dgecho01.c## + int nread;## 61 ##src/sigio/dgecho01.c## + DG *ptr;## 62 ##src/sigio/dgecho01.c## + + for (nread = 0;;) {## 63 ##src/sigio/dgecho01.c## + if (nqueue >= QSIZE)## 64 ##src/sigio/dgecho01.c## + err_quit("receive overflow");## 65 ##src/sigio/dgecho01.c## + + ptr = &dg[iput];## 66 ##src/sigio/dgecho01.c## + ptr->dg_salen = clilen;## 67 ##src/sigio/dgecho01.c## + len = recvfrom(sockfd, ptr->dg_data, MAXDG, 0,## 68 ##src/sigio/dgecho01.c## + ptr->dg_sa, &ptr->dg_salen);## 69 ##src/sigio/dgecho01.c## + if (len < 0) {## 70 ##src/sigio/dgecho01.c## + if (errno == EWOULDBLOCK)## 71 ##src/sigio/dgecho01.c## + break; /* all done; no more queued to read */## 72 ##src/sigio/dgecho01.c## + else## 73 ##src/sigio/dgecho01.c## + err_sys("recvfrom error");## 74 ##src/sigio/dgecho01.c## + }## 75 ##src/sigio/dgecho01.c## + ptr->dg_len = len;## 76 ##src/sigio/dgecho01.c## + + nread++;## 77 ##src/sigio/dgecho01.c## + nqueue++;## 78 ##src/sigio/dgecho01.c## + if (++iput >= QSIZE)## 79 ##src/sigio/dgecho01.c## + iput = 0;## 80 ##src/sigio/dgecho01.c## + + }## 81 ##src/sigio/dgecho01.c## + cntread[nread]++; /* histogram of #datagrams read per signal */## 82 ##src/sigio/dgecho01.c## +}## 83 ##src/sigio/dgecho01.c## +/* end sig_io */ + +/* include sig_hup */ +static void## 84 ##src/sigio/dgecho01.c## +sig_hup(int signo)## 85 ##src/sigio/dgecho01.c## +{## 86 ##src/sigio/dgecho01.c## + int i;## 87 ##src/sigio/dgecho01.c## + + for (i = 0; i <= QSIZE; i++)## 88 ##src/sigio/dgecho01.c## + printf("cntread[%d] = %ld\n", i, cntread[i]);## 89 ##src/sigio/dgecho01.c## +}## 90 ##src/sigio/dgecho01.c## +/* end sig_hup */ diff --git a/sigio/script.1 b/sigio/script.1 new file mode 100755 index 0000000..3e39f49 --- /dev/null +++ b/sigio/script.1 @@ -0,0 +1,10 @@ +#!/bin/sh + +./udpcli01 140.252.13.35 < /usr/share/misc/termcap > /home/rstevens/temp.1 & +./udpcli01 140.252.13.35 < /usr/share/misc/termcap > /home/rstevens/temp.2 & +./udpcli01 140.252.13.35 < /usr/share/misc/termcap > /home/rstevens/temp.3 & +./udpcli01 140.252.13.35 < /usr/share/misc/termcap > /home/rstevens/temp.4 & +./udpcli01 140.252.13.35 < /usr/share/misc/termcap > /home/rstevens/temp.5 & +./udpcli01 140.252.13.35 < /usr/share/misc/termcap > /home/rstevens/temp.6 & + +wait diff --git a/sigio/script.2 b/sigio/script.2 new file mode 100755 index 0000000..b7a60e6 --- /dev/null +++ b/sigio/script.2 @@ -0,0 +1,10 @@ +#!/bin/sh + +./udpcli01 140.252.13.37 < /usr/share/lib/termcap > /home/rstevens/temp.1 & +./udpcli01 140.252.13.37 < /usr/share/lib/termcap > /home/rstevens/temp.2 & +./udpcli01 140.252.13.37 < /usr/share/lib/termcap > /home/rstevens/temp.3 & +./udpcli01 140.252.13.37 < /usr/share/lib/termcap > /home/rstevens/temp.4 & +./udpcli01 140.252.13.37 < /usr/share/lib/termcap > /home/rstevens/temp.5 & +./udpcli01 140.252.13.37 < /usr/share/lib/termcap > /home/rstevens/temp.6 & + +wait diff --git a/sigio/udpcli01.c b/sigio/udpcli01.c new file mode 100644 index 0000000..24ce753 --- /dev/null +++ b/sigio/udpcli01.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli01 "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/sigio/udpserv01.c b/sigio/udpserv01.c new file mode 100644 index 0000000..a21a857 --- /dev/null +++ b/sigio/udpserv01.c @@ -0,0 +1,19 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr, cliaddr; + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr)); +} diff --git a/sock/Makefile b/sock/Makefile new file mode 100644 index 0000000..b2e3e79 --- /dev/null +++ b/sock/Makefile @@ -0,0 +1,17 @@ +include ../Make.defines + +PROGS = sock +OBJS = buffers.o cliopen.o crlf.o error.o looptcp.o loopudp.o \ + main.o multicast.o pattern.o servopen.o sleepus.o sockopts.o \ + sourceroute.o sourcetcp.o sourceudp.o sinktcp.o sinkudp.o \ + tellwait.o write.o + +all: ${PROGS} + +${OBJS}: sock.h + +sock: ${OBJS} + ${CC} ${CFLAGS} -o $@ ${OBJS} ${LIBS} + +clean: + rm -f ${PROGS} core core.* *.o temp.* *.out typescript* diff --git a/sock/README b/sock/README new file mode 100644 index 0000000..d4ba778 --- /dev/null +++ b/sock/README @@ -0,0 +1,14 @@ + The source files in this directory are all copyrighted (c) 1993 by +W. Richard Stevens. + + This source files in this directory assume tab stops every 4 positions, +not every 8 (the default). Just ":set tabstop=4" in vi, for example. + + If your system doesn't define the POSIX.1 ssize_t data type, then +delete the appropriate #ifdef/#endif lines at the beginning of "ourhdr.h". + + If your system's doesn't define the variables for getopt(), +then delete the appropriate #ifdef/#endif lines at the beginning of "ourhdr.h". + + If your system doesn't support send() and recv() (e.g., OSF/1) then +delete the appropriate #ifdef/#endif lines at the beginning of "ourhdr.h". diff --git a/sock/TODO b/sock/TODO new file mode 100644 index 0000000..34b870f --- /dev/null +++ b/sock/TODO @@ -0,0 +1,4 @@ +- With -v print IP address after gethostbyname returns. + +- First, option to write() in small chunks. Then option to use writev() + instead of write(). See what happens, with and without TCO_NODELAY. diff --git a/sock/buffers.c b/sock/buffers.c new file mode 100644 index 0000000..8caf351 --- /dev/null +++ b/sock/buffers.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" + +void +buffers(int sockfd) +{ + int n; + socklen_t optlen; + + /* Allocate the read and write buffers. */ + + if (rbuf == NULL) { + if ( (rbuf = malloc(readlen)) == NULL) + err_sys("malloc error for read buffer"); + } + + if (wbuf == NULL) { + if ( (wbuf = malloc(writelen)) == NULL) + err_sys("malloc error for write buffer"); + } + + /* Set the socket send and receive buffer sizes (if specified). + The receive buffer size is tied to TCP's advertised window. */ + + if (rcvbuflen) { + if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuflen, + sizeof(rcvbuflen)) < 0) + err_sys("SO_RCVBUF setsockopt error"); + + optlen = sizeof(n); + if (getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &n, &optlen) < 0) + err_sys("SO_RCVBUF getsockopt error"); + if (n != rcvbuflen) + err_quit("rcvbuflen = %d, SO_RCVBUF = %d", rcvbuflen, n); + if (verbose) + fprintf(stderr, "SO_RCVBUF = %d\n", n); + } + + if (sndbuflen) { + if (setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sndbuflen, + sizeof(sndbuflen)) < 0) + err_sys("SO_SNDBUF setsockopt error"); + + optlen = sizeof(n); + if (getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &n, &optlen) < 0) + err_sys("SO_SNDBUF getsockopt error"); + if (n != sndbuflen) + err_quit("sndbuflen = %d, SO_SNDBUF = %d", sndbuflen, n); + if (verbose) + fprintf(stderr, "SO_SNDBUF = %d\n", n); + } +} diff --git a/sock/cliopen.c b/sock/cliopen.c new file mode 100644 index 0000000..e982e01 --- /dev/null +++ b/sock/cliopen.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" + +int +cliopen(char *host, char *port) +{ + int fd, i, on; + const char *protocol; + struct in_addr inaddr; + struct servent *sp; + struct hostent *hp; + + protocol = udp ? "udp" : "tcp"; + + /* initialize socket address structure */ + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + + /* 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); + + /* + * First try to convert the host name as a dotted-decimal number. + * Only if that fails do we call gethostbyname(). + */ + + if (inet_aton(host, &inaddr) == 1) + servaddr.sin_addr = inaddr; /* it's dotted-decimal */ + else if ( (hp = gethostbyname(host)) != NULL) + memcpy(&servaddr.sin_addr, hp->h_addr, hp->h_length); + else + err_quit("invalid hostname: %s", host); + + if ( (fd = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) + err_sys("socket() error"); + + if (reuseaddr) { + on = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0) + err_sys("setsockopt of SO_REUSEADDR error"); + } + +#ifdef SO_REUSEPORT + if (reuseport) { + on = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof (on)) < 0) + err_sys("setsockopt of SO_REUSEPORT error"); + } +#endif + + /* + * User can specify port number for client to bind. Only real use + * is to see a TCP connection initiated by both ends at the same time. + * Also, if UDP is being used, we specifically call bind() to assign + * an ephemeral port to the socket. + * Also, for experimentation, client can also set local IP address + * (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"); + } + + /* Need to allocate buffers before connect(), since they can affect + * TCP options (window scale, etc.). + */ + + buffers(fd); + sockopts(fd, 0); /* may also want to set SO_DEBUG */ + + /* + * Connect to the server. Required for TCP, optional for UDP. + */ + + if (udp == 0 || connectudp) { + for ( ; ; ) { + if (connect(fd, (struct sockaddr *) &servaddr, sizeof(servaddr)) + == 0) + break; /* all OK */ + if (errno == EINTR) /* can happen with SIGIO */ + continue; + if (errno == EISCONN) /* can happen with SIGIO */ + break; + err_sys("connect() error"); + } + } + + if (verbose) { + /* 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)); + } + + sockopts(fd, 1); /* some options get set after connect() */ + + return(fd); +} diff --git a/sock/crlf.c b/sock/crlf.c new file mode 100644 index 0000000..df71a19 --- /dev/null +++ b/sock/crlf.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" + +/* Convert newline to return/newline. */ + +int +crlf_add(char *dst, int dstsize, const char *src, int lenin) +{ + int lenout; + char c; + + if ( (lenout = lenin) > dstsize) + err_quit("crlf_add: destination not big enough"); + + for ( ; lenin > 0; lenin--) { + if ( (c = *src++) == '\n') { + if (++lenout >= dstsize) + err_quit("crlf_add: destination not big enough"); + *dst++ = '\r'; + } + *dst++ = c; + } + + return(lenout); +} + +int +crlf_strip(char *dst, int dstsize, const char *src, int lenin) +{ + int lenout; + char c; + + for (lenout = 0; lenin > 0; lenin--) { + if ( (c = *src++) != '\r') { + if (++lenout >= dstsize) + err_quit("crlf_strip: destination not big enough"); + *dst++ = c; + } + } + + return(lenout); +} diff --git a/sock/error.c b/sock/error.c new file mode 100644 index 0000000..fa26c6f --- /dev/null +++ b/sock/error.c @@ -0,0 +1,103 @@ +#include /* for definition of errno */ +#include /* ANSI C header file */ +#include "ourhdr.h" + +static void err_doit(int, const char *, va_list); + +char *pname = NULL; /* caller can set this from argv[0] */ + +/* Nonfatal error related to a system call. + * Print a message and return. */ + +void +/* $f err_ret $ */ +err_ret(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(1, fmt, ap); + va_end(ap); + return; +} + +/* Fatal error related to a system call. + * Print a message and terminate. */ + +void +/* $f err_sys $ */ +err_sys(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(1, fmt, ap); + va_end(ap); + exit(1); +} + +/* Fatal error related to a system call. + * Print a message, dump core, and terminate. */ + +void +/* $f err_dump $ */ +err_dump(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(1, fmt, ap); + va_end(ap); + abort(); /* dump core and terminate */ + exit(1); /* shouldn't get here */ +} + +/* Nonfatal error unrelated to a system call. + * Print a message and return. */ + +void +/* $f err_msg $ */ +err_msg(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(0, fmt, ap); + va_end(ap); + return; +} + +/* Fatal error unrelated to a system call. + * Print a message and terminate. */ + +void +/* $f err_quit $ */ +err_quit(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + err_doit(0, fmt, ap); + va_end(ap); + exit(1); +} + +/* Print a message and return to caller. + * Caller specifies "errnoflag". */ + +static void +err_doit(int errnoflag, const char *fmt, va_list ap) +{ + int errno_save; + char buf[MAXLINE]; + + errno_save = errno; /* value caller might want printed */ + vsprintf(buf, fmt, ap); + if (errnoflag) + sprintf(buf+strlen(buf), ": %s", strerror(errno_save)); + strcat(buf, "\n"); + fflush(stdout); /* in case stdout and stderr are the same */ + fputs(buf, stderr); + fflush(stderr); /* SunOS 4.1.* doesn't grok NULL argument */ + return; +} diff --git a/sock/loop.c b/sock/loop.c new file mode 100644 index 0000000..c44bfb4 --- /dev/null +++ b/sock/loop.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" + +/* Copy everything from stdin to "sockfd", + * and everything from "sockfd" to stdout. */ + +void tty_atexit(void); /* in library */ +void sig_catch(int); /* my function */ + +void +loop(int sockfd) +{ + int maxfdp1, nread, ntowrite, stdineof, clilen; + fd_set rset; + struct sockaddr_in cliaddr; /* for UDP server */ + +#ifdef MSG_TRUNC /* 4.3BSD Reno and later */ + struct iovec iov[1]; + struct msghdr msg; + +#ifdef IP_RECVDSTADDR /* 4.3BSD Reno and later */ + static struct cmsghdr *cmptr = NULL; /* malloc'ed */ + struct in_addr dstinaddr; /* for UDP server */ +#define CONTROLLEN (sizeof(struct cmsghdr) + sizeof(struct in_addr)) +#endif /* IP_RECVDSTADDR */ + +#endif /* MSG_TRUNC */ + +#ifdef notdef /* following doesn't appear to work */ + /* + * This is an attempt to set stdin to cbreak, so that input characters + * are delivered one at a time, to see Nagle algorithm in effect + * (or disabled). + */ + if (cbreak && isatty(STDIN_FILENO)) { + if (tty_cbreak(STDIN_FILENO) < 0) + err_sys("tty_cbreak error"); + if (atexit(tty_atexit) < 0) + err_sys("tty_atexit error"); + + if (signal(SIGINT, sig_catch) == SIG_ERR) + err_sys("signal error"); + if (signal(SIGQUIT, sig_catch) == SIG_ERR) + err_sys("signal error"); + if (signal(SIGTERM, sig_catch) == SIG_ERR) + err_sys("signal error"); + } +#endif + + if (pauseinit) + sleep(pauseinit); /* intended for server */ + + stdineof = 0; + FD_ZERO(&rset); + maxfdp1 = sockfd + 1; /* check descriptors [0..sockfd] */ + + /* UDP client issues connect(), so read() and write() are used. + Server is harder since cannot issue connect(). We use recvfrom() + or recvmsg(), depending on OS. */ + + for ( ; ; ) { + if (stdineof == 0) + FD_SET(STDIN_FILENO, &rset); + FD_SET(sockfd, &rset); + + if (select(maxfdp1, &rset, NULL, NULL, NULL) < 0) + err_sys("select error"); + + if (FD_ISSET(STDIN_FILENO, &rset)) { /* data to read on stdin */ + if ( (nread = read(STDIN_FILENO, rbuf, readlen)) < 0) + err_sys("read error from stdin"); + else if (nread == 0) { /* EOF on stdin */ + if (halfclose) { + if (shutdown(sockfd, 1) < 0) + err_sys("shutdown() error"); + + FD_CLR(STDIN_FILENO, &rset); + stdineof = 1; /* don't read stdin anymore */ + continue; /* back to select() */ + } + break; /* default: stdin EOF -> done */ + } + + if (crlf) { + ntowrite = crlf_add(wbuf, writelen, rbuf, nread); + if (write(sockfd, wbuf, ntowrite) != ntowrite) + err_sys("write error"); + } else { + if (write(sockfd, rbuf, nread) != nread) + err_sys("write error"); + } + } + + if (FD_ISSET(sockfd, &rset)) { /* data to read from socket */ + if (udp && server) { + clilen = sizeof(cliaddr); +#ifndef MSG_TRUNC /* vanilla BSD sockets */ + nread = recvfrom(sockfd, rbuf, readlen, 0, + (struct sockaddr *) &cliaddr, &clilen); + +#else /* 4.3BSD Reno and later; use recvmsg() to get at MSG_TRUNC flag */ + /* Also lets us get at control information (destination address) */ + + + 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; + +#ifdef IP_RECVDSTADDR + if (cmptr == NULL && (cmptr = malloc(CONTROLLEN)) == NULL) + err_sys("malloc error for control buffer"); + + msg.msg_control = (caddr_t) cmptr; /* for dest address */ + msg.msg_controllen = CONTROLLEN; +#else + msg.msg_control = (caddr_t) 0; /* no ancillary data */ + msg.msg_controllen = 0; +#endif /* IP_RECVDSTADDR */ + msg.msg_flags = 0; /* flags returned here */ + + nread = recvmsg(sockfd, &msg, 0); +#endif /* MSG_TRUNC */ + if (nread < 0) + err_sys("datagram receive error"); + + if (verbose) { + printf("from %s", INET_NTOA(cliaddr.sin_addr)); +#ifdef MSG_TRUNC +#ifdef IP_RECVDSTADDR + if (recvdstaddr) { + if (cmptr->cmsg_level != IPPROTO_IP) + err_quit("control level != IPPROTO_IP"); + if (cmptr->cmsg_type != IP_RECVDSTADDR) + err_quit("control type != IP_RECVDSTADDR"); + if (cmptr->cmsg_len != CONTROLLEN) + err_quit("control length (%d) != %d", + cmptr->cmsg_len, CONTROLLEN); + memcpy((char *) &dstinaddr, (char *) CMSG_DATA(cmptr), + sizeof(struct in_addr)); + + printf(", to %s", INET_NTOA(dstinaddr)); + } +#endif /* IP_RECVDSTADDR */ +#endif /* MSG_TRUNC */ + printf(": "); + fflush(stdout); + } + +#ifdef MSG_TRUNC + if (msg.msg_flags & MSG_TRUNC) + printf("(datagram truncated)\n"); +#endif + + } else { + if ( (nread = read(sockfd, rbuf, readlen)) < 0) + err_sys("read error"); + else if (nread == 0) { + if (verbose) + fprintf(stderr, "connection closed by peer\n"); + break; /* EOF, terminate */ + } + } + + if (crlf) { + ntowrite = crlf_strip(wbuf, writelen, rbuf, nread); + if (writen(STDOUT_FILENO, wbuf, ntowrite) != ntowrite) + err_sys("writen error to stdout"); + } else { + if (writen(STDOUT_FILENO, rbuf, nread) != nread) + err_sys("writen error to stdout"); + } + } + } + + if (pauseclose) { + if (verbose) + fprintf(stderr, "pausing before close\n"); + sleep(pauseclose); + } + + if (close(sockfd) < 0) + err_sys("close error"); /* since SO_LINGER may be set */ +} + +void +sig_catch(int signo) +{ + exit(0); /* exit handler will reset tty state */ +} diff --git a/sock/looptcp.c b/sock/looptcp.c new file mode 100644 index 0000000..cf7b805 --- /dev/null +++ b/sock/looptcp.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" + +/* Copy everything from stdin to "sockfd", + * and everything from "sockfd" to stdout. */ + +void +loop_tcp(int sockfd) +{ + int maxfdp1, nread, ntowrite, stdineof, flags; + fd_set rset; + + if (pauseinit) + sleep_us(pauseinit*1000); /* intended for server */ + + flags = 0; + stdineof = 0; + FD_ZERO(&rset); + maxfdp1 = sockfd + 1; /* check descriptors [0..sockfd] */ + + for ( ; ; ) { + if (stdineof == 0) + FD_SET(STDIN_FILENO, &rset); + FD_SET(sockfd, &rset); + + if (select(maxfdp1, &rset, NULL, NULL, NULL) < 0) + err_sys("select error"); + + if (FD_ISSET(STDIN_FILENO, &rset)) { /* data to read on stdin */ + if ( (nread = read(STDIN_FILENO, rbuf, readlen)) < 0) + err_sys("read error from stdin"); + else if (nread == 0) { /* EOF on stdin */ + if (halfclose) { + if (shutdown(sockfd, SHUT_WR) < 0) + err_sys("shutdown() error"); + + FD_CLR(STDIN_FILENO, &rset); + stdineof = 1; /* don't read stdin anymore */ + continue; /* back to select() */ + } + break; /* default: stdin EOF -> done */ + } + + if (crlf) { + ntowrite = crlf_add(wbuf, writelen, rbuf, nread); + if (dowrite(sockfd, wbuf, ntowrite) != ntowrite) + err_sys("write error"); + } else { + if (dowrite(sockfd, rbuf, nread) != nread) + err_sys("write error"); + } + } + + if (FD_ISSET(sockfd, &rset)) { /* data to read from socket */ + /* msgpeek = 0 or MSG_PEEK */ + flags = msgpeek; + oncemore: + if ( (nread = recv(sockfd, rbuf, readlen, flags)) < 0) + err_sys("recv error"); + else if (nread == 0) { + if (verbose) + fprintf(stderr, "connection closed by peer\n"); + break; /* EOF, terminate */ + } + + if (crlf) { + ntowrite = crlf_strip(wbuf, writelen, rbuf, nread); + if (writen(STDOUT_FILENO, wbuf, ntowrite) != ntowrite) + err_sys("writen error to stdout"); + } else { + if (writen(STDOUT_FILENO, rbuf, nread) != nread) + err_sys("writen error to stdout"); + } + + if (flags != 0) { + flags = 0; /* no infinite loop */ + goto oncemore; /* read the message again */ + } + } + } + + if (pauseclose) { + if (verbose) + fprintf(stderr, "pausing before close\n"); + sleep_us(pauseclose*1000); + } + + if (close(sockfd) < 0) + err_sys("close error"); /* since SO_LINGER may be set */ +} diff --git a/sock/loopudp.c b/sock/loopudp.c new file mode 100644 index 0000000..351f5f0 --- /dev/null +++ b/sock/loopudp.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" + +/* Copy everything from stdin to "sockfd", + * and everything from "sockfd" to stdout. */ + +void +loop_udp(int sockfd) +{ + int maxfdp1, nread, ntowrite, stdineof, + clilen, servlen, flags; + fd_set rset; + struct sockaddr_in cliaddr; /* for UDP server */ + struct sockaddr_in servaddr; /* for UDP client */ + +#ifdef HAVE_MSGHDR_MSG_CONTROL + struct iovec iov[1]; + struct msghdr msg; + +#ifdef IP_RECVDSTADDR /* 4.3BSD Reno and later */ + static struct cmsghdr *cmptr = NULL; /* malloc'ed */ + struct in_addr dstinaddr; /* for UDP server */ +#define CONTROLLEN (sizeof(struct cmsghdr) + sizeof(struct in_addr)) +#endif /* IP_RECVDSTADDR */ + +#endif /* HAVE_MSGHDR_MSG_CONTROL */ + + if (pauseinit) + sleep_us(pauseinit*1000); /* intended for server */ + + flags = 0; + stdineof = 0; + FD_ZERO(&rset); + maxfdp1 = sockfd + 1; /* check descriptors [0..sockfd] */ + + /* If UDP client issues connect(), recv() and write() are used. + Server is harder since cannot issue connect(). We use recvfrom() + or recvmsg(), depending on OS. */ + + for ( ; ; ) { + if (stdineof == 0) + FD_SET(STDIN_FILENO, &rset); + FD_SET(sockfd, &rset); + + if (select(maxfdp1, &rset, NULL, NULL, NULL) < 0) + err_sys("select error"); + + if (FD_ISSET(STDIN_FILENO, &rset)) { /* data to read on stdin */ + if ( (nread = read(STDIN_FILENO, rbuf, readlen)) < 0) + err_sys("read error from stdin"); + else if (nread == 0) { /* EOF on stdin */ + if (halfclose) { + if (shutdown(sockfd, SHUT_WR) < 0) + err_sys("shutdown() error"); + + FD_CLR(STDIN_FILENO, &rset); + stdineof = 1; /* don't read stdin anymore */ + continue; /* back to select() */ + } + break; /* default: stdin EOF -> done */ + } + + if (crlf) { + ntowrite = crlf_add(wbuf, writelen, rbuf, nread); + if (connectudp) { + 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"); + } + } 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 (FD_ISSET(sockfd, &rset)) { /* data to read from socket */ + if (server) { + clilen = sizeof(cliaddr); +#ifndef HAVE_MSGHDR_MSG_CONTROL /* vanilla BSD sockets */ + nread = recvfrom(sockfd, rbuf, readlen, 0, + (struct sockaddr *) &cliaddr, &clilen); + +#else /* 4.3BSD Reno and later; use recvmsg() to get at MSG_TRUNC flag */ + /* Also lets us get at control information (destination address) */ + + + 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; + +#ifdef IP_RECVDSTADDR + if (cmptr == NULL && (cmptr = malloc(CONTROLLEN)) == NULL) + err_sys("malloc error for control buffer"); + + msg.msg_control = (caddr_t) cmptr; /* for dest address */ + msg.msg_controllen = CONTROLLEN; +#else + msg.msg_control = (caddr_t) 0; /* no ancillary data */ + msg.msg_controllen = 0; +#endif /* IP_RECVDSTADDR */ + msg.msg_flags = 0; /* flags returned here */ + + nread = recvmsg(sockfd, &msg, 0); +#endif /* HAVE_MSGHDR_MSG_CONTROL */ + if (nread < 0) + err_sys("datagram receive error"); + + if (verbose) { + printf("from %s", INET_NTOA(cliaddr.sin_addr)); +#ifdef HAVE_MSGHDR_MSG_CONTROL +#ifdef IP_RECVDSTADDR + if (recvdstaddr) { + if (cmptr->cmsg_len != CONTROLLEN) + err_quit("control length (%d) != %d", + 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"); + memcpy(&dstinaddr, CMSG_DATA(cmptr), + sizeof(struct in_addr)); + bzero(cmptr, CONTROLLEN); + + printf(", to %s", INET_NTOA(dstinaddr)); + } +#endif /* IP_RECVDSTADDR */ +#endif /* HAVE_MSGHDR_MSG_CONTROL */ + printf(": "); + fflush(stdout); + } + +#ifdef MSG_TRUNC + if (msg.msg_flags & MSG_TRUNC) + printf("(datagram truncated)\n"); +#endif + + } else if (connectudp) { + /* msgpeek = 0 or MSG_PEEK */ + flags = msgpeek; + oncemore: + if ( (nread = recv(sockfd, rbuf, readlen, flags)) < 0) + err_sys("recv error"); + else if (nread == 0) { + if (verbose) + fprintf(stderr, "connection closed by peer\n"); + break; /* EOF, terminate */ + } + + } else { + /* Must use recvfrom() for unconnected UDP client */ + servlen = sizeof(servaddr); + nread = recvfrom(sockfd, rbuf, readlen, 0, + (struct sockaddr *) &servaddr, &servlen); + if (nread < 0) + err_sys("datagram recvfrom() error"); + + if (verbose) { + printf("from %s", INET_NTOA(servaddr.sin_addr)); + printf(": "); + fflush(stdout); + } + } + + if (crlf) { + ntowrite = crlf_strip(wbuf, writelen, rbuf, nread); + if (writen(STDOUT_FILENO, wbuf, ntowrite) != ntowrite) + err_sys("writen error to stdout"); + } else { + if (writen(STDOUT_FILENO, rbuf, nread) != nread) + err_sys("writen error to stdout"); + } + + if (flags != 0) { + flags = 0; /* no infinite loop */ + goto oncemore; /* read the message again */ + } + } + } + + if (pauseclose) { + if (verbose) + fprintf(stderr, "pausing before close\n"); + sleep_us(pauseclose*1000); + } + + if (close(sockfd) < 0) + err_sys("close error"); /* since SO_LINGER may be set */ +} diff --git a/sock/main.c b/sock/main.c new file mode 100644 index 0000000..dab3d7f --- /dev/null +++ b/sock/main.c @@ -0,0 +1,436 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" + +char *host; /* hostname or dotted-decimal string */ +char *port; + + /* DefinE global variables */ +int bindport; /* 0 or TCP or UDP port number to bind */ + /* 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 */ +int client = 1; /* acting as client is the default */ +int connectudp = 1; /* connect UDP client */ +int crlf; /* convert newline to CR/LF & vice versa */ +int debug; /* SO_DEBUG */ +int dofork; /* concurrent server, do a fork() */ +int dontroute; /* SO_DONTROUTE */ +char foreignip[32]; /* foreign IP address, dotted-decimal string */ +int foreignport; /* foreign port number */ +int halfclose; /* TCP half close option */ +int ignorewerr; /* true if write() errors should be ignored */ +int iptos = -1; /* IP_TOS opton */ +int ipttl = -1; /* IP_TTL opton */ +char joinip[32]; /* multicast IP address, dotted-decimal string */ +int keepalive; /* SO_KEEPALIVE */ +long linger = -1; /* 0 or positive turns on option */ +int listenq = 5; /* listen queue for TCP Server */ +char localip[32]; /* local IP address, dotted-decimal string */ +int maxseg; /* TCP_MAXSEG */ +int mcastttl; /* multicast TTL */ +int msgpeek; /* MSG_PEEK */ +int nodelay; /* TCP_NODELAY (Nagle algorithm) */ +int nbuf = 1024; /* number of buffers to write (sink mode) */ +int onesbcast; /* set IP_ONESBCAST for 255.255.255.255 bcasts */ +int pauseclose; /* #ms to sleep after recv FIN, before close */ +int pauseinit; /* #ms to sleep before first read */ +int pauselisten; /* #ms to sleep after listen() */ +int pauserw; /* #ms to sleep before each read or write */ +int reuseaddr; /* SO_REUSEADDR */ +int reuseport; /* SO_REUSEPORT */ +int readlen = 1024; /* default read length for socket */ +int writelen = 1024; /* default write length for socket */ +int recvdstaddr; /* IP_RECVDSTADDR option */ +int rcvbuflen; /* size for SO_RCVBUF */ +int sndbuflen; /* size for SO_SNDBUF */ +long rcvtimeo; /* SO_RCVTIMEO */ +long sndtimeo; /* SO_SNDTIMEO */ +int sroute_cnt; /* count of #IP addresses in route */ +char *rbuf; /* pointer that is malloc'ed */ +char *wbuf; /* pointer that is malloc'ed */ +int server; /* to act as server requires -s option */ +int sigio; /* send SIGIO */ +int sourcesink; /* source/sink mode */ +int udp; /* use UDP instead of TCP */ +int urgwrite; /* write urgent byte after this write */ +int verbose; /* each -v increments this by 1 */ +int usewritev; /* use writev() instead of write() */ + +struct sockaddr_in cliaddr, servaddr; + +static void usage(const char *); + +int +main(int argc, char *argv[]) +{ + int c, fd; + char *ptr; + + if (argc < 2) + 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) { + switch (c) { +#ifdef IP_ONESBCAST + case '2': /* use 255.255.255.255 as broadcast address */ + onesbcast = 1; + break; +#endif + + case 'b': + bindport = atoi(optarg); + break; + + case 'c': /* convert newline to CR/LF & vice versa */ + crlf = 1; + break; + + case 'f': /* foreign IP address and port#: a.b.c.d.p */ + if ( (ptr = strrchr(optarg, '.')) == NULL) + usage("invalid -f option"); + + *ptr++ = 0; /* null replaces final period */ + foreignport = atoi(ptr); /* port number */ + strcpy(foreignip, optarg); /* save dotted-decimal IP */ + break; + + case 'g': /* loose source route */ + sroute_doopt(0, optarg); + break; + + case 'h': /* TCP half-close option */ + halfclose = 1; + break; + + case 'i': /* source/sink option */ + sourcesink = 1; + break; + +#ifdef IP_ADD_MEMBERSHIP + case 'j': /* join multicast group a.b.c.d */ + strcpy(joinip, optarg); /* save dotted-decimal IP */ + break; +#endif + + case 'k': /* chunk-write option */ + chunkwrite = 1; + break; + + case 'l': /* local IP address and port#: a.b.c.d.p */ + if ( (ptr = strrchr(optarg, '.')) == NULL) + usage("invalid -l option"); + + *ptr++ = 0; /* null replaces final period */ + bindport = atoi(ptr); /* port number */ + strcpy(localip, optarg); /* save dotted-decimal IP */ + break; + + case 'n': /* number of buffers to write */ + nbuf = atol(optarg); + break; + + case 'o': /* do not connect UDP client */ + connectudp = 0; + break; + + case 'p': /* pause before each read or write */ + pauserw = atoi(optarg); + break; + + case 'q': /* listen queue for TCP server */ + listenq = atoi(optarg); + break; + + case 'r': /* read() length */ + readlen = atoi(optarg); + break; + + case 's': /* server */ + server = 1; + client = 0; + break; + +#ifdef IP_MULTICAST_TTL + case 't': /* IP_MULTICAST_TTL */ + mcastttl = atoi(optarg); + break; +#endif + + case 'u': /* use UDP instead of TCP */ + udp = 1; + break; + + case 'v': /* output what's going on */ + verbose++; + break; + + case 'w': /* write() length */ + writelen = atoi(optarg); + break; + + case 'x': /* SO_RCVTIMEO socket option */ + rcvtimeo = atol(optarg); + break; + + case 'y': /* SO_SNDTIMEO socket option */ + sndtimeo = atol(optarg); + break; + + case 'A': /* SO_REUSEADDR socket option */ + reuseaddr = 1; + break; + + case 'B': /* SO_BROADCAST socket option */ + broadcast = 1; + break; + + case 'C': /* set standard input to cbreak mode */ + cbreak = 1; + break; + + case 'D': /* SO_DEBUG socket option */ + debug = 1; + break; + + case 'E': /* IP_RECVDSTADDR socket option */ + recvdstaddr = 1; + break; + + case 'F': /* concurrent server, do a fork() */ + dofork = 1; + break; + + case 'G': /* strict source route */ + sroute_doopt(1, optarg); + break; + +#ifdef IP_TOS + case 'H': /* IP_TOS socket option */ + iptos = atoi(optarg); + break; +#endif + + case 'I': /* SIGIO signal */ + sigio = 1; + break; + +#ifdef IP_TTL + case 'J': /* IP_TTL socket option */ + ipttl = atoi(optarg); + break; +#endif + + case 'K': /* SO_KEEPALIVE socket option */ + keepalive = 1; + break; + + case 'L': /* SO_LINGER socket option */ + linger = atol(optarg); + break; + + case 'N': /* SO_NODELAY socket option */ + nodelay = 1; + break; + + case 'O': /* pause before listen(), before first accept() */ + pauselisten = atoi(optarg); + break; + + case 'P': /* pause before first read() */ + pauseinit = atoi(optarg); + break; + + case 'Q': /* pause after receiving FIN, but before close() */ + pauseclose = atoi(optarg); + break; + + case 'R': /* SO_RCVBUF socket option */ + rcvbuflen = atoi(optarg); + break; + + case 'S': /* SO_SNDBUF socket option */ + sndbuflen = atoi(optarg); + break; + +#ifdef SO_REUSEPORT + case 'T': /* SO_REUSEPORT socket option */ + reuseport = 1; + break; +#endif + + case 'U': /* when to write urgent byte */ + urgwrite = atoi(optarg); + break; + + case 'V': /* use writev() instead of write() */ + usewritev = 1; + chunkwrite = 1; /* implies this option too */ + break; + + case 'W': /* ignore write errors */ + ignorewerr = 1; + break; + + case 'X': /* TCP maximum segment size option */ + maxseg = atoi(optarg); + break; + + case 'Y': /* SO_DONTROUTE socket option */ + dontroute = 1; + break; + + case 'Z': /* MSG_PEEK option */ + msgpeek = MSG_PEEK; + break; + + case '?': + usage("unrecognized option"); + } + } + + /* check for options that don't make sense */ + if (udp && halfclose) + usage("can't specify -h and -u"); + if (udp && debug) + usage("can't specify -D and -u"); + if (udp && linger >= 0) + usage("can't specify -L and -u"); + if (udp && nodelay) + usage("can't specify -N and -u"); +#ifdef notdef + if (udp == 0 && broadcast) + usage("can't specify -B with TCP"); +#endif + if (udp == 0 && foreignip[0] != 0) + usage("can't specify -f with TCP"); + + if (client) { + if (optind != argc-2) + usage("missing and/or "); + host = argv[optind]; + port = argv[optind+1]; + + } else { + /* If server specifies host and port, then local address is + bound to the "host" argument, instead of being wildcarded. */ + if (optind == argc-2) { + host = argv[optind]; + port = argv[optind+1]; + } else if (optind == argc-1) { + host = NULL; + port = argv[optind]; + } else + usage("missing "); + } + + if (client) + fd = cliopen(host, port); + else + fd = servopen(host, port); + + if (sourcesink) { /* ignore stdin/stdout */ + if (client) { + if (udp) + source_udp(fd); + else + source_tcp(fd); + } else { + if (udp) + sink_udp(fd); + else + sink_tcp(fd); + } + + } else { /* copy stdin/stdout to/from socket */ + if (udp) + loop_udp(fd); + else + loop_tcp(fd); + } + + exit(0); +} + +static void +usage(const char *msg) +{ + err_msg( +"usage: sock [ options ] (for client; default)\n" +" sock [ options ] -s [ ] (for server)\n" +" sock [ options ] -i (for \"source\" client)\n" +" sock [ options ] -i -s [ ] (for \"sink\" server)\n" +"options: -b n bind n as client's local port number\n" +" -c convert newline to CR/LF & vice versa\n" +" -f a.b.c.d.p foreign IP address = a.b.c.d, foreign port # = p\n" +" -g a.b.c.d loose source route\n" +" -h issue TCP half close on standard input EOF\n" +" -i \"source\" data to socket, \"sink\" data from socket (w/-s)\n" +#ifdef IP_ADD_MEMBERSHIP +" -j a.b.c.d join multicast group\n" +#endif +" -k write or writev in chunks\n" +" -l a.b.c.d.p client's local IP address = a.b.c.d, local port # = p\n" +" -n n # buffers to write for \"source\" client (default 1024)\n" +" -o do NOT connect UDP client\n" +" -p n # ms to pause before each read or write (source/sink)\n" +" -q n size of listen queue for TCP server (default 5)\n" +" -r n # bytes per read() for \"sink\" server (default 1024)\n" +" -s operate as server instead of client\n" +#ifdef IP_MULTICAST_TTL +" -t n set multicast ttl\n" +#endif +" -u use UDP instead of TCP\n" +" -v verbose\n" +" -w n # bytes per write() for \"source\" client (default 1024)\n" +" -x n # ms for SO_RCVTIMEO (receive timeout)\n" +" -y n # ms for SO_SNDTIMEO (send timeout)\n" +" -A SO_REUSEADDR option\n" +" -B SO_BROADCAST option\n" +" -C set terminal to cbreak mode\n" +" -D SO_DEBUG option\n" +" -E IP_RECVDSTADDR option\n" +" -F fork after connection accepted (TCP concurrent server)\n" +" -G a.b.c.d strict source route\n" +#ifdef IP_TOS +" -H n IP_TOS option (16=min del, 8=max thru, 4=max rel, 2=min$)\n" +#endif +" -I SIGIO signal\n" +#ifdef IP_TTL +" -J n IP_TTL option\n" +#endif +" -K SO_KEEPALIVE option\n" +" -L n SO_LINGER option, n = linger time\n" +" -N TCP_NODELAY option\n" +" -O n # ms to pause after listen, but before first accept\n" +" -P n # ms to pause before first read or write (source/sink)\n" +" -Q n # ms to pause after receiving FIN, but before close\n" +" -R n SO_RCVBUF option\n" +" -S n SO_SNDBUF option\n" +#ifdef SO_REUSEPORT +" -T SO_REUSEPORT option\n" +#endif +" -U n enter urgent mode before write number n (source only)\n" +" -V use writev() instead of write(); enables -k too\n" +" -W ignore write errors for sink client\n" +" -X n TCP_MAXSEG option (set MSS)\n" +" -Y SO_DONTROUTE option\n" +" -Z MSG_PEEK\n" +#ifdef IP_ONESBCAST +" -2 IP_ONESBCAST option (255.255.255.255 for broadcast\n" +#endif +); + + if (msg[0] != 0) + err_quit("%s", msg); + exit(1); +} diff --git a/sock/multicast.c b/sock/multicast.c new file mode 100644 index 0000000..0aa1fb4 --- /dev/null +++ b/sock/multicast.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" + +void +join_mcast(int fd, struct sockaddr_in *sin) +{ +#ifdef IP_ADD_MEMBERSHIP /* only include if host supports mcasting */ + u_long inaddr; + struct ip_mreq mreq; + + inaddr = sin->sin_addr.s_addr; + if (IN_MULTICAST(inaddr) == 0) + return; /* not a multicast address */ + + 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 (verbose) + fprintf(stderr, "multicast group joined\n"); +#endif /* IP_ADD_MEMBERSHIP */ +} diff --git a/sock/ourhdr.h b/sock/ourhdr.h new file mode 100644 index 0000000..358781e --- /dev/null +++ b/sock/ourhdr.h @@ -0,0 +1,121 @@ +/* Our own header, to be included *after* all standard system headers */ + +#ifndef __ourhdr_h +#define __ourhdr_h + +#include /* required for some of our prototypes */ +#include /* for convenience */ +#include /* for convenience */ +#include /* for convenience */ +#include /* for convenience */ + +#ifdef notdef /* delete for systems that don't define this (SunOS 4.x) */ +typedef int ssize_t; +#endif + +#ifdef notdef /* delete if doesn't define these for getopt() */ +extern char *optarg; +extern int optind, opterr, optopt; +#endif + +#ifdef notdef /* delete if send() not supported (DEC OSF/1) */ +#define send(a,b,c,d) sendto((a), (b), (c), (d), (struct sockaddr *) NULL, 0) +#endif + +#define MAXLINE 4096 /* max line length */ + +#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) + /* default file access permissions for new files */ +#define DIR_MODE (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH) + /* default permissions for new directories */ + +typedef void Sigfunc(int); /* for signal handlers */ + + /* 4.3BSD Reno doesn't define SIG_ERR */ +#if defined(SIG_IGN) && !defined(SIG_ERR) +#define SIG_ERR ((Sigfunc *)-1) +#endif + +#define min(a,b) ((a) < (b) ? (a) : (b)) +#define max(a,b) ((a) > (b) ? (a) : (b)) + + /* prototypes for our own functions */ +char *path_alloc(int *); /* {Prog pathalloc} */ +int open_max(void); /* {Prog openmax} */ +void clr_fl(int, int); /* {Prog setfl} */ +void set_fl(int, int); /* {Prog setfl} */ +void pr_exit(int); /* {Prog prexit} */ +void pr_mask(const char *); /* {Prog prmask} */ +Sigfunc *signal_intr(int, Sigfunc *);/* {Prog signal_intr_function} */ + +int tty_cbreak(int); /* {Prog raw} */ +int tty_raw(int); /* {Prog raw} */ +int tty_reset(int); /* {Prog raw} */ +void tty_atexit(void); /* {Prog raw} */ +#ifdef ECHO /* only if has been included */ +struct termios *tty_termios(void); /* {Prog raw} */ +#endif + +void sleep_us(unsigned int); /* {Ex sleepus} */ +ssize_t readn(int, void *, size_t);/* {Prog readn} */ +ssize_t writen(int, const void *, size_t);/* {Prog writen} */ +int daemon_init(void); /* {Prog daemoninit} */ + +int s_pipe(int *); /* {Progs svr4_spipe bsd_spipe} */ +int recv_fd(int, ssize_t (*func)(int, const void *, size_t)); + /* {Progs recvfd_svr4 recvfd_43bsd} */ +int send_fd(int, int); /* {Progs sendfd_svr4 sendfd_43bsd} */ +int send_err(int, int, const char *);/* {Prog senderr} */ +int serv_listen(const char *); /* {Progs servlisten_svr4 servlisten_44bsd} */ +int serv_accept(int, uid_t *); /* {Progs servaccept_svr4 servaccept_44bsd} */ +int cli_conn(const char *); /* {Progs cliconn_svr4 cliconn_44bsd} */ +int buf_args(char *, int (*func)(int, char **)); + /* {Prog bufargs} */ + +int ptym_open(char *); /* {Progs ptyopen_svr4 ptyopen_44bsd} */ +int ptys_open(int, char *); /* {Progs ptyopen_svr4 ptyopen_44bsd} */ +#ifdef TIOCGWINSZ +pid_t pty_fork(int *, char *, const struct termios *, + const struct winsize *); /* {Prog ptyfork} */ +#endif + +int lock_reg(int, int, int, off_t, int, off_t); + /* {Prog lockreg} */ +#define read_lock(fd, offset, whence, len) \ + lock_reg(fd, F_SETLK, F_RDLCK, offset, whence, len) +#define readw_lock(fd, offset, whence, len) \ + lock_reg(fd, F_SETLKW, F_RDLCK, offset, whence, len) +#define write_lock(fd, offset, whence, len) \ + lock_reg(fd, F_SETLK, F_WRLCK, offset, whence, len) +#define writew_lock(fd, offset, whence, len) \ + lock_reg(fd, F_SETLKW, F_WRLCK, offset, whence, len) +#define un_lock(fd, offset, whence, len) \ + lock_reg(fd, F_SETLK, F_UNLCK, offset, whence, len) + +pid_t lock_test(int, int, off_t, int, off_t); + /* {Prog locktest} */ + +#define is_readlock(fd, offset, whence, len) \ + lock_test(fd, F_RDLCK, offset, whence, len) +#define is_writelock(fd, offset, whence, len) \ + lock_test(fd, F_WRLCK, offset, whence, len) + +void err_dump(const char *, ...); /* {App misc_source} */ +void err_msg(const char *, ...); +void err_quit(const char *, ...); +void err_ret(const char *, ...); +void err_sys(const char *, ...); + +void log_msg(const char *, ...); /* {App misc_source} */ +void log_open(const char *, int, int); +void log_quit(const char *, ...); +void log_ret(const char *, ...); +void log_sys(const char *, ...); + +void TELL_WAIT(void); /* parent/child from {Sec race_conditions} */ +void TELL_PARENT(pid_t); +void TELL_CHILD(pid_t); +void WAIT_PARENT(void); +void WAIT_CHILD(void); + +#endif /* __ourhdr_h */ diff --git a/sock/pattern.c b/sock/pattern.c new file mode 100644 index 0000000..e41f5b6 --- /dev/null +++ b/sock/pattern.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" +#include + +void +pattern(char *ptr, int len) +{ + char c; + + c = 0; + while(len-- > 0) { + while(isprint((c & 0x7F)) == 0) + c++; /* skip over nonprinting characters */ + *ptr++ = (c++ & 0x7F); + } +} diff --git a/sock/servopen.c b/sock/servopen.c new file mode 100644 index 0000000..08a268a --- /dev/null +++ b/sock/servopen.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" + +int +servopen(char *host, char *port) +{ + int fd, newfd, i, on, pid; + const char *protocol; + struct in_addr inaddr; + struct servent *sp; + + protocol = udp ? "udp" : "tcp"; + + /* Initialize the socket address structure */ + bzero(&servaddr, sizeof(servaddr)); + servaddr.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; + } + + /* 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); + + if ( (fd = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) + err_sys("socket() error"); + + if (reuseaddr) { + on = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) + err_sys("setsockopt of SO_REUSEADDR error"); + } + +#ifdef SO_REUSEPORT + if (reuseport) { + on = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0) + err_sys("setsockopt of SO_REUSEPORT error"); + } +#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"); + + join_mcast(fd, &servaddr); + + if (udp) { + buffers(fd); + + if (foreignip[0] != 0) { /* connect to foreignip/port# */ + bzero(&cliaddr, sizeof(cliaddr)); + if (inet_aton(foreignip, &cliaddr.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 */ + + if (connect(fd, (struct sockaddr *) &cliaddr, sizeof(cliaddr)) + < 0) + err_sys("connect() error"); + + } + + sockopts(fd, 1); + + return(fd); /* nothing else to do */ + } + + 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 (dofork) + TELL_WAIT(); /* initialize synchronization primitives */ + + for ( ; ; ) { + i = sizeof(cliaddr); + if ( (newfd = accept(fd, (struct sockaddr *) &cliaddr, &i)) < 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() */ + } else { + close(fd); /* child closes listening socket */ + } + } + + /* 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"); + + /* 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)); + } + + 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 */ + + if (dofork) + TELL_PARENT(getppid()); /* tell parent we're done with terminal */ + + return(newfd); + } +} diff --git a/sock/sinktcp.c b/sock/sinktcp.c new file mode 100644 index 0000000..91e88ba --- /dev/null +++ b/sock/sinktcp.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" + +void +sink_tcp(int sockfd) +{ + int n, flags; + + if (pauseinit) + sleep_us(pauseinit*1000); + + for ( ; ; ) { /* read until peer closes connection; -n opt ignored */ + /* msgpeek = 0 or MSG_PEEK */ + flags = msgpeek; + oncemore: + if ( (n = recv(sockfd, rbuf, readlen, flags)) < 0) { + err_sys("recv error"); + + } else if (n == 0) { + if (verbose) + fprintf(stderr, "connection closed by peer\n"); + break; + +#ifdef notdef /* following not possible with TCP */ + } else if (n != readlen) + err_quit("read returned %d, expected %d", n, readlen); +#else + } +#endif + + if (verbose) + fprintf(stderr, "received %d bytes%s\n", n, + (flags == MSG_PEEK) ? " (MSG_PEEK)" : ""); + + if (pauserw) + sleep_us(pauserw*1000); + + if (flags != 0) { + flags = 0; /* no infinite loop */ + goto oncemore; /* read the message again */ + } + } + + if (pauseclose) { /* pausing here puts peer into FIN_WAIT_2 */ + if (verbose) + fprintf(stderr, "pausing before close\n"); + sleep_us(pauseclose*1000); + } + + if (close(sockfd) < 0) + err_sys("close error"); /* since SO_LINGER may be set */ +} diff --git a/sock/sinkudp.c b/sock/sinkudp.c new file mode 100644 index 0000000..1a0dae1 --- /dev/null +++ b/sock/sinkudp.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" + +void +sink_udp(int sockfd) /* TODO: use recvfrom ?? */ +{ + int n, flags; + + if (pauseinit) + sleep_us(pauseinit*1000); + + for ( ; ; ) { /* read until peer closes connection; -n opt ignored */ + /* msgpeek = 0 or MSG_PEEK */ + flags = msgpeek; + oncemore: + if ( (n = recv(sockfd, rbuf, readlen, flags)) < 0) { + err_sys("recv error"); + + } else if (n == 0) { + if (verbose) + fprintf(stderr, "connection closed by peer\n"); + break; + +#ifdef notdef /* following not possible with TCP */ + } else if (n != readlen) + err_quit("read returned %d, expected %d", n, readlen); +#else + } +#endif + + if (verbose) { + fprintf(stderr, "received %d bytes%s\n", n, + (flags == MSG_PEEK) ? " (MSG_PEEK)" : ""); + if (verbose > 1) { + fprintf(stderr, "printing %d bytes\n", n); + rbuf[n] = 0; /* make certain it's null terminated */ + fprintf(stderr, "SDAP header: %lx\n", *((long *) rbuf)); + fprintf(stderr, "next long: %lx\n", *((long *) rbuf+4)); + fputs(&rbuf[8], stderr); + } + } + + if (pauserw) + sleep_us(pauserw*1000); + + if (flags != 0) { + flags = 0; /* avoid infinite loop */ + goto oncemore; /* read the message again */ + } + } + + if (pauseclose) { + if (verbose) + fprintf(stderr, "pausing before close\n"); + sleep_us(pauseclose*1000); + } + + if (close(sockfd) < 0) + err_sys("close error"); +} diff --git a/sock/sleepus.c b/sock/sleepus.c new file mode 100644 index 0000000..37eaec2 --- /dev/null +++ b/sock/sleepus.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include +#include "ourhdr.h" + +void +sleep_us(unsigned int nusecs) +{ + struct timeval tval; + + for ( ; ; ) { + tval.tv_sec = nusecs / 1000000; + tval.tv_usec = nusecs % 1000000; + if (select(0, NULL, NULL, NULL, &tval) == 0) + break; /* all OK */ + /* + * Note than on an interrupted system call (i.e, SIGIO) there's not + * much we can do, since the timeval{} isn't updated with the time + * remaining. We could obtain the clock time before the call, and + * then obtain the clock time here, subtracting them to determine + * how long select() blocked before it was interrupted, but that + * seems like too much work :-) + */ + if (errno == EINTR) + continue; + err_sys("sleep_us: select error"); + } +} diff --git a/sock/sock.h b/sock/sock.h new file mode 100644 index 0000000..1a7c240 --- /dev/null +++ b/sock/sock.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "unp.h" + +#include +#ifdef __bsdi__ +#include /* required before tcp.h, for BYTE_ORDER */ +#endif +#include /* TCP_NODELAY */ +#include /* getservbyname(), gethostbyname() */ + + /* declare global variables */ +extern int bindport; +extern int broadcast; +extern int cbreak; +extern int chunkwrite; +extern int client; +extern int connectudp; +extern int crlf; +extern int debug; +extern int dofork; +extern int dontroute; +extern char foreignip[]; +extern int foreignport; +extern int halfclose; +extern int ignorewerr; +extern int iptos; +extern int ipttl; +extern char joinip[]; +extern int keepalive; +extern long linger; +extern int listenq; +extern char localip[]; +extern int maxseg; +extern int mcastttl; +extern int msgpeek; +extern int nodelay; +extern int nbuf; +extern int onesbcast; +extern int pauseclose; +extern int pauseinit; +extern int pauselisten; +extern int pauserw; +extern int reuseaddr; +extern int reuseport; +extern int readlen; +extern int writelen; +extern int recvdstaddr; +extern int rcvbuflen; +extern int sndbuflen; +extern long rcvtimeo; +extern long sndtimeo; +extern char *rbuf; +extern char *wbuf; +extern int server; +extern int sigio; +extern int sourcesink; +extern int sroute_cnt; +extern int udp; +extern int urgwrite; +extern int verbose; +extern int usewritev; + +extern struct sockaddr_in cliaddr, servaddr; + +/* Earlier versions of gcc under SunOS 4.x have problems passing arguments + that are structs (as opposed to pointers to structs). This shows up + with inet_ntoa, whose argument is a "struct in_addr". */ + +#if defined(sun) && defined(__GNUC__) && defined(GCC_STRUCT_PROBLEM) +#define INET_NTOA(foo) inet_ntoa(&foo) +#else +#define INET_NTOA(foo) inet_ntoa(foo) +#endif + + /* function prototypes */ +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 loop_tcp(int); +void loop_udp(int); +void pattern(char *, int); +int servopen(char *, char *); +void sink_tcp(int); +void sink_udp(int); +void source_tcp(int); +void source_udp(int); +void sroute_doopt(int, char *); +void sroute_set(int); +void sleep_us(unsigned int); +void sockopts(int, int); +ssize_t dowrite(int, const void *, size_t); + +void TELL_WAIT(void); +void TELL_PARENT(pid_t); +void WAIT_PARENT(void); +void TELL_CHILD(pid_t); +void WAIT_CHILD(void); diff --git a/sock/sock.in b/sock/sock.in new file mode 100644 index 0000000..2d42c2f --- /dev/null +++ b/sock/sock.in @@ -0,0 +1 @@ +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 diff --git a/sock/sockopts.c b/sock/sockopts.c new file mode 100644 index 0000000..6e276de --- /dev/null +++ b/sock/sockopts.c @@ -0,0 +1,361 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" +#include +#include + +void +sockopts(int sockfd, int doall) +{ + int option, optlen; + struct linger ling; + struct timeval timer; + + /* "doall" is 0 for a server's listening socket (i.e., before + accept() has returned.) Some socket options such as SO_KEEPALIVE + don't make sense at this point, while others like SO_DEBUG do. */ + + if (debug) { + option = 1; + if (setsockopt(sockfd, SOL_SOCKET, SO_DEBUG, + &option, sizeof(option)) < 0) + err_sys("SO_DEBUG setsockopt error"); + + option = 0; + optlen = sizeof(option); + if (getsockopt(sockfd, SOL_SOCKET, SO_DEBUG, + &option, &optlen) < 0) + err_sys("SO_DEBUG getsockopt error"); + if (option == 0) + err_quit("SO_DEBUG not set (%d)", option); + + if (verbose) + fprintf(stderr, "SO_DEBUG set\n"); + } + + if (dontroute) { + option = 1; + if (setsockopt(sockfd, SOL_SOCKET, SO_DONTROUTE, + &option, sizeof(option)) < 0) + err_sys("SO_DONTROUTE setsockopt error"); + + option = 0; + optlen = sizeof(option); + if (getsockopt(sockfd, SOL_SOCKET, SO_DONTROUTE, + &option, &optlen) < 0) + err_sys("SO_DONTROUTE getsockopt error"); + if (option == 0) + err_quit("SO_DONTROUTE not set (%d)", option); + + if (verbose) + fprintf(stderr, "SO_DONTROUTE set\n"); + } + +#ifdef IP_TOS + if (iptos != -1 && doall == 0) { + if (setsockopt(sockfd, IPPROTO_IP, IP_TOS, + &iptos, sizeof(iptos)) < 0) + err_sys("IP_TOS setsockopt error"); + + option = 0; + optlen = sizeof(option); + if (getsockopt(sockfd, IPPROTO_IP, IP_TOS, + &option, &optlen) < 0) + err_sys("IP_TOS getsockopt error"); + if (option != iptos) + err_quit("IP_TOS not set (%d)", option); + + if (verbose) + fprintf(stderr, "IP_TOS set to %d\n", iptos); + } +#endif + +#ifdef IP_TTL + if (ipttl != -1 && doall == 0) { + if (setsockopt(sockfd, IPPROTO_IP, IP_TTL, + &ipttl, sizeof(ipttl)) < 0) + err_sys("IP_TTL setsockopt error"); + + option = 0; + optlen = sizeof(option); + if (getsockopt(sockfd, IPPROTO_IP, IP_TTL, + &option, &optlen) < 0) + err_sys("IP_TTL getsockopt error"); + if (option != ipttl) + err_quit("IP_TTL not set (%d)", option); + + if (verbose) + fprintf(stderr, "IP_TTL set to %d\n", ipttl); + } +#endif + + if (maxseg && udp == 0) { + /* Need to set MSS for server before connection established */ + /* Beware: some kernels do not let the process set this socket + option; others only let it be decreased. */ + if (setsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, + &maxseg, sizeof(maxseg)) < 0) + err_sys("TCP_MAXSEG setsockopt error"); + + option = 0; + optlen = sizeof(option); + if (getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, + &option, &optlen) < 0) + err_sys("TCP_MAXSEG getsockopt error"); + + if (verbose) + fprintf(stderr, "TCP_MAXSEG = %d\n", option); + } + + if (sroute_cnt > 0) + sroute_set(sockfd); + + if (broadcast) { + option = 1; + if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, + &option, sizeof(option)) < 0) + err_sys("SO_BROADCAST setsockopt error"); + + option = 0; + optlen = sizeof(option); + if (getsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, + &option, &optlen) < 0) + err_sys("SO_BROADCAST getsockopt error"); + if (option == 0) + err_quit("SO_BROADCAST not set (%d)", option); + + if (verbose) + fprintf(stderr, "SO_BROADCAST set\n"); + +#ifdef IP_ONESBCAST + if (onesbcast) { + option = 1; + if (setsockopt(sockfd, IPPROTO_IP, IP_ONESBCAST, + &option, sizeof(option)) < 0) + err_sys("IP_ONESBCAST setsockopt error"); + + option = 0; + optlen = sizeof(option); + if (getsockopt(sockfd, IPPROTO_IP, IP_ONESBCAST, + &option, &optlen) < 0) + err_sys("IP_ONESBCAST getsockopt error"); + if (option == 0) + err_quit("IP_ONESBCAST not set (%d)", option); + + if (verbose) + fprintf(stderr, "IP_ONESBCAST set\n"); + } +#endif + } + +#ifdef IP_ADD_MEMBERSHIP + if (joinip[0]) { + struct ip_mreq join; + + 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, + &join, sizeof(join)) < 0) + err_sys("IP_ADD_MEMBERSHIP setsockopt error"); + + if (verbose) + fprintf(stderr, "IP_ADD_MEMBERSHIP set\n"); + } +#endif + +#ifdef IP_MULTICAST_TTL + if (mcastttl) { + u_char ttl = mcastttl; + + if (setsockopt(sockfd, IPPROTO_IP, 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, + &ttl, &optlen) < 0) + err_sys("IP_MULTICAST_TTL getsockopt error"); + if (ttl != mcastttl) + err_quit("IP_MULTICAST_TTL not set (%d)", ttl); + + if (verbose) + fprintf(stderr, "IP_MULTICAST_TTL set to %d\n", ttl); + } +#endif + + if (keepalive && doall && udp == 0) { + option = 1; + if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, + &option, sizeof(option)) < 0) + err_sys("SO_KEEPALIVE setsockopt error"); + + option = 0; + optlen = sizeof(option); + if (getsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, + &option, &optlen) < 0) + err_sys("SO_KEEPALIVE getsockopt error"); + if (option == 0) + err_quit("SO_KEEPALIVE not set (%d)", option); + + if (verbose) + fprintf(stderr, "SO_KEEPALIVE set\n"); + } + + if (nodelay && doall && udp == 0) { + option = 1; + if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, + &option, sizeof(option)) < 0) + err_sys("TCP_NODELAY setsockopt error"); + + option = 0; + optlen = sizeof(option); + if (getsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, + &option, &optlen) < 0) + err_sys("TCP_NODELAY getsockopt error"); + if (option == 0) + err_quit("TCP_NODELAY not set (%d)", option); + + if (verbose) + fprintf(stderr, "TCP_NODELAY set\n"); + } + + if (doall && verbose && udp == 0) { /* just print MSS if verbose */ + option = 0; + optlen = sizeof(option); + if (getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, + &option, &optlen) < 0) + err_sys("TCP_MAXSEG getsockopt error"); + + fprintf(stderr, "TCP_MAXSEG = %d\n", option); + } + + if (linger >= 0 && doall && udp == 0) { + ling.l_onoff = 1; + ling.l_linger = linger; /* 0 for abortive disconnect */ + if (setsockopt(sockfd, SOL_SOCKET, SO_LINGER, + &ling, sizeof(ling)) < 0) + err_sys("SO_LINGER setsockopt error"); + + ling.l_onoff = 0; + ling.l_linger = -1; + optlen = sizeof(struct linger); + if (getsockopt(sockfd, SOL_SOCKET, SO_LINGER, + &ling, &optlen) < 0) + err_sys("SO_LINGER getsockopt error"); + if (ling.l_onoff == 0 || ling.l_linger != linger) + err_quit("SO_LINGER not set (%d, %d)", ling.l_onoff, ling.l_linger); + + if (verbose) + fprintf(stderr, "linger %s, time = %d\n", + ling.l_onoff ? "on" : "off", ling.l_linger); + } + + if (doall && rcvtimeo) { +#ifdef SO_RCVTIMEO + /* User specifies millisec, must convert to sec/usec */ + timer.tv_sec = rcvtimeo / 1000; + timer.tv_usec = (rcvtimeo % 1000) * 1000; + if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, + &timer, sizeof(timer)) < 0) + err_sys("SO_RCVTIMEO setsockopt error"); + + timer.tv_sec = timer.tv_usec = 0; + optlen = sizeof(timer); + if (getsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, + &timer, &optlen) < 0) + err_sys("SO_RCVTIMEO getsockopt error"); + + if (verbose) + fprintf(stderr, "SO_RCVTIMEO: %ld.%06ld\n", + timer.tv_sec, timer.tv_usec); +#else + fprintf(stderr, "warning: SO_RCVTIMEO not supported by host\n"); +#endif + } + + if (doall && sndtimeo) { +#ifdef SO_SNDTIMEO + /* User specifies millisec, must convert to sec/usec */ + timer.tv_sec = sndtimeo / 1000; + timer.tv_usec = (sndtimeo % 1000) * 1000; + if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, + &timer, sizeof(timer)) < 0) + err_sys("SO_SNDTIMEO setsockopt error"); + + timer.tv_sec = timer.tv_usec = 0; + optlen = sizeof(timer); + if (getsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, + &timer, &optlen) < 0) + err_sys("SO_SNDTIMEO getsockopt error"); + + if (verbose) + fprintf(stderr, "SO_SNDTIMEO: %ld.%06ld\n", + timer.tv_sec, timer.tv_usec); +#else + fprintf(stderr, "warning: SO_SNDTIMEO not supported by host\n"); +#endif + } + + if (recvdstaddr && udp) { +#ifdef IP_RECVDSTADDR + option = 1; + if (setsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, + &option, sizeof(option)) < 0) + err_sys("IP_RECVDSTADDR setsockopt error"); + + option = 0; + optlen = sizeof(option); + if (getsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, + &option, &optlen) < 0) + err_sys("IP_RECVDSTADDR getsockopt error"); + if (option == 0) + err_quit("IP_RECVDSTADDR not set (%d)", option); + + if (verbose) + fprintf(stderr, "IP_RECVDSTADDR set\n"); +#else + fprintf(stderr, "warning: IP_RECVDSTADDR not supported by host\n"); +#endif + } + + if (sigio) { +#ifdef FIOASYNC + static void sigio_func(int); + + /* + * Should be able to set this with fcntl(O_ASYNC) or fcntl(FASYNC), + * but some systems (AIX?) only do it with ioctl(). + * + * Need to set this for listening socket and for connected socket. + */ + signal(SIGIO, sigio_func); + + if (fcntl(sockfd, F_SETOWN, getpid()) < 0) + err_sys("fcntl F_SETOWN error"); + + option = 1; + if (ioctl(sockfd, FIOASYNC, (char *) &option) < 0) + err_sys("ioctl FIOASYNC error"); + + if (verbose) + fprintf(stderr, "FIOASYNC set\n"); +#else + fprintf(stderr, "warning: FIOASYNC not supported by host\n"); +#endif + } +} + +static void +sigio_func(int signo) +{ + fprintf(stderr, "SIGIO\n"); + /* shouldn't printf from a signal handler ... */ +} diff --git a/sock/sourceroute.c b/sock/sourceroute.c new file mode 100644 index 0000000..acb393c --- /dev/null +++ b/sock/sourceroute.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" +#include +#include + +/* + * There is a fundamental limit of 9 IP addresses in a source route. + * But we allocate sroute_opt[44] with room for 10 IP addresses (and + * the 3-byte source route type/len/offset) because with the BSD + * IP_OPTIONS socket option we can specify up to 9 addresses, followed + * by the destination address. The in_pcbopts() function in the kernel + * then takes the final address in the list (the destination) and moves + * it to the front, as shown in Figure 9.33 of "TCP/IP Illustrated, + * Volume 2". Also note that this destination address that we pass as + * the final IP address in our array overrides the destination address + * of the sendto() (Figure 9.28 of Volume 2). + */ + +u_char sroute_opt[44]; /* some implementations require this to be + on a 4-byte boundary */ +u_char *optr; /* pointer into options being formed */ + +/* + * Process either the -g (loose) or -G (strict) command-line option, + * specifying one hop in a source route. + * Either option can be specified up to 9 times. + * With IPv4 the entire source route is either loose or strict, but we + * set the source route type field based on the first option encountered, + * either -g or -G. + */ + +void +sroute_doopt(int strict, char *argptr) +{ + struct in_addr inaddr; + struct hostent *hp; + + if (sroute_cnt >= 9) + err_quit("too many source routes with: %s", argptr); + + if (sroute_cnt == 0) { /* first one */ + bzero(sroute_opt, sizeof(sroute_opt)); + optr = sroute_opt; + *optr++ = strict ? IPOPT_SSRR : IPOPT_LSRR; + optr++; /* we fill in the total length later */ + *optr++ = 4; /* ptr to first source-route address */ + } + + if (inet_aton(argptr, &inaddr) == 1) { + memcpy(optr, &inaddr, sizeof(u_long)); /* dotted decimal */ + if (verbose) + fprintf(stderr, "source route to %s\n", inet_ntoa(inaddr)); + } else if ( (hp = gethostbyname(argptr)) != NULL) { + memcpy(optr, hp->h_addr, sizeof(u_long));/* hostname */ + if (verbose) + fprintf(stderr, "source route to %s\n", + inet_ntoa(*((struct in_addr *) hp->h_addr))); + } else + err_quit("unknown host: %s\n", argptr); + + optr += sizeof(u_long); /* for next IP addr in list */ + sroute_cnt++; +} + +/* + * Set the actual source route with the IP_OPTIONS socket option. + * This function is called if srouce_cnt is nonzero. + * The final destination goes at the end of the list of IP addresses. + */ + +void +sroute_set(int sockfd) +{ + sroute_cnt++; /* account for destination */ + sroute_opt[1] = 3 + (sroute_cnt * 4);/* total length, incl. destination */ + + /* destination must be stored as final entry */ + memcpy(optr, &servaddr.sin_addr, 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 size %d bytes\n", sroute_opt[1]); + } + + /* + * The number of bytes that we pass to setsockopt() must be a multiple + * of 4. Since the buffer was initialized to 0, this leaves an EOL + * following the final IP address. + * For optimization we could put a NOP before the 3-byte type/len/offset + * field, which would then align all the IP addresses on 4-byte boundaries, + * but the source routing code is not exactly in the fast path of most + * routers. + */ + while ((optr - sroute_opt) & 3) + optr++; + + if (setsockopt(sockfd, IPPROTO_IP, IP_OPTIONS, + sroute_opt, optr - sroute_opt) < 0) + err_sys("setsockopt error for IP_OPTIONS"); + + sroute_cnt = 0; /* don't call this function again */ +} diff --git a/sock/sourcesink.c b/sock/sourcesink.c new file mode 100644 index 0000000..0a00845 --- /dev/null +++ b/sock/sourcesink.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" +#include + +void pattern(char *ptr, int len); + +void +sink(int sockfd) +{ + int i, n; + char oob; + + if (client) { + pattern(wbuf, writelen); /* fill send buffer with a pattern */ + + if (pauseinit) + sleep(pauseinit); + + for (i = 1; i <= nbuf; i++) { + if (urgwrite == i) { + oob = urgwrite; + if ( (n = send(sockfd, &oob, 1, MSG_OOB)) != 1) + err_sys("send of MSG_OOB returned %d, expected %d", + n, writelen); + if (verbose) + fprintf(stderr, "wrote %d byte of urgent data\n", n); + } + + if ( (n = write(sockfd, wbuf, writelen)) != writelen) + err_sys("write returned %d, expected %d", n, writelen); + if (verbose) + fprintf(stderr, "wrote %d bytes\n", n); + + if (pauserw) + sleep(pauserw); + } + + } else { + + if (pauseinit) + sleep(pauseinit); + + for ( ; ; ) { + if ( (n = read(sockfd, rbuf, readlen)) < 0) { + err_sys("read error"); + + } else if (n == 0) { + break; /* connection closed by peer */ + + } else if (n != readlen) + err_quit("read returned %d, expected %d", n, readlen); + + if (verbose) + fprintf(stderr, "received %d bytes\n", n); + + if (pauserw) + sleep(pauserw); + } + } + + if (pauseclose) { + if (verbose) + fprintf(stderr, "pausing before close\n"); + sleep(pauseclose); + } + + if (close(sockfd) < 0) + err_sys("close error"); /* since SO_LINGER may be set */ +} + +void +pattern(char *ptr, int len) +{ + char c; + + c = 0; + while(len-- > 0) { + while(isprint((c & 0x7F)) == 0) + c++; /* skip over nonprinting characters */ + *ptr++ = (c++ & 0x7F); + } +} diff --git a/sock/sourcetcp.c b/sock/sourcetcp.c new file mode 100644 index 0000000..a399594 --- /dev/null +++ b/sock/sourcetcp.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" + +void +source_tcp(int sockfd) +{ + int i, n, option; + socklen_t optlen; + char oob; + + pattern(wbuf, writelen); /* fill send buffer with a pattern */ + + if (pauseinit) + sleep_us(pauseinit*1000); + + for (i = 1; i <= nbuf; i++) { + if (urgwrite == i) { + oob = urgwrite; + if ( (n = send(sockfd, &oob, 1, MSG_OOB)) != 1) + err_sys("send of MSG_OOB returned %d, expected %d", + n, writelen); + if (verbose) + fprintf(stderr, "wrote %d byte of urgent data\n", n); + } + + 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 */ + 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); + + } else if (verbose) + fprintf(stderr, "wrote %d bytes\n", n); + + if (pauserw) + sleep_us(pauserw*1000); + } + + if (pauseclose) { + if (verbose) + fprintf(stderr, "pausing before close\n"); + sleep_us(pauseclose*1000); + } + + if (close(sockfd) < 0) + err_sys("close error"); /* since SO_LINGER may be set */ +} diff --git a/sock/sourceudp.c b/sock/sourceudp.c new file mode 100644 index 0000000..b305ca1 --- /dev/null +++ b/sock/sourceudp.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" + +void +source_udp(int sockfd) /* TODO: use sendto ?? */ +{ + int i, n, option; + socklen_t optlen; + + pattern(wbuf, writelen); /* fill send buffer with a pattern */ + + if (pauseinit) + sleep_us(pauseinit*1000); + + for (i = 1; i <= nbuf; i++) { + 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 */ + 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); + } + } else { + if ( (n = sendto(sockfd, wbuf, writelen, 0, + (struct sockaddr *) &servaddr, + sizeof(servaddr))) != 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 (verbose) + fprintf(stderr, "wrote %d bytes\n", n); + + if (pauserw) + sleep_us(pauserw*1000); + } + + if (pauseclose) { + if (verbose) + fprintf(stderr, "pausing before close\n"); + sleep_us(pauseclose*1000); + } + + if (close(sockfd) < 0) + err_sys("close error"); /* since SO_LINGER may be set */ +} diff --git a/sock/strerror.c b/sock/strerror.c new file mode 100644 index 0000000..1c11d9e --- /dev/null +++ b/sock/strerror.c @@ -0,0 +1,16 @@ +#include + +extern const char *const sys_errlist[]; +extern int sys_nerr; + +char * +strerror(int error) +{ + static char mesg[30]; + + if (error >= 0 && error <= sys_nerr) + return(sys_errlist[error]); + + snprintf(mesg, sizeof(mesg), "Unknown error (%d)", error); + return(mesg); +} diff --git a/sock/tellwait.c b/sock/tellwait.c new file mode 100644 index 0000000..53f4e9b --- /dev/null +++ b/sock/tellwait.c @@ -0,0 +1,67 @@ +#include +#include "ourhdr.h" + +static volatile sig_atomic_t sigflag; + /* set nonzero by signal handler */ +static sigset_t newmask, oldmask, zeromask; + +static void +sig_usr(int signo) /* one signal handler for SIGUSR1 and SIGUSR2 */ +{ + sigflag = 1; + return; +} + +void +TELL_WAIT() +{ + if (signal(SIGUSR1, sig_usr) == SIG_ERR) + err_sys("signal(SIGINT) error"); + if (signal(SIGUSR2, sig_usr) == SIG_ERR) + err_sys("signal(SIGQUIT) error"); + + sigemptyset(&zeromask); + + sigemptyset(&newmask); + sigaddset(&newmask, SIGUSR1); + sigaddset(&newmask, SIGUSR2); + /* block SIGUSR1 and SIGUSR2, and save current signal mask */ + if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) + err_sys("SIG_BLOCK error"); +} + +void +TELL_PARENT(pid_t pid) +{ + kill(pid, SIGUSR2); /* tell parent we're done */ +} + +void +WAIT_PARENT(void) +{ + while (sigflag == 0) + sigsuspend(&zeromask); /* and wait for parent */ + + sigflag = 0; + /* reset signal mask to original value */ + if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) + err_sys("SIG_SETMASK error"); +} + +void +TELL_CHILD(pid_t pid) +{ + kill(pid, SIGUSR1); /* tell child we're done */ +} + +void +WAIT_CHILD(void) +{ + while (sigflag == 0) + sigsuspend(&zeromask); /* and wait for child */ + + sigflag = 0; + /* reset signal mask to original value */ + if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) + err_sys("SIG_SETMASK error"); +} diff --git a/sock/write.c b/sock/write.c new file mode 100644 index 0000000..205524d --- /dev/null +++ b/sock/write.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 1993 W. Richard Stevens. All rights reserved. + * Permission to use or modify this software and its documentation only for + * educational purposes and without fee is hereby granted, provided that + * the above copyright notice appear in all copies. The author makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "sock.h" +#include /* for writev() */ + +#ifndef UIO_MAXIOV +#define UIO_MAXIOV 16 /* we assume this; may not be true? */ +#endif + +ssize_t +dowrite(int fd, const void *vptr, size_t nbytes) +{ + struct iovec iov[UIO_MAXIOV]; + const char *ptr; + int chunksize, i, n, nleft, nwritten, ntotal; + + if (chunkwrite == 0 && usewritev == 0) + return(write(fd, vptr, nbytes)); /* common case */ + + /* + * Figure out what sized chunks to write. + * Try to use UIO_MAXIOV chunks. + */ + + chunksize = nbytes / UIO_MAXIOV; + if (chunksize <= 0) + chunksize = 1; + else if ((nbytes % UIO_MAXIOV) != 0) + chunksize++; + + ptr = vptr; + nleft = nbytes; + for (i = 0; i < UIO_MAXIOV; i++) { + iov[i].iov_base = ptr; + n = (nleft >= chunksize) ? chunksize : nleft; + iov[i].iov_len = n; + if (verbose) + fprintf(stderr, "iov[%2d].iov_base = %x, iov[%2d].iov_len = %d\n", + i, iov[i].iov_base, i, iov[i].iov_len); + ptr += n; + if ((nleft -= n) == 0) + break; + } + if (i == UIO_MAXIOV) + err_quit("i == UIO_MAXIOV"); + + if (usewritev) + return(writev(fd, iov, i+1)); + else { + ntotal = 0; + for (n = 0; n <= i; n++) { + nwritten = write(fd, iov[n].iov_base, iov[n].iov_len); + if (nwritten != iov[n].iov_len) + return(-1); + ntotal += nwritten; + } + return(ntotal); + } +} diff --git a/sock/writen.c b/sock/writen.c new file mode 100644 index 0000000..bd47da2 --- /dev/null +++ b/sock/writen.c @@ -0,0 +1,19 @@ +#include "ourhdr.h" + +ssize_t /* Write "n" bytes to a descriptor. */ +writen(int fd, const void *vptr, size_t n) +{ + size_t nleft, nwritten; + const char *ptr; + + ptr = vptr; /* can't do pointer arithmetic on void* */ + nleft = n; + while (nleft > 0) { + if ( (nwritten = write(fd, ptr, nleft)) <= 0) + return(nwritten); /* error */ + + nleft -= nwritten; + ptr += nwritten; + } + return(n); +} diff --git a/sockopt/Makefile b/sockopt/Makefile new file mode 100644 index 0000000..a014f97 --- /dev/null +++ b/sockopt/Makefile @@ -0,0 +1,23 @@ +include ../Make.defines + +PROGS = checkopts prdefaults rcvbuf rcvbufset sockopt + +all: ${PROGS} + +sockopt: sockopt.o + ${CC} ${CFLAGS} -o $@ sockopt.o ${LIBS} + +checkopts: checkopts.o + ${CC} ${CFLAGS} -o $@ checkopts.o ${LIBS} + +prdefaults: prdefaults.o + ${CC} ${CFLAGS} -o $@ prdefaults.o ${LIBS} + +rcvbuf: rcvbuf.o + ${CC} ${CFLAGS} -o $@ rcvbuf.o ${LIBS} + +rcvbufset: rcvbufset.o + ${CC} ${CFLAGS} -o $@ rcvbufset.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/sockopt/checkopts.c b/sockopt/checkopts.c new file mode 100644 index 0000000..3aa8199 --- /dev/null +++ b/sockopt/checkopts.c @@ -0,0 +1,189 @@ +/* include checkopts1 */ +/* *INDENT-OFF* */ +#include "unp.h" +#include /* for TCP_xxx defines */ + +union val { + int i_val; + long l_val; + struct linger linger_val; + struct timeval timeval_val; +} val; + +static char *sock_str_flag(union val *, int); +static char *sock_str_int(union val *, int); +static char *sock_str_linger(union val *, int); +static char *sock_str_timeval(union val *, int); + +struct sock_opts { + const char *opt_str; + int opt_level; + int opt_name; + char *(*opt_val_str)(union val *, int); +} sock_opts[] = { + { "SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, sock_str_flag }, + { "SO_DEBUG", SOL_SOCKET, SO_DEBUG, sock_str_flag }, + { "SO_DONTROUTE", SOL_SOCKET, SO_DONTROUTE, sock_str_flag }, + { "SO_ERROR", SOL_SOCKET, SO_ERROR, sock_str_int }, + { "SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, sock_str_flag }, + { "SO_LINGER", SOL_SOCKET, SO_LINGER, sock_str_linger }, + { "SO_OOBINLINE", SOL_SOCKET, SO_OOBINLINE, sock_str_flag }, + { "SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, sock_str_int }, + { "SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, sock_str_int }, + { "SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, sock_str_int }, + { "SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, sock_str_int }, + { "SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, sock_str_timeval }, + { "SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, sock_str_timeval }, + { "SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, sock_str_flag }, +#ifdef SO_REUSEPORT + { "SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, sock_str_flag }, +#else + { "SO_REUSEPORT", 0, 0, NULL }, +#endif + { "SO_TYPE", SOL_SOCKET, SO_TYPE, sock_str_int }, + { "SO_USELOOPBACK", SOL_SOCKET, SO_USELOOPBACK, sock_str_flag }, + { "IP_TOS", IPPROTO_IP, IP_TOS, sock_str_int }, + { "IP_TTL", IPPROTO_IP, IP_TTL, sock_str_int }, +#ifdef IPV6_DONTFRAG + { "IPV6_DONTFRAG", IPPROTO_IPV6,IPV6_DONTFRAG, sock_str_flag }, +#else + { "IPV6_DONTFRAG", 0, 0, NULL }, +#endif +#ifdef IPV6_UNICAST_HOPS + { "IPV6_UNICAST_HOPS", IPPROTO_IPV6,IPV6_UNICAST_HOPS,sock_str_int }, +#else + { "IPV6_UNICAST_HOPS", 0, 0, NULL }, +#endif +#ifdef IPV6_V6ONLY + { "IPV6_V6ONLY", IPPROTO_IPV6,IPV6_V6ONLY, sock_str_flag }, +#else + { "IPV6_V6ONLY", 0, 0, NULL }, +#endif + { "TCP_MAXSEG", IPPROTO_TCP,TCP_MAXSEG, sock_str_int }, + { "TCP_NODELAY", IPPROTO_TCP,TCP_NODELAY, sock_str_flag }, +#ifdef SCTP_AUTOCLOSE + { "SCTP_AUTOCLOSE", IPPROTO_SCTP,SCTP_AUTOCLOSE,sock_str_int }, +#else + { "SCTP_AUTOCLOSE", 0, 0, NULL }, +#endif +#ifdef SCTP_MAXBURST + { "SCTP_MAXBURST", IPPROTO_SCTP,SCTP_MAXBURST, sock_str_int }, +#else + { "SCTP_MAXBURST", 0, 0, NULL }, +#endif +#ifdef SCTP_MAXSEG + { "SCTP_MAXSEG", IPPROTO_SCTP,SCTP_MAXSEG, sock_str_int }, +#else + { "SCTP_MAXSEG", 0, 0, NULL }, +#endif +#ifdef SCTP_NODELAY + { "SCTP_NODELAY", IPPROTO_SCTP,SCTP_NODELAY, sock_str_flag }, +#else + { "SCTP_NODELAY", 0, 0, NULL }, +#endif + { NULL, 0, 0, NULL } +}; +/* *INDENT-ON* */ +/* end checkopts1 */ + +/* include checkopts2 */ +int +main(int argc, char **argv) +{ + int fd; + socklen_t len; + struct sock_opts *ptr; + + for (ptr = sock_opts; ptr->opt_str != NULL; ptr++) { + printf("%s: ", ptr->opt_str); + if (ptr->opt_val_str == NULL) + printf("(undefined)\n"); + else { + switch(ptr->opt_level) { + case SOL_SOCKET: + case IPPROTO_IP: + case IPPROTO_TCP: + fd = Socket(AF_INET, SOCK_STREAM, 0); + break; +#ifdef IPV6 + case IPPROTO_IPV6: + fd = Socket(AF_INET6, SOCK_STREAM, 0); + break; +#endif +#ifdef IPPROTO_SCTP + case IPPROTO_SCTP: + fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); + break; +#endif + default: + err_quit("Can't create fd for level %d\n", ptr->opt_level); + } + + len = sizeof(val); + if (getsockopt(fd, ptr->opt_level, ptr->opt_name, + &val, &len) == -1) { + err_ret("getsockopt error"); + } else { + printf("default = %s\n", (*ptr->opt_val_str)(&val, len)); + } + close(fd); + } + } + exit(0); +} +/* end checkopts2 */ + +/* include checkopts3 */ +static char strres[128]; + +static char * +sock_str_flag(union val *ptr, int len) +{ +/* *INDENT-OFF* */ + if (len != sizeof(int)) + snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len); + else + snprintf(strres, sizeof(strres), + "%s", (ptr->i_val == 0) ? "off" : "on"); + return(strres); +/* *INDENT-ON* */ +} +/* end checkopts3 */ + +static char * +sock_str_int(union val *ptr, int len) +{ + if (len != sizeof(int)) + snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len); + else + snprintf(strres, sizeof(strres), "%d", ptr->i_val); + return(strres); +} + +static char * +sock_str_linger(union val *ptr, int len) +{ + struct linger *lptr = &ptr->linger_val; + + if (len != sizeof(struct linger)) + snprintf(strres, sizeof(strres), + "size (%d) not sizeof(struct linger)", len); + else + snprintf(strres, sizeof(strres), "l_onoff = %d, l_linger = %d", + lptr->l_onoff, lptr->l_linger); + return(strres); +} + +static char * +sock_str_timeval(union val *ptr, int len) +{ + struct timeval *tvptr = &ptr->timeval_val; + + if (len != sizeof(struct timeval)) + snprintf(strres, sizeof(strres), + "size (%d) not sizeof(struct timeval)", len); + else + snprintf(strres, sizeof(strres), "%d sec, %d usec", + tvptr->tv_sec, tvptr->tv_usec); + return(strres); +} diff --git a/sockopt/checkopts.lc b/sockopt/checkopts.lc new file mode 100644 index 0000000..5cb5dbb --- /dev/null +++ b/sockopt/checkopts.lc @@ -0,0 +1,131 @@ +/* include checkopts1 */ +#include "unp.h"## 1 ##src/sockopt/checkopts.c## +#include /* for TCP_xxx defines */## 2 ##src/sockopt/checkopts.c## + +union val {## 3 ##src/sockopt/checkopts.c## + int i_val;## 4 ##src/sockopt/checkopts.c## + long l_val;## 5 ##src/sockopt/checkopts.c## + char c_val[10];## 6 ##src/sockopt/checkopts.c## + struct linger linger_val;## 7 ##src/sockopt/checkopts.c## + struct timeval timeval_val;## 8 ##src/sockopt/checkopts.c## +} val;## 9 ##src/sockopt/checkopts.c## + +static char *sock_str_flag(union val *, int);## 10 ##src/sockopt/checkopts.c## +static char *sock_str_int(union val *, int);## 11 ##src/sockopt/checkopts.c## +static char *sock_str_linger(union val *, int);## 12 ##src/sockopt/checkopts.c## +static char *sock_str_timeval(union val *, int);## 13 ##src/sockopt/checkopts.c## + +struct sock_opts {## 14 ##src/sockopt/checkopts.c## + char *opt_str;## 15 ##src/sockopt/checkopts.c## + int opt_level;## 16 ##src/sockopt/checkopts.c## + int opt_name;## 17 ##src/sockopt/checkopts.c## + char *(*opt_val_str)(union val *, int);## 18 ##src/sockopt/checkopts.c## +} sock_opts[] = {## 19 ##src/sockopt/checkopts.c## + "SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, sock_str_flag,## 20 ##src/sockopt/checkopts.c## + "SO_DEBUG", SOL_SOCKET, SO_DEBUG, sock_str_flag,## 21 ##src/sockopt/checkopts.c## + "SO_DONTROUTE", SOL_SOCKET, SO_DONTROUTE, sock_str_flag,## 22 ##src/sockopt/checkopts.c## + "SO_ERROR", SOL_SOCKET, SO_ERROR, sock_str_int,## 23 ##src/sockopt/checkopts.c## + "SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, sock_str_flag,## 24 ##src/sockopt/checkopts.c## + "SO_LINGER", SOL_SOCKET, SO_LINGER, sock_str_linger,## 25 ##src/sockopt/checkopts.c## + "SO_OOBINLINE", SOL_SOCKET, SO_OOBINLINE, sock_str_flag,## 26 ##src/sockopt/checkopts.c## + "SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, sock_str_int,## 27 ##src/sockopt/checkopts.c## + "SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, sock_str_int,## 28 ##src/sockopt/checkopts.c## + "SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, sock_str_int,## 29 ##src/sockopt/checkopts.c## + "SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, sock_str_int,## 30 ##src/sockopt/checkopts.c## + "SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, sock_str_timeval,## 31 ##src/sockopt/checkopts.c## + "SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, sock_str_timeval,## 32 ##src/sockopt/checkopts.c## + "SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, sock_str_flag,## 33 ##src/sockopt/checkopts.c## +#ifdef SO_REUSEPORT## 34 ##src/sockopt/checkopts.c## + "SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, sock_str_flag,## 35 ##src/sockopt/checkopts.c## +#else## 36 ##src/sockopt/checkopts.c## + "SO_REUSEPORT", 0, 0, NULL,## 37 ##src/sockopt/checkopts.c## +#endif## 38 ##src/sockopt/checkopts.c## + "SO_TYPE", SOL_SOCKET, SO_TYPE, sock_str_int,## 39 ##src/sockopt/checkopts.c## + "SO_USELOOPBACK", SOL_SOCKET, SO_USELOOPBACK, sock_str_flag,## 40 ##src/sockopt/checkopts.c## + "IP_TOS", IPPROTO_IP, IP_TOS, sock_str_int,## 41 ##src/sockopt/checkopts.c## + "IP_TTL", IPPROTO_IP, IP_TTL, sock_str_int,## 42 ##src/sockopt/checkopts.c## + "TCP_MAXSEG", IPPROTO_TCP,TCP_MAXSEG, sock_str_int,## 43 ##src/sockopt/checkopts.c## + "TCP_NODELAY", IPPROTO_TCP,TCP_NODELAY, sock_str_flag,## 44 ##src/sockopt/checkopts.c## + NULL, 0, 0, NULL## 45 ##src/sockopt/checkopts.c## +};## 46 ##src/sockopt/checkopts.c## +/* end checkopts1 */ + +/* include checkopts2 */ +int## 47 ##src/sockopt/checkopts.c## +main(int argc, char **argv)## 48 ##src/sockopt/checkopts.c## +{## 49 ##src/sockopt/checkopts.c## + int fd, len;## 50 ##src/sockopt/checkopts.c## + struct sock_opts *ptr;## 51 ##src/sockopt/checkopts.c## + + fd = Socket(AF_INET, SOCK_STREAM, 0);## 52 ##src/sockopt/checkopts.c## + + for (ptr = sock_opts; ptr->opt_str != NULL; ptr++) {## 53 ##src/sockopt/checkopts.c## + printf("%s: ", ptr->opt_str);## 54 ##src/sockopt/checkopts.c## + if (ptr->opt_val_str == NULL)## 55 ##src/sockopt/checkopts.c## + printf("(undefined)\n");## 56 ##src/sockopt/checkopts.c## + else {## 57 ##src/sockopt/checkopts.c## + len = sizeof(val);## 58 ##src/sockopt/checkopts.c## + if (getsockopt(fd, ptr->opt_level, ptr->opt_name,## 59 ##src/sockopt/checkopts.c## + &val, &len) == -1) {## 60 ##src/sockopt/checkopts.c## + err_ret("getsockopt error");## 61 ##src/sockopt/checkopts.c## + } else {## 62 ##src/sockopt/checkopts.c## + printf("default = %s\n", (*ptr->opt_val_str) (&val, len));## 63 ##src/sockopt/checkopts.c## + }## 64 ##src/sockopt/checkopts.c## + }## 65 ##src/sockopt/checkopts.c## + }## 66 ##src/sockopt/checkopts.c## + exit(0);## 67 ##src/sockopt/checkopts.c## +}## 68 ##src/sockopt/checkopts.c## +/* end checkopts2 */ + +/* include checkopts3 */ +static char strres[128];## 69 ##src/sockopt/checkopts.c## + +static char *## 70 ##src/sockopt/checkopts.c## +sock_str_flag(union val *ptr, int len)## 71 ##src/sockopt/checkopts.c## +{## 72 ##src/sockopt/checkopts.c## + if (len != sizeof(int))## 73 ##src/sockopt/checkopts.c## + snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len);## 74 ##src/sockopt/checkopts.c## + else## 75 ##src/sockopt/checkopts.c## + snprintf(strres, sizeof(strres),## 76 ##src/sockopt/checkopts.c## + "%s", (ptr->i_val == 0) ? "off" : "on");## 77 ##src/sockopt/checkopts.c## + return(strres);## 78 ##src/sockopt/checkopts.c## +}## 79 ##src/sockopt/checkopts.c## +/* end checkopts3 */ + +static char *## 80 ##src/sockopt/checkopts.c## +sock_str_int(union val *ptr, int len)## 81 ##src/sockopt/checkopts.c## +{## 82 ##src/sockopt/checkopts.c## + if (len != sizeof(int))## 83 ##src/sockopt/checkopts.c## + snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len);## 84 ##src/sockopt/checkopts.c## + else## 85 ##src/sockopt/checkopts.c## + snprintf(strres, sizeof(strres), "%d", ptr->i_val);## 86 ##src/sockopt/checkopts.c## + return (strres);## 87 ##src/sockopt/checkopts.c## +}## 88 ##src/sockopt/checkopts.c## + +static char *## 89 ##src/sockopt/checkopts.c## +sock_str_linger(union val *ptr, int len)## 90 ##src/sockopt/checkopts.c## +{## 91 ##src/sockopt/checkopts.c## + struct linger *lptr = &ptr->linger_val;## 92 ##src/sockopt/checkopts.c## + + if (len != sizeof(struct linger))## 93 ##src/sockopt/checkopts.c## + snprintf(strres, sizeof(strres),## 94 ##src/sockopt/checkopts.c## + "size (%d) not sizeof(struct linger)", len);## 95 ##src/sockopt/checkopts.c## + else## 96 ##src/sockopt/checkopts.c## + snprintf(strres, sizeof(strres), "l_onoff = %d, l_linger = %d",## 97 ##src/sockopt/checkopts.c## + lptr->l_onoff, lptr->l_linger);## 98 ##src/sockopt/checkopts.c## + return (strres);## 99 ##src/sockopt/checkopts.c## +}##100 ##src/sockopt/checkopts.c## + +static char *##101 ##src/sockopt/checkopts.c## +sock_str_timeval(union val *ptr, int len)##102 ##src/sockopt/checkopts.c## +{##103 ##src/sockopt/checkopts.c## + struct timeval *tvptr = &ptr->timeval_val;##104 ##src/sockopt/checkopts.c## + + if (len != sizeof(struct timeval))##105 ##src/sockopt/checkopts.c## + snprintf(strres, sizeof(strres),##106 ##src/sockopt/checkopts.c## + "size (%d) not sizeof(struct timeval)", len);##107 ##src/sockopt/checkopts.c## + else##108 ##src/sockopt/checkopts.c## + snprintf(strres, sizeof(strres), "%d sec, %d usec",##109 ##src/sockopt/checkopts.c## + tvptr->tv_sec, tvptr->tv_usec);##110 ##src/sockopt/checkopts.c## + return (strres);##111 ##src/sockopt/checkopts.c## +}##112 ##src/sockopt/checkopts.c## diff --git a/sockopt/prdefaults.c b/sockopt/prdefaults.c new file mode 100644 index 0000000..46d7369 --- /dev/null +++ b/sockopt/prdefaults.c @@ -0,0 +1,59 @@ +#include "unp.h" + +static doit(int, const char *); + +void +main() +{ + int tcpsock, udpsock; + struct sockaddr_in servaddr; + + if ( (tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + err_sys("TCP socket error"); + +#ifdef notdef + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(9); + if (ascii2addr(AF_INET, "127.0.0.1", &servaddr.sin_addr) != 4) + err_quit("ascii2addr error"); + + if (connect(tcpsock, (SA *) &servaddr, sizeof(servaddr)) < 0) + err_sys("connect error"); +#endif + + doit(tcpsock, "tcp"); + + if ( (udpsock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + err_sys("UDP socket error"); + + doit(udpsock, "udp"); + exit(0); +} + +static +doit(int fd, const char *name) +{ + int val; + socklen_t optlen; + + optlen = sizeof(val); + if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, &optlen) < 0) + err_sys("SO_SNDBUF getsockopt error"); + printf("%s send buffer size = %d\n", name, val); + + optlen = sizeof(val); + if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, &optlen) < 0) + err_sys("SO_RCVBUF getsockopt error"); + printf("%s recv buffer size = %d\n", name, val); + + optlen = sizeof(val); + if (getsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &val, &optlen) < 0) + err_sys("SO_SNDLOWAT getsockopt error"); + printf("%s send low-water mark = %d\n", name, val); + + optlen = sizeof(val); + if (getsockopt(fd, SOL_SOCKET, SO_RCVLOWAT, &val, &optlen) < 0) + err_sys("SO_RCVLOWAT getsockopt error"); + printf("%s receive low-water mark size = %d\n", name, val); +} diff --git a/sockopt/rcvbuf.c b/sockopt/rcvbuf.c new file mode 100644 index 0000000..af83f30 --- /dev/null +++ b/sockopt/rcvbuf.c @@ -0,0 +1,36 @@ +#include "unp.h" +#include /* for TCP_MAXSEG */ + +int +main(int argc, char **argv) +{ + int sockfd, rcvbuf, mss; + socklen_t len; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: rcvbuf "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + len = sizeof(rcvbuf); + Getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len); + len = sizeof(mss); + Getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len); + printf("defaults: SO_RCVBUF = %d, MSS = %d\n", rcvbuf, mss); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(13); /* daytime server */ + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + len = sizeof(rcvbuf); + Getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len); + len = sizeof(mss); + Getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len); + printf("after connect: SO_RCVBUF = %d, MSS = %d\n", rcvbuf, mss); + + exit(0); +} diff --git a/sockopt/rcvbufset.c b/sockopt/rcvbufset.c new file mode 100644 index 0000000..8eab891 --- /dev/null +++ b/sockopt/rcvbufset.c @@ -0,0 +1,43 @@ +#include "unp.h" +#include /* for TCP_MAXSEG */ + +int +main(int argc, char **argv) +{ + int sockfd, rcvbuf, mss; + socklen_t len; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: rcvbufset "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + len = sizeof(rcvbuf); + Getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len); + len = sizeof(mss); + Getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len); + printf("defaults: SO_RCVBUF = %d, MSS = %d\n", rcvbuf, mss); + + rcvbuf = 9973; /* a prime number */ + Setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)); + len = sizeof(rcvbuf); + Getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len); + printf("SO_RCVBUF = %d (after setting it to 9973)\n", rcvbuf); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(13); /* daytime server */ + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + len = sizeof(rcvbuf); + Getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len); + len = sizeof(mss); + Getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len); + printf("after connect: SO_RCVBUF = %d, MSS = %d\n", rcvbuf, mss); + + + exit(0); +} diff --git a/sockopt/sockopt.c b/sockopt/sockopt.c new file mode 100644 index 0000000..7b0c940 --- /dev/null +++ b/sockopt/sockopt.c @@ -0,0 +1,25 @@ +#include "unp.h" +#include /* for TCP_MAXSEG value */ + +int +main(int argc, char **argv) +{ + int sockfd, mss, sendbuff; + socklen_t optlen; + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + /* Fetch and print the TCP maximum segment size. */ + optlen = sizeof(mss); + Getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &optlen); + printf("TCP mss = %d\n", mss); + + /* Set the send buffer size, then fetch it and print its value. */ + sendbuff = 65536; + Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)); + + optlen = sizeof(sendbuff); + Getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen); + printf("send buffer size = %d\n", sendbuff); + exit(0); +} diff --git a/sparc64-unknown-freebsd5.1/config.h b/sparc64-unknown-freebsd5.1/config.h new file mode 100644 index 0000000..dac099b --- /dev/null +++ b/sparc64-unknown-freebsd5.1/config.h @@ -0,0 +1,305 @@ +/* config.h. Generated automatically by configure. */ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* CPU, vendor, and operating system */ +#define CPU_VENDOR_OS "sparc64-unknown-freebsd5.1" + +/* Define if defines struct addrinfo */ +#define HAVE_ADDRINFO_STRUCT 1 + +/* Define if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define if you have the `bzero' function. */ +#define HAVE_BZERO 1 + +/* Define if the /dev/streams/xtiso/tcp device exists */ +/* #undef HAVE_DEV_STREAMS_XTISO_TCP */ + +/* Define if the /dev/tcp device exists */ +/* #undef HAVE_DEV_TCP */ + +/* Define if the /dev/xti/tcp device exists */ +/* #undef HAVE_DEV_XTI_TCP */ + +/* Define if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the `getaddrinfo' function. */ +#define HAVE_GETADDRINFO 1 + +/* define if getaddrinfo prototype is in */ +#define HAVE_GETADDRINFO_PROTO 1 + +/* Define if you have the `gethostbyname2' function. */ +#define HAVE_GETHOSTBYNAME2 1 + +/* Define if you have the `gethostbyname_r' function. */ +/* #undef HAVE_GETHOSTBYNAME_R */ + +/* Define if you have the `gethostname' function. */ +#define HAVE_GETHOSTNAME 1 + +/* define if gethostname prototype is in */ +#define HAVE_GETHOSTNAME_PROTO 1 + +/* Define if you have the `getnameinfo' function. */ +#define HAVE_GETNAMEINFO 1 + +/* define if getnameinfo prototype is in */ +#define HAVE_GETNAMEINFO_PROTO 1 + +/* define if getrusage prototype is in */ +#define HAVE_GETRUSAGE_PROTO 1 + +/* Define if you have the `hstrerror' function. */ +#define HAVE_HSTRERROR 1 + +/* define if hstrerror prototype is in */ +#define HAVE_HSTRERROR_PROTO 1 + +/* Define if defines struct if_nameindex */ +#define HAVE_IF_NAMEINDEX_STRUCT 1 + +/* Define if you have the `if_nametoindex' function. */ +#define HAVE_IF_NAMETOINDEX 1 + +/* define if if_nametoindex prototype is in */ +#define HAVE_IF_NAMETOINDEX_PROTO 1 + +/* Define if you have the `inet_aton' function. */ +#define HAVE_INET_ATON 1 + +/* define if inet_aton prototype is in */ +#define HAVE_INET_ATON_PROTO 1 + +/* Define if you have the `inet_pton' function. */ +#define HAVE_INET_PTON 1 + +/* define if inet_pton prototype is in */ +#define HAVE_INET_PTON_PROTO 1 + +/* Define if you have the `kevent' function. */ +#define HAVE_KEVENT 1 + +/* Define if you have the `kqueue' function. */ +#define HAVE_KQUEUE 1 + +/* Define if you have the `nsl' library (-lnsl). */ +/* #undef HAVE_LIBNSL */ + +/* Define if you have the `pthread' library (-lpthread). */ +/* #undef HAVE_LIBPTHREAD */ + +/* Define if you have the `pthreads' library (-lpthreads). */ +/* #undef HAVE_LIBPTHREADS */ + +/* Define if you have the `resolv' library (-lresolv). */ +/* #undef HAVE_LIBRESOLV */ + +/* Define if you have the `xti' library (-lxti). */ +/* #undef HAVE_LIBXTI */ + +/* Define if you have the `mkstemp' function. */ +#define HAVE_MKSTEMP 1 + +/* define if struct msghdr contains the msg_control element */ +#define HAVE_MSGHDR_MSG_CONTROL 1 + +/* Define if you have the header file. */ +#define HAVE_NETCONFIG_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_NETDIR_H */ + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_IF_DL_H 1 + +/* Define if you have the `poll' function. */ +#define HAVE_POLL 1 + +/* Define if you have the header file. */ +#define HAVE_POLL_H 1 + +/* Define if you have the `pselect' function. */ +#define HAVE_PSELECT 1 + +/* define if pselect prototype is in */ +#define HAVE_PSELECT_PROTO 1 + +/* Define if you have the header file. */ +#define HAVE_PTHREAD_H 1 + +/* Define if you have the header file. */ +#define HAVE_SIGNAL_H 1 + +/* Define if you have the `snprintf' function. */ +#define HAVE_SNPRINTF 1 + +/* define if snprintf prototype is in */ +#define HAVE_SNPRINTF_PROTO 1 + +/* Define if defines struct sockaddr_dl */ +#define HAVE_SOCKADDR_DL_STRUCT 1 + +/* define if socket address structures have length fields */ +#define HAVE_SOCKADDR_SA_LEN 1 + +/* Define if you have the `sockatmark' function. */ +#define HAVE_SOCKATMARK 1 + +/* define if sockatmark prototype is in */ +#define HAVE_SOCKATMARK_PROTO 1 + +/* Define if you have the header file. */ +#define HAVE_STDIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_STROPTS_H */ + +/* Define if `ifr_mtu' is member of `struct ifreq'. */ +#define HAVE_STRUCT_IFREQ_IFR_MTU 1 + +/* Define if the system has the type `struct sockaddr_storage'. */ +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_EVENT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_FILIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SOCKIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SYSCTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UN_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define if defines struct timespec */ +#define HAVE_TIMESPEC_STRUCT 1 + +/* Define if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the `vsnprintf' function. */ +#define HAVE_VSNPRINTF 1 + +/* Define if you have the header file. */ +/* #undef HAVE_XTI_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_XTI_INET_H */ + +/* Define if the system supports IPv4 */ +#define IPV4 1 + +/* Define if the system supports IPv6 */ +#define IPV6 1 + +/* Define if the system supports IPv4 */ +#define IPv4 1 + +/* Define if the system supports IPv6 */ +#define IPv6 1 + +/* Define if the system supports IP Multicast */ +#define MCAST 1 + +/* the size of the sa_family field in a socket address structure */ +/* #undef SA_FAMILY_T */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define if the system supports UNIX domain sockets */ +#define UNIXDOMAIN 1 + +/* Define if the system supports UNIX domain sockets */ +#define UNIXdomain 1 + +/* 16 bit signed type */ +/* #undef int16_t */ + +/* 32 bit signed type */ +/* #undef int32_t */ + +/* the type of the sa_family struct element */ +/* #undef sa_family_t */ + +/* unsigned integer type of the result of the sizeof operator */ +/* #undef size_t */ + +/* a type appropriate for address */ +/* #undef socklen_t */ + +/* define to __ss_family if sockaddr_storage has that instead of ss_family */ +/* #undef ss_family */ + +/* a signed type appropriate for a count of bytes or an error indication */ +/* #undef ssize_t */ + +/* scalar type */ +#define t_scalar_t int32_t + +/* unsigned scalar type */ +#define t_uscalar_t uint32_t + +/* 16 bit unsigned type */ +/* #undef uint16_t */ + +/* 32 bit unsigned type */ +/* #undef uint32_t */ + +/* 8-bit unsigned type */ +/* #undef uint8_t */ diff --git a/ssntp/Makefile b/ssntp/Makefile new file mode 100644 index 0000000..7082bce --- /dev/null +++ b/ssntp/Makefile @@ -0,0 +1,11 @@ +include ../Make.defines + +PROGS = ssntp + +all: ${PROGS} + +ssntp: main.o sntp_proc.o + ${CC} ${CFLAGS} -o $@ main.o sntp_proc.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/ssntp/main.c b/ssntp/main.c new file mode 100644 index 0000000..86a3993 --- /dev/null +++ b/ssntp/main.c @@ -0,0 +1,43 @@ +#include "sntp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + char buf[MAXLINE]; + ssize_t n; + socklen_t salen, len; + struct ifi_info *ifi; + struct sockaddr *mcastsa, *wild, *from; + struct timeval now; + + if (argc != 2) + err_quit("usage: ssntp "); + + sockfd = Udp_client(argv[1], "ntp", (void **) &mcastsa, &salen); + + wild = Malloc(salen); + memcpy(wild, mcastsa, salen); /* copy family and port */ + sock_set_wild(wild, salen); + Bind(sockfd, wild, salen); /* bind wildcard */ + +#ifdef MCAST + /* 4obtain interface list and process each one */ + for (ifi = Get_ifi_info(mcastsa->sa_family, 1); ifi != NULL; + ifi = ifi->ifi_next) { + if (ifi->ifi_flags & IFF_MULTICAST) { + Mcast_join(sockfd, mcastsa, salen, ifi->ifi_name, 0); + printf("joined %s on %s\n", + Sock_ntop(mcastsa, salen), ifi->ifi_name); + } + } +#endif + + from = Malloc(salen); + for ( ; ; ) { + len = salen; + n = Recvfrom(sockfd, buf, sizeof(buf), 0, from, &len); + Gettimeofday(&now, NULL); + sntp_proc(buf, n, &now); + } +} diff --git a/ssntp/main.lc b/ssntp/main.lc new file mode 100644 index 0000000..8cd65fb --- /dev/null +++ b/ssntp/main.lc @@ -0,0 +1,43 @@ +#include "sntp.h"## 1 ##src/ssntp/main.c## + +int## 2 ##src/ssntp/main.c## +main(int argc, char **argv)## 3 ##src/ssntp/main.c## +{## 4 ##src/ssntp/main.c## + int sockfd;## 5 ##src/ssntp/main.c## + char buf[MAXLINE];## 6 ##src/ssntp/main.c## + ssize_t n;## 7 ##src/ssntp/main.c## + socklen_t salen, len;## 8 ##src/ssntp/main.c## + struct ifi_info *ifi;## 9 ##src/ssntp/main.c## + struct sockaddr *mcastsa, *wild, *from;## 10 ##src/ssntp/main.c## + struct timeval now;## 11 ##src/ssntp/main.c## + + if (argc != 2)## 12 ##src/ssntp/main.c## + err_quit("usage: ssntp ");## 13 ##src/ssntp/main.c## + + sockfd = Udp_client(argv[1], "ntp", (void **) &mcastsa, &salen);## 14 ##src/ssntp/main.c## + + wild = Malloc(salen);## 15 ##src/ssntp/main.c## + memcpy(wild, mcastsa, salen); /* copy family and port */## 16 ##src/ssntp/main.c## + sock_set_wild(wild, salen);## 17 ##src/ssntp/main.c## + Bind(sockfd, wild, salen); /* bind wildcard */## 18 ##src/ssntp/main.c## + +#ifdef MCAST## 19 ##src/ssntp/main.c## + /* 4obtain interface list and process each one */## 20 ##src/ssntp/main.c## + for (ifi = Get_ifi_info(mcastsa->sa_family, 1); ifi != NULL;## 21 ##src/ssntp/main.c## + ifi = ifi->ifi_next) {## 22 ##src/ssntp/main.c## + if (ifi->ifi_flags & IFF_MULTICAST) {## 23 ##src/ssntp/main.c## + Mcast_join(sockfd, mcastsa, salen, ifi->ifi_name, 0);## 24 ##src/ssntp/main.c## + printf("joined %s on %s\n",## 25 ##src/ssntp/main.c## + Sock_ntop(mcastsa, salen), ifi->ifi_name);## 26 ##src/ssntp/main.c## + }## 27 ##src/ssntp/main.c## + }## 28 ##src/ssntp/main.c## +#endif## 29 ##src/ssntp/main.c## + + from = Malloc(salen);## 30 ##src/ssntp/main.c## + for (;;) {## 31 ##src/ssntp/main.c## + len = salen;## 32 ##src/ssntp/main.c## + n = Recvfrom(sockfd, buf, sizeof(buf), 0, from, &len);## 33 ##src/ssntp/main.c## + Gettimeofday(&now, NULL);## 34 ##src/ssntp/main.c## + sntp_proc(buf, n, &now);## 35 ##src/ssntp/main.c## + }## 36 ##src/ssntp/main.c## +}## 37 ##src/ssntp/main.c## diff --git a/ssntp/ntp.h b/ssntp/ntp.h new file mode 100644 index 0000000..105de53 --- /dev/null +++ b/ssntp/ntp.h @@ -0,0 +1,32 @@ +#define JAN_1970 2208988800UL /* 1970 - 1900 in seconds */ + +struct l_fixedpt { /* 64-bit fixed-point */ + uint32_t int_part; + uint32_t fraction; +}; + +struct s_fixedpt { /* 32-bit fixed-point */ + uint16_t int_part; + uint16_t fraction; +}; + +struct ntpdata { /* NTP header */ + u_char status; + u_char stratum; + u_char ppoll; + int precision:8; + struct s_fixedpt distance; + struct s_fixedpt dispersion; + uint32_t refid; + struct l_fixedpt reftime; + struct l_fixedpt org; + struct l_fixedpt rec; + struct l_fixedpt xmt; +}; + +#define VERSION_MASK 0x38 +#define MODE_MASK 0x07 + +#define MODE_CLIENT 3 +#define MODE_SERVER 4 +#define MODE_BROADCAST 5 diff --git a/ssntp/sntp.h b/ssntp/sntp.h new file mode 100644 index 0000000..64200a5 --- /dev/null +++ b/ssntp/sntp.h @@ -0,0 +1,4 @@ +#include "unpifi.h" +#include "ntp.h" + +void sntp_proc(char *, ssize_t, struct timeval *); diff --git a/ssntp/sntp_proc.c b/ssntp/sntp_proc.c new file mode 100644 index 0000000..192ab45 --- /dev/null +++ b/ssntp/sntp_proc.c @@ -0,0 +1,39 @@ +#include "sntp.h" + +void +sntp_proc(char *buf, ssize_t n, struct timeval *nowptr) +{ + int version, mode; + uint32_t nsec, useci; + double usecf; + struct timeval diff; + struct ntpdata *ntp; + + if (n < (ssize_t)sizeof(struct ntpdata)) { + printf("\npacket too small: %d bytes\n", n); + return; + } + + ntp = (struct ntpdata *) buf; + version = (ntp->status & VERSION_MASK) >> 3; + mode = ntp->status & MODE_MASK; + printf("\nv%d, mode %d, strat %d, ", version, mode, ntp->stratum); + if (mode == MODE_CLIENT) { + printf("client\n"); + return; + } + + nsec = ntohl(ntp->xmt.int_part) - JAN_1970; + useci = ntohl(ntp->xmt.fraction); /* 32-bit integer fraction */ + usecf = useci; /* integer fraction -> double */ + usecf /= 4294967296.0; /* divide by 2**32 -> [0, 1.0) */ + useci = usecf * 1000000.0; /* fraction -> parts per million */ + + diff.tv_sec = nowptr->tv_sec - nsec; + if ( (diff.tv_usec = nowptr->tv_usec - useci) < 0) { + diff.tv_usec += 1000000; + diff.tv_sec--; + } + useci = (diff.tv_sec * 1000000) + diff.tv_usec; /* diff in microsec */ + printf("clock difference = %d usec\n", useci); +} diff --git a/streams/Makefile b/streams/Makefile new file mode 100644 index 0000000..7d6fe30 --- /dev/null +++ b/streams/Makefile @@ -0,0 +1,18 @@ +include ../Make.defines + +PROGS = strlist_sock strlist_xti tpi_daytime + +all: ${PROGS} + +strlist_sock: strlist_sock.o + ${CC} ${CFLAGS} -o $@ strlist_sock.o ${LIBS_XTI} + +strlist_xti: strlist_xti.o + ${CC} ${CFLAGS} -o $@ strlist_xti.o ${LIBS_XTI} + +tpi_daytime: tpi_daytime.o tpi_bind.o tpi_connect.o tpi_read.o tpi_close.o + ${CC} ${CFLAGS} -o $@ tpi_daytime.o tpi_bind.o tpi_connect.o \ + tpi_read.o tpi_close.o ${LIBS_XTI} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/streams/stream_dg/Makefile b/streams/stream_dg/Makefile new file mode 100644 index 0000000..be1d2b8 --- /dev/null +++ b/streams/stream_dg/Makefile @@ -0,0 +1,7 @@ +all: client server + +client: client.o net_stream.o + cc client.o net_stream.o -o client -lnsl + +server: server.o net_stream.o + cc server.o net_stream.o -o server -lnsl diff --git a/streams/stream_dg/client.c b/streams/stream_dg/client.c new file mode 100644 index 0000000..4fac1f4 --- /dev/null +++ b/streams/stream_dg/client.c @@ -0,0 +1,66 @@ +#include +#include +#include + +#include +#include + +extern int errno; + +#define SERV_HOST_ADDR "128.220.101.4" +#define SERV_TCP_PORT 6000 + +main() +{ + int fd; + struct sockaddr_in my_addr; + struct sockaddr_in serv_addr; + char buf[128]; + void echo_driver(int, struct sockaddr_in *); + + if ((fd = net_open ("/dev/udp", O_RDWR)) < 0) + { + fprintf (stderr, "open failed.\n"); + exit (-1); + } + /* + * bind any address to us. + */ + bzero((char *) &my_addr, sizeof(my_addr)); + my_addr.sin_family = AF_INET; + my_addr.sin_addr.s_addr = htonl (INADDR_ANY); + my_addr.sin_port = htons(0); + + fd = net_bind (fd, &my_addr, sizeof (struct sockaddr_in)); + + /* + * set up server's address + */ + bzero((char *) &serv_addr, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = inet_addr (SERV_HOST_ADDR); + serv_addr.sin_port = htons(SERV_TCP_PORT); + + echo_driver (fd, &serv_addr); + close (fd); + + exit (0); +} + +void +echo_driver(int fd, struct sockaddr_in *serv_addr) +{ + char buf[512]; + int n; + struct sockaddr_in fm_addr; + + while ((n = read (0, buf, sizeof (buf))) != 0) + { + net_send (fd, buf, n, serv_addr, sizeof (struct sockaddr_in)); + + n = net_recv (fd, buf, sizeof (buf), &fm_addr, sizeof (struct sockaddr_in)); + + write (1, buf, n); + } + return; +} diff --git a/streams/stream_dg/net_stream.c b/streams/stream_dg/net_stream.c new file mode 100644 index 0000000..468cc54 --- /dev/null +++ b/streams/stream_dg/net_stream.c @@ -0,0 +1,181 @@ +#include +#include +#include +#include + +#include +#include +#include + + +extern int errno; + +int +net_open (char *path, int oflags, void *addr, int addrlen) +{ + int fd; + int flags; + + if ((fd = open (path, oflags)) < 0) + { + perror ("open"); + return (-1); + } + return (fd); +} + +int +net_bind (int fd, void *addr, int addrlen) +{ + struct { + struct T_bind_req msg_hdr; + char addr[128]; + } bind_req; + struct strbuf ctlbuf; + union T_primitives rcvbuf; + struct T_error_ack *error_ack; + int flags; + + if (addr == NULL || addrlen == 0) + { + fprintf (stderr, "No address\n"); + return (-1); + } + + bind_req.msg_hdr.PRIM_type = T_BIND_REQ; + bind_req.msg_hdr.ADDR_length = addrlen; + bind_req.msg_hdr.ADDR_offset = sizeof (struct T_bind_req); + bind_req.msg_hdr.CONIND_number = 5; + bcopy (addr, bind_req.addr, addrlen); + + ctlbuf.len = sizeof (struct T_bind_req) + addrlen; + ctlbuf.buf = (char *) &bind_req; + + if (putmsg (fd, &ctlbuf, NULL, 0) < 0) + { + return (-1); + } + /* + * Wait for acknowledgement + */ + ctlbuf.maxlen = sizeof (union T_primitives); + ctlbuf.len = 0; + ctlbuf.buf = (char *) &rcvbuf; + flags = RS_HIPRI; + if (getmsg (fd, &ctlbuf, NULL, &flags) < 0) + { + perror ("getmsg"); + return (-1); + } + + if (ctlbuf.len < sizeof (long)) + { + fprintf (stderr, "Bad length from getmsg.\n"); + errno = EPROTO; + return (-1); + } + switch (rcvbuf.type) + { + case T_BIND_ACK: + return (fd); + case T_ERROR_ACK: + if (ctlbuf.len < sizeof (struct T_error_ack)) + { + errno = EPROTO; + return (-1); + } + error_ack = (struct T_error_ack *) &rcvbuf; + fprintf (stderr, "Error ack from bind (%d %d %d)\n", + error_ack->ERROR_prim, + error_ack->TLI_error, + error_ack->UNIX_error); + errno = error_ack->UNIX_error; + break; + default: + fprintf (stderr, "No ack from bind?\n"); + errno = EPROTO; + break; + } + return (-1); +} +int +net_send (int fd, char *buf, int len, char *to_addr, int addrlen) +{ + struct strbuf ctlbuf; + struct strbuf databuf; + struct { + struct T_unitdata_req unitdata_req; + char buf[128]; + } netdata; + + bcopy (to_addr, netdata.buf, addrlen); + netdata.unitdata_req.PRIM_type = T_UNITDATA_REQ; + netdata.unitdata_req.DEST_length = addrlen; + netdata.unitdata_req.DEST_offset = sizeof (struct T_unitdata_req); + /* + * for now, presume no options. + */ + netdata.unitdata_req.OPT_length = 0; + netdata.unitdata_req.OPT_offset = 0; + + ctlbuf.len = sizeof (struct T_unitdata_req) + addrlen; + ctlbuf.buf = (char *) &netdata; + + databuf.len = len; + databuf.buf = buf; + + if (putmsg (fd, &ctlbuf, &databuf, 0) < 0) + return (0); + free (netdata.buf); + return (len); +} + +int +net_recv (int fd, char *buf, int len, char *from_addr, int addrlen) +{ + struct strbuf ctlbuf; + struct strbuf databuf; + struct { + struct T_unitdata_ind unitdata_ind; + char buf[128]; + } netdata; + char *c; + int retval; + int flags; + + ctlbuf.maxlen = sizeof (netdata); + ctlbuf.buf = (char *) &netdata; + + databuf.maxlen = len; + databuf.len = 0; + databuf.buf = buf; + + flags = 0; + + if ((retval = getmsg (fd, &ctlbuf, &databuf, &flags)) < 0) + return (-1); + + if (netdata.unitdata_ind.PRIM_type != T_UNITDATA_IND) + { + fprintf (stderr, "net_recv: Got %d\n", netdata.unitdata_ind.PRIM_type); + errno = EPROTO; + return (0); + } + if (retval) + { + errno = EIO; + return (0); + } + /* + * Copy return address for the user + */ + if (netdata.unitdata_ind.SRC_length < addrlen) + addrlen = netdata.unitdata_ind.SRC_length; + + c = (char *) &netdata; + bcopy (&(c[netdata.unitdata_ind.SRC_offset]), + from_addr, + addrlen); + + return (databuf.len); +} diff --git a/streams/stream_dg/server.c b/streams/stream_dg/server.c new file mode 100644 index 0000000..812fb9a --- /dev/null +++ b/streams/stream_dg/server.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include + +#include +#include + +extern int errno; + +#define SERV_TCP_PORT 6000 + +main() +{ + int fd; + struct sockaddr_in my_addr; + void echo_serv (int); + + bzero((char *) &my_addr, sizeof(my_addr)); + my_addr.sin_family = AF_INET; + my_addr.sin_addr.s_addr = htonl (INADDR_ANY); + my_addr.sin_port = htons(SERV_TCP_PORT); + + fd = net_open ("/dev/udp", O_RDWR); + fd = net_bind (fd, &my_addr, sizeof (struct sockaddr_in)); + + echo_serv (fd); + exit (0); /* not reached */ +} + +void +echo_serv (int fd) +{ + struct sockaddr_in fm_addr; + char buf[512]; + int n; + + while (1) + { + n = net_recv (fd, buf, sizeof (buf), + &fm_addr, sizeof (struct sockaddr_in)); + + net_send (fd, buf, n, + &fm_addr, sizeof (struct sockaddr_in)); + } +} diff --git a/streams/strlist_sock.c b/streams/strlist_sock.c new file mode 100644 index 0000000..49a069c --- /dev/null +++ b/streams/strlist_sock.c @@ -0,0 +1,28 @@ +#include "unp.h" +#include + +int +main(int argc, char *argv[]) +{ + int fd, i, nmods; + struct str_list list; + + if (argc != 2) + err_quit("usage: a.out { tcp | udp }"); + + fd = Socket(AF_INET, (strcmp(argv[1], "tcp") == 0) + ? SOCK_STREAM : SOCK_DGRAM, 0); + if (isastream(fd) == 0) + err_quit("%s is not a stream", argv[1]); + + list.sl_nmods = nmods = Ioctl(fd, I_LIST, (void *) 0); + printf("%d modules\n", nmods); + list.sl_modlist = Calloc(nmods, sizeof(struct str_mlist)); + + Ioctl(fd, I_LIST, &list); + + for (i = 1; i <= nmods; i++) + printf(" %s: %s\n", (i == nmods) ? "driver" : "module", + list.sl_modlist++); + exit(0); +} diff --git a/streams/strlist_xti.c b/streams/strlist_xti.c new file mode 100644 index 0000000..b8dc557 --- /dev/null +++ b/streams/strlist_xti.c @@ -0,0 +1,27 @@ +#include "unpxti.h" +#include + +int +main(int argc, char *argv[]) +{ + int fd, i, nmods; + struct str_list list; + + if (argc != 2) + err_quit("usage: a.out "); + + fd = T_open(argv[1], O_RDWR, NULL); + if (isastream(fd) == 0) + err_quit("%s is not a stream", argv[1]); + + list.sl_nmods = nmods = Ioctl(fd, I_LIST, (void *) 0); + printf("%d modules\n", nmods); + list.sl_modlist = Calloc(nmods, sizeof(struct str_mlist)); + + Ioctl(fd, I_LIST, &list); + + for (i = 1; i <= nmods; i++) + printf(" %s: %s\n", (i == nmods) ? "driver" : "module", + list.sl_modlist++); + exit(0); +} diff --git a/streams/tpi_bind.c b/streams/tpi_bind.c new file mode 100644 index 0000000..386df52 --- /dev/null +++ b/streams/tpi_bind.c @@ -0,0 +1,55 @@ +#include "tpi_daytime.h" + +void +tpi_bind(int fd, const void *addr, size_t addrlen) +{ + struct { + struct T_bind_req msg_hdr; + char addr[128]; + } bind_req; + struct { + struct T_bind_ack msg_hdr; + char addr[128]; + } bind_ack; + struct strbuf ctlbuf; + struct T_error_ack *error_ack; + int flags; + + bind_req.msg_hdr.PRIM_type = T_BIND_REQ; + bind_req.msg_hdr.ADDR_length = addrlen; + bind_req.msg_hdr.ADDR_offset = sizeof(struct T_bind_req); + bind_req.msg_hdr.CONIND_number = 0; + memcpy(bind_req.addr, addr, addrlen); /* sockaddr_in{} */ + + ctlbuf.len = sizeof(struct T_bind_req) + addrlen; + ctlbuf.buf = (char *) &bind_req; + Putmsg(fd, &ctlbuf, NULL, 0); + + ctlbuf.maxlen = sizeof(bind_ack); + ctlbuf.len = 0; + ctlbuf.buf = (char *) &bind_ack; + flags = RS_HIPRI; + Getmsg(fd, &ctlbuf, NULL, &flags); + +/* *INDENT-OFF* */ + if (ctlbuf.len < (int) sizeof(long)) + err_quit("bad length from getmsg"); +/* *INDENT-ON* */ + + switch(bind_ack.msg_hdr.PRIM_type) { + case T_BIND_ACK: + return; + + case T_ERROR_ACK: +/* *INDENT-OFF* */ + if (ctlbuf.len < (int) sizeof(struct T_error_ack)) + err_quit("bad length for T_ERROR_ACK"); + error_ack = (struct T_error_ack *) &bind_ack.msg_hdr; + err_quit("T_ERROR_ACK from bind (%d, %d)", + error_ack->TLI_error, error_ack->UNIX_error); +/* *INDENT-ON* */ + + default: + err_quit("unexpected message type: %d", bind_ack.msg_hdr.PRIM_type); + } +} diff --git a/streams/tpi_close.c b/streams/tpi_close.c new file mode 100644 index 0000000..84fd2bb --- /dev/null +++ b/streams/tpi_close.c @@ -0,0 +1,16 @@ +#include "tpi_daytime.h" + +void +tpi_close(int fd) +{ + struct T_ordrel_req ordrel_req; + struct strbuf ctlbuf; + + ordrel_req.PRIM_type = T_ORDREL_REQ; + + ctlbuf.len = sizeof(struct T_ordrel_req); + ctlbuf.buf = (char *) &ordrel_req; + Putmsg(fd, &ctlbuf, NULL, 0); + + Close(fd); +} diff --git a/streams/tpi_close.lc b/streams/tpi_close.lc new file mode 100644 index 0000000..d762fe0 --- /dev/null +++ b/streams/tpi_close.lc @@ -0,0 +1,16 @@ +#include "tpi_daytime.h"## 1 ##src/streams/tpi_close.c## + +void## 2 ##src/streams/tpi_close.c## +tpi_close(int fd)## 3 ##src/streams/tpi_close.c## +{## 4 ##src/streams/tpi_close.c## + struct T_ordrel_req ordrel_req;## 5 ##src/streams/tpi_close.c## + struct strbuf ctlbuf;## 6 ##src/streams/tpi_close.c## + + ordrel_req.PRIM_type = T_ORDREL_REQ;## 7 ##src/streams/tpi_close.c## + + ctlbuf.len = sizeof(struct T_ordrel_req);## 8 ##src/streams/tpi_close.c## + ctlbuf.buf = (char *) &ordrel_req;## 9 ##src/streams/tpi_close.c## + Putmsg(fd, &ctlbuf, NULL, 0);## 10 ##src/streams/tpi_close.c## + + Close(fd);## 11 ##src/streams/tpi_close.c## +}## 12 ##src/streams/tpi_close.c## diff --git a/streams/tpi_connect.c b/streams/tpi_connect.c new file mode 100644 index 0000000..e5a9b72 --- /dev/null +++ b/streams/tpi_connect.c @@ -0,0 +1,87 @@ +#include "tpi_daytime.h" + +void +tpi_connect(int fd, const void *addr, size_t addrlen) +{ + struct { + struct T_conn_req msg_hdr; + char addr[128]; + } conn_req; + struct { + struct T_conn_con msg_hdr; + char addr[128]; + } conn_con; + struct strbuf ctlbuf; + union T_primitives rcvbuf; + struct T_error_ack *error_ack; + struct T_discon_ind *discon_ind; + int flags; + + conn_req.msg_hdr.PRIM_type = T_CONN_REQ; + conn_req.msg_hdr.DEST_length = addrlen; + conn_req.msg_hdr.DEST_offset = sizeof(struct T_conn_req); + conn_req.msg_hdr.OPT_length = 0; + conn_req.msg_hdr.OPT_offset = 0; + memcpy(conn_req.addr, addr, addrlen); /* sockaddr_in{} */ + + ctlbuf.len = sizeof(struct T_conn_req) + addrlen; + ctlbuf.buf = (char *) &conn_req; + Putmsg(fd, &ctlbuf, NULL, 0); + + ctlbuf.maxlen = sizeof(union T_primitives); + ctlbuf.len = 0; + ctlbuf.buf = (char *) &rcvbuf; + flags = RS_HIPRI; + Getmsg(fd, &ctlbuf, NULL, &flags); + +/* *INDENT-OFF* */ + if (ctlbuf.len < (int) sizeof(long)) + err_quit("tpi_connect: bad length from getmsg"); +/* *INDENT-ON* */ + + switch(rcvbuf.type) { + case T_OK_ACK: + break; + + case T_ERROR_ACK: +/* *INDENT-OFF* */ + if (ctlbuf.len < (int) sizeof(struct T_error_ack)) + err_quit("tpi_connect: bad length for T_ERROR_ACK"); + error_ack = (struct T_error_ack *) &rcvbuf; + err_quit("tpi_connect: T_ERROR_ACK from conn (%d, %d)", + error_ack->TLI_error, error_ack->UNIX_error); +/* *INDENT-ON* */ + + default: + err_quit("tpi_connect: unexpected message type: %d", rcvbuf.type); + } + + ctlbuf.maxlen = sizeof(conn_con); + ctlbuf.len = 0; + ctlbuf.buf = (char *) &conn_con; + flags = 0; + Getmsg(fd, &ctlbuf, NULL, &flags); + +/* *INDENT-OFF* */ + if (ctlbuf.len < (int) sizeof(long)) + err_quit("tpi_connect2: bad length from getmsg"); +/* *INDENT-ON* */ + + switch(conn_con.msg_hdr.PRIM_type) { + case T_CONN_CON: + break; + + case T_DISCON_IND: +/* *INDENT-OFF* */ + if (ctlbuf.len < (int) sizeof(struct T_discon_ind)) + err_quit("tpi_connect2: bad length for T_DISCON_IND"); + discon_ind = (struct T_discon_ind *) &conn_con.msg_hdr; + err_quit("tpi_connect2: T_DISCON_IND from conn (%d)", + discon_ind->DISCON_reason); +/* *INDENT-ON* */ + + default: + err_quit("tpi_connect2: unexpected message type: %d", + conn_con.msg_hdr.PRIM_type); + } +} diff --git a/streams/tpi_connect.lc b/streams/tpi_connect.lc new file mode 100644 index 0000000..93e8d72 --- /dev/null +++ b/streams/tpi_connect.lc @@ -0,0 +1,79 @@ +#include "tpi_daytime.h"## 1 ##src/streams/tpi_connect.c## + +void## 2 ##src/streams/tpi_connect.c## +tpi_connect(int fd, const void *addr, size_t addrlen)## 3 ##src/streams/tpi_connect.c## +{## 4 ##src/streams/tpi_connect.c## + struct {## 5 ##src/streams/tpi_connect.c## + struct T_conn_req msg_hdr;## 6 ##src/streams/tpi_connect.c## + char addr[128];## 7 ##src/streams/tpi_connect.c## + } conn_req;## 8 ##src/streams/tpi_connect.c## + struct {## 9 ##src/streams/tpi_connect.c## + struct T_conn_con msg_hdr;## 10 ##src/streams/tpi_connect.c## + char addr[128];## 11 ##src/streams/tpi_connect.c## + } conn_con;## 12 ##src/streams/tpi_connect.c## + struct strbuf ctlbuf;## 13 ##src/streams/tpi_connect.c## + union T_primitives rcvbuf;## 14 ##src/streams/tpi_connect.c## + struct T_error_ack *error_ack;## 15 ##src/streams/tpi_connect.c## + struct T_discon_ind *discon_ind;## 16 ##src/streams/tpi_connect.c## + int flags;## 17 ##src/streams/tpi_connect.c## + + conn_req.msg_hdr.PRIM_type = T_CONN_REQ;## 18 ##src/streams/tpi_connect.c## + conn_req.msg_hdr.DEST_length = addrlen;## 19 ##src/streams/tpi_connect.c## + conn_req.msg_hdr.DEST_offset = sizeof(struct T_conn_req);## 20 ##src/streams/tpi_connect.c## + conn_req.msg_hdr.OPT_length = 0;## 21 ##src/streams/tpi_connect.c## + conn_req.msg_hdr.OPT_offset = 0;## 22 ##src/streams/tpi_connect.c## + memcpy(conn_req.addr, addr, addrlen); /* sockaddr_in{} */## 23 ##src/streams/tpi_connect.c## + + ctlbuf.len = sizeof(struct T_conn_req) + addrlen;## 24 ##src/streams/tpi_connect.c## + ctlbuf.buf = (char *) &conn_req;## 25 ##src/streams/tpi_connect.c## + Putmsg(fd, &ctlbuf, NULL, 0);## 26 ##src/streams/tpi_connect.c## + + ctlbuf.maxlen = sizeof(union T_primitives);## 27 ##src/streams/tpi_connect.c## + ctlbuf.len = 0;## 28 ##src/streams/tpi_connect.c## + ctlbuf.buf = (char *) &rcvbuf;## 29 ##src/streams/tpi_connect.c## + flags = RS_HIPRI;## 30 ##src/streams/tpi_connect.c## + Getmsg(fd, &ctlbuf, NULL, &flags);## 31 ##src/streams/tpi_connect.c## + + if (ctlbuf.len < (int) sizeof(long))## 32 ##src/streams/tpi_connect.c## + err_quit("tpi_connect: bad length from getmsg");## 33 ##src/streams/tpi_connect.c## + + switch (rcvbuf.type) {## 34 ##src/streams/tpi_connect.c## + case T_OK_ACK:## 35 ##src/streams/tpi_connect.c## + break;## 36 ##src/streams/tpi_connect.c## + + case T_ERROR_ACK:## 37 ##src/streams/tpi_connect.c## + if (ctlbuf.len < (int) sizeof(struct T_error_ack))## 38 ##src/streams/tpi_connect.c## + err_quit("tpi_connect: bad length for T_ERROR_ACK");## 39 ##src/streams/tpi_connect.c## + error_ack = (struct T_error_ack *) &rcvbuf;## 40 ##src/streams/tpi_connect.c## + err_quit("tpi_connect: T_ERROR_ACK from conn (%d, %d)",## 41 ##src/streams/tpi_connect.c## + error_ack->TLI_error, error_ack->UNIX_error);## 42 ##src/streams/tpi_connect.c## + + default:## 43 ##src/streams/tpi_connect.c## + err_quit("tpi_connect: unexpected message type: %d", rcvbuf.type);## 44 ##src/streams/tpi_connect.c## + }## 45 ##src/streams/tpi_connect.c## + + ctlbuf.maxlen = sizeof(conn_con);## 46 ##src/streams/tpi_connect.c## + ctlbuf.len = 0;## 47 ##src/streams/tpi_connect.c## + ctlbuf.buf = (char *) &conn_con;## 48 ##src/streams/tpi_connect.c## + flags = 0;## 49 ##src/streams/tpi_connect.c## + Getmsg(fd, &ctlbuf, NULL, &flags);## 50 ##src/streams/tpi_connect.c## + + if (ctlbuf.len < (int) sizeof(long))## 51 ##src/streams/tpi_connect.c## + err_quit("tpi_connect2: bad length from getmsg");## 52 ##src/streams/tpi_connect.c## + + switch (conn_con.msg_hdr.PRIM_type) {## 53 ##src/streams/tpi_connect.c## + case T_CONN_CON:## 54 ##src/streams/tpi_connect.c## + break;## 55 ##src/streams/tpi_connect.c## + + case T_DISCON_IND:## 56 ##src/streams/tpi_connect.c## + if (ctlbuf.len < (int) sizeof(struct T_discon_ind))## 57 ##src/streams/tpi_connect.c## + err_quit("tpi_connect2: bad length for T_DISCON_IND");## 58 ##src/streams/tpi_connect.c## + discon_ind = (struct T_discon_ind *) &conn_con.msg_hdr;## 59 ##src/streams/tpi_connect.c## + err_quit("tpi_connect2: T_DISCON_IND from conn (%d)",## 60 ##src/streams/tpi_connect.c## + discon_ind->DISCON_reason);## 61 ##src/streams/tpi_connect.c## + + default:## 62 ##src/streams/tpi_connect.c## + err_quit("tpi_connect2: unexpected message type: %d",## 63 ##src/streams/tpi_connect.c## + conn_con.msg_hdr.PRIM_type);## 64 ##src/streams/tpi_connect.c## + }## 65 ##src/streams/tpi_connect.c## +}## 66 ##src/streams/tpi_connect.c## diff --git a/streams/tpi_daytime.c b/streams/tpi_daytime.c new file mode 100644 index 0000000..37a8416 --- /dev/null +++ b/streams/tpi_daytime.c @@ -0,0 +1,43 @@ +#include "tpi_daytime.h" + +int +main(int argc, char **argv) +{ + int fd, n; + char recvline[MAXLINE + 1]; + struct sockaddr_in myaddr, servaddr; + + if (argc != 2) + err_quit("usage: tpi_daytime "); + + fd = Open(XTI_TCP, O_RDWR, 0); + + /*4bind any local address */ + bzero(&myaddr, sizeof(myaddr)); + myaddr.sin_family = AF_INET; + myaddr.sin_addr.s_addr = htonl(INADDR_ANY); + myaddr.sin_port = htons(0); + + tpi_bind(fd, &myaddr, sizeof(struct sockaddr_in)); + + /*4fill in server's address */ + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(13); /* daytime server */ + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + tpi_connect(fd, &servaddr, sizeof(struct sockaddr_in)); + + for ( ; ; ) { + if ( (n = tpi_read(fd, recvline, MAXLINE)) <= 0) { + if (n == 0) + break; + else + err_sys("tpi_read error"); + } + recvline[n] = 0; /* null terminate */ + fputs(recvline, stdout); + } + tpi_close(fd); + exit(0); +} diff --git a/streams/tpi_daytime.h b/streams/tpi_daytime.h new file mode 100644 index 0000000..2389cf1 --- /dev/null +++ b/streams/tpi_daytime.h @@ -0,0 +1,8 @@ +#include "unpxti.h" +#include +#include + +void tpi_bind(int, const void *, size_t); +void tpi_connect(int, const void *, size_t); +ssize_t tpi_read(int, void *, size_t); +void tpi_close(int); diff --git a/streams/tpi_read.c b/streams/tpi_read.c new file mode 100644 index 0000000..a163b94 --- /dev/null +++ b/streams/tpi_read.c @@ -0,0 +1,32 @@ +#include "tpi_daytime.h" + +ssize_t +tpi_read(int fd, void *buf, size_t len) +{ + struct strbuf ctlbuf; + struct strbuf datbuf; + union T_primitives rcvbuf; + int flags; + + ctlbuf.maxlen = sizeof(union T_primitives); + ctlbuf.buf = (char *) &rcvbuf; + + datbuf.maxlen = len; + datbuf.buf = buf; + datbuf.len = 0; + + flags = 0; + Getmsg(fd, &ctlbuf, &datbuf, &flags); + + if (ctlbuf.len >= (int) sizeof(long)) { + if (rcvbuf.type == T_DATA_IND) + return(datbuf.len); + else if (rcvbuf.type == T_ORDREL_IND) + return(0); + else + err_quit("tpi_read: unexpected type %d", rcvbuf.type); + } else if (ctlbuf.len == -1) + return(datbuf.len); + else + err_quit("tpi_read: bad length from getmsg"); +} diff --git a/streams/tpi_read.lc b/streams/tpi_read.lc new file mode 100644 index 0000000..5ad154c --- /dev/null +++ b/streams/tpi_read.lc @@ -0,0 +1,32 @@ +#include "tpi_daytime.h"## 1 ##src/streams/tpi_read.c## + +ssize_t## 2 ##src/streams/tpi_read.c## +tpi_read(int fd, void *buf, size_t len)## 3 ##src/streams/tpi_read.c## +{## 4 ##src/streams/tpi_read.c## + struct strbuf ctlbuf;## 5 ##src/streams/tpi_read.c## + struct strbuf datbuf;## 6 ##src/streams/tpi_read.c## + union T_primitives rcvbuf;## 7 ##src/streams/tpi_read.c## + int flags;## 8 ##src/streams/tpi_read.c## + + ctlbuf.maxlen = sizeof(union T_primitives);## 9 ##src/streams/tpi_read.c## + ctlbuf.buf = (char *) &rcvbuf;## 10 ##src/streams/tpi_read.c## + + datbuf.maxlen = len;## 11 ##src/streams/tpi_read.c## + datbuf.buf = buf;## 12 ##src/streams/tpi_read.c## + datbuf.len = 0;## 13 ##src/streams/tpi_read.c## + + flags = 0;## 14 ##src/streams/tpi_read.c## + Getmsg(fd, &ctlbuf, &datbuf, &flags);## 15 ##src/streams/tpi_read.c## + + if (ctlbuf.len >= (int) sizeof(long)) {## 16 ##src/streams/tpi_read.c## + if (rcvbuf.type == T_DATA_IND)## 17 ##src/streams/tpi_read.c## + return (datbuf.len);## 18 ##src/streams/tpi_read.c## + else if (rcvbuf.type == T_ORDREL_IND)## 19 ##src/streams/tpi_read.c## + return (0);## 20 ##src/streams/tpi_read.c## + else## 21 ##src/streams/tpi_read.c## + err_quit("tpi_read: unexpected type %d", rcvbuf.type);## 22 ##src/streams/tpi_read.c## + } else if (ctlbuf.len == -1)## 23 ##src/streams/tpi_read.c## + return (datbuf.len);## 24 ##src/streams/tpi_read.c## + else## 25 ##src/streams/tpi_read.c## + err_quit("tpi_read: bad length from getmsg");## 26 ##src/streams/tpi_read.c## +}## 27 ##src/streams/tpi_read.c## diff --git a/streams/unpxti.h b/streams/unpxti.h new file mode 100644 index 0000000..6fe4b18 --- /dev/null +++ b/streams/unpxti.h @@ -0,0 +1,152 @@ +/* include unpxtih1 */ +#ifndef __unp_xti_h +#define __unp_xti_h + +#include "unp.h" + +#include +#ifdef HAVE_XTI_INET_H +# include +#endif +#ifdef HAVE_NETCONFIG_H +# include +#endif +#ifdef HAVE_NETDIR_H +# include +#endif + +#ifdef INFTIM_UNPH +#undef INFTIM /* was not in , undef for */ +#endif + +#include + +/* Provide compatibility with the new names prepended with T_ + in XNS Issue 5, which are not in Posix.1g. */ + +#ifndef T_INET_TCP +#define T_INET_TCP INET_TCP +/* $$.Ic T_INET_TCP$$ */ +#endif +/* end unpxtih1 */ +#ifndef T_INET_UDP +#define T_INET_UDP INET_UDP +#endif +#ifndef T_INET_IP +#define T_INET_IP INET_IP +#endif +#ifndef T_TCP_NODELAY +#define T_TCP_NODELAY TCP_NODELAY +#endif +#ifndef T_TCP_MAXSEG +#define T_TCP_MAXSEG TCP_MAXSEG +#endif +#ifndef T_TCP_KEEPALIVE +#define T_TCP_KEEPALIVE TCP_KEEPALIVE +#endif +#ifndef T_UDP_CHECKSUM +#define T_UDP_CHECKSUM UDP_CHECKSUM +#endif +#ifndef T_IP_OPTIONS +#define T_IP_OPTIONS IP_OPTIONS +#endif +#ifndef T_IP_TOS +#define T_IP_TOS IP_TOS +#endif +#ifndef T_IP_TTL +#define T_IP_TTL IP_TTL +#endif +#ifndef T_IP_REUSEADDR +#define T_IP_REUSEADDR IP_REUSEADDR +#endif +#ifndef T_IP_DONTROUTE +#define T_IP_DONTROUTE IP_DONTROUTE +#endif +/* include unpxtih2 */ +#ifndef T_IP_BROADCAST +#define T_IP_BROADCAST IP_BROADCAST +/* $$.Ic T_IP_BROADCAST$$ */ +#endif + +/* Define the appropriate devices for t_open(). */ +#ifdef HAVE_DEV_TCP +# define XTI_TCP "/dev/tcp" +# define XTI_UDP "/dev/udp" +#endif +#ifdef HAVE_DEV_XTI_TCP +# define XTI_TCP "/dev/xti/tcp" +# define XTI_UDP "/dev/xti/udp" +#endif +#ifdef HAVE_DEV_STREAMS_XTISO_TCP +# define XTI_TCP "/dev/streams/xtiso/tcp+" /* + for XPG4 */ +# define XTI_UDP "/dev/streams/xtiso/udp+" /* + for XPG4 */ +#endif + + /* 4device to t_open() for t_accept(); set by tcp_listen() */ +/* $$.Id xti_serv_dev$$ */ +extern char xti_serv_dev[]; +/* end unpxtih2 */ + +void err_xti(const char *fmt, ...); +void err_xti_ret(const char *fmt, ...); + +int Getmsg(int, struct strbuf *, struct strbuf *, int *); +void Putmsg(int, const struct strbuf *, const struct strbuf *, int); + +#ifdef HAVE_NETCONFIG_H +void *Setnetconfig(void); +void *Setnetpath(void); +#endif + +void *T_alloc(int, int, int); +int T_accept(int, int, struct t_call *); +void T_bind(int, const struct t_bind *, struct t_bind *); +void T_close(int); +void T_connect(int, const struct t_call *, struct t_call *); +void T_free(void *, int); +void T_getprotaddr(int, struct t_bind *, struct t_bind *); +int T_getstate(int); +void T_listen(int, struct t_call *); +int T_look(int); +int T_open(const char *, int, struct t_info *); +void T_optmgmt(int, const struct t_optmgmt *, struct t_optmgmt *); +int T_rcv(int, void *, unsigned int, int *); +void T_rcvdis(int, struct t_discon *); +void T_rcvrel(int); +void T_rcvudata(int, struct t_unitdata *, int *); +void T_rcvuderr(int, struct t_uderr *); +void T_snd(int, void *, unsigned int, int); +void T_sndrel(int); +void T_sndudata(int, struct t_unitdata *); + +int xti_accept(int, struct netbuf *, int); +int xti_getopt(int, int, int, void *, socklen_t *); +char *xti_flags_str(int); +char *xti_tlook_str(int); +char *xti_ntop(const struct netbuf *); +char *xti_ntop_host(const struct netbuf *); +int xti_rdwr(int); +int xti_setopt(int, int, int, void *, socklen_t); + +int Xti_accept(int, struct netbuf *, int); +void Xti_getopt(int, int, int, void *, socklen_t *); +char *Xti_flags_str(int); +char *Xti_tlook_str(int); +char *Xti_ntop(const struct netbuf *); +char *Xti_ntop_host(const struct netbuf *); +void Xti_rdwr(int); +void Xti_setopt(int, int, int, void *, socklen_t); + +char *xti_str_lend(struct t_opthdr *); +char *xti_str_uscalard(struct t_opthdr *); +char *xti_str_uchard(struct t_opthdr *); +char *xti_str_ucharx(struct t_opthdr *); +char *xti_str_yn(t_uscalar_t); +char *xti_str_syng(t_scalar_t); +char *xti_str_uiyn(struct t_opthdr *); +char *xti_str_usyn(struct t_opthdr *); +char *xti_str_linger(struct t_opthdr *); +char *xti_str_kpalive(struct t_opthdr *); +char *xti_str_flags(t_scalar_t); + +#endif /* __unp_xti_h */ diff --git a/tcpcliserv/Makefile b/tcpcliserv/Makefile new file mode 100644 index 0000000..9f114d0 --- /dev/null +++ b/tcpcliserv/Makefile @@ -0,0 +1,67 @@ +include ../Make.defines + +PROGS = tcpcli01 tcpcli04 tcpcli05 tcpcli06 \ + tcpcli07 tcpcli08 tcpcli09 tcpcli10 \ + tcpserv01 tcpserv02 tcpserv03 tcpserv04 \ + tcpserv08 tcpserv09 tcpservselect01 tcpservpoll01 tsigpipe + +all: ${PROGS} + +tcpcli01: tcpcli01.o + ${CC} ${CFLAGS} -o $@ tcpcli01.o ${LIBS} + +tcpcli04: tcpcli04.o + ${CC} ${CFLAGS} -o $@ tcpcli04.o ${LIBS} + +tcpcli05: tcpcli05.o + ${CC} ${CFLAGS} -o $@ tcpcli05.o ${LIBS} + +tcpcli06: tcpcli06.o + ${CC} ${CFLAGS} -o $@ tcpcli06.o ${LIBS} + +tcpcli07: tcpcli07.o + ${CC} ${CFLAGS} -o $@ tcpcli07.o ${LIBS} + +tcpcli08: tcpcli08.o str_cli08.o + ${CC} ${CFLAGS} -o $@ tcpcli08.o str_cli08.o ${LIBS} + +tcpcli09: tcpcli09.o str_cli09.o + ${CC} ${CFLAGS} -o $@ tcpcli09.o str_cli09.o ${LIBS} + +tcpcli10: tcpcli10.o + ${CC} ${CFLAGS} -o $@ tcpcli10.o ${LIBS} + +tcpcli11: tcpcli11.o str_cli11.o + ${CC} ${CFLAGS} -o $@ tcpcli11.o str_cli11.o ${LIBS} + +tcpserv01: tcpserv01.o + ${CC} ${CFLAGS} -o $@ tcpserv01.o ${LIBS} + +tcpserv02: tcpserv02.o sigchldwait.o + ${CC} ${CFLAGS} -o $@ tcpserv02.o sigchldwait.o ${LIBS} + +tcpserv03: tcpserv03.o sigchldwait.o + ${CC} ${CFLAGS} -o $@ tcpserv03.o sigchldwait.o ${LIBS} + +tcpserv04: tcpserv04.o sigchldwaitpid.o + ${CC} ${CFLAGS} -o $@ tcpserv04.o sigchldwaitpid.o ${LIBS} + +tcpserv08: tcpserv08.o str_echo08.o sigchldwaitpid.o + ${CC} ${CFLAGS} -o $@ tcpserv08.o str_echo08.o sigchldwaitpid.o \ + ${LIBS} + +tcpserv09: tcpserv09.o str_echo09.o sigchldwaitpid.o + ${CC} ${CFLAGS} -o $@ tcpserv09.o str_echo09.o sigchldwaitpid.o \ + ${LIBS} + +tcpservselect01: tcpservselect01.o + ${CC} ${CFLAGS} -o $@ tcpservselect01.o ${LIBS} + +tcpservpoll01: tcpservpoll01.o + ${CC} ${CFLAGS} -o $@ tcpservpoll01.o ${LIBS} + +tsigpipe: tsigpipe.o + ${CC} ${CFLAGS} -o $@ tsigpipe.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/tcpcliserv/sigchldwait.c b/tcpcliserv/sigchldwait.c new file mode 100644 index 0000000..9730af0 --- /dev/null +++ b/tcpcliserv/sigchldwait.c @@ -0,0 +1,12 @@ +#include "unp.h" + +void +sig_chld(int signo) +{ + pid_t pid; + int stat; + + pid = wait(&stat); + printf("child %d terminated\n", pid); + return; +} diff --git a/tcpcliserv/sigchldwait.lc b/tcpcliserv/sigchldwait.lc new file mode 100644 index 0000000..fd749fe --- /dev/null +++ b/tcpcliserv/sigchldwait.lc @@ -0,0 +1,12 @@ +#include "unp.h"## 1 ##src/tcpcliserv/sigchldwait.c## + +void## 2 ##src/tcpcliserv/sigchldwait.c## +sig_chld(int signo)## 3 ##src/tcpcliserv/sigchldwait.c## +{## 4 ##src/tcpcliserv/sigchldwait.c## + pid_t pid;## 5 ##src/tcpcliserv/sigchldwait.c## + int stat;## 6 ##src/tcpcliserv/sigchldwait.c## + + pid = wait(&stat);## 7 ##src/tcpcliserv/sigchldwait.c## + printf("child %d terminated\n", pid);## 8 ##src/tcpcliserv/sigchldwait.c## + return;## 9 ##src/tcpcliserv/sigchldwait.c## +}## 10 ##src/tcpcliserv/sigchldwait.c## diff --git a/tcpcliserv/sigchldwaitpid.c b/tcpcliserv/sigchldwaitpid.c new file mode 100644 index 0000000..12b5ff3 --- /dev/null +++ b/tcpcliserv/sigchldwaitpid.c @@ -0,0 +1,12 @@ +#include "unp.h" + +void +sig_chld(int signo) +{ + pid_t pid; + int stat; + + while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) + printf("child %d terminated\n", pid); + return; +} diff --git a/tcpcliserv/sigchldwaitpid.lc b/tcpcliserv/sigchldwaitpid.lc new file mode 100644 index 0000000..c196fb7 --- /dev/null +++ b/tcpcliserv/sigchldwaitpid.lc @@ -0,0 +1,12 @@ +#include "unp.h"## 1 ##src/tcpcliserv/sigchldwaitpid.c## + +void## 2 ##src/tcpcliserv/sigchldwaitpid.c## +sig_chld(int signo)## 3 ##src/tcpcliserv/sigchldwaitpid.c## +{## 4 ##src/tcpcliserv/sigchldwaitpid.c## + pid_t pid;## 5 ##src/tcpcliserv/sigchldwaitpid.c## + int stat;## 6 ##src/tcpcliserv/sigchldwaitpid.c## + + while ((pid = waitpid(-1, &stat, WNOHANG)) > 0)## 7 ##src/tcpcliserv/sigchldwaitpid.c## + printf("child %d terminated\n", pid);## 8 ##src/tcpcliserv/sigchldwaitpid.c## + return;## 9 ##src/tcpcliserv/sigchldwaitpid.c## +}## 10 ##src/tcpcliserv/sigchldwaitpid.c## diff --git a/tcpcliserv/str_cli08.c b/tcpcliserv/str_cli08.c new file mode 100644 index 0000000..ea0f9da --- /dev/null +++ b/tcpcliserv/str_cli08.c @@ -0,0 +1,17 @@ +#include "unp.h" + +void +str_cli(FILE *fp, int sockfd) +{ + char sendline[MAXLINE], recvline[MAXLINE]; + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Writen(sockfd, sendline, strlen(sendline)); + + if (Readline(sockfd, recvline, MAXLINE) == 0) + err_quit("str_cli: server terminated prematurely"); + + Fputs(recvline, stdout); + } +} diff --git a/tcpcliserv/str_cli09.c b/tcpcliserv/str_cli09.c new file mode 100644 index 0000000..ce74d00 --- /dev/null +++ b/tcpcliserv/str_cli09.c @@ -0,0 +1,24 @@ +#include "unp.h" +#include "sum.h" + +void +str_cli(FILE *fp, int sockfd) +{ + char sendline[MAXLINE]; + struct args args; + struct result result; + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + if (sscanf(sendline, "%ld%ld", &args.arg1, &args.arg2) != 2) { + printf("invalid input: %s", sendline); + continue; + } + Writen(sockfd, &args, sizeof(args)); + + if (Readn(sockfd, &result, sizeof(result)) == 0) + err_quit("str_cli: server terminated prematurely"); + + printf("%ld\n", result.sum); + } +} diff --git a/tcpcliserv/str_cli11.c b/tcpcliserv/str_cli11.c new file mode 100644 index 0000000..e5a29e1 --- /dev/null +++ b/tcpcliserv/str_cli11.c @@ -0,0 +1,19 @@ +#include "unp.h" + +void +str_cli(FILE *fp, int sockfd) +{ + char sendline[MAXLINE], recvline[MAXLINE]; + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Writen(sockfd, sendline, 1); + sleep(1); + Writen(sockfd, sendline+1, strlen(sendline)-1); + + if (Readline(sockfd, recvline, MAXLINE) == 0) + err_quit("str_cli: server terminated prematurely"); + + Fputs(recvline, stdout); + } +} diff --git a/tcpcliserv/str_cli11.lc b/tcpcliserv/str_cli11.lc new file mode 100644 index 0000000..f02bd61 --- /dev/null +++ b/tcpcliserv/str_cli11.lc @@ -0,0 +1,19 @@ +#include "unp.h"## 1 ##src/tcpcliserv/str_cli11.c## + +void## 2 ##src/tcpcliserv/str_cli11.c## +str_cli(FILE *fp, int sockfd)## 3 ##src/tcpcliserv/str_cli11.c## +{## 4 ##src/tcpcliserv/str_cli11.c## + char sendline[MAXLINE], recvline[MAXLINE];## 5 ##src/tcpcliserv/str_cli11.c## + + while (Fgets(sendline, MAXLINE, fp) != NULL) {## 6 ##src/tcpcliserv/str_cli11.c## + + Writen(sockfd, sendline, 1);## 7 ##src/tcpcliserv/str_cli11.c## + sleep(1);## 8 ##src/tcpcliserv/str_cli11.c## + Writen(sockfd, sendline + 1, strlen(sendline) - 1);## 9 ##src/tcpcliserv/str_cli11.c## + + if (Readline(sockfd, recvline, MAXLINE) == 0)## 10 ##src/tcpcliserv/str_cli11.c## + err_quit("str_cli: server terminated prematurely");## 11 ##src/tcpcliserv/str_cli11.c## + + Fputs(recvline, stdout);## 12 ##src/tcpcliserv/str_cli11.c## + }## 13 ##src/tcpcliserv/str_cli11.c## +}## 14 ##src/tcpcliserv/str_cli11.c## diff --git a/tcpcliserv/str_echo08.c b/tcpcliserv/str_echo08.c new file mode 100644 index 0000000..cd2202e --- /dev/null +++ b/tcpcliserv/str_echo08.c @@ -0,0 +1,22 @@ +#include "unp.h" + +void +str_echo(int sockfd) +{ + long arg1, arg2; + ssize_t n; + char line[MAXLINE]; + + for ( ; ; ) { + if ( (n = Readline(sockfd, line, MAXLINE)) == 0) + return; /* connection closed by other end */ + + if (sscanf(line, "%ld%ld", &arg1, &arg2) == 2) + snprintf(line, sizeof(line), "%ld\n", arg1 + arg2); + else + snprintf(line, sizeof(line), "input error\n"); + + n = strlen(line); + Writen(sockfd, line, n); + } +} diff --git a/tcpcliserv/str_echo08.lc b/tcpcliserv/str_echo08.lc new file mode 100644 index 0000000..641cd68 --- /dev/null +++ b/tcpcliserv/str_echo08.lc @@ -0,0 +1,22 @@ +#include "unp.h"## 1 ##src/tcpcliserv/str_echo08.c## + +void## 2 ##src/tcpcliserv/str_echo08.c## +str_echo(int sockfd)## 3 ##src/tcpcliserv/str_echo08.c## +{## 4 ##src/tcpcliserv/str_echo08.c## + long arg1, arg2;## 5 ##src/tcpcliserv/str_echo08.c## + ssize_t n;## 6 ##src/tcpcliserv/str_echo08.c## + char line[MAXLINE];## 7 ##src/tcpcliserv/str_echo08.c## + + for (;;) {## 8 ##src/tcpcliserv/str_echo08.c## + if ((n = Readline(sockfd, line, MAXLINE)) == 0)## 9 ##src/tcpcliserv/str_echo08.c## + return; /* connection closed by other end */## 10 ##src/tcpcliserv/str_echo08.c## + + if (sscanf(line, "%ld%ld", &arg1, &arg2) == 2)## 11 ##src/tcpcliserv/str_echo08.c## + snprintf(line, sizeof(line), "%ld\n", arg1 + arg2);## 12 ##src/tcpcliserv/str_echo08.c## + else## 13 ##src/tcpcliserv/str_echo08.c## + snprintf(line, sizeof(line), "input error\n");## 14 ##src/tcpcliserv/str_echo08.c## + + n = strlen(line);## 15 ##src/tcpcliserv/str_echo08.c## + Writen(sockfd, line, n);## 16 ##src/tcpcliserv/str_echo08.c## + }## 17 ##src/tcpcliserv/str_echo08.c## +}## 18 ##src/tcpcliserv/str_echo08.c## diff --git a/tcpcliserv/str_echo09.c b/tcpcliserv/str_echo09.c new file mode 100644 index 0000000..0face1f --- /dev/null +++ b/tcpcliserv/str_echo09.c @@ -0,0 +1,18 @@ +#include "unp.h" +#include "sum.h" + +void +str_echo(int sockfd) +{ + ssize_t n; + struct args args; + struct result result; + + for ( ; ; ) { + if ( (n = Readn(sockfd, &args, sizeof(args))) == 0) + return; /* connection closed by other end */ + + result.sum = args.arg1 + args.arg2; + Writen(sockfd, &result, sizeof(result)); + } +} diff --git a/tcpcliserv/sum.h b/tcpcliserv/sum.h new file mode 100644 index 0000000..32e8a3b --- /dev/null +++ b/tcpcliserv/sum.h @@ -0,0 +1,8 @@ +struct args { + long arg1; + long arg2; +}; + +struct result { + long sum; +}; diff --git a/tcpcliserv/tcpcli01.c b/tcpcliserv/tcpcli01.c new file mode 100644 index 0000000..af1f1bf --- /dev/null +++ b/tcpcliserv/tcpcli01.c @@ -0,0 +1,24 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/tcpcliserv/tcpcli01.lc b/tcpcliserv/tcpcli01.lc new file mode 100644 index 0000000..1059abe --- /dev/null +++ b/tcpcliserv/tcpcli01.lc @@ -0,0 +1,24 @@ +#include "unp.h"## 1 ##src/tcpcliserv/tcpcli01.c## + +int## 2 ##src/tcpcliserv/tcpcli01.c## +main(int argc, char **argv)## 3 ##src/tcpcliserv/tcpcli01.c## +{## 4 ##src/tcpcliserv/tcpcli01.c## + int sockfd;## 5 ##src/tcpcliserv/tcpcli01.c## + struct sockaddr_in servaddr;## 6 ##src/tcpcliserv/tcpcli01.c## + + if (argc != 2)## 7 ##src/tcpcliserv/tcpcli01.c## + err_quit("usage: tcpcli ");## 8 ##src/tcpcliserv/tcpcli01.c## + + sockfd = Socket(AF_INET, SOCK_STREAM, 0);## 9 ##src/tcpcliserv/tcpcli01.c## + + bzero(&servaddr, sizeof(servaddr));## 10 ##src/tcpcliserv/tcpcli01.c## + servaddr.sin_family = AF_INET;## 11 ##src/tcpcliserv/tcpcli01.c## + servaddr.sin_port = htons(SERV_PORT);## 12 ##src/tcpcliserv/tcpcli01.c## + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);## 13 ##src/tcpcliserv/tcpcli01.c## + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));## 14 ##src/tcpcliserv/tcpcli01.c## + + str_cli(stdin, sockfd); /* do it all */## 15 ##src/tcpcliserv/tcpcli01.c## + + exit(0);## 16 ##src/tcpcliserv/tcpcli01.c## +}## 17 ##src/tcpcliserv/tcpcli01.c## diff --git a/tcpcliserv/tcpcli04.c b/tcpcliserv/tcpcli04.c new file mode 100644 index 0000000..1f76455 --- /dev/null +++ b/tcpcliserv/tcpcli04.c @@ -0,0 +1,26 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int i, sockfd[5]; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + for (i = 0; i < 5; i++) { + sockfd[i] = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd[i], (SA *) &servaddr, sizeof(servaddr)); + } + + str_cli(stdin, sockfd[0]); /* do it all */ + + exit(0); +} diff --git a/tcpcliserv/tcpcli05.c b/tcpcliserv/tcpcli05.c new file mode 100644 index 0000000..c9b4898 --- /dev/null +++ b/tcpcliserv/tcpcli05.c @@ -0,0 +1,25 @@ +/* Use standard echo server; baseline measurements for nonblocking version */ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(7); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/tcpcliserv/tcpcli06.c b/tcpcliserv/tcpcli06.c new file mode 100644 index 0000000..5f1c7da --- /dev/null +++ b/tcpcliserv/tcpcli06.c @@ -0,0 +1,28 @@ +/* Test version of client that sends one line without a newline, + to break tcpservselect01.c */ + +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + Writen(sockfd, "foo", 3); /* no newline */ + sleep(30); + + exit(0); +} diff --git a/tcpcliserv/tcpcli07.c b/tcpcliserv/tcpcli07.c new file mode 100644 index 0000000..19dc02e --- /dev/null +++ b/tcpcliserv/tcpcli07.c @@ -0,0 +1,41 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + void sig_alrm(int); + struct itimerval val; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + /* Set interval timer to go off before 3WHS completes */ + Signal(SIGALRM, sig_alrm); + val.it_interval.tv_sec = 0; + val.it_interval.tv_usec = 0; + val.it_value.tv_sec = 0; + val.it_value.tv_usec = 50000; /* 50 ms */ + if (setitimer(ITIMER_REAL, &val, NULL) == -1) + err_sys("setitimer error"); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} + +void +sig_alrm(int signo) +{ + exit(0); +} diff --git a/tcpcliserv/tcpcli08.c b/tcpcliserv/tcpcli08.c new file mode 100644 index 0000000..af1f1bf --- /dev/null +++ b/tcpcliserv/tcpcli08.c @@ -0,0 +1,24 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/tcpcliserv/tcpcli09.c b/tcpcliserv/tcpcli09.c new file mode 100644 index 0000000..af1f1bf --- /dev/null +++ b/tcpcliserv/tcpcli09.c @@ -0,0 +1,24 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/tcpcliserv/tcpcli10.c b/tcpcliserv/tcpcli10.c new file mode 100644 index 0000000..6a0b499 --- /dev/null +++ b/tcpcliserv/tcpcli10.c @@ -0,0 +1,29 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct linger ling; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + str_cli(stdin, sockfd); /* do it all */ + + ling.l_onoff = 1; + ling.l_linger = 0; + Setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)); + + exit(0); +} diff --git a/tcpcliserv/tcpcli11.c b/tcpcliserv/tcpcli11.c new file mode 100644 index 0000000..c9b4898 --- /dev/null +++ b/tcpcliserv/tcpcli11.c @@ -0,0 +1,25 @@ +/* Use standard echo server; baseline measurements for nonblocking version */ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(7); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/tcpcliserv/tcpserv01.c b/tcpcliserv/tcpserv01.c new file mode 100644 index 0000000..1720e83 --- /dev/null +++ b/tcpcliserv/tcpserv01.c @@ -0,0 +1,33 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + pid_t childpid; + socklen_t clilen; + struct sockaddr_in cliaddr, servaddr; + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + for ( ; ; ) { + clilen = sizeof(cliaddr); + connfd = Accept(listenfd, (SA *) &cliaddr, &clilen); + + if ( (childpid = Fork()) == 0) { /* child process */ + Close(listenfd); /* close listening socket */ + str_echo(connfd); /* process the request */ + exit(0); + } + Close(connfd); /* parent closes connected socket */ + } +} diff --git a/tcpcliserv/tcpserv01.lc b/tcpcliserv/tcpserv01.lc new file mode 100644 index 0000000..bd441fb --- /dev/null +++ b/tcpcliserv/tcpserv01.lc @@ -0,0 +1,33 @@ +#include "unp.h"## 1 ##src/tcpcliserv/tcpserv01.c## + +int## 2 ##src/tcpcliserv/tcpserv01.c## +main(int argc, char **argv)## 3 ##src/tcpcliserv/tcpserv01.c## +{## 4 ##src/tcpcliserv/tcpserv01.c## + int listenfd, connfd;## 5 ##src/tcpcliserv/tcpserv01.c## + pid_t childpid;## 6 ##src/tcpcliserv/tcpserv01.c## + socklen_t clilen;## 7 ##src/tcpcliserv/tcpserv01.c## + struct sockaddr_in cliaddr, servaddr;## 8 ##src/tcpcliserv/tcpserv01.c## + + listenfd = Socket(AF_INET, SOCK_STREAM, 0);## 9 ##src/tcpcliserv/tcpserv01.c## + + bzero(&servaddr, sizeof(servaddr));## 10 ##src/tcpcliserv/tcpserv01.c## + servaddr.sin_family = AF_INET;## 11 ##src/tcpcliserv/tcpserv01.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 12 ##src/tcpcliserv/tcpserv01.c## + servaddr.sin_port = htons(SERV_PORT);## 13 ##src/tcpcliserv/tcpserv01.c## + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));## 14 ##src/tcpcliserv/tcpserv01.c## + + Listen(listenfd, LISTENQ);## 15 ##src/tcpcliserv/tcpserv01.c## + + for (;;) {## 16 ##src/tcpcliserv/tcpserv01.c## + clilen = sizeof(cliaddr);## 17 ##src/tcpcliserv/tcpserv01.c## + connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);## 18 ##src/tcpcliserv/tcpserv01.c## + + if ((childpid = Fork()) == 0) { /* child process */## 19 ##src/tcpcliserv/tcpserv01.c## + Close(listenfd); /* close listening socket */## 20 ##src/tcpcliserv/tcpserv01.c## + str_echo(connfd); /* process the request */## 21 ##src/tcpcliserv/tcpserv01.c## + exit(0);## 22 ##src/tcpcliserv/tcpserv01.c## + }## 23 ##src/tcpcliserv/tcpserv01.c## + Close(connfd); /* parent closes connected socket */## 24 ##src/tcpcliserv/tcpserv01.c## + }## 25 ##src/tcpcliserv/tcpserv01.c## +}## 26 ##src/tcpcliserv/tcpserv01.c## diff --git a/tcpcliserv/tcpserv02.c b/tcpcliserv/tcpserv02.c new file mode 100644 index 0000000..9e8b43d --- /dev/null +++ b/tcpcliserv/tcpserv02.c @@ -0,0 +1,36 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + pid_t childpid; + socklen_t clilen; + struct sockaddr_in cliaddr, servaddr; + void sig_chld(int); + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + Signal(SIGCHLD, sig_chld); + + for ( ; ; ) { + clilen = sizeof(cliaddr); + connfd = Accept(listenfd, (SA *) &cliaddr, &clilen); + + if ( (childpid = Fork()) == 0) { /* child process */ + Close(listenfd); /* close listening socket */ + str_echo(connfd); /* process the request */ + exit(0); + } + Close(connfd); /* parent closes connected socket */ + } +} diff --git a/tcpcliserv/tcpserv03.c b/tcpcliserv/tcpserv03.c new file mode 100644 index 0000000..a964276 --- /dev/null +++ b/tcpcliserv/tcpserv03.c @@ -0,0 +1,41 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + pid_t childpid; + socklen_t clilen; + struct sockaddr_in cliaddr, servaddr; + void sig_chld(int); + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + Signal(SIGCHLD, sig_chld); + + for ( ; ; ) { + clilen = sizeof(cliaddr); + if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) { + if (errno == EINTR) + continue; /* back to for() */ + else + err_sys("accept error"); + } + + if ( (childpid = Fork()) == 0) { /* child process */ + Close(listenfd); /* close listening socket */ + str_echo(connfd); /* process the request */ + exit(0); + } + Close(connfd); /* parent closes connected socket */ + } +} diff --git a/tcpcliserv/tcpserv04.c b/tcpcliserv/tcpserv04.c new file mode 100644 index 0000000..9388cee --- /dev/null +++ b/tcpcliserv/tcpserv04.c @@ -0,0 +1,41 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + pid_t childpid; + socklen_t clilen; + struct sockaddr_in cliaddr, servaddr; + void sig_chld(int); + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + Signal(SIGCHLD, sig_chld); /* must call waitpid() */ + + for ( ; ; ) { + clilen = sizeof(cliaddr); + if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) { + if (errno == EINTR) + continue; /* back to for() */ + else + err_sys("accept error"); + } + + if ( (childpid = Fork()) == 0) { /* child process */ + Close(listenfd); /* close listening socket */ + str_echo(connfd); /* process the request */ + exit(0); + } + Close(connfd); /* parent closes connected socket */ + } +} diff --git a/tcpcliserv/tcpserv04.lc b/tcpcliserv/tcpserv04.lc new file mode 100644 index 0000000..eb5ee30 --- /dev/null +++ b/tcpcliserv/tcpserv04.lc @@ -0,0 +1,41 @@ +#include "unp.h"## 1 ##src/tcpcliserv/tcpserv04.c## + +int## 2 ##src/tcpcliserv/tcpserv04.c## +main(int argc, char **argv)## 3 ##src/tcpcliserv/tcpserv04.c## +{## 4 ##src/tcpcliserv/tcpserv04.c## + int listenfd, connfd;## 5 ##src/tcpcliserv/tcpserv04.c## + pid_t childpid;## 6 ##src/tcpcliserv/tcpserv04.c## + socklen_t clilen;## 7 ##src/tcpcliserv/tcpserv04.c## + struct sockaddr_in cliaddr, servaddr;## 8 ##src/tcpcliserv/tcpserv04.c## + void sig_chld(int);## 9 ##src/tcpcliserv/tcpserv04.c## + + listenfd = Socket(AF_INET, SOCK_STREAM, 0);## 10 ##src/tcpcliserv/tcpserv04.c## + + bzero(&servaddr, sizeof(servaddr));## 11 ##src/tcpcliserv/tcpserv04.c## + servaddr.sin_family = AF_INET;## 12 ##src/tcpcliserv/tcpserv04.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 13 ##src/tcpcliserv/tcpserv04.c## + servaddr.sin_port = htons(SERV_PORT);## 14 ##src/tcpcliserv/tcpserv04.c## + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));## 15 ##src/tcpcliserv/tcpserv04.c## + + Listen(listenfd, LISTENQ);## 16 ##src/tcpcliserv/tcpserv04.c## + + Signal(SIGCHLD, sig_chld); /* must call waitpid() */## 17 ##src/tcpcliserv/tcpserv04.c## + + for (;;) {## 18 ##src/tcpcliserv/tcpserv04.c## + clilen = sizeof(cliaddr);## 19 ##src/tcpcliserv/tcpserv04.c## + if ((connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {## 20 ##src/tcpcliserv/tcpserv04.c## + if (errno == EINTR)## 21 ##src/tcpcliserv/tcpserv04.c## + continue; /* back to for() */## 22 ##src/tcpcliserv/tcpserv04.c## + else## 23 ##src/tcpcliserv/tcpserv04.c## + err_sys("accept error");## 24 ##src/tcpcliserv/tcpserv04.c## + }## 25 ##src/tcpcliserv/tcpserv04.c## + + if ((childpid = Fork()) == 0) { /* child process */## 26 ##src/tcpcliserv/tcpserv04.c## + Close(listenfd); /* close listening socket */## 27 ##src/tcpcliserv/tcpserv04.c## + str_echo(connfd); /* process the request */## 28 ##src/tcpcliserv/tcpserv04.c## + exit(0);## 29 ##src/tcpcliserv/tcpserv04.c## + }## 30 ##src/tcpcliserv/tcpserv04.c## + Close(connfd); /* parent closes connected socket */## 31 ##src/tcpcliserv/tcpserv04.c## + }## 32 ##src/tcpcliserv/tcpserv04.c## +}## 33 ##src/tcpcliserv/tcpserv04.c## diff --git a/tcpcliserv/tcpserv08.c b/tcpcliserv/tcpserv08.c new file mode 100644 index 0000000..a964276 --- /dev/null +++ b/tcpcliserv/tcpserv08.c @@ -0,0 +1,41 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + pid_t childpid; + socklen_t clilen; + struct sockaddr_in cliaddr, servaddr; + void sig_chld(int); + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + Signal(SIGCHLD, sig_chld); + + for ( ; ; ) { + clilen = sizeof(cliaddr); + if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) { + if (errno == EINTR) + continue; /* back to for() */ + else + err_sys("accept error"); + } + + if ( (childpid = Fork()) == 0) { /* child process */ + Close(listenfd); /* close listening socket */ + str_echo(connfd); /* process the request */ + exit(0); + } + Close(connfd); /* parent closes connected socket */ + } +} diff --git a/tcpcliserv/tcpserv09.c b/tcpcliserv/tcpserv09.c new file mode 100644 index 0000000..a964276 --- /dev/null +++ b/tcpcliserv/tcpserv09.c @@ -0,0 +1,41 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + pid_t childpid; + socklen_t clilen; + struct sockaddr_in cliaddr, servaddr; + void sig_chld(int); + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + Signal(SIGCHLD, sig_chld); + + for ( ; ; ) { + clilen = sizeof(cliaddr); + if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) { + if (errno == EINTR) + continue; /* back to for() */ + else + err_sys("accept error"); + } + + if ( (childpid = Fork()) == 0) { /* child process */ + Close(listenfd); /* close listening socket */ + str_echo(connfd); /* process the request */ + exit(0); + } + Close(connfd); /* parent closes connected socket */ + } +} diff --git a/tcpcliserv/tcpservpoll01.c b/tcpcliserv/tcpservpoll01.c new file mode 100644 index 0000000..d874dfc --- /dev/null +++ b/tcpcliserv/tcpservpoll01.c @@ -0,0 +1,91 @@ +/* include fig01 */ +#include "unp.h" +#include /* for OPEN_MAX */ + +int +main(int argc, char **argv) +{ + int i, maxi, listenfd, connfd, sockfd; + int nready; + ssize_t n; + char buf[MAXLINE]; + socklen_t clilen; + struct pollfd client[OPEN_MAX]; + struct sockaddr_in cliaddr, servaddr; + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + client[0].fd = listenfd; + client[0].events = POLLRDNORM; + for (i = 1; i < OPEN_MAX; i++) + client[i].fd = -1; /* -1 indicates available entry */ + maxi = 0; /* max index into client[] array */ +/* end fig01 */ + +/* include fig02 */ + for ( ; ; ) { + nready = Poll(client, maxi+1, INFTIM); + + if (client[0].revents & POLLRDNORM) { /* new client connection */ + clilen = sizeof(cliaddr); + connfd = Accept(listenfd, (SA *) &cliaddr, &clilen); +#ifdef NOTDEF + printf("new client: %s\n", Sock_ntop((SA *) &cliaddr, clilen)); +#endif + + for (i = 1; i < OPEN_MAX; i++) + if (client[i].fd < 0) { + client[i].fd = connfd; /* save descriptor */ + break; + } + if (i == OPEN_MAX) + err_quit("too many clients"); + + client[i].events = POLLRDNORM; + if (i > maxi) + maxi = i; /* max index in client[] array */ + + if (--nready <= 0) + continue; /* no more readable descriptors */ + } + + for (i = 1; i <= maxi; i++) { /* check all clients for data */ + if ( (sockfd = client[i].fd) < 0) + continue; + if (client[i].revents & (POLLRDNORM | POLLERR)) { + if ( (n = read(sockfd, buf, MAXLINE)) < 0) { + if (errno == ECONNRESET) { + /*4connection reset by client */ +#ifdef NOTDEF + printf("client[%d] aborted connection\n", i); +#endif + Close(sockfd); + client[i].fd = -1; + } else + err_sys("read error"); + } else if (n == 0) { + /*4connection closed by client */ +#ifdef NOTDEF + printf("client[%d] closed connection\n", i); +#endif + Close(sockfd); + client[i].fd = -1; + } else + Writen(sockfd, buf, n); + + if (--nready <= 0) + break; /* no more readable descriptors */ + } + } + } +} +/* end fig02 */ diff --git a/tcpcliserv/tcpservpoll01.lc b/tcpcliserv/tcpservpoll01.lc new file mode 100644 index 0000000..3cc99ad --- /dev/null +++ b/tcpcliserv/tcpservpoll01.lc @@ -0,0 +1,82 @@ +/* include fig01 */ +#include "unp.h"## 1 ##src/tcpcliserv/tcpservpoll01.c## +#include /* for OPEN_MAX */## 2 ##src/tcpcliserv/tcpservpoll01.c## + +int## 3 ##src/tcpcliserv/tcpservpoll01.c## +main(int argc, char **argv)## 4 ##src/tcpcliserv/tcpservpoll01.c## +{## 5 ##src/tcpcliserv/tcpservpoll01.c## + int i, maxi, listenfd, connfd, sockfd;## 6 ##src/tcpcliserv/tcpservpoll01.c## + int nready;## 7 ##src/tcpcliserv/tcpservpoll01.c## + ssize_t n;## 8 ##src/tcpcliserv/tcpservpoll01.c## + char line[MAXLINE];## 9 ##src/tcpcliserv/tcpservpoll01.c## + socklen_t clilen;## 10 ##src/tcpcliserv/tcpservpoll01.c## + struct pollfd client[OPEN_MAX];## 11 ##src/tcpcliserv/tcpservpoll01.c## + struct sockaddr_in cliaddr, servaddr;## 12 ##src/tcpcliserv/tcpservpoll01.c## + + listenfd = Socket(AF_INET, SOCK_STREAM, 0);## 13 ##src/tcpcliserv/tcpservpoll01.c## + + bzero(&servaddr, sizeof(servaddr));## 14 ##src/tcpcliserv/tcpservpoll01.c## + servaddr.sin_family = AF_INET;## 15 ##src/tcpcliserv/tcpservpoll01.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 16 ##src/tcpcliserv/tcpservpoll01.c## + servaddr.sin_port = htons(SERV_PORT);## 17 ##src/tcpcliserv/tcpservpoll01.c## + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));## 18 ##src/tcpcliserv/tcpservpoll01.c## + + Listen(listenfd, LISTENQ);## 19 ##src/tcpcliserv/tcpservpoll01.c## + + client[0].fd = listenfd;## 20 ##src/tcpcliserv/tcpservpoll01.c## + client[0].events = POLLRDNORM;## 21 ##src/tcpcliserv/tcpservpoll01.c## + for (i = 1; i < OPEN_MAX; i++)## 22 ##src/tcpcliserv/tcpservpoll01.c## + client[i].fd = -1; /* -1 indicates available entry */## 23 ##src/tcpcliserv/tcpservpoll01.c## + maxi = 0; /* max index into client[] array */## 24 ##src/tcpcliserv/tcpservpoll01.c## +/* end fig01 */ + +/* include fig02 */ + for (;;) {## 25 ##src/tcpcliserv/tcpservpoll01.c## + nready = Poll(client, maxi + 1, INFTIM);## 26 ##src/tcpcliserv/tcpservpoll01.c## + + if (client[0].revents & POLLRDNORM) { /* new client connection */## 27 ##src/tcpcliserv/tcpservpoll01.c## + clilen = sizeof(cliaddr);## 28 ##src/tcpcliserv/tcpservpoll01.c## + connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);## 29 ##src/tcpcliserv/tcpservpoll01.c## + + for (i = 1; i < OPEN_MAX; i++)## 30 ##src/tcpcliserv/tcpservpoll01.c## + if (client[i].fd < 0) {## 31 ##src/tcpcliserv/tcpservpoll01.c## + client[i].fd = connfd; /* save descriptor */## 32 ##src/tcpcliserv/tcpservpoll01.c## + break;## 33 ##src/tcpcliserv/tcpservpoll01.c## + }## 34 ##src/tcpcliserv/tcpservpoll01.c## + if (i == OPEN_MAX)## 35 ##src/tcpcliserv/tcpservpoll01.c## + err_quit("too many clients");## 36 ##src/tcpcliserv/tcpservpoll01.c## + + client[i].events = POLLRDNORM;## 37 ##src/tcpcliserv/tcpservpoll01.c## + if (i > maxi)## 38 ##src/tcpcliserv/tcpservpoll01.c## + maxi = i; /* max index in client[] array */## 39 ##src/tcpcliserv/tcpservpoll01.c## + + if (--nready <= 0)## 40 ##src/tcpcliserv/tcpservpoll01.c## + continue; /* no more readable descriptors */## 41 ##src/tcpcliserv/tcpservpoll01.c## + }## 42 ##src/tcpcliserv/tcpservpoll01.c## + + for (i = 1; i <= maxi; i++) { /* check all clients for data */## 43 ##src/tcpcliserv/tcpservpoll01.c## + if ((sockfd = client[i].fd) < 0)## 44 ##src/tcpcliserv/tcpservpoll01.c## + continue;## 45 ##src/tcpcliserv/tcpservpoll01.c## + if (client[i].revents & (POLLRDNORM | POLLERR)) {## 46 ##src/tcpcliserv/tcpservpoll01.c## + if ((n = readline(sockfd, line, MAXLINE)) < 0) {## 47 ##src/tcpcliserv/tcpservpoll01.c## + if (errno == ECONNRESET) {## 48 ##src/tcpcliserv/tcpservpoll01.c## + /* 4connection reset by client */## 49 ##src/tcpcliserv/tcpservpoll01.c## + Close(sockfd);## 50 ##src/tcpcliserv/tcpservpoll01.c## + client[i].fd = -1;## 51 ##src/tcpcliserv/tcpservpoll01.c## + } else## 52 ##src/tcpcliserv/tcpservpoll01.c## + err_sys("readline error");## 53 ##src/tcpcliserv/tcpservpoll01.c## + } else if (n == 0) {## 54 ##src/tcpcliserv/tcpservpoll01.c## + /* 4connection closed by client */## 55 ##src/tcpcliserv/tcpservpoll01.c## + Close(sockfd);## 56 ##src/tcpcliserv/tcpservpoll01.c## + client[i].fd = -1;## 57 ##src/tcpcliserv/tcpservpoll01.c## + } else## 58 ##src/tcpcliserv/tcpservpoll01.c## + Writen(sockfd, line, n);## 59 ##src/tcpcliserv/tcpservpoll01.c## + + if (--nready <= 0)## 60 ##src/tcpcliserv/tcpservpoll01.c## + break; /* no more readable descriptors */## 61 ##src/tcpcliserv/tcpservpoll01.c## + }## 62 ##src/tcpcliserv/tcpservpoll01.c## + }## 63 ##src/tcpcliserv/tcpservpoll01.c## + }## 64 ##src/tcpcliserv/tcpservpoll01.c## +}## 65 ##src/tcpcliserv/tcpservpoll01.c## +/* end fig02 */ diff --git a/tcpcliserv/tcpservselect01.c b/tcpcliserv/tcpservselect01.c new file mode 100644 index 0000000..0aba1b4 --- /dev/null +++ b/tcpcliserv/tcpservselect01.c @@ -0,0 +1,84 @@ +/* include fig01 */ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int i, maxi, maxfd, listenfd, connfd, sockfd; + int nready, client[FD_SETSIZE]; + ssize_t n; + fd_set rset, allset; + char buf[MAXLINE]; + socklen_t clilen; + struct sockaddr_in cliaddr, servaddr; + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + maxfd = listenfd; /* initialize */ + maxi = -1; /* index into client[] array */ + for (i = 0; i < FD_SETSIZE; i++) + client[i] = -1; /* -1 indicates available entry */ + FD_ZERO(&allset); + FD_SET(listenfd, &allset); +/* end fig01 */ + +/* include fig02 */ + for ( ; ; ) { + rset = allset; /* structure assignment */ + nready = Select(maxfd+1, &rset, NULL, NULL, NULL); + + if (FD_ISSET(listenfd, &rset)) { /* new client connection */ + clilen = sizeof(cliaddr); + connfd = Accept(listenfd, (SA *) &cliaddr, &clilen); +#ifdef NOTDEF + printf("new client: %s, port %d\n", + Inet_ntop(AF_INET, &cliaddr.sin_addr, 4, NULL), + ntohs(cliaddr.sin_port)); +#endif + + for (i = 0; i < FD_SETSIZE; i++) + if (client[i] < 0) { + client[i] = connfd; /* save descriptor */ + break; + } + if (i == FD_SETSIZE) + err_quit("too many clients"); + + FD_SET(connfd, &allset); /* add new descriptor to set */ + if (connfd > maxfd) + maxfd = connfd; /* for select */ + if (i > maxi) + maxi = i; /* max index in client[] array */ + + if (--nready <= 0) + continue; /* no more readable descriptors */ + } + + for (i = 0; i <= maxi; i++) { /* check all clients for data */ + if ( (sockfd = client[i]) < 0) + continue; + if (FD_ISSET(sockfd, &rset)) { + if ( (n = Read(sockfd, buf, MAXLINE)) == 0) { + /*4connection closed by client */ + Close(sockfd); + FD_CLR(sockfd, &allset); + client[i] = -1; + } else + Writen(sockfd, buf, n); + + if (--nready <= 0) + break; /* no more readable descriptors */ + } + } + } +} +/* end fig02 */ diff --git a/tcpcliserv/tcpservselect01.lc b/tcpcliserv/tcpservselect01.lc new file mode 100644 index 0000000..7b2fdcf --- /dev/null +++ b/tcpcliserv/tcpservselect01.lc @@ -0,0 +1,79 @@ +/* include fig01 */ +#include "unp.h"## 1 ##src/tcpcliserv/tcpservselect01.c## + +int## 2 ##src/tcpcliserv/tcpservselect01.c## +main(int argc, char **argv)## 3 ##src/tcpcliserv/tcpservselect01.c## +{## 4 ##src/tcpcliserv/tcpservselect01.c## + int i, maxi, maxfd, listenfd, connfd, sockfd;## 5 ##src/tcpcliserv/tcpservselect01.c## + int nready, client[FD_SETSIZE];## 6 ##src/tcpcliserv/tcpservselect01.c## + ssize_t n;## 7 ##src/tcpcliserv/tcpservselect01.c## + fd_set rset, allset;## 8 ##src/tcpcliserv/tcpservselect01.c## + char line[MAXLINE];## 9 ##src/tcpcliserv/tcpservselect01.c## + socklen_t clilen;## 10 ##src/tcpcliserv/tcpservselect01.c## + struct sockaddr_in cliaddr, servaddr;## 11 ##src/tcpcliserv/tcpservselect01.c## + + listenfd = Socket(AF_INET, SOCK_STREAM, 0);## 12 ##src/tcpcliserv/tcpservselect01.c## + + bzero(&servaddr, sizeof(servaddr));## 13 ##src/tcpcliserv/tcpservselect01.c## + servaddr.sin_family = AF_INET;## 14 ##src/tcpcliserv/tcpservselect01.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 15 ##src/tcpcliserv/tcpservselect01.c## + servaddr.sin_port = htons(SERV_PORT);## 16 ##src/tcpcliserv/tcpservselect01.c## + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));## 17 ##src/tcpcliserv/tcpservselect01.c## + + Listen(listenfd, LISTENQ);## 18 ##src/tcpcliserv/tcpservselect01.c## + + maxfd = listenfd; /* initialize */## 19 ##src/tcpcliserv/tcpservselect01.c## + maxi = -1; /* index into client[] array */## 20 ##src/tcpcliserv/tcpservselect01.c## + for (i = 0; i < FD_SETSIZE; i++)## 21 ##src/tcpcliserv/tcpservselect01.c## + client[i] = -1; /* -1 indicates available entry */## 22 ##src/tcpcliserv/tcpservselect01.c## + FD_ZERO(&allset);## 23 ##src/tcpcliserv/tcpservselect01.c## + FD_SET(listenfd, &allset);## 24 ##src/tcpcliserv/tcpservselect01.c## +/* end fig01 */ + +/* include fig02 */ + for (;;) {## 25 ##src/tcpcliserv/tcpservselect01.c## + rset = allset; /* structure assignment */## 26 ##src/tcpcliserv/tcpservselect01.c## + nready = Select(maxfd + 1, &rset, NULL, NULL, NULL);## 27 ##src/tcpcliserv/tcpservselect01.c## + + if (FD_ISSET(listenfd, &rset)) { /* new client connection */## 28 ##src/tcpcliserv/tcpservselect01.c## + clilen = sizeof(cliaddr);## 29 ##src/tcpcliserv/tcpservselect01.c## + connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);## 30 ##src/tcpcliserv/tcpservselect01.c## + + for (i = 0; i < FD_SETSIZE; i++)## 31 ##src/tcpcliserv/tcpservselect01.c## + if (client[i] < 0) {## 32 ##src/tcpcliserv/tcpservselect01.c## + client[i] = connfd; /* save descriptor */## 33 ##src/tcpcliserv/tcpservselect01.c## + break;## 34 ##src/tcpcliserv/tcpservselect01.c## + }## 35 ##src/tcpcliserv/tcpservselect01.c## + if (i == FD_SETSIZE)## 36 ##src/tcpcliserv/tcpservselect01.c## + err_quit("too many clients");## 37 ##src/tcpcliserv/tcpservselect01.c## + + FD_SET(connfd, &allset); /* add new descriptor to set */## 38 ##src/tcpcliserv/tcpservselect01.c## + if (connfd > maxfd)## 39 ##src/tcpcliserv/tcpservselect01.c## + maxfd = connfd; /* for select */## 40 ##src/tcpcliserv/tcpservselect01.c## + if (i > maxi)## 41 ##src/tcpcliserv/tcpservselect01.c## + maxi = i; /* max index in client[] array */## 42 ##src/tcpcliserv/tcpservselect01.c## + + if (--nready <= 0)## 43 ##src/tcpcliserv/tcpservselect01.c## + continue; /* no more readable descriptors */## 44 ##src/tcpcliserv/tcpservselect01.c## + }## 45 ##src/tcpcliserv/tcpservselect01.c## + + for (i = 0; i <= maxi; i++) { /* check all clients for data */## 46 ##src/tcpcliserv/tcpservselect01.c## + if ((sockfd = client[i]) < 0)## 47 ##src/tcpcliserv/tcpservselect01.c## + continue;## 48 ##src/tcpcliserv/tcpservselect01.c## + if (FD_ISSET(sockfd, &rset)) {## 49 ##src/tcpcliserv/tcpservselect01.c## + if ((n = Readline(sockfd, line, MAXLINE)) == 0) {## 50 ##src/tcpcliserv/tcpservselect01.c## + /* 4connection closed by client */## 51 ##src/tcpcliserv/tcpservselect01.c## + Close(sockfd);## 52 ##src/tcpcliserv/tcpservselect01.c## + FD_CLR(sockfd, &allset);## 53 ##src/tcpcliserv/tcpservselect01.c## + client[i] = -1;## 54 ##src/tcpcliserv/tcpservselect01.c## + } else## 55 ##src/tcpcliserv/tcpservselect01.c## + Writen(sockfd, line, n);## 56 ##src/tcpcliserv/tcpservselect01.c## + + if (--nready <= 0)## 57 ##src/tcpcliserv/tcpservselect01.c## + break; /* no more readable descriptors */## 58 ##src/tcpcliserv/tcpservselect01.c## + }## 59 ##src/tcpcliserv/tcpservselect01.c## + }## 60 ##src/tcpcliserv/tcpservselect01.c## + }## 61 ##src/tcpcliserv/tcpservselect01.c## +}## 62 ##src/tcpcliserv/tcpservselect01.c## +/* end fig02 */ diff --git a/tcpcliserv/tsigpipe.c b/tcpcliserv/tsigpipe.c new file mode 100644 index 0000000..f4656d8 --- /dev/null +++ b/tcpcliserv/tsigpipe.c @@ -0,0 +1,36 @@ +#include "unp.h" + +void +sig_pipe(int signo) +{ + printf("SIGPIPE received\n"); + return; +} + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: tcpcli "); + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(13); /* daytime server */ + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Signal(SIGPIPE, sig_pipe); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + sleep(2); + Write(sockfd, "hello", 5); + sleep(2); + Write(sockfd, "world", 5); + + exit(0); +} diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..8b77a58 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,38 @@ +include ../Make.defines + +PROGS = accept_eintr test1 treadline1 treadline2 treadline3 \ + tsnprintf tisfdtype tshutdown + +TEST1_OBJS = test1.o funcs.o + +all: ${PROGS} + +test1: ${TEST1_OBJS} + ${CC} ${CFLAGS} -o $@ ${TEST1_OBJS} ${LIBS} + +test2: test2.o + ${CC} ${CFLAGS} -o $@ test2.o ${LIBS} + +accept_eintr: accept_eintr.o + ${CC} ${CFLAGS} -o $@ accept_eintr.o ${LIBS} + +treadline1: treadline1.o readline1.o + ${CC} ${CFLAGS} -o $@ treadline1.o readline1.o ${LIBS} + +treadline2: treadline2.o readline2.o + ${CC} ${CFLAGS} -o $@ treadline2.o readline2.o ${LIBS} + +treadline3: treadline3.o readline3.o + ${CC} ${CFLAGS} -o $@ treadline3.o readline3.o ${LIBS} + +tsnprintf: tsnprintf.o + ${CC} ${CFLAGS} -o $@ tsnprintf.o ${LIBS} + +tisfdtype: tisfdtype.o + ${CC} ${CFLAGS} -o $@ tisfdtype.o ${LIBS} + +tshutdown: tshutdown.o + ${CC} ${CFLAGS} -o $@ tshutdown.o ${LIBS} + +clean: + rm -f ${PROGS} core core.* *.o temp.* *.out typescript* diff --git a/test/accept_eintr.c b/test/accept_eintr.c new file mode 100644 index 0000000..af550d2 --- /dev/null +++ b/test/accept_eintr.c @@ -0,0 +1,37 @@ +#include "unp.h" + +/* Let's see if accept() is automatically restarted by the implementation. */ + +void +sig_int(int signo) +{ + printf("received SIGINT\n"); + return; +} + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + socklen_t clilen; + struct sockaddr_in cliaddr, servaddr; + + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + Signal(SIGINT, sig_int); /* sets SA_RESTART */ + + for ( ; ; ) { + clilen = sizeof(cliaddr); + connfd = Accept(listenfd, (SA *) &cliaddr, &clilen); + /* error from Accept() if not restarted */ + } +} diff --git a/test/funcs.c b/test/funcs.c new file mode 100644 index 0000000..8dff9cf --- /dev/null +++ b/test/funcs.c @@ -0,0 +1,63 @@ +#include "test.h" + +/* + * Fill in the global servaddr{} as a side effect. + */ + +int +TcpSockByAddr(char *ipaddr, int port /* host byte order */ ) +{ + int sockfd; + + sockfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(port); + Inet_pton(AF_INET, ipaddr, &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + return(sockfd); +} + +/* + * Create the default (unconnected) UDP socket. + * Fill in the global servaddr{} for the caller to use. + */ + +int +UdpSockByAddr(char *ipaddr, int port /* host byte order */ ) +{ + int sockfd; + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(port); + Inet_pton(AF_INET, ipaddr, &servaddr.sin_addr); + + return(sockfd); +} + +/* + * Create a connected UDP socket. + */ + +int +UdpConnSockByAddr(char *ipaddr, int port /* host byte order */ ) +{ + int sockfd; + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(port); + Inet_pton(AF_INET, ipaddr, &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + return(sockfd); +} diff --git a/test/readline.h b/test/readline.h new file mode 100644 index 0000000..badf6cf --- /dev/null +++ b/test/readline.h @@ -0,0 +1,12 @@ +typedef struct { + int read_fd; /* caller's descriptor to read from */ + char *read_ptr; /* caller's buffer to read into */ + size_t read_maxlen; /* max #bytes to read */ + /* next three are used internally by the function */ + int rl_cnt; /* initialize to 0 */ + char *rl_bufptr; /* initialize to rl_buf */ + char rl_buf[MAXLINE]; +} Rline; + +void readline_rinit(int, void *, size_t, Rline *); +ssize_t readline_r(Rline *); diff --git a/test/readline1.c b/test/readline1.c new file mode 100644 index 0000000..f264639 --- /dev/null +++ b/test/readline1.c @@ -0,0 +1,41 @@ +/* include readline */ +#include "unp.h" + +/* PAINFULLY SLOW VERSION -- example only */ +ssize_t +readline(int fd, void *vptr, size_t maxlen) +{ + ssize_t n, rc; + char c, *ptr; + + ptr = vptr; + for (n = 1; n < maxlen; n++) { +again: + if ( (rc = read(fd, &c, 1)) == 1) { + *ptr++ = c; + if (c == '\n') + break; /* newline is stored, like fgets() */ + } else if (rc == 0) { + *ptr = 0; + return(n - 1); /* EOF, n - 1 bytes were read */ + } else { + if (errno == EINTR) + goto again; + return(-1); /* error, errno set by read() */ + } + } + + *ptr = 0; /* null terminate like fgets() */ + return(n); +} +/* end readline */ + +ssize_t +Readline(int fd, void *ptr, size_t maxlen) +{ + ssize_t n; + + if ( (n = readline(fd, ptr, maxlen)) < 0) + err_sys("readline error"); + return(n); +} diff --git a/test/readline1.lc b/test/readline1.lc new file mode 100644 index 0000000..a12ac08 --- /dev/null +++ b/test/readline1.lc @@ -0,0 +1,42 @@ +/* include readline */ +#include "unp.h"## 1 ##src/test/readline1.c## + +ssize_t## 2 ##src/test/readline1.c## +readline(int fd, void *vptr, size_t maxlen)## 3 ##src/test/readline1.c## +{## 4 ##src/test/readline1.c## + ssize_t n, rc;## 5 ##src/test/readline1.c## + char c, *ptr;## 6 ##src/test/readline1.c## + + ptr = vptr;## 7 ##src/test/readline1.c## + for (n = 1; n < maxlen; n++) {## 8 ##src/test/readline1.c## + again:## 9 ##src/test/readline1.c## + if ((rc = read(fd, &c, 1)) == 1) {## 10 ##src/test/readline1.c## + *ptr++ = c;## 11 ##src/test/readline1.c## + if (c == '\n')## 12 ##src/test/readline1.c## + break; /* newline is stored, like fgets() */## 13 ##src/test/readline1.c## + } else if (rc == 0) {## 14 ##src/test/readline1.c## + if (n == 1)## 15 ##src/test/readline1.c## + return (0); /* EOF, no data read */## 16 ##src/test/readline1.c## + else## 17 ##src/test/readline1.c## + break; /* EOF, some data was read */## 18 ##src/test/readline1.c## + } else {## 19 ##src/test/readline1.c## + if (errno == EINTR)## 20 ##src/test/readline1.c## + goto again;## 21 ##src/test/readline1.c## + return (-1); /* error, errno set by read() */## 22 ##src/test/readline1.c## + }## 23 ##src/test/readline1.c## + }## 24 ##src/test/readline1.c## + + *ptr = 0; /* null terminate like fgets() */## 25 ##src/test/readline1.c## + return (n);## 26 ##src/test/readline1.c## +}## 27 ##src/test/readline1.c## +/* end readline */ + +ssize_t## 28 ##src/test/readline1.c## +Readline(int fd, void *ptr, size_t maxlen)## 29 ##src/test/readline1.c## +{## 30 ##src/test/readline1.c## + ssize_t n;## 31 ##src/test/readline1.c## + + if ((n = readline(fd, ptr, maxlen)) < 0)## 32 ##src/test/readline1.c## + err_sys("readline error");## 33 ##src/test/readline1.c## + return (n);## 34 ##src/test/readline1.c## +}## 35 ##src/test/readline1.c## diff --git a/test/readline2.c b/test/readline2.c new file mode 100644 index 0000000..a8de93b --- /dev/null +++ b/test/readline2.c @@ -0,0 +1,56 @@ +/* include readline */ +#include "unp.h" + +static ssize_t +my_read(int fd, char *ptr) +{ + static int read_cnt = 0; + static char *read_ptr; + static char read_buf[MAXLINE]; + + if (read_cnt <= 0) { + if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) + err_sys("read error"); + else if (read_cnt == 0) + return(0); + read_ptr = read_buf; + } + + read_cnt--; + *ptr = *read_ptr++ & 255; + return(1); +} + +ssize_t +readline(int fd, void *vptr, size_t maxlen) +{ + int n, rc; + char c, *ptr; + + ptr = vptr; + for (n = 1; n < maxlen; n++) { + if ( (rc = my_read(fd, &c)) == 1) { + *ptr++ = c; + if (c == '\n') + break; + } else if (rc == 0) { + *ptr = 0; + return(n - 1); /* EOF, n - 1 bytes were read */ + } else + return(-1); /* error */ + } + + *ptr = 0; + return(n); +} +/* end readline */ + +ssize_t +Readline(int fd, void *ptr, size_t maxlen) +{ + ssize_t n; + + if ( (n = readline(fd, ptr, maxlen)) == -1) + err_sys("readline error"); + return(n); +} diff --git a/test/readline3.c b/test/readline3.c new file mode 100644 index 0000000..4b8f8bb --- /dev/null +++ b/test/readline3.c @@ -0,0 +1,70 @@ +/* include readline */ +#include "unp.h" +#include "readline.h" + +static ssize_t +my_read(Rline *rptr, char *ptr) +{ + if (rptr->rl_cnt <= 0) { +again: + rptr->rl_cnt = read(rptr->read_fd, rptr->rl_buf, sizeof(rptr->rl_buf)); + if (rptr->rl_cnt < 0) { + if (errno == EINTR) + goto again; + else + return(-1); + } + else if (rptr->rl_cnt == 0) + return(0); + rptr->rl_bufptr = rptr->rl_buf; + } + + rptr->rl_cnt--; + *ptr = *rptr->rl_bufptr++ & 255; + return(1); +} + +void +readline_rinit(int fd, void *ptr, size_t maxlen, Rline *rptr) +{ + rptr->read_fd = fd; /* save caller's arguments */ + rptr->read_ptr = ptr; + rptr->read_maxlen = maxlen; + + rptr->rl_cnt = 0; /* and init our counter & pointer */ + rptr->rl_bufptr = rptr->rl_buf; +} + +ssize_t +readline_r(Rline *rptr) +{ + int n, rc; + char c, *ptr; + + ptr = rptr->read_ptr; + for (n = 1; n < rptr->read_maxlen; n++) { + if ( (rc = my_read(rptr, &c)) == 1) { + *ptr++ = c; + if (c == '\n') + break; + } else if (rc == 0) { + *ptr = 0; + return(n - 1); /* EOF, n - 1 bytes were read */ + } else + return(-1); /* error */ + } + + *ptr = 0; + return(n); +} +/* end readline */ + +ssize_t +Readline(int fd, void *ptr, size_t maxlen) +{ + ssize_t n; + + if ( (n = readline(fd, ptr, maxlen)) == -1) + err_sys("readline error"); + return(n); +} diff --git a/test/test.h b/test/test.h new file mode 100644 index 0000000..911eff0 --- /dev/null +++ b/test/test.h @@ -0,0 +1,10 @@ +#include "unp.h" + + /* globals */ +extern struct sockaddr_in servaddr, cliaddr; +extern char buff[8192]; +extern int verbose; + +int TcpSockByAddr(char *, int); +int UdpSockByAddr(char *, int); +int UdpConnSockByAddr(char *, int); diff --git a/test/test1.c b/test/test1.c new file mode 100644 index 0000000..6b671f5 --- /dev/null +++ b/test/test1.c @@ -0,0 +1,206 @@ +#include "test.h" + +/* + * Socket test program. + * Try and figure out everything that we can automatically. + * Lines preceded by a + are deviations from 4.4BSD. + * Lines preceded by a ! are fatal errors. + * Lines without a + or ! are just informational. + */ + + /* allocate globals */ +struct sockaddr_in servaddr, cliaddr; +char buff[8192]; +int verbose; + +/* + * Check whether various header flags are defined. + */ + +void +header_flags() +{ + + /* these are all "if not defined" */ +#ifndef MSG_DONTROUTE + printf("+ MSG_DONTROUTE not defined\n"); +#endif + +#ifndef MSG_OOB + printf("+ MSG_OOB not defined\n"); +#endif + +#ifndef MSG_PEEK + printf("+ MSG_PEEK not defined\n"); +#endif + +#ifndef MSG_WAITALL + printf("+ MSG_WAITALL not defined\n"); +#endif +} + +/* + * Check whether we can use sendto() and recvfrom() with a TCP socket. + * Use a different length for each output function, so if it does work, + * we can see it with tcpdump and separate it from the other outputs. + */ + +void +sendto_01() +{ + int sockfd, n; + socklen_t len; + + sockfd = TcpSockByAddr("140.252.13.34", 7); /* echo server */ + + /* + * This also verifies that we can call sendto() on a TCP socket + * if we don't specify a destination address. + */ + + Sendto(sockfd, "hello", 5, 0, NULL, NULL); + + if ( (n = Recvfrom(sockfd, buff, sizeof(buff), 0, NULL, NULL)) != 5) + err_quit("! Recvfrom expected 5"); + + /* + * Now see what happens when we ask for the server's address. + * Berkeley-derived implementations do not return this (p. 517, tcpipiv2) + * while Solaris does. + */ + + Sendto(sockfd, "world", 5, 0, NULL, NULL); + + len = sizeof(servaddr) * 2; /* that's a lie */ + if ( (n = Recvfrom(sockfd, buff, sizeof(buff), 0, + (SA *) &servaddr, &len)) != 5) + err_quit("! Recvfrom expected 5"); + if (len != 0) { + err_msg("+ recvfrom on TCP socket returns len = %d for sender's addr", + len); + if (len == sizeof(servaddr)) + printf(" recvfrom from %s, port %d\n", + inet_ntoa(servaddr.sin_addr), ntohs(servaddr.sin_port)); + } + + Close(sockfd); + + /* + * Now try and specify a destination address for sendto() on + * a TCP socket. + */ + + sockfd = TcpSockByAddr("140.252.13.34", 7); /* echo server */ + + /* should not work with destination address specified */ + n = sendto(sockfd, "hello1", 6, 0, (SA *) &servaddr, sizeof(servaddr)); + if (n < 0) + err_ret("sendto on TCP socket specifying dest addr returns error"); + else if (n == 6) +#ifdef MSG_EOF /* defined only if T/TCP supported */ + err_msg("+ sendto on TCP socket specifying dest addr OK (T/TCP supported)"); +#else + err_msg("+ sendto on TCP socket specifying dest addr OK"); +#endif + else + err_quit("! sendto on TCP socket specifying dest addr, n = %d", n); + + Close(sockfd); + + /* + * Now an unconnected UDP socket. + */ + + sockfd = UdpSockByAddr("140.252.13.34", 7); /* echo server */ + + /* should not work */ + if ( (n = sendto(sockfd, "hello12", 7, 0, (SA *) 0, 0)) >= 0) + err_msg("+ sendto on unconnected UDP without dest addr OK, n = %d", n); + else if (errno != EDESTADDRREQ) + err_ret("+ sendto on unconnected UDP without dest addr, unexpected errno"); + + /* should not work */ + if ( (n = write(sockfd, "hello", 7)) >= 0) + err_msg("+ write on unconnected UDP OK, n = %d", n); + else if (errno != EDESTADDRREQ) + err_ret("+ write on unconnected UDP, unexpected errno"); + + Close(sockfd); + + /* + * Now a connected UDP socket. + */ + + sockfd = UdpConnSockByAddr("140.252.13.34", 7); /* echo server */ + + /* should work */ + if ( (n = write(sockfd, "hello123", 8)) < 0) + err_sys("! write on connected UDP, n = %d", n); + else if (n != 8) + err_quit("! write on connected UDP, n = %d", n); + + /* should work */ + if ( (n = sendto(sockfd, "hello1234", 9, 0, (SA *) 0, 0)) < 0) + err_sys("! sendto on connected UDP without dest addr, n = %d", n); + else if (n != 9) + err_quit("! sendto on connected UDP without dest addr, n = %d", n); + + /* should not work */ + n = sendto(sockfd, "hello12345", 10, 0, (SA *) &servaddr, sizeof(servaddr)); + if (n < 0 && errno != EISCONN) + err_ret("+ sendto on connected UDP with dest addr, unexpected errno"); + else if (n >= 0) + err_msg("+ sendto on connected UDP with dest addr OK, n = %d", n); + + Close(sockfd); +} + +/* + * Send a UDP datagram to a server at IP address 1, and look at + * the return address in the response. If the server is multihomed, + * the return address can differ from our original destination address. + */ + +void +udp_01() +{ +} + +static void +usage(const char *msg) +{ + err_msg( +"options: -v verbose\n" +); + + if (msg[0] != 0) + err_quit("%s", msg); + exit(1); +} + +int +main(int argc, char **argv) +{ + int c; + + opterr = 0; /* don't want getopt() writing to stderr */ + while ( (c = getopt(argc, argv, "v")) != -1) { + switch (c) { + case 'v': + verbose = 1; + break; + + case '?': + usage("unrecognized option"); + } + } + + if (verbose) printf("header_flags\n"); + header_flags(); + + if (verbose) printf("udp_01\n"); + udp_01(); + + if (verbose) printf("sendto_01\n"); + sendto_01(); +} diff --git a/test/test2.c b/test/test2.c new file mode 100644 index 0000000..9fbc122 --- /dev/null +++ b/test/test2.c @@ -0,0 +1,65 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + socklen_t salen; + struct addrinfo *res; + struct sockaddr *cli, *serv; + + if (argc != 2) + err_quit("usage: test2 "); + +#ifdef notdef + res = Host_serv(argv[1], "daytime", AF_UNSPEC, SOCK_DGRAM); + printf("res->ai_addrlen = %d\n", res->ai_addrlen); + printf("res->ai_addr = %p\n", res->ai_addr); + printf("res->ai_next = %p\n", res->ai_next); + printf("res->ai_addr->sa_family = %p\n", res->ai_addr->sa_family); +#endif + sockfd = Udp_client(argv[1], "13", (void **) &serv, &salen); + printf("sockfd = %d\n", sockfd); + + exit(0); +} +#ifdef notdef +int +udp_client(const char *host, const char *serv, void **saptr, socklen_t *lenp) +{ + int sockfd, n; + struct addrinfo hints, *res, *ressave; + + bzero(&hints, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + + if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0) + err_quit("udp_client error for %s, %s: %s", + host, serv, gai_strerror(n)); + ressave = res; + + do { + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (sockfd >= 0) + break; /* success */ + } while ( (res = res->ai_next) != NULL); + + if (res == NULL) /* errno set from final socket() */ + err_sys("udp_client error for %s, %s", host, serv); + + *saptr = Malloc(res->ai_addrlen); + memcpy(*saptr, res->ai_addr, res->ai_addrlen); + *lenp = res->ai_addrlen; + + freeaddrinfo(ressave); + + return(sockfd); +} + +int +Udp_client(const char *host, const char *serv, void **saptr, socklen_t *lenptr) +{ + return(udp_client(host, serv, saptr, lenptr)); +} +#endif diff --git a/test/tisfdtype.c b/test/tisfdtype.c new file mode 100644 index 0000000..6cd9de2 --- /dev/null +++ b/test/tisfdtype.c @@ -0,0 +1,18 @@ +#include "unp.h" + +main() +{ + int tcpsock, udpsock; + + printf("stdin: %d\n", Isfdtype(STDIN_FILENO, S_IFSOCK)); + printf("stdout: %d\n", Isfdtype(STDOUT_FILENO, S_IFSOCK)); + printf("stderr: %d\n", Isfdtype(STDERR_FILENO, S_IFSOCK)); + + tcpsock = Socket(AF_INET, SOCK_STREAM, 0); + printf("TCP socket: %d\n", Isfdtype(tcpsock, S_IFSOCK)); + + udpsock = Socket(AF_INET, SOCK_DGRAM, 0); + printf("UDP socket: %d\n", Isfdtype(udpsock, S_IFSOCK)); + + exit(0); +} diff --git a/test/treadline1.c b/test/treadline1.c new file mode 100644 index 0000000..8551c10 --- /dev/null +++ b/test/treadline1.c @@ -0,0 +1,13 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int count = 0; + ssize_t n; + char recvline[MAXLINE]; + + while ( ( n = readline(STDIN_FILENO, recvline, MAXLINE)) > 0) + count++; + printf("%d lines\n", count); +} diff --git a/test/treadline2.c b/test/treadline2.c new file mode 100644 index 0000000..8551c10 --- /dev/null +++ b/test/treadline2.c @@ -0,0 +1,13 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int count = 0; + ssize_t n; + char recvline[MAXLINE]; + + while ( ( n = readline(STDIN_FILENO, recvline, MAXLINE)) > 0) + count++; + printf("%d lines\n", count); +} diff --git a/test/treadline3.c b/test/treadline3.c new file mode 100644 index 0000000..b580c0d --- /dev/null +++ b/test/treadline3.c @@ -0,0 +1,16 @@ +#include "unp.h" +#include "readline.h" + +int +main(int argc, char **argv) +{ + int count = 0; + ssize_t n; + char recvline[MAXLINE]; + Rline rline; + + readline_rinit(STDIN_FILENO, recvline, MAXLINE, &rline); + while ( (n = readline_r(&rline)) > 0) + count++; + printf("%d lines\n", count); +} diff --git a/test/tshutdown.c b/test/tshutdown.c new file mode 100644 index 0000000..7d8bbaf --- /dev/null +++ b/test/tshutdown.c @@ -0,0 +1,34 @@ +#include "unp.h" + +#define BUFF 100000 +char buff[BUFF]; + +int +main(int argc, char **argv) +{ + int sockfd, nbytes; + ssize_t n; + + if (argc != 3) + err_quit("usage: tshutdown "); + + sockfd = Tcp_connect(argv[1], argv[2]); + fprintf(stderr, "connected\n"); + + while ( (n = Read(STDIN_FILENO, buff, BUFF)) > 0) { + Writen(sockfd, buff, n); + } + Close(STDIN_FILENO); + /* Shutdown(sockfd, SHUT_WR); */ + + nbytes = 0; + while ( (n = Read(sockfd, buff, BUFF)) > 0) { + /* fprintf(stderr, "read %d bytes from socket\n", n); */ + Write(STDOUT_FILENO, buff, n); + nbytes += n; + } + fprintf(stderr, "total: %d bytes read from socket\n", nbytes); + Close(STDOUT_FILENO); + + exit(0); +} diff --git a/test/tsnprintf.c b/test/tsnprintf.c new file mode 100644 index 0000000..ae0ea45 --- /dev/null +++ b/test/tsnprintf.c @@ -0,0 +1,25 @@ +/* + * If your system does not provide snprintf(), this program will compile + * but will have an undefined error from the linker. + * + * If you are using the lib/snprintf.c function that is supplied for + * systems without snprintf(), you should get an error output from our + * library function. + * + * If your system provides the function, and it works, there should be + * no output. + */ + +#include "unp.h" + +int +main(int argc, char **argv) +{ + int n; + char buf[1024]; + + n = snprintf(buf, 4, "%d", 9999); + if (n > 3) + printf("error: snprintf overflowed buffer, n = %d\n", n); + exit(0); +} diff --git a/threads/Makefile b/threads/Makefile new file mode 100644 index 0000000..7a12f79 --- /dev/null +++ b/threads/Makefile @@ -0,0 +1,65 @@ +include ../Make.defines + +PROGS = web01 web02 web03 \ + tcpcli01 tcpcli02 tcpserv01 tcpserv02 \ + test01 example01 example02 example03 + +all: ${PROGS} + +web01: web01.o + ${CC} ${CFLAGS} -o $@ web01.o ${LIBS} + +web02: web02.o + ${CC} ${CFLAGS} -o $@ web02.o ${LIBS} + +web03: web03.o + ${CC} ${CFLAGS} -o $@ web03.o ${LIBS} + +tcpcli01: tcpcli01.o strclithread.o + ${CC} ${CFLAGS} -o $@ tcpcli01.o strclithread.o ${LIBS} + +tcpcli02: tcpcli02.o strclithread2.o + ${CC} ${CFLAGS} -o $@ tcpcli02.o strclithread2.o ${LIBS} + +tcpserv01: tcpserv01.o + ${CC} ${CFLAGS} -o $@ tcpserv01.o ${LIBS} + +# Broken one that uses readline() from library. +tcpserv02: tcpserv02.o + ${CC} ${CFLAGS} -o $@ tcpserv02.o ${LIBS} + +# Correct one that uses thread-safe readline(). +tcpserv02g: tcpserv02.o readline.o + ${CC} ${CFLAGS} -o $@ tcpserv02.o readline.o ${LIBS} + +test01: test01.o + ${CC} ${CFLAGS} -o $@ test01.o ${LIBS} + +test02: test02.o + ${CC} ${CFLAGS} -o $@ test02.o ${LIBS} + +test03: test03.o + ${CC} ${CFLAGS} -o $@ test03.o ${LIBS} + +# Bad version uses readline() from library. +test04b: test04.o + ${CC} ${CFLAGS} -o $@ test04.o ${LIBS} + +# Good version uses readline.c in this directory. +test04g: test04.o readline.o + ${CC} ${CFLAGS} -o $@ test04.o readline.o ${LIBS} + +test05: test05.o + ${CC} ${CFLAGS} -o $@ test05.o ${LIBS} + +example01: example01.o + ${CC} ${CFLAGS} -o $@ example01.o ${LIBS} + +example02: example02.o + ${CC} ${CFLAGS} -o $@ example02.o ${LIBS} + +example03: example03.o + ${CC} ${CFLAGS} -o $@ example03.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/threads/doit.1 b/threads/doit.1 new file mode 100755 index 0000000..dea312e --- /dev/null +++ b/threads/doit.1 @@ -0,0 +1,18 @@ +#!/bin/sh + +case $# in +1) break ;; +*) echo "one argument (#simultaneous connections) required" 1>&2 + exit 1 ;; +esac + +time ./web03 $1 192.207.117.2 / \ + /img/logo/awl_logo_blue_50x40.gif \ + /img/a_world_of_learning.gif \ + /img/toolbar_soptions.gif \ + /img/toolbar_purchase.gif \ + /img/toolbar_feedback.gif \ + /img/toolbar_top_hilite.gif \ + /img/toolbar_qsearch.gif \ + /img/blue_dot.gif \ + /img/logo/pearson_logo_50.gif diff --git a/threads/doit.2 b/threads/doit.2 new file mode 100755 index 0000000..75ea42b --- /dev/null +++ b/threads/doit.2 @@ -0,0 +1,17 @@ +#!/bin/sh + +ClientP=/nfs/kohala/home/rstevens/doc/unp/src/tcpcliserv/tcpcli01 # client prog +ServerH="206.62.226.33" # server host +Infile=/usr/share/misc/zipcodes # big BSD/OS text file + +$ClientP $ServerH < $Infile > temp.1 & +$ClientP $ServerH < $Infile > temp.2 & +$ClientP $ServerH < $Infile > temp.3 & +# $ClientP $ServerH < $Infile > temp.4 & +# $ClientP $ServerH < $Infile > temp.5 & +# $ClientP $ServerH < $Infile > temp.6 & +# $ClientP $ServerH < $Infile > temp.7 & +# $ClientP $ServerH < $Infile > temp.8 & +# $ClientP $ServerH < $Infile > temp.9 & + +wait diff --git a/threads/example01.c b/threads/example01.c new file mode 100644 index 0000000..960bf53 --- /dev/null +++ b/threads/example01.c @@ -0,0 +1,41 @@ +#include "unpthread.h" + +#define NLOOP 5000 + +int counter; /* incremented by threads */ + +void *doit(void *); + +int +main(int argc, char **argv) +{ + pthread_t tidA, tidB; + + Pthread_create(&tidA, NULL, &doit, NULL); + Pthread_create(&tidB, NULL, &doit, NULL); + + /* 4wait for both threads to terminate */ + Pthread_join(tidA, NULL); + Pthread_join(tidB, NULL); + + exit(0); +} + +void * +doit(void *vptr) +{ + int i, val; + + /* + * Each thread fetches, prints, and increments the counter NLOOP times. + * The value of the counter should increase monotonically. + */ + + for (i = 0; i < NLOOP; i++) { + val = counter; + printf("%d: %d\n", pthread_self(), val + 1); + counter = val + 1; + } + + return(NULL); +} diff --git a/threads/example01.lc b/threads/example01.lc new file mode 100644 index 0000000..b02a372 --- /dev/null +++ b/threads/example01.lc @@ -0,0 +1,41 @@ +#include "unpthread.h"## 1 ##src/threads/example01.c## + +#define NLOOP 5000## 2 ##src/threads/example01.c## + +int counter; /* this is incremented by the threads */## 3 ##src/threads/example01.c## + +void *doit(void *);## 4 ##src/threads/example01.c## + +int## 5 ##src/threads/example01.c## +main(int argc, char **argv)## 6 ##src/threads/example01.c## +{## 7 ##src/threads/example01.c## + pthread_t tidA, tidB;## 8 ##src/threads/example01.c## + + Pthread_create(&tidA, NULL, &doit, NULL);## 9 ##src/threads/example01.c## + Pthread_create(&tidB, NULL, &doit, NULL);## 10 ##src/threads/example01.c## + + /* 4wait for both threads to terminate */## 11 ##src/threads/example01.c## + Pthread_join(tidA, NULL);## 12 ##src/threads/example01.c## + Pthread_join(tidB, NULL);## 13 ##src/threads/example01.c## + + exit(0);## 14 ##src/threads/example01.c## +}## 15 ##src/threads/example01.c## + +void *## 16 ##src/threads/example01.c## +doit(void *vptr)## 17 ##src/threads/example01.c## +{## 18 ##src/threads/example01.c## + int i, val;## 19 ##src/threads/example01.c## + + /* ## 20 ##src/threads/example01.c## + * Each thread fetches, prints, and increments the counter NLOOP times.## 21 ##src/threads/example01.c## + * The value of the counter should increase monotonically.## 22 ##src/threads/example01.c## + */## 23 ##src/threads/example01.c## + + for (i = 0; i < NLOOP; i++) {## 24 ##src/threads/example01.c## + val = counter;## 25 ##src/threads/example01.c## + printf("%d: %d\n", pthread_self(), val + 1);## 26 ##src/threads/example01.c## + counter = val + 1;## 27 ##src/threads/example01.c## + }## 28 ##src/threads/example01.c## + + return (NULL);## 29 ##src/threads/example01.c## +}## 30 ##src/threads/example01.c## diff --git a/threads/example02.c b/threads/example02.c new file mode 100644 index 0000000..1b91a3d --- /dev/null +++ b/threads/example02.c @@ -0,0 +1,46 @@ +#include "unpthread.h" + +#define NLOOP 5000 + +int counter; /* incremented by threads */ +pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER; + +void *doit(void *); + +int +main(int argc, char **argv) +{ + pthread_t tidA, tidB; + + Pthread_create(&tidA, NULL, &doit, NULL); + Pthread_create(&tidB, NULL, &doit, NULL); + + /* 4wait for both threads to terminate */ + Pthread_join(tidA, NULL); + Pthread_join(tidB, NULL); + + exit(0); +} + +void * +doit(void *vptr) +{ + int i, val; + + /* + * Each thread fetches, prints, and increments the counter NLOOP times. + * The value of the counter should increase monotonically. + */ + + for (i = 0; i < NLOOP; i++) { + Pthread_mutex_lock(&counter_mutex); + + val = counter; + printf("%d: %d\n", pthread_self(), val + 1); + counter = val + 1; + + Pthread_mutex_unlock(&counter_mutex); + } + + return(NULL); +} diff --git a/threads/example02.lc b/threads/example02.lc new file mode 100644 index 0000000..07b7ec6 --- /dev/null +++ b/threads/example02.lc @@ -0,0 +1,46 @@ +#include "unpthread.h"## 1 ##src/threads/example02.c## + +#define NLOOP 5000## 2 ##src/threads/example02.c## + +int counter; /* this is incremented by the threads */## 3 ##src/threads/example02.c## +pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;## 4 ##src/threads/example02.c## + +void *doit(void *);## 5 ##src/threads/example02.c## + +int## 6 ##src/threads/example02.c## +main(int argc, char **argv)## 7 ##src/threads/example02.c## +{## 8 ##src/threads/example02.c## + pthread_t tidA, tidB;## 9 ##src/threads/example02.c## + + Pthread_create(&tidA, NULL, &doit, NULL);## 10 ##src/threads/example02.c## + Pthread_create(&tidB, NULL, &doit, NULL);## 11 ##src/threads/example02.c## + + /* 4wait for both threads to terminate */## 12 ##src/threads/example02.c## + Pthread_join(tidA, NULL);## 13 ##src/threads/example02.c## + Pthread_join(tidB, NULL);## 14 ##src/threads/example02.c## + + exit(0);## 15 ##src/threads/example02.c## +}## 16 ##src/threads/example02.c## + +void *## 17 ##src/threads/example02.c## +doit(void *vptr)## 18 ##src/threads/example02.c## +{## 19 ##src/threads/example02.c## + int i, val;## 20 ##src/threads/example02.c## + + /* ## 21 ##src/threads/example02.c## + * Each thread fetches, prints, and increments the counter NLOOP times.## 22 ##src/threads/example02.c## + * The value of the counter should increase monotonically.## 23 ##src/threads/example02.c## + */## 24 ##src/threads/example02.c## + + for (i = 0; i < NLOOP; i++) {## 25 ##src/threads/example02.c## + Pthread_mutex_lock(&counter_mutex);## 26 ##src/threads/example02.c## + + val = counter;## 27 ##src/threads/example02.c## + printf("%d: %d\n", pthread_self(), val + 1);## 28 ##src/threads/example02.c## + counter = val + 1;## 29 ##src/threads/example02.c## + + Pthread_mutex_unlock(&counter_mutex);## 30 ##src/threads/example02.c## + }## 31 ##src/threads/example02.c## + + return (NULL);## 32 ##src/threads/example02.c## +}## 33 ##src/threads/example02.c## diff --git a/threads/example03.c b/threads/example03.c new file mode 100644 index 0000000..65ec7e5 --- /dev/null +++ b/threads/example03.c @@ -0,0 +1,130 @@ +#include "unpthread.h" + +#define Pthread_mutex_lock(mptr) \ + { int n; \ + if ( (n = pthread_mutex_lock(mptr)) != 0) \ + { errno = n; err_sys("pthread_mutex_lock error"); } \ + } +#define Pthread_mutex_unlock(mptr) \ + { int n; \ + if ( (n = pthread_mutex_unlock(mptr)) != 0) \ + { errno = n; err_sys("pthread_mutex_unlock error"); } \ + } +#define Pthread_cond_wait(cptr,mptr) \ + { int n; \ + if ( (n = pthread_cond_wait(cptr,mptr)) != 0) \ + { errno = n; err_sys("pthread_cond_wait error"); } \ + } +#define Pthread_cond_signal(cptr) \ + { int n; \ + if ( (n = pthread_cond_signal(cptr)) != 0) \ + { errno = n; err_sys("pthread_cond_signal error"); } \ + } + +#define NLOOP 50 +#define BUFFSIZE 10 + +struct buf_t { + int b_buf[BUFFSIZE]; /* the buffer which contains integer items */ + int b_nitems; /* #items currently in buffer */ + int b_nextget; + int b_nextput; + pthread_mutex_t b_mutex; + pthread_cond_t b_cond_consumer; /* consumer waiting to get */ + pthread_cond_t b_cond_producer; /* producer waiting to put */ +} buf_t; + +void *produce_loop(void *); +void *consume_loop(void *); + +int +main(int argc, char **argv) +{ + int n; + pthread_t tidA, tidB; + + printf("main, addr(stack) = %x, addr(global) = %x, addr(func) = %x\n", + &n, &buf_t, &produce_loop); + if ( (n = pthread_create(&tidA, NULL, &produce_loop, NULL)) != 0) + errno = n, err_sys("pthread_create error for A"); + if ( (n = pthread_create(&tidB, NULL, &consume_loop, NULL)) != 0) + errno = n, err_sys("pthread_create error for B"); + + /* wait for both threads to terminate */ + if ( (n = pthread_join(tidA, NULL)) != 0) + errno = n, err_sys("pthread_join error for A"); + if ( (n = pthread_join(tidB, NULL)) != 0) + errno = n, err_sys("pthread_join error for B"); + + exit(0); +} + +void +produce(struct buf_t *bptr, int val) +{ + Pthread_mutex_lock(&bptr->b_mutex); + /* Wait if buffer is full */ + while (bptr->b_nitems >= BUFFSIZE) + Pthread_cond_wait(&bptr->b_cond_producer, &bptr->b_mutex); + + /* There is room, store the new value */ + printf("produce %d\n", val); + bptr->b_buf[bptr->b_nextput] = val; + if (++bptr->b_nextput >= BUFFSIZE) + bptr->b_nextput = 0; + bptr->b_nitems++; + + /* Signal consumer */ + Pthread_cond_signal(&bptr->b_cond_consumer); + Pthread_mutex_unlock(&bptr->b_mutex); +} + +int +consume(struct buf_t *bptr) +{ + int val; + + Pthread_mutex_lock(&bptr->b_mutex); + /* Wait if buffer is empty */ + while (bptr->b_nitems <= 0) + Pthread_cond_wait(&bptr->b_cond_consumer, &bptr->b_mutex); + + /* There is data, fetch the value */ + val = bptr->b_buf[bptr->b_nextget]; + printf("consume %d\n", val); + if (++bptr->b_nextget >= BUFFSIZE) + bptr->b_nextget = 0; + bptr->b_nitems--; + + /* Signal producer; it might be waiting for space to store */ + Pthread_cond_signal(&bptr->b_cond_producer); + Pthread_mutex_unlock(&bptr->b_mutex); + + return(val); +} + +void * +produce_loop(void *vptr) +{ + int i; + + printf("produce_loop thread, addr(stack) = %x\n", &i); + for (i = 0; i < NLOOP; i++) { + produce(&buf_t, i); + } + + return(NULL); +} + +void * +consume_loop(void *vptr) +{ + int i, val; + + printf("consume_loop thread, addr(stack) = %x\n", &i); + for (i = 0; i < NLOOP; i++) { + val = consume(&buf_t); + } + + return(NULL); +} diff --git a/threads/readline.c b/threads/readline.c new file mode 100644 index 0000000..5d372ef --- /dev/null +++ b/threads/readline.c @@ -0,0 +1,85 @@ +/* include readline1 */ +#include "unpthread.h" + +static pthread_key_t rl_key; +static pthread_once_t rl_once = PTHREAD_ONCE_INIT; + +static void +readline_destructor(void *ptr) +{ + free(ptr); +} + +static void +readline_once(void) +{ + Pthread_key_create(&rl_key, readline_destructor); +} + +typedef struct { + int rl_cnt; /* initialize to 0 */ + char *rl_bufptr; /* initialize to rl_buf */ + char rl_buf[MAXLINE]; +} Rline; +/* end readline1 */ + +/* include readline2 */ +static ssize_t +my_read(Rline *tsd, int fd, char *ptr) +{ + if (tsd->rl_cnt <= 0) { +again: + if ( (tsd->rl_cnt = read(fd, tsd->rl_buf, MAXLINE)) < 0) { + if (errno == EINTR) + goto again; + return(-1); + } else if (tsd->rl_cnt == 0) + return(0); + tsd->rl_bufptr = tsd->rl_buf; + } + + tsd->rl_cnt--; + *ptr = *tsd->rl_bufptr++; + return(1); +} + +ssize_t +readline(int fd, void *vptr, size_t maxlen) +{ + size_t n, rc; + char c, *ptr; + Rline *tsd; + + Pthread_once(&rl_once, readline_once); + if ( (tsd = pthread_getspecific(rl_key)) == NULL) { + tsd = Calloc(1, sizeof(Rline)); /* init to 0 */ + Pthread_setspecific(rl_key, tsd); + } + + ptr = vptr; + for (n = 1; n < maxlen; n++) { + if ( (rc = my_read(tsd, fd, &c)) == 1) { + *ptr++ = c; + if (c == '\n') + break; + } else if (rc == 0) { + *ptr = 0; + return(n - 1); /* EOF, n - 1 bytes read */ + } else + return(-1); /* error, errno set by read() */ + } + + *ptr = 0; + return(n); +} +/* end readline2 */ + +ssize_t +Readline(int fd, void *ptr, size_t maxlen) +{ + ssize_t n; + + if ( (n = readline(fd, ptr, maxlen)) < 0) + err_sys("readline error"); + return(n); +} diff --git a/threads/readline.lc b/threads/readline.lc new file mode 100644 index 0000000..66e70c9 --- /dev/null +++ b/threads/readline.lc @@ -0,0 +1,87 @@ +/* include readline1 */ +#include "unpthread.h"## 1 ##src/threads/readline.c## + +static pthread_key_t rl_key;## 2 ##src/threads/readline.c## +static pthread_once_t rl_once = PTHREAD_ONCE_INIT;## 3 ##src/threads/readline.c## + +static void## 4 ##src/threads/readline.c## +readline_destructor(void *ptr)## 5 ##src/threads/readline.c## +{## 6 ##src/threads/readline.c## + free(ptr);## 7 ##src/threads/readline.c## +}## 8 ##src/threads/readline.c## + +static void## 9 ##src/threads/readline.c## +readline_once(void)## 10 ##src/threads/readline.c## +{## 11 ##src/threads/readline.c## + Pthread_key_create(&rl_key, readline_destructor);## 12 ##src/threads/readline.c## +}## 13 ##src/threads/readline.c## + +typedef struct {## 14 ##src/threads/readline.c## + int rl_cnt; /* initialize to 0 */## 15 ##src/threads/readline.c## + char *rl_bufptr; /* initialize to rl_buf */## 16 ##src/threads/readline.c## + char rl_buf[MAXLINE];## 17 ##src/threads/readline.c## +} Rline;## 18 ##src/threads/readline.c## +/* end readline1 */ + +/* include readline2 */ +static ssize_t## 19 ##src/threads/readline.c## +my_read(Rline *tsd, int fd, char *ptr)## 20 ##src/threads/readline.c## +{## 21 ##src/threads/readline.c## + if (tsd->rl_cnt <= 0) {## 22 ##src/threads/readline.c## + again:## 23 ##src/threads/readline.c## + if ((tsd->rl_cnt = read(fd, tsd->rl_buf, MAXLINE)) < 0) {## 24 ##src/threads/readline.c## + if (errno == EINTR)## 25 ##src/threads/readline.c## + goto again;## 26 ##src/threads/readline.c## + return (-1);## 27 ##src/threads/readline.c## + } else if (tsd->rl_cnt == 0)## 28 ##src/threads/readline.c## + return (0);## 29 ##src/threads/readline.c## + tsd->rl_bufptr = tsd->rl_buf;## 30 ##src/threads/readline.c## + }## 31 ##src/threads/readline.c## + + tsd->rl_cnt--;## 32 ##src/threads/readline.c## + *ptr = *tsd->rl_bufptr++;## 33 ##src/threads/readline.c## + return (1);## 34 ##src/threads/readline.c## +}## 35 ##src/threads/readline.c## + +ssize_t## 36 ##src/threads/readline.c## +readline(int fd, void *vptr, size_t maxlen)## 37 ##src/threads/readline.c## +{## 38 ##src/threads/readline.c## + int n, rc;## 39 ##src/threads/readline.c## + char c, *ptr;## 40 ##src/threads/readline.c## + Rline *tsd;## 41 ##src/threads/readline.c## + + Pthread_once(&rl_once, readline_once);## 42 ##src/threads/readline.c## + if ((tsd = pthread_getspecific(rl_key)) == NULL) {## 43 ##src/threads/readline.c## + tsd = Calloc(1, sizeof(Rline)); /* init to 0 */## 44 ##src/threads/readline.c## + Pthread_setspecific(rl_key, tsd);## 45 ##src/threads/readline.c## + }## 46 ##src/threads/readline.c## + + ptr = vptr;## 47 ##src/threads/readline.c## + for (n = 1; n < maxlen; n++) {## 48 ##src/threads/readline.c## + if ((rc = my_read(tsd, fd, &c)) == 1) {## 49 ##src/threads/readline.c## + *ptr++ = c;## 50 ##src/threads/readline.c## + if (c == '\n')## 51 ##src/threads/readline.c## + break;## 52 ##src/threads/readline.c## + } else if (rc == 0) {## 53 ##src/threads/readline.c## + if (n == 1)## 54 ##src/threads/readline.c## + return (0); /* EOF, no data read */## 55 ##src/threads/readline.c## + else## 56 ##src/threads/readline.c## + break; /* EOF, some data was read */## 57 ##src/threads/readline.c## + } else## 58 ##src/threads/readline.c## + return (-1); /* error, errno set by read() */## 59 ##src/threads/readline.c## + }## 60 ##src/threads/readline.c## + + *ptr = 0;## 61 ##src/threads/readline.c## + return (n);## 62 ##src/threads/readline.c## +}## 63 ##src/threads/readline.c## +/* end readline2 */ + +ssize_t## 64 ##src/threads/readline.c## +Readline(int fd, void *ptr, size_t maxlen)## 65 ##src/threads/readline.c## +{## 66 ##src/threads/readline.c## + ssize_t n;## 67 ##src/threads/readline.c## + + if ((n = readline(fd, ptr, maxlen)) < 0)## 68 ##src/threads/readline.c## + err_sys("readline error");## 69 ##src/threads/readline.c## + return (n);## 70 ##src/threads/readline.c## +}## 71 ##src/threads/readline.c## diff --git a/threads/script.example01 b/threads/script.example01 new file mode 100644 index 0000000..b8836d8 --- /dev/null +++ b/threads/script.example01 @@ -0,0 +1,10000 @@ +4: 1 +4: 2 +4: 3 +4: 4 +4: 5 +4: 6 +4: 7 +4: 8 +4: 9 +4: 10 +4: 11 +4: 12 +4: 13 +4: 14 +4: 15 +4: 16 +4: 17 +4: 18 +4: 19 +4: 20 +4: 21 +4: 22 +4: 23 +4: 24 +4: 25 +4: 26 +4: 27 +4: 28 +4: 29 +4: 30 +4: 31 +4: 32 +4: 33 +4: 34 +4: 35 +4: 36 +4: 37 +4: 38 +4: 39 +4: 40 +4: 41 +4: 42 +4: 43 +4: 44 +4: 45 +4: 46 +4: 47 +4: 48 +4: 49 +4: 50 +4: 51 +4: 52 +4: 53 +4: 54 +4: 55 +4: 56 +4: 57 +4: 58 +4: 59 +4: 60 +4: 61 +4: 62 +4: 63 +4: 64 +4: 65 +4: 66 +4: 67 +4: 68 +4: 69 +4: 70 +4: 71 +4: 72 +4: 73 +4: 74 +4: 75 +4: 76 +4: 77 +4: 78 +4: 79 +4: 80 +4: 81 +4: 82 +4: 83 +4: 84 +4: 85 +4: 86 +4: 87 +4: 88 +4: 89 +4: 90 +4: 91 +4: 92 +4: 93 +4: 94 +4: 95 +4: 96 +4: 97 +4: 98 +4: 99 +4: 100 +4: 101 +4: 102 +4: 103 +4: 104 +4: 105 +4: 106 +4: 107 +4: 108 +4: 109 +4: 110 +4: 111 +4: 112 +4: 113 +4: 114 +4: 115 +4: 116 +4: 117 +4: 118 +4: 119 +4: 120 +4: 121 +4: 122 +4: 123 +4: 124 +4: 125 +4: 126 +4: 127 +4: 128 +4: 129 +4: 130 +4: 131 +4: 132 +4: 133 +4: 134 +4: 135 +4: 136 +4: 137 +4: 138 +4: 139 +4: 140 +4: 141 +4: 142 +4: 143 +4: 144 +4: 145 +4: 146 +4: 147 +4: 148 +4: 149 +4: 150 +4: 151 +4: 152 +4: 153 +4: 154 +4: 155 +4: 156 +4: 157 +4: 158 +4: 159 +4: 160 +4: 161 +4: 162 +4: 163 +4: 164 +4: 165 +4: 166 +4: 167 +4: 168 +4: 169 +4: 170 +4: 171 +4: 172 +4: 173 +4: 174 +4: 175 +4: 176 +4: 177 +4: 178 +4: 179 +4: 180 +4: 181 +4: 182 +4: 183 +4: 184 +4: 185 +4: 186 +4: 187 +4: 188 +4: 189 +4: 190 +4: 191 +4: 192 +4: 193 +4: 194 +4: 195 +4: 196 +4: 197 +4: 198 +4: 199 +4: 200 +4: 201 +4: 202 +4: 203 +4: 204 +4: 205 +4: 206 +4: 207 +4: 208 +4: 209 +4: 210 +4: 211 +4: 212 +4: 213 +4: 214 +4: 215 +4: 216 +4: 217 +4: 218 +4: 219 +4: 220 +4: 221 +4: 222 +4: 223 +4: 224 +4: 225 +4: 226 +4: 227 +4: 228 +4: 229 +4: 230 +4: 231 +4: 232 +4: 233 +4: 234 +4: 235 +4: 236 +4: 237 +4: 238 +4: 239 +4: 240 +4: 241 +4: 242 +4: 243 +4: 244 +4: 245 +4: 246 +4: 247 +4: 248 +4: 249 +4: 250 +4: 251 +4: 252 +4: 253 +4: 254 +4: 255 +4: 256 +4: 257 +4: 258 +4: 259 +4: 260 +4: 261 +4: 262 +4: 263 +4: 264 +4: 265 +4: 266 +4: 267 +4: 268 +4: 269 +4: 270 +4: 271 +4: 272 +4: 273 +4: 274 +4: 275 +4: 276 +4: 277 +4: 278 +4: 279 +4: 280 +4: 281 +4: 282 +4: 283 +4: 284 +4: 285 +4: 286 +4: 287 +4: 288 +4: 289 +4: 290 +4: 291 +4: 292 +4: 293 +4: 294 +4: 295 +4: 296 +4: 297 +4: 298 +4: 299 +4: 300 +4: 301 +4: 302 +4: 303 +4: 304 +4: 305 +4: 306 +4: 307 +4: 308 +4: 309 +4: 310 +4: 311 +4: 312 +4: 313 +4: 314 +4: 315 +4: 316 +4: 317 +4: 318 +4: 319 +4: 320 +4: 321 +4: 322 +4: 323 +4: 324 +4: 325 +4: 326 +4: 327 +4: 328 +4: 329 +4: 330 +4: 331 +4: 332 +4: 333 +4: 334 +4: 335 +4: 336 +4: 337 +4: 338 +4: 339 +4: 340 +4: 341 +4: 342 +4: 343 +4: 344 +4: 345 +4: 346 +4: 347 +4: 348 +4: 349 +4: 350 +4: 351 +4: 352 +4: 353 +4: 354 +4: 355 +4: 356 +4: 357 +4: 358 +4: 359 +4: 360 +4: 361 +4: 362 +4: 363 +4: 364 +4: 365 +4: 366 +4: 367 +4: 368 +4: 369 +4: 370 +4: 371 +4: 372 +4: 373 +4: 374 +4: 375 +4: 376 +4: 377 +4: 378 +4: 379 +4: 380 +4: 381 +4: 382 +4: 383 +4: 384 +4: 385 +4: 386 +4: 387 +4: 388 +4: 389 +4: 390 +4: 391 +4: 392 +4: 393 +4: 394 +4: 395 +4: 396 +4: 397 +4: 398 +4: 399 +4: 400 +4: 401 +4: 402 +4: 403 +4: 404 +4: 405 +4: 406 +4: 407 +4: 408 +4: 409 +4: 410 +4: 411 +4: 412 +4: 413 +4: 414 +4: 415 +4: 416 +4: 417 +4: 418 +4: 419 +4: 420 +4: 421 +4: 422 +4: 423 +4: 424 +4: 425 +4: 426 +4: 427 +4: 428 +4: 429 +4: 430 +4: 431 +4: 432 +4: 433 +4: 434 +4: 435 +4: 436 +4: 437 +4: 438 +4: 439 +4: 440 +4: 441 +4: 442 +4: 443 +4: 444 +4: 445 +4: 446 +4: 447 +4: 448 +4: 449 +4: 450 +4: 451 +4: 452 +4: 453 +4: 454 +4: 455 +4: 456 +4: 457 +4: 458 +4: 459 +4: 460 +4: 461 +4: 462 +4: 463 +4: 464 +4: 465 +4: 466 +4: 467 +4: 468 +4: 469 +4: 470 +4: 471 +4: 472 +4: 473 +4: 474 +4: 475 +4: 476 +4: 477 +4: 478 +4: 479 +4: 480 +4: 481 +4: 482 +4: 483 +4: 484 +4: 485 +4: 486 +4: 487 +4: 488 +4: 489 +4: 490 +4: 491 +4: 492 +4: 493 +4: 494 +4: 495 +4: 496 +4: 497 +4: 498 +4: 499 +4: 500 +4: 501 +4: 502 +4: 503 +4: 504 +4: 505 +4: 506 +4: 507 +4: 508 +4: 509 +4: 510 +4: 511 +4: 512 +4: 513 +4: 514 +4: 515 +4: 516 +4: 517 +4: 518 +5: 518 +5: 519 +5: 520 +5: 521 +5: 522 +5: 523 +5: 524 +5: 525 +5: 526 +5: 527 +5: 528 +5: 529 +5: 530 +5: 531 +5: 532 +5: 533 +5: 534 +5: 535 +5: 536 +5: 537 +5: 538 +5: 539 +5: 540 +5: 541 +5: 542 +5: 543 +5: 544 +5: 545 +5: 546 +5: 547 +5: 548 +5: 549 +5: 550 +5: 551 +5: 552 +5: 553 +5: 554 +5: 555 +5: 556 +5: 557 +5: 558 +5: 559 +5: 560 +5: 561 +5: 562 +5: 563 +5: 564 +5: 565 +5: 566 +5: 567 +5: 568 +5: 569 +5: 570 +5: 571 +5: 572 +5: 573 +5: 574 +5: 575 +5: 576 +5: 577 +5: 578 +5: 579 +5: 580 +5: 581 +5: 582 +5: 583 +5: 584 +5: 585 +5: 586 +5: 587 +5: 588 +5: 589 +5: 590 +5: 591 +5: 592 +5: 593 +5: 594 +5: 595 +5: 596 +5: 597 +5: 598 +5: 599 +5: 600 +5: 601 +5: 602 +5: 603 +5: 604 +5: 605 +5: 606 +5: 607 +5: 608 +5: 609 +5: 610 +5: 611 +5: 612 +5: 613 +5: 614 +5: 615 +5: 616 +5: 617 +5: 618 +5: 619 +5: 620 +5: 621 +5: 622 +5: 623 +5: 624 +5: 625 +5: 626 +5: 627 +5: 628 +5: 629 +5: 630 +5: 631 +5: 632 +5: 633 +5: 634 +5: 635 +5: 636 +5: 637 +5: 638 +5: 639 +5: 640 +5: 641 +5: 642 +5: 643 +5: 644 +5: 645 +5: 646 +5: 647 +5: 648 +5: 649 +5: 650 +5: 651 +5: 652 +5: 653 +5: 654 +5: 655 +5: 656 +5: 657 +5: 658 +5: 659 +5: 660 +5: 661 +5: 662 +5: 663 +5: 664 +5: 665 +5: 666 +5: 667 +5: 668 +5: 669 +5: 670 +5: 671 +5: 672 +5: 673 +5: 674 +5: 675 +5: 676 +5: 677 +5: 678 +5: 679 +5: 680 +5: 681 +5: 682 +5: 683 +5: 684 +5: 685 +5: 686 +5: 687 +5: 688 +5: 689 +5: 690 +5: 691 +5: 692 +5: 693 +5: 694 +5: 695 +5: 696 +5: 697 +5: 698 +5: 699 +5: 700 +5: 701 +5: 702 +5: 703 +5: 704 +5: 705 +5: 706 +5: 707 +5: 708 +5: 709 +5: 710 +5: 711 +5: 712 +5: 713 +5: 714 +5: 715 +5: 716 +5: 717 +5: 718 +5: 719 +5: 720 +5: 721 +5: 722 +5: 723 +5: 724 +5: 725 +5: 726 +5: 727 +5: 728 +5: 729 +5: 730 +5: 731 +5: 732 +5: 733 +5: 734 +5: 735 +5: 736 +5: 737 +5: 738 +5: 739 +5: 740 +5: 741 +5: 742 +5: 743 +5: 744 +5: 745 +5: 746 +5: 747 +5: 748 +5: 749 +5: 750 +5: 751 +5: 752 +5: 753 +5: 754 +5: 755 +5: 756 +5: 757 +5: 758 +5: 759 +5: 760 +5: 761 +5: 762 +5: 763 +5: 764 +5: 765 +5: 766 +5: 767 +5: 768 +5: 769 +5: 770 +5: 771 +5: 772 +5: 773 +5: 774 +5: 775 +5: 776 +5: 777 +5: 778 +5: 779 +5: 780 +5: 781 +5: 782 +5: 783 +5: 784 +5: 785 +5: 786 +5: 787 +5: 788 +5: 789 +5: 790 +5: 791 +5: 792 +5: 793 +5: 794 +5: 795 +5: 796 +5: 797 +5: 798 +5: 799 +5: 800 +5: 801 +5: 802 +5: 803 +5: 804 +5: 805 +5: 806 +5: 807 +5: 808 +5: 809 +5: 810 +5: 811 +5: 812 +5: 813 +5: 814 +5: 815 +5: 816 +5: 817 +5: 818 +5: 819 +5: 820 +5: 821 +5: 822 +5: 823 +5: 824 +5: 825 +5: 826 +5: 827 +5: 828 +5: 829 +5: 830 +5: 831 +5: 832 +5: 833 +5: 834 +5: 835 +5: 836 +5: 837 +5: 838 +5: 839 +5: 840 +5: 841 +5: 842 +5: 843 +5: 844 +5: 845 +5: 846 +5: 847 +5: 848 +5: 849 +5: 850 +5: 851 +5: 852 +5: 853 +5: 854 +5: 855 +5: 856 +5: 857 +5: 858 +5: 859 +5: 860 +5: 861 +5: 862 +5: 863 +5: 864 +5: 865 +5: 866 +5: 867 +5: 868 +5: 869 +5: 870 +5: 871 +5: 872 +5: 873 +5: 874 +5: 875 +5: 876 +5: 877 +5: 878 +5: 879 +5: 880 +5: 881 +5: 882 +5: 883 +5: 884 +5: 885 +5: 886 +5: 887 +5: 888 +5: 889 +5: 890 +5: 891 +5: 892 +5: 893 +5: 894 +5: 895 +5: 896 +5: 897 +5: 898 +5: 899 +5: 900 +5: 901 +5: 902 +5: 903 +5: 904 +5: 905 +5: 906 +5: 907 +5: 908 +5: 909 +5: 910 +5: 911 +5: 912 +5: 913 +5: 914 +5: 915 +5: 916 +5: 917 +5: 918 +5: 919 +5: 920 +5: 921 +5: 922 +5: 923 +5: 924 +5: 925 +5: 926 +5: 927 +4: 519 +4: 520 +4: 521 +4: 522 +4: 523 +4: 524 +4: 525 +4: 526 +4: 527 +4: 528 +4: 529 +4: 530 +4: 531 +4: 532 +4: 533 +4: 534 +4: 535 +4: 536 +4: 537 +4: 538 +4: 539 +4: 540 +4: 541 +4: 542 +4: 543 +4: 544 +4: 545 +4: 546 +4: 547 +4: 548 +4: 549 +4: 550 +4: 551 +4: 552 +4: 553 +4: 554 +4: 555 +4: 556 +4: 557 +4: 558 +4: 559 +4: 560 +4: 561 +4: 562 +4: 563 +4: 564 +4: 565 +4: 566 +4: 567 +4: 568 +4: 569 +4: 570 +4: 571 +4: 572 +4: 573 +4: 574 +4: 575 +4: 576 +4: 577 +4: 578 +4: 579 +4: 580 +4: 581 +4: 582 +4: 583 +4: 584 +4: 585 +4: 586 +4: 587 +4: 588 +4: 589 +4: 590 +4: 591 +4: 592 +4: 593 +4: 594 +4: 595 +4: 596 +4: 597 +4: 598 +4: 599 +4: 600 +4: 601 +4: 602 +4: 603 +4: 604 +4: 605 +4: 606 +4: 607 +4: 608 +4: 609 +4: 610 +4: 611 +4: 612 +4: 613 +4: 614 +4: 615 +4: 616 +4: 617 +4: 618 +4: 619 +4: 620 +4: 621 +4: 622 +4: 623 +4: 624 +4: 625 +4: 626 +4: 627 +4: 628 +4: 629 +4: 630 +4: 631 +4: 632 +4: 633 +4: 634 +4: 635 +4: 636 +4: 637 +4: 638 +4: 639 +4: 640 +4: 641 +4: 642 +4: 643 +4: 644 +4: 645 +4: 646 +4: 647 +4: 648 +4: 649 +4: 650 +4: 651 +4: 652 +4: 653 +4: 654 +4: 655 +4: 656 +4: 657 +4: 658 +4: 659 +4: 660 +4: 661 +4: 662 +4: 663 +4: 664 +4: 665 +4: 666 +4: 667 +4: 668 +4: 669 +4: 670 +4: 671 +4: 672 +4: 673 +4: 674 +5: 928 +5: 929 +5: 930 +5: 931 +5: 932 +5: 933 +5: 934 +5: 935 +5: 936 +5: 937 +5: 938 +5: 939 +5: 940 +5: 941 +5: 942 +5: 943 +5: 944 +5: 945 +5: 946 +5: 947 +5: 948 +5: 949 +5: 950 +5: 951 +5: 952 +5: 953 +5: 954 +5: 955 +5: 956 +5: 957 +5: 958 +5: 959 +5: 960 +5: 961 +5: 962 +5: 963 +5: 964 +5: 965 +5: 966 +5: 967 +5: 968 +5: 969 +5: 970 +5: 971 +5: 972 +5: 973 +5: 974 +5: 975 +5: 976 +5: 977 +5: 978 +5: 979 +5: 980 +5: 981 +5: 982 +5: 983 +5: 984 +5: 985 +5: 986 +5: 987 +5: 988 +5: 989 +5: 990 +5: 991 +5: 992 +5: 993 +5: 994 +5: 995 +5: 996 +5: 997 +5: 998 +5: 999 +5: 1000 +5: 1001 +5: 1002 +5: 1003 +5: 1004 +5: 1005 +5: 1006 +5: 1007 +5: 1008 +5: 1009 +5: 1010 +5: 1011 +5: 1012 +5: 1013 +5: 1014 +5: 1015 +5: 1016 +5: 1017 +5: 1018 +5: 1019 +5: 1020 +5: 1021 +5: 1022 +5: 1023 +5: 1024 +5: 1025 +5: 1026 +5: 1027 +5: 1028 +5: 1029 +5: 1030 +5: 1031 +5: 1032 +5: 1033 +5: 1034 +5: 1035 +5: 1036 +5: 1037 +5: 1038 +5: 1039 +5: 1040 +5: 1041 +5: 1042 +5: 1043 +5: 1044 +5: 1045 +5: 1046 +5: 1047 +5: 1048 +5: 1049 +5: 1050 +5: 1051 +5: 1052 +5: 1053 +5: 1054 +5: 1055 +5: 1056 +5: 1057 +5: 1058 +5: 1059 +5: 1060 +5: 1061 +5: 1062 +5: 1063 +5: 1064 +5: 1065 +5: 1066 +5: 1067 +5: 1068 +5: 1069 +5: 1070 +5: 1071 +5: 1072 +5: 1073 +5: 1074 +5: 1075 +5: 1076 +5: 1077 +5: 1078 +5: 1079 +5: 1080 +5: 1081 +5: 1082 +5: 1083 +5: 1084 +5: 1085 +5: 1086 +5: 1087 +5: 1088 +5: 1089 +5: 1090 +5: 1091 +5: 1092 +5: 1093 +5: 1094 +5: 1095 +4: 675 +4: 676 +4: 677 +4: 678 +4: 679 +4: 680 +4: 681 +4: 682 +4: 683 +4: 684 +4: 685 +4: 686 +4: 687 +4: 688 +4: 689 +4: 690 +4: 691 +4: 692 +4: 693 +4: 694 +4: 695 +4: 696 +4: 697 +4: 698 +4: 699 +4: 700 +4: 701 +4: 702 +4: 703 +4: 704 +4: 705 +4: 706 +4: 707 +4: 708 +4: 709 +4: 710 +4: 711 +4: 712 +4: 713 +4: 714 +4: 715 +4: 716 +4: 717 +4: 718 +4: 719 +4: 720 +4: 721 +4: 722 +4: 723 +4: 724 +4: 725 +4: 726 +4: 727 +4: 728 +4: 729 +4: 730 +4: 731 +4: 732 +4: 733 +4: 734 +4: 735 +4: 736 +4: 737 +4: 738 +4: 739 +4: 740 +4: 741 +4: 742 +4: 743 +4: 744 +4: 745 +4: 746 +4: 747 +4: 748 +4: 749 +4: 750 +4: 751 +4: 752 +4: 753 +4: 754 +4: 755 +4: 756 +4: 757 +4: 758 +4: 759 +4: 760 +4: 761 +4: 762 +4: 763 +4: 764 +4: 765 +4: 766 +4: 767 +4: 768 +4: 769 +4: 770 +4: 771 +4: 772 +4: 773 +4: 774 +4: 775 +4: 776 +4: 777 +5: 1096 +5: 1097 +5: 1098 +5: 1099 +5: 1100 +5: 1101 +5: 1102 +5: 1103 +5: 1104 +5: 1105 +5: 1106 +5: 1107 +5: 1108 +5: 1109 +5: 1110 +5: 1111 +5: 1112 +5: 1113 +5: 1114 +5: 1115 +5: 1116 +5: 1117 +5: 1118 +5: 1119 +5: 1120 +5: 1121 +5: 1122 +5: 1123 +5: 1124 +5: 1125 +5: 1126 +5: 1127 +5: 1128 +5: 1129 +5: 1130 +5: 1131 +5: 1132 +5: 1133 +5: 1134 +5: 1135 +5: 1136 +5: 1137 +5: 1138 +5: 1139 +5: 1140 +5: 1141 +5: 1142 +5: 1143 +5: 1144 +5: 1145 +5: 1146 +5: 1147 +5: 1148 +5: 1149 +5: 1150 +5: 1151 +5: 1152 +5: 1153 +5: 1154 +5: 1155 +5: 1156 +5: 1157 +5: 1158 +5: 1159 +5: 1160 +5: 1161 +5: 1162 +5: 1163 +5: 1164 +5: 1165 +5: 1166 +5: 1167 +5: 1168 +5: 1169 +5: 1170 +5: 1171 +5: 1172 +5: 1173 +5: 1174 +5: 1175 +5: 1176 +5: 1177 +5: 1178 +5: 1179 +5: 1180 +5: 1181 +5: 1182 +5: 1183 +5: 1184 +5: 1185 +5: 1186 +5: 1187 +5: 1188 +5: 1189 +5: 1190 +5: 1191 +5: 1192 +5: 1193 +5: 1194 +5: 1195 +5: 1196 +5: 1197 +5: 1198 +5: 1199 +5: 1200 +5: 1201 +5: 1202 +5: 1203 +5: 1204 +5: 1205 +5: 1206 +5: 1207 +5: 1208 +5: 1209 +5: 1210 +5: 1211 +5: 1212 +5: 1213 +5: 1214 +5: 1215 +5: 1216 +5: 1217 +5: 1218 +5: 1219 +5: 1220 +5: 1221 +5: 1222 +5: 1223 +5: 1224 +5: 1225 +5: 1226 +5: 1227 +5: 1228 +5: 1229 +5: 1230 +5: 1231 +5: 1232 +5: 1233 +5: 1234 +5: 1235 +5: 1236 +5: 1237 +5: 1238 +5: 1239 +5: 1240 +5: 1241 +5: 1242 +5: 1243 +5: 1244 +5: 1245 +5: 1246 +5: 1247 +5: 1248 +5: 1249 +5: 1250 +5: 1251 +5: 1252 +5: 1253 +5: 1254 +5: 1255 +5: 1256 +5: 1257 +5: 1258 +5: 1259 +5: 1260 +5: 1261 +5: 1262 +5: 1263 +5: 1264 +5: 1265 +5: 1266 +5: 1267 +5: 1268 +5: 1269 +5: 1270 +5: 1271 +5: 1272 +5: 1273 +5: 1274 +5: 1275 +5: 1276 +5: 1277 +5: 1278 +5: 1279 +5: 1280 +5: 1281 +5: 1282 +5: 1283 +5: 1284 +5: 1285 +5: 1286 +5: 1287 +5: 1288 +5: 1289 +5: 1290 +5: 1291 +5: 1292 +5: 1293 +5: 1294 +5: 1295 +5: 1296 +5: 1297 +5: 1298 +5: 1299 +5: 1300 +5: 1301 +5: 1302 +5: 1303 +5: 1304 +5: 1305 +5: 1306 +5: 1307 +5: 1308 +5: 1309 +5: 1310 +5: 1311 +5: 1312 +5: 1313 +5: 1314 +5: 1315 +5: 1316 +5: 1317 +5: 1318 +5: 1319 +5: 1320 +5: 1321 +5: 1322 +5: 1323 +5: 1324 +5: 1325 +5: 1326 +5: 1327 +5: 1328 +5: 1329 +5: 1330 +5: 1331 +5: 1332 +5: 1333 +5: 1334 +5: 1335 +5: 1336 +5: 1337 +5: 1338 +4: 778 +4: 779 +4: 780 +4: 781 +4: 782 +4: 783 +4: 784 +4: 785 +4: 786 +4: 787 +4: 788 +4: 789 +4: 790 +4: 791 +4: 792 +4: 793 +4: 794 +4: 795 +4: 796 +4: 797 +4: 798 +4: 799 +4: 800 +4: 801 +4: 802 +4: 803 +4: 804 +4: 805 +4: 806 +4: 807 +4: 808 +4: 809 +4: 810 +4: 811 +4: 812 +4: 813 +4: 814 +4: 815 +4: 816 +4: 817 +4: 818 +4: 819 +4: 820 +4: 821 +4: 822 +4: 823 +4: 824 +4: 825 +4: 826 +4: 827 +4: 828 +4: 829 +4: 830 +4: 831 +4: 832 +4: 833 +4: 834 +4: 835 +4: 836 +4: 837 +4: 838 +4: 839 +4: 840 +4: 841 +4: 842 +4: 843 +4: 844 +4: 845 +4: 846 +4: 847 +4: 848 +4: 849 +4: 850 +4: 851 +4: 852 +4: 853 +4: 854 +4: 855 +4: 856 +4: 857 +4: 858 +4: 859 +4: 860 +4: 861 +4: 862 +4: 863 +4: 864 +4: 865 +4: 866 +4: 867 +4: 868 +4: 869 +4: 870 +4: 871 +4: 872 +4: 873 +4: 874 +4: 875 +4: 876 +4: 877 +4: 878 +4: 879 +4: 880 +4: 881 +4: 882 +4: 883 +4: 884 +4: 885 +4: 886 +4: 887 +4: 888 +4: 889 +4: 890 +4: 891 +4: 892 +4: 893 +4: 894 +4: 895 +4: 896 +4: 897 +4: 898 +4: 899 +4: 900 +4: 901 +4: 902 +4: 903 +4: 904 +4: 905 +4: 906 +4: 907 +4: 908 +4: 909 +4: 910 +4: 911 +4: 912 +4: 913 +4: 914 +4: 915 +4: 916 +4: 917 +4: 918 +4: 919 +4: 920 +4: 921 +4: 922 +4: 923 +4: 924 +4: 925 +4: 926 +4: 927 +4: 928 +4: 929 +4: 930 +4: 931 +4: 932 +4: 933 +4: 934 +4: 935 +4: 936 +4: 937 +4: 938 +4: 939 +4: 940 +4: 941 +4: 942 +4: 943 +4: 944 +4: 945 +4: 946 +4: 947 +4: 948 +4: 949 +4: 950 +4: 951 +4: 952 +4: 953 +4: 954 +4: 955 +4: 956 +4: 957 +4: 958 +4: 959 +4: 960 +4: 961 +4: 962 +4: 963 +4: 964 +4: 965 +4: 966 +4: 967 +4: 968 +4: 969 +4: 970 +4: 971 +4: 972 +4: 973 +4: 974 +4: 975 +4: 976 +4: 977 +4: 978 +4: 979 +4: 980 +4: 981 +4: 982 +4: 983 +4: 984 +4: 985 +4: 986 +4: 987 +4: 988 +4: 989 +4: 990 +4: 991 +4: 992 +4: 993 +4: 994 +4: 995 +4: 996 +4: 997 +4: 998 +4: 999 +4: 1000 +4: 1001 +4: 1002 +4: 1003 +4: 1004 +4: 1005 +4: 1006 +4: 1007 +4: 1008 +4: 1009 +4: 1010 +4: 1011 +4: 1012 +4: 1013 +4: 1014 +4: 1015 +4: 1016 +4: 1017 +4: 1018 +4: 1019 +4: 1020 +4: 1021 +4: 1022 +4: 1023 +4: 1024 +4: 1025 +4: 1026 +4: 1027 +4: 1028 +4: 1029 +4: 1030 +4: 1031 +4: 1032 +4: 1033 +4: 1034 +4: 1035 +4: 1036 +4: 1037 +4: 1038 +4: 1039 +4: 1040 +4: 1041 +4: 1042 +4: 1043 +4: 1044 +4: 1045 +4: 1046 +4: 1047 +4: 1048 +4: 1049 +4: 1050 +4: 1051 +4: 1052 +4: 1053 +4: 1054 +4: 1055 +4: 1056 +4: 1057 +4: 1058 +4: 1059 +4: 1060 +4: 1061 +4: 1062 +4: 1063 +4: 1064 +4: 1065 +4: 1066 +4: 1067 +4: 1068 +4: 1069 +4: 1070 +4: 1071 +4: 1072 +4: 1073 +4: 1074 +4: 1075 +4: 1076 +4: 1077 +4: 1078 +4: 1079 +4: 1080 +4: 1081 +4: 1082 +4: 1083 +4: 1084 +4: 1085 +4: 1086 +4: 1087 +4: 1088 +4: 1089 +4: 1090 +4: 1091 +4: 1092 +4: 1093 +4: 1094 +4: 1095 +4: 1096 +4: 1097 +4: 1098 +4: 1099 +4: 1100 +4: 1101 +4: 1102 +4: 1103 +4: 1104 +4: 1105 +4: 1106 +4: 1107 +4: 1108 +4: 1109 +4: 1110 +4: 1111 +5: 1339 +5: 1340 +5: 1341 +5: 1342 +5: 1343 +5: 1344 +5: 1345 +5: 1346 +5: 1347 +5: 1348 +5: 1349 +5: 1350 +5: 1351 +5: 1352 +5: 1353 +5: 1354 +5: 1355 +5: 1356 +5: 1357 +5: 1358 +5: 1359 +5: 1360 +5: 1361 +5: 1362 +5: 1363 +5: 1364 +5: 1365 +5: 1366 +5: 1367 +5: 1368 +5: 1369 +5: 1370 +5: 1371 +5: 1372 +5: 1373 +5: 1374 +5: 1375 +5: 1376 +5: 1377 +5: 1378 +5: 1379 +5: 1380 +5: 1381 +5: 1382 +5: 1383 +5: 1384 +5: 1385 +5: 1386 +5: 1387 +5: 1388 +5: 1389 +5: 1390 +5: 1391 +5: 1392 +5: 1393 +5: 1394 +5: 1395 +5: 1396 +5: 1397 +5: 1398 +5: 1399 +5: 1400 +5: 1401 +5: 1402 +5: 1403 +5: 1404 +5: 1405 +5: 1406 +5: 1407 +5: 1408 +5: 1409 +5: 1410 +5: 1411 +5: 1412 +5: 1413 +5: 1414 +5: 1415 +5: 1416 +5: 1417 +5: 1418 +5: 1419 +5: 1420 +5: 1421 +5: 1422 +5: 1423 +5: 1424 +5: 1425 +5: 1426 +5: 1427 +5: 1428 +5: 1429 +5: 1430 +5: 1431 +5: 1432 +5: 1433 +5: 1434 +5: 1435 +5: 1436 +5: 1437 +5: 1438 +5: 1439 +5: 1440 +5: 1441 +5: 1442 +5: 1443 +5: 1444 +5: 1445 +5: 1446 +5: 1447 +5: 1448 +5: 1449 +5: 1450 +5: 1451 +5: 1452 +5: 1453 +5: 1454 +5: 1455 +5: 1456 +5: 1457 +5: 1458 +5: 1459 +5: 1460 +5: 1461 +5: 1462 +5: 1463 +5: 1464 +5: 1465 +5: 1466 +5: 1467 +5: 1468 +5: 1469 +5: 1470 +5: 1471 +5: 1472 +5: 1473 +5: 1474 +5: 1475 +5: 1476 +5: 1477 +5: 1478 +5: 1479 +5: 1480 +5: 1481 +5: 1482 +5: 1483 +5: 1484 +5: 1485 +5: 1486 +5: 1487 +5: 1488 +5: 1489 +5: 1490 +5: 1491 +5: 1492 +5: 1493 +5: 1494 +5: 1495 +5: 1496 +5: 1497 +5: 1498 +5: 1499 +5: 1500 +5: 1501 +5: 1502 +5: 1503 +5: 1504 +5: 1505 +5: 1506 +5: 1507 +5: 1508 +5: 1509 +5: 1510 +5: 1511 +5: 1512 +5: 1513 +5: 1514 +5: 1515 +5: 1516 +5: 1517 +5: 1518 +5: 1519 +5: 1520 +5: 1521 +5: 1522 +5: 1523 +5: 1524 +5: 1525 +5: 1526 +5: 1527 +5: 1528 +5: 1529 +5: 1530 +5: 1531 +5: 1532 +5: 1533 +5: 1534 +5: 1535 +5: 1536 +5: 1537 +5: 1538 +5: 1539 +5: 1540 +5: 1541 +5: 1542 +5: 1543 +5: 1544 +5: 1545 +5: 1546 +5: 1547 +5: 1548 +5: 1549 +5: 1550 +5: 1551 +5: 1552 +5: 1553 +5: 1554 +5: 1555 +5: 1556 +5: 1557 +5: 1558 +5: 1559 +5: 1560 +5: 1561 +5: 1562 +5: 1563 +5: 1564 +5: 1565 +5: 1566 +5: 1567 +5: 1568 +5: 1569 +5: 1570 +5: 1571 +5: 1572 +5: 1573 +5: 1574 +5: 1575 +5: 1576 +5: 1577 +5: 1578 +5: 1579 +5: 1580 +5: 1581 +5: 1582 +5: 1583 +5: 1584 +5: 1585 +5: 1586 +5: 1587 +5: 1588 +5: 1589 +5: 1590 +5: 1591 +5: 1592 +5: 1593 +5: 1594 +5: 1595 +5: 1596 +5: 1597 +5: 1598 +5: 1599 +5: 1600 +5: 1601 +5: 1602 +5: 1603 +5: 1604 +5: 1605 +5: 1606 +5: 1607 +5: 1608 +5: 1609 +5: 1610 +5: 1611 +5: 1612 +5: 1613 +5: 1614 +5: 1615 +5: 1616 +5: 1617 +5: 1618 +5: 1619 +5: 1620 +5: 1621 +5: 1622 +5: 1623 +5: 1624 +5: 1625 +5: 1626 +5: 1627 +5: 1628 +5: 1629 +5: 1630 +5: 1631 +5: 1632 +5: 1633 +5: 1634 +5: 1635 +5: 1636 +5: 1637 +5: 1638 +5: 1639 +5: 1640 +5: 1641 +5: 1642 +5: 1643 +5: 1644 +5: 1645 +5: 1646 +5: 1647 +5: 1648 +5: 1649 +5: 1650 +5: 1651 +5: 1652 +5: 1653 +5: 1654 +5: 1655 +5: 1656 +5: 1657 +5: 1658 +5: 1659 +5: 1660 +5: 1661 +5: 1662 +5: 1663 +5: 1664 +5: 1665 +5: 1666 +5: 1667 +5: 1668 +5: 1669 +5: 1670 +5: 1671 +5: 1672 +5: 1673 +5: 1674 +5: 1675 +5: 1676 +5: 1677 +5: 1678 +5: 1679 +5: 1680 +5: 1681 +5: 1682 +5: 1683 +5: 1684 +5: 1685 +5: 1686 +5: 1687 +5: 1688 +5: 1689 +5: 1690 +5: 1691 +5: 1692 +5: 1693 +5: 1694 +5: 1695 +5: 1696 +5: 1697 +5: 1698 +5: 1699 +5: 1700 +5: 1701 +5: 1702 +5: 1703 +4: 1112 +4: 1113 +4: 1114 +4: 1115 +4: 1116 +4: 1117 +4: 1118 +4: 1119 +4: 1120 +4: 1121 +4: 1122 +4: 1123 +4: 1124 +4: 1125 +4: 1126 +4: 1127 +4: 1128 +4: 1129 +4: 1130 +4: 1131 +4: 1132 +4: 1133 +4: 1134 +4: 1135 +4: 1136 +4: 1137 +4: 1138 +4: 1139 +4: 1140 +4: 1141 +4: 1142 +4: 1143 +4: 1144 +4: 1145 +4: 1146 +4: 1147 +4: 1148 +4: 1149 +4: 1150 +4: 1151 +4: 1152 +4: 1153 +4: 1154 +4: 1155 +4: 1156 +4: 1157 +4: 1158 +4: 1159 +4: 1160 +4: 1161 +4: 1162 +4: 1163 +4: 1164 +4: 1165 +4: 1166 +4: 1167 +4: 1168 +4: 1169 +4: 1170 +4: 1171 +4: 1172 +4: 1173 +4: 1174 +4: 1175 +4: 1176 +4: 1177 +4: 1178 +4: 1179 +4: 1180 +4: 1181 +4: 1182 +4: 1183 +4: 1184 +4: 1185 +4: 1186 +4: 1187 +4: 1188 +4: 1189 +4: 1190 +4: 1191 +4: 1192 +4: 1193 +4: 1194 +4: 1195 +4: 1196 +4: 1197 +4: 1198 +4: 1199 +4: 1200 +4: 1201 +4: 1202 +4: 1203 +4: 1204 +4: 1205 +4: 1206 +4: 1207 +4: 1208 +4: 1209 +4: 1210 +4: 1211 +4: 1212 +4: 1213 +4: 1214 +4: 1215 +4: 1216 +4: 1217 +4: 1218 +4: 1219 +4: 1220 +4: 1221 +4: 1222 +4: 1223 +4: 1224 +4: 1225 +4: 1226 +4: 1227 +4: 1228 +4: 1229 +4: 1230 +4: 1231 +4: 1232 +4: 1233 +4: 1234 +4: 1235 +4: 1236 +4: 1237 +4: 1238 +4: 1239 +4: 1240 +4: 1241 +4: 1242 +4: 1243 +4: 1244 +4: 1245 +4: 1246 +4: 1247 +4: 1248 +4: 1249 +4: 1250 +4: 1251 +4: 1252 +4: 1253 +4: 1254 +4: 1255 +4: 1256 +4: 1257 +4: 1258 +4: 1259 +4: 1260 +4: 1261 +4: 1262 +4: 1263 +4: 1264 +4: 1265 +4: 1266 +4: 1267 +4: 1268 +4: 1269 +4: 1270 +4: 1271 +4: 1272 +4: 1273 +4: 1274 +4: 1275 +4: 1276 +4: 1277 +4: 1278 +4: 1279 +4: 1280 +4: 1281 +4: 1282 +4: 1283 +4: 1284 +4: 1285 +4: 1286 +4: 1287 +4: 1288 +4: 1289 +4: 1290 +4: 1291 +4: 1292 +4: 1293 +4: 1294 +4: 1295 +4: 1296 +4: 1297 +4: 1298 +4: 1299 +4: 1300 +4: 1301 +4: 1302 +4: 1303 +4: 1304 +4: 1305 +4: 1306 +4: 1307 +4: 1308 +4: 1309 +4: 1310 +4: 1311 +4: 1312 +4: 1313 +4: 1314 +4: 1315 +4: 1316 +4: 1317 +4: 1318 +4: 1319 +4: 1320 +4: 1321 +4: 1322 +4: 1323 +4: 1324 +4: 1325 +4: 1326 +4: 1327 +4: 1328 +4: 1329 +4: 1330 +4: 1331 +4: 1332 +4: 1333 +4: 1334 +4: 1335 +4: 1336 +4: 1337 +4: 1338 +4: 1339 +4: 1340 +4: 1341 +4: 1342 +4: 1343 +4: 1344 +4: 1345 +4: 1346 +4: 1347 +4: 1348 +4: 1349 +4: 1350 +4: 1351 +4: 1352 +4: 1353 +4: 1354 +4: 1355 +4: 1356 +4: 1357 +4: 1358 +4: 1359 +4: 1360 +4: 1361 +4: 1362 +4: 1363 +4: 1364 +4: 1365 +4: 1366 +4: 1367 +4: 1368 +4: 1369 +4: 1370 +4: 1371 +4: 1372 +4: 1373 +4: 1374 +4: 1375 +4: 1376 +4: 1377 +4: 1378 +4: 1379 +4: 1380 +4: 1381 +4: 1382 +4: 1383 +4: 1384 +4: 1385 +4: 1386 +4: 1387 +4: 1388 +4: 1389 +4: 1390 +4: 1391 +4: 1392 +4: 1393 +4: 1394 +4: 1395 +4: 1396 +4: 1397 +4: 1398 +4: 1399 +5: 1704 +5: 1705 +5: 1706 +5: 1707 +5: 1708 +5: 1709 +5: 1710 +5: 1711 +5: 1712 +5: 1713 +5: 1714 +5: 1715 +5: 1716 +5: 1717 +5: 1718 +5: 1719 +5: 1720 +5: 1721 +5: 1722 +5: 1723 +5: 1724 +5: 1725 +5: 1726 +5: 1727 +5: 1728 +5: 1729 +5: 1730 +5: 1731 +5: 1732 +5: 1733 +5: 1734 +5: 1735 +5: 1736 +5: 1737 +5: 1738 +5: 1739 +5: 1740 +5: 1741 +5: 1742 +5: 1743 +5: 1744 +5: 1745 +5: 1746 +5: 1747 +5: 1748 +5: 1749 +5: 1750 +5: 1751 +5: 1752 +5: 1753 +5: 1754 +5: 1755 +5: 1756 +5: 1757 +5: 1758 +5: 1759 +5: 1760 +5: 1761 +5: 1762 +5: 1763 +5: 1764 +5: 1765 +5: 1766 +5: 1767 +5: 1768 +5: 1769 +5: 1770 +5: 1771 +5: 1772 +5: 1773 +5: 1774 +5: 1775 +5: 1776 +5: 1777 +5: 1778 +5: 1779 +5: 1780 +5: 1781 +5: 1782 +5: 1783 +5: 1784 +5: 1785 +5: 1786 +5: 1787 +5: 1788 +5: 1789 +5: 1790 +5: 1791 +5: 1792 +5: 1793 +5: 1794 +5: 1795 +5: 1796 +5: 1797 +5: 1798 +5: 1799 +5: 1800 +5: 1801 +5: 1802 +5: 1803 +5: 1804 +5: 1805 +5: 1806 +5: 1807 +5: 1808 +5: 1809 +5: 1810 +5: 1811 +5: 1812 +5: 1813 +5: 1814 +5: 1815 +5: 1816 +5: 1817 +5: 1818 +5: 1819 +5: 1820 +5: 1821 +5: 1822 +5: 1823 +5: 1824 +5: 1825 +5: 1826 +5: 1827 +5: 1828 +5: 1829 +5: 1830 +5: 1831 +5: 1832 +5: 1833 +5: 1834 +5: 1835 +5: 1836 +5: 1837 +5: 1838 +5: 1839 +5: 1840 +5: 1841 +5: 1842 +5: 1843 +5: 1844 +5: 1845 +5: 1846 +5: 1847 +5: 1848 +5: 1849 +5: 1850 +5: 1851 +5: 1852 +5: 1853 +5: 1854 +5: 1855 +5: 1856 +5: 1857 +5: 1858 +5: 1859 +5: 1860 +5: 1861 +5: 1862 +5: 1863 +5: 1864 +5: 1865 +5: 1866 +5: 1867 +5: 1868 +5: 1869 +5: 1870 +5: 1871 +5: 1872 +5: 1873 +5: 1874 +5: 1875 +5: 1876 +5: 1877 +5: 1878 +5: 1879 +5: 1880 +5: 1881 +5: 1882 +5: 1883 +5: 1884 +5: 1885 +5: 1886 +5: 1887 +5: 1888 +5: 1889 +5: 1890 +5: 1891 +5: 1892 +5: 1893 +5: 1894 +5: 1895 +5: 1896 +5: 1897 +5: 1898 +5: 1899 +5: 1900 +5: 1901 +5: 1902 +5: 1903 +5: 1904 +5: 1905 +5: 1906 +5: 1907 +5: 1908 +5: 1909 +5: 1910 +5: 1911 +5: 1912 +5: 1913 +5: 1914 +5: 1915 +5: 1916 +5: 1917 +5: 1918 +5: 1919 +5: 1920 +5: 1921 +5: 1922 +5: 1923 +5: 1924 +5: 1925 +5: 1926 +5: 1927 +5: 1928 +5: 1929 +5: 1930 +5: 1931 +5: 1932 +5: 1933 +5: 1934 +5: 1935 +5: 1936 +5: 1937 +5: 1938 +5: 1939 +5: 1940 +5: 1941 +5: 1942 +5: 1943 +5: 1944 +5: 1945 +5: 1946 +5: 1947 +5: 1948 +5: 1949 +5: 1950 +5: 1951 +5: 1952 +5: 1953 +5: 1954 +5: 1955 +5: 1956 +5: 1957 +5: 1958 +5: 1959 +5: 1960 +5: 1961 +5: 1962 +5: 1963 +5: 1964 +5: 1965 +5: 1966 +5: 1967 +5: 1968 +5: 1969 +5: 1970 +5: 1971 +5: 1972 +5: 1973 +5: 1974 +5: 1975 +5: 1976 +5: 1977 +5: 1978 +5: 1979 +5: 1980 +5: 1981 +5: 1982 +5: 1983 +5: 1984 +5: 1985 +5: 1986 +5: 1987 +5: 1988 +5: 1989 +5: 1990 +5: 1991 +5: 1992 +5: 1993 +5: 1994 +5: 1995 +5: 1996 +5: 1997 +5: 1998 +5: 1999 +5: 2000 +5: 2001 +5: 2002 +5: 2003 +5: 2004 +5: 2005 +5: 2006 +5: 2007 +5: 2008 +5: 2009 +5: 2010 +5: 2011 +5: 2012 +5: 2013 +5: 2014 +5: 2015 +5: 2016 +5: 2017 +5: 2018 +5: 2019 +5: 2020 +5: 2021 +5: 2022 +5: 2023 +5: 2024 +5: 2025 +5: 2026 +5: 2027 +5: 2028 +5: 2029 +5: 2030 +5: 2031 +5: 2032 +5: 2033 +5: 2034 +5: 2035 +5: 2036 +5: 2037 +5: 2038 +5: 2039 +5: 2040 +5: 2041 +5: 2042 +5: 2043 +5: 2044 +5: 2045 +5: 2046 +5: 2047 +5: 2048 +5: 2049 +5: 2050 +5: 2051 +5: 2052 +5: 2053 +5: 2054 +5: 2055 +5: 2056 +5: 2057 +5: 2058 +5: 2059 +5: 2060 +5: 2061 +5: 2062 +5: 2063 +5: 2064 +5: 2065 +5: 2066 +5: 2067 +5: 2068 +5: 2069 +5: 2070 +5: 2071 +5: 2072 +5: 2073 +5: 2074 +5: 2075 +5: 2076 +5: 2077 +5: 2078 +5: 2079 +5: 2080 +5: 2081 +5: 2082 +5: 2083 +5: 2084 +5: 2085 +5: 2086 +5: 2087 +5: 2088 +5: 2089 +5: 2090 +5: 2091 +5: 2092 +5: 2093 +5: 2094 +5: 2095 +5: 2096 +5: 2097 +5: 2098 +5: 2099 +5: 2100 +5: 2101 +5: 2102 +5: 2103 +5: 2104 +5: 2105 +5: 2106 +5: 2107 +5: 2108 +5: 2109 +5: 2110 +5: 2111 +5: 2112 +5: 2113 +5: 2114 +5: 2115 +5: 2116 +5: 2117 +5: 2118 +5: 2119 +5: 2120 +5: 2121 +5: 2122 +5: 2123 +5: 2124 +5: 2125 +5: 2126 +5: 2127 +5: 2128 +5: 2129 +5: 2130 +5: 2131 +5: 2132 +5: 2133 +5: 2134 +5: 2135 +5: 2136 +5: 2137 +5: 2138 +5: 2139 +5: 2140 +5: 2141 +5: 2142 +5: 2143 +5: 2144 +5: 2145 +5: 2146 +5: 2147 +5: 2148 +5: 2149 +4: 1400 +4: 1401 +4: 1402 +4: 1403 +4: 1404 +4: 1405 +4: 1406 +4: 1407 +4: 1408 +4: 1409 +4: 1410 +4: 1411 +4: 1412 +4: 1413 +4: 1414 +4: 1415 +4: 1416 +4: 1417 +4: 1418 +4: 1419 +4: 1420 +4: 1421 +4: 1422 +4: 1423 +4: 1424 +4: 1425 +4: 1426 +4: 1427 +4: 1428 +4: 1429 +4: 1430 +4: 1431 +4: 1432 +4: 1433 +4: 1434 +4: 1435 +4: 1436 +4: 1437 +4: 1438 +4: 1439 +4: 1440 +4: 1441 +4: 1442 +4: 1443 +4: 1444 +4: 1445 +4: 1446 +4: 1447 +4: 1448 +4: 1449 +4: 1450 +4: 1451 +4: 1452 +4: 1453 +4: 1454 +4: 1455 +4: 1456 +4: 1457 +4: 1458 +4: 1459 +4: 1460 +4: 1461 +4: 1462 +4: 1463 +4: 1464 +4: 1465 +4: 1466 +4: 1467 +4: 1468 +4: 1469 +4: 1470 +4: 1471 +4: 1472 +4: 1473 +4: 1474 +4: 1475 +4: 1476 +4: 1477 +4: 1478 +4: 1479 +4: 1480 +4: 1481 +4: 1482 +4: 1483 +4: 1484 +4: 1485 +4: 1486 +4: 1487 +4: 1488 +4: 1489 +4: 1490 +4: 1491 +4: 1492 +4: 1493 +4: 1494 +4: 1495 +4: 1496 +4: 1497 +4: 1498 +4: 1499 +4: 1500 +4: 1501 +4: 1502 +4: 1503 +4: 1504 +4: 1505 +4: 1506 +4: 1507 +4: 1508 +4: 1509 +4: 1510 +4: 1511 +4: 1512 +4: 1513 +4: 1514 +4: 1515 +4: 1516 +4: 1517 +4: 1518 +4: 1519 +4: 1520 +4: 1521 +4: 1522 +4: 1523 +4: 1524 +4: 1525 +4: 1526 +4: 1527 +4: 1528 +4: 1529 +4: 1530 +4: 1531 +4: 1532 +4: 1533 +4: 1534 +4: 1535 +4: 1536 +4: 1537 +4: 1538 +4: 1539 +4: 1540 +4: 1541 +4: 1542 +4: 1543 +4: 1544 +4: 1545 +4: 1546 +4: 1547 +4: 1548 +4: 1549 +4: 1550 +4: 1551 +4: 1552 +4: 1553 +4: 1554 +4: 1555 +4: 1556 +4: 1557 +4: 1558 +4: 1559 +4: 1560 +4: 1561 +4: 1562 +4: 1563 +4: 1564 +4: 1565 +4: 1566 +4: 1567 +4: 1568 +4: 1569 +4: 1570 +4: 1571 +4: 1572 +4: 1573 +4: 1574 +4: 1575 +4: 1576 +4: 1577 +4: 1578 +4: 1579 +4: 1580 +4: 1581 +4: 1582 +4: 1583 +4: 1584 +4: 1585 +4: 1586 +4: 1587 +4: 1588 +4: 1589 +4: 1590 +4: 1591 +4: 1592 +4: 1593 +4: 1594 +4: 1595 +4: 1596 +4: 1597 +4: 1598 +4: 1599 +4: 1600 +4: 1601 +4: 1602 +4: 1603 +4: 1604 +4: 1605 +4: 1606 +4: 1607 +4: 1608 +4: 1609 +4: 1610 +4: 1611 +4: 1612 +4: 1613 +4: 1614 +4: 1615 +4: 1616 +4: 1617 +4: 1618 +4: 1619 +4: 1620 +4: 1621 +4: 1622 +4: 1623 +4: 1624 +4: 1625 +4: 1626 +4: 1627 +4: 1628 +4: 1629 +4: 1630 +4: 1631 +4: 1632 +4: 1633 +4: 1634 +4: 1635 +4: 1636 +4: 1637 +4: 1638 +4: 1639 +4: 1640 +4: 1641 +4: 1642 +4: 1643 +4: 1644 +4: 1645 +4: 1646 +4: 1647 +4: 1648 +4: 1649 +4: 1650 +4: 1651 +4: 1652 +4: 1653 +4: 1654 +4: 1655 +4: 1656 +4: 1657 +4: 1658 +4: 1659 +4: 1660 +4: 1661 +4: 1662 +4: 1663 +4: 1664 +4: 1665 +4: 1666 +4: 1667 +4: 1668 +4: 1669 +4: 1670 +4: 1671 +4: 1672 +4: 1673 +4: 1674 +4: 1675 +4: 1676 +4: 1677 +4: 1678 +4: 1679 +4: 1680 +4: 1681 +4: 1682 +4: 1683 +4: 1684 +4: 1685 +4: 1686 +4: 1687 +4: 1688 +4: 1689 +4: 1690 +4: 1691 +4: 1692 +4: 1693 +4: 1694 +4: 1695 +4: 1696 +4: 1697 +4: 1698 +4: 1699 +4: 1700 +4: 1701 +4: 1702 +4: 1703 +4: 1704 +4: 1705 +4: 1706 +4: 1707 +4: 1708 +4: 1709 +4: 1710 +4: 1711 +4: 1712 +4: 1713 +4: 1714 +4: 1715 +4: 1716 +4: 1717 +4: 1718 +4: 1719 +4: 1720 +4: 1721 +4: 1722 +4: 1723 +4: 1724 +4: 1725 +4: 1726 +4: 1727 +4: 1728 +4: 1729 +4: 1730 +4: 1731 +4: 1732 +4: 1733 +4: 1734 +4: 1735 +4: 1736 +4: 1737 +4: 1738 +4: 1739 +4: 1740 +4: 1741 +4: 1742 +4: 1743 +4: 1744 +4: 1745 +4: 1746 +4: 1747 +4: 1748 +4: 1749 +4: 1750 +4: 1751 +4: 1752 +4: 1753 +4: 1754 +4: 1755 +4: 1756 +4: 1757 +4: 1758 +4: 1759 +4: 1760 +4: 1761 +4: 1762 +4: 1763 +4: 1764 +4: 1765 +4: 1766 +4: 1767 +4: 1768 +4: 1769 +4: 1770 +4: 1771 +4: 1772 +4: 1773 +4: 1774 +4: 1775 +4: 1776 +4: 1777 +4: 1778 +4: 1779 +4: 1780 +4: 1781 +4: 1782 +4: 1783 +4: 1784 +4: 1785 +4: 1786 +4: 1787 +4: 1788 +4: 1789 +4: 1790 +4: 1791 +4: 1792 +4: 1793 +4: 1794 +4: 1795 +4: 1796 +4: 1797 +4: 1798 +4: 1799 +4: 1800 +4: 1801 +4: 1802 +4: 1803 +4: 1804 +4: 1805 +4: 1806 +4: 1807 +4: 1808 +4: 1809 +4: 1810 +4: 1811 +4: 1812 +4: 1813 +4: 1814 +4: 1815 +4: 1816 +4: 1817 +4: 1818 +4: 1819 +4: 1820 +4: 1821 +4: 1822 +4: 1823 +4: 1824 +4: 1825 +4: 1826 +4: 1827 +4: 1828 +4: 1829 +4: 1830 +4: 1831 +4: 1832 +4: 1833 +4: 1834 +4: 1835 +4: 1836 +4: 1837 +4: 1838 +4: 1839 +4: 1840 +4: 1841 +4: 1842 +4: 1843 +4: 1844 +4: 1845 +4: 1846 +4: 1847 +4: 1848 +4: 1849 +4: 1850 +4: 1851 +4: 1852 +4: 1853 +4: 1854 +4: 1855 +4: 1856 +4: 1857 +4: 1858 +4: 1859 +4: 1860 +4: 1861 +4: 1862 +4: 1863 +4: 1864 +4: 1865 +4: 1866 +4: 1867 +4: 1868 +4: 1869 +4: 1870 +4: 1871 +4: 1872 +4: 1873 +4: 1874 +4: 1875 +4: 1876 +4: 1877 +4: 1878 +4: 1879 +4: 1880 +4: 1881 +4: 1882 +4: 1883 +4: 1884 +4: 1885 +4: 1886 +4: 1887 +4: 1888 +4: 1889 +4: 1890 +4: 1891 +4: 1892 +4: 1893 +4: 1894 +4: 1895 +4: 1896 +4: 1897 +4: 1898 +4: 1899 +4: 1900 +4: 1901 +4: 1902 +4: 1903 +4: 1904 +4: 1905 +4: 1906 +4: 1907 +4: 1908 +4: 1909 +4: 1910 +4: 1911 +4: 1912 +4: 1913 +4: 1914 +4: 1915 +4: 1916 +4: 1917 +4: 1918 +4: 1919 +4: 1920 +4: 1921 +4: 1922 +4: 1923 +4: 1924 +4: 1925 +4: 1926 +4: 1927 +4: 1928 +4: 1929 +4: 1930 +4: 1931 +4: 1932 +4: 1933 +4: 1934 +4: 1935 +4: 1936 +4: 1937 +4: 1938 +4: 1939 +4: 1940 +4: 1941 +4: 1942 +4: 1943 +4: 1944 +4: 1945 +4: 1946 +4: 1947 +4: 1948 +4: 1949 +4: 1950 +4: 1951 +4: 1952 +4: 1953 +4: 1954 +4: 1955 +4: 1956 +4: 1957 +4: 1958 +4: 1959 +4: 1960 +4: 1961 +4: 1962 +4: 1963 +4: 1964 +4: 1965 +4: 1966 +4: 1967 +4: 1968 +4: 1969 +4: 1970 +4: 1971 +4: 1972 +4: 1973 +4: 1974 +4: 1975 +4: 1976 +4: 1977 +4: 1978 +4: 1979 +4: 1980 +4: 1981 +4: 1982 +4: 1983 +4: 1984 +4: 1985 +4: 1986 +4: 1987 +4: 1988 +4: 1989 +4: 1990 +4: 1991 +4: 1992 +4: 1993 +4: 1994 +4: 1995 +4: 1996 +4: 1997 +4: 1998 +4: 1999 +4: 2000 +4: 2001 +4: 2002 +4: 2003 +4: 2004 +4: 2005 +4: 2006 +4: 2007 +4: 2008 +4: 2009 +4: 2010 +4: 2011 +4: 2012 +4: 2013 +4: 2014 +4: 2015 +4: 2016 +4: 2017 +4: 2018 +4: 2019 +4: 2020 +4: 2021 +4: 2022 +4: 2023 +4: 2024 +4: 2025 +4: 2026 +4: 2027 +4: 2028 +4: 2029 +4: 2030 +4: 2031 +4: 2032 +4: 2033 +4: 2034 +4: 2035 +4: 2036 +4: 2037 +4: 2038 +4: 2039 +4: 2040 +4: 2041 +4: 2042 +4: 2043 +4: 2044 +4: 2045 +4: 2046 +4: 2047 +4: 2048 +4: 2049 +4: 2050 +4: 2051 +4: 2052 +4: 2053 +4: 2054 +4: 2055 +4: 2056 +4: 2057 +4: 2058 +4: 2059 +4: 2060 +4: 2061 +4: 2062 +4: 2063 +4: 2064 +4: 2065 +4: 2066 +4: 2067 +4: 2068 +4: 2069 +4: 2070 +4: 2071 +4: 2072 +4: 2073 +4: 2074 +4: 2075 +4: 2076 +4: 2077 +4: 2078 +4: 2079 +4: 2080 +4: 2081 +4: 2082 +4: 2083 +4: 2084 +4: 2085 +4: 2086 +4: 2087 +4: 2088 +4: 2089 +4: 2090 +4: 2091 +4: 2092 +4: 2093 +4: 2094 +4: 2095 +4: 2096 +4: 2097 +4: 2098 +4: 2099 +4: 2100 +4: 2101 +4: 2102 +4: 2103 +4: 2104 +4: 2105 +4: 2106 +4: 2107 +4: 2108 +4: 2109 +4: 2110 +4: 2111 +4: 2112 +4: 2113 +4: 2114 +4: 2115 +4: 2116 +4: 2117 +4: 2118 +4: 2119 +4: 2120 +4: 2121 +4: 2122 +4: 2123 +4: 2124 +4: 2125 +4: 2126 +4: 2127 +4: 2128 +4: 2129 +4: 2130 +4: 2131 +4: 2132 +4: 2133 +4: 2134 +4: 2135 +4: 2136 +4: 2137 +4: 2138 +4: 2139 +4: 2140 +4: 2141 +4: 2142 +4: 2143 +4: 2144 +4: 2145 +4: 2146 +4: 2147 +4: 2148 +4: 2149 +4: 2150 +4: 2151 +4: 2152 +4: 2153 +4: 2154 +4: 2155 +4: 2156 +4: 2157 +4: 2158 +4: 2159 +4: 2160 +4: 2161 +4: 2162 +4: 2163 +4: 2164 +4: 2165 +4: 2166 +4: 2167 +4: 2168 +4: 2169 +4: 2170 +4: 2171 +4: 2172 +4: 2173 +4: 2174 +4: 2175 +4: 2176 +4: 2177 +4: 2178 +4: 2179 +4: 2180 +4: 2181 +4: 2182 +4: 2183 +4: 2184 +4: 2185 +4: 2186 +4: 2187 +4: 2188 +4: 2189 +4: 2190 +4: 2191 +4: 2192 +4: 2193 +4: 2194 +4: 2195 +4: 2196 +4: 2197 +4: 2198 +4: 2199 +4: 2200 +4: 2201 +4: 2202 +4: 2203 +4: 2204 +4: 2205 +4: 2206 +4: 2207 +4: 2208 +4: 2209 +4: 2210 +4: 2211 +4: 2212 +4: 2213 +4: 2214 +4: 2215 +4: 2216 +4: 2217 +4: 2218 +4: 2219 +4: 2220 +4: 2221 +4: 2222 +4: 2223 +4: 2224 +4: 2225 +4: 2226 +4: 2227 +4: 2228 +4: 2229 +4: 2230 +4: 2231 +4: 2232 +4: 2233 +4: 2234 +4: 2235 +4: 2236 +4: 2237 +4: 2238 +4: 2239 +4: 2240 +4: 2241 +4: 2242 +4: 2243 +4: 2244 +4: 2245 +4: 2246 +4: 2247 +4: 2248 +4: 2249 +4: 2250 +4: 2251 +4: 2252 +4: 2253 +4: 2254 +4: 2255 +4: 2256 +4: 2257 +4: 2258 +4: 2259 +4: 2260 +4: 2261 +4: 2262 +4: 2263 +4: 2264 +4: 2265 +4: 2266 +4: 2267 +4: 2268 +4: 2269 +4: 2270 +4: 2271 +4: 2272 +4: 2273 +4: 2274 +4: 2275 +4: 2276 +4: 2277 +4: 2278 +4: 2279 +4: 2280 +4: 2281 +4: 2282 +5: 2150 +5: 2151 +5: 2152 +5: 2153 +5: 2154 +5: 2155 +5: 2156 +5: 2157 +5: 2158 +5: 2159 +5: 2160 +5: 2161 +5: 2162 +5: 2163 +5: 2164 +5: 2165 +5: 2166 +5: 2167 +5: 2168 +5: 2169 +5: 2170 +5: 2171 +5: 2172 +5: 2173 +5: 2174 +5: 2175 +5: 2176 +5: 2177 +5: 2178 +5: 2179 +5: 2180 +5: 2181 +5: 2182 +5: 2183 +5: 2184 +5: 2185 +5: 2186 +5: 2187 +5: 2188 +5: 2189 +5: 2190 +5: 2191 +5: 2192 +5: 2193 +5: 2194 +5: 2195 +5: 2196 +5: 2197 +5: 2198 +5: 2199 +5: 2200 +5: 2201 +5: 2202 +5: 2203 +5: 2204 +5: 2205 +5: 2206 +5: 2207 +5: 2208 +5: 2209 +5: 2210 +5: 2211 +5: 2212 +5: 2213 +5: 2214 +5: 2215 +5: 2216 +5: 2217 +5: 2218 +5: 2219 +5: 2220 +5: 2221 +5: 2222 +5: 2223 +5: 2224 +5: 2225 +5: 2226 +5: 2227 +5: 2228 +5: 2229 +5: 2230 +5: 2231 +5: 2232 +5: 2233 +5: 2234 +5: 2235 +5: 2236 +5: 2237 +5: 2238 +5: 2239 +5: 2240 +5: 2241 +5: 2242 +5: 2243 +5: 2244 +5: 2245 +5: 2246 +5: 2247 +5: 2248 +5: 2249 +5: 2250 +5: 2251 +5: 2252 +5: 2253 +5: 2254 +5: 2255 +5: 2256 +5: 2257 +5: 2258 +5: 2259 +5: 2260 +5: 2261 +5: 2262 +5: 2263 +5: 2264 +5: 2265 +5: 2266 +5: 2267 +5: 2268 +5: 2269 +5: 2270 +5: 2271 +5: 2272 +5: 2273 +5: 2274 +5: 2275 +5: 2276 +5: 2277 +5: 2278 +5: 2279 +5: 2280 +5: 2281 +5: 2282 +5: 2283 +5: 2284 +5: 2285 +5: 2286 +5: 2287 +5: 2288 +5: 2289 +5: 2290 +5: 2291 +5: 2292 +5: 2293 +5: 2294 +5: 2295 +5: 2296 +5: 2297 +5: 2298 +5: 2299 +5: 2300 +5: 2301 +5: 2302 +5: 2303 +5: 2304 +5: 2305 +5: 2306 +5: 2307 +5: 2308 +5: 2309 +5: 2310 +5: 2311 +5: 2312 +5: 2313 +5: 2314 +5: 2315 +5: 2316 +5: 2317 +5: 2318 +5: 2319 +5: 2320 +5: 2321 +5: 2322 +5: 2323 +5: 2324 +5: 2325 +5: 2326 +5: 2327 +5: 2328 +5: 2329 +5: 2330 +5: 2331 +5: 2332 +5: 2333 +5: 2334 +5: 2335 +5: 2336 +5: 2337 +5: 2338 +5: 2339 +5: 2340 +5: 2341 +5: 2342 +5: 2343 +5: 2344 +5: 2345 +5: 2346 +5: 2347 +5: 2348 +5: 2349 +5: 2350 +5: 2351 +5: 2352 +5: 2353 +5: 2354 +5: 2355 +5: 2356 +5: 2357 +5: 2358 +5: 2359 +5: 2360 +5: 2361 +5: 2362 +5: 2363 +5: 2364 +5: 2365 +5: 2366 +5: 2367 +5: 2368 +5: 2369 +5: 2370 +5: 2371 +5: 2372 +5: 2373 +5: 2374 +5: 2375 +5: 2376 +5: 2377 +5: 2378 +5: 2379 +5: 2380 +5: 2381 +5: 2382 +5: 2383 +5: 2384 +5: 2385 +5: 2386 +5: 2387 +5: 2388 +5: 2389 +5: 2390 +5: 2391 +5: 2392 +5: 2393 +5: 2394 +5: 2395 +5: 2396 +5: 2397 +5: 2398 +5: 2399 +5: 2400 +5: 2401 +5: 2402 +5: 2403 +5: 2404 +5: 2405 +5: 2406 +5: 2407 +5: 2408 +5: 2409 +5: 2410 +5: 2411 +5: 2412 +5: 2413 +5: 2414 +5: 2415 +5: 2416 +5: 2417 +5: 2418 +5: 2419 +5: 2420 +5: 2421 +5: 2422 +5: 2423 +5: 2424 +5: 2425 +5: 2426 +5: 2427 +5: 2428 +5: 2429 +5: 2430 +5: 2431 +5: 2432 +5: 2433 +5: 2434 +5: 2435 +5: 2436 +5: 2437 +5: 2438 +5: 2439 +5: 2440 +5: 2441 +5: 2442 +5: 2443 +5: 2444 +5: 2445 +5: 2446 +5: 2447 +5: 2448 +5: 2449 +5: 2450 +5: 2451 +5: 2452 +5: 2453 +5: 2454 +5: 2455 +5: 2456 +5: 2457 +5: 2458 +5: 2459 +5: 2460 +5: 2461 +5: 2462 +5: 2463 +5: 2464 +5: 2465 +5: 2466 +5: 2467 +5: 2468 +5: 2469 +5: 2470 +5: 2471 +5: 2472 +5: 2473 +5: 2474 +5: 2475 +5: 2476 +5: 2477 +5: 2478 +5: 2479 +5: 2480 +5: 2481 +5: 2482 +5: 2483 +5: 2484 +4: 2283 +4: 2284 +4: 2285 +4: 2286 +4: 2287 +4: 2288 +4: 2289 +4: 2290 +4: 2291 +4: 2292 +4: 2293 +4: 2294 +4: 2295 +4: 2296 +4: 2297 +4: 2298 +4: 2299 +4: 2300 +4: 2301 +4: 2302 +4: 2303 +4: 2304 +4: 2305 +4: 2306 +4: 2307 +4: 2308 +4: 2309 +4: 2310 +4: 2311 +4: 2312 +4: 2313 +4: 2314 +4: 2315 +4: 2316 +4: 2317 +4: 2318 +4: 2319 +4: 2320 +4: 2321 +4: 2322 +4: 2323 +4: 2324 +4: 2325 +4: 2326 +4: 2327 +4: 2328 +4: 2329 +4: 2330 +4: 2331 +4: 2332 +4: 2333 +4: 2334 +4: 2335 +4: 2336 +4: 2337 +4: 2338 +4: 2339 +4: 2340 +4: 2341 +4: 2342 +4: 2343 +4: 2344 +4: 2345 +4: 2346 +4: 2347 +4: 2348 +4: 2349 +4: 2350 +4: 2351 +4: 2352 +4: 2353 +4: 2354 +4: 2355 +4: 2356 +4: 2357 +4: 2358 +4: 2359 +4: 2360 +4: 2361 +4: 2362 +4: 2363 +4: 2364 +4: 2365 +4: 2366 +4: 2367 +4: 2368 +4: 2369 +4: 2370 +4: 2371 +4: 2372 +4: 2373 +4: 2374 +4: 2375 +4: 2376 +4: 2377 +4: 2378 +4: 2379 +4: 2380 +4: 2381 +4: 2382 +4: 2383 +4: 2384 +4: 2385 +4: 2386 +4: 2387 +4: 2388 +4: 2389 +4: 2390 +4: 2391 +4: 2392 +4: 2393 +4: 2394 +4: 2395 +4: 2396 +4: 2397 +4: 2398 +4: 2399 +4: 2400 +4: 2401 +4: 2402 +4: 2403 +4: 2404 +4: 2405 +4: 2406 +4: 2407 +4: 2408 +4: 2409 +4: 2410 +4: 2411 +4: 2412 +4: 2413 +4: 2414 +4: 2415 +4: 2416 +4: 2417 +4: 2418 +4: 2419 +4: 2420 +4: 2421 +4: 2422 +4: 2423 +4: 2424 +4: 2425 +4: 2426 +4: 2427 +4: 2428 +4: 2429 +4: 2430 +4: 2431 +4: 2432 +4: 2433 +4: 2434 +4: 2435 +4: 2436 +4: 2437 +4: 2438 +4: 2439 +4: 2440 +4: 2441 +4: 2442 +4: 2443 +4: 2444 +4: 2445 +4: 2446 +4: 2447 +4: 2448 +4: 2449 +4: 2450 +4: 2451 +4: 2452 +4: 2453 +4: 2454 +4: 2455 +4: 2456 +4: 2457 +4: 2458 +4: 2459 +4: 2460 +4: 2461 +4: 2462 +4: 2463 +4: 2464 +4: 2465 +4: 2466 +4: 2467 +4: 2468 +4: 2469 +4: 2470 +4: 2471 +4: 2472 +4: 2473 +4: 2474 +4: 2475 +4: 2476 +4: 2477 +4: 2478 +4: 2479 +4: 2480 +4: 2481 +4: 2482 +4: 2483 +4: 2484 +4: 2485 +4: 2486 +4: 2487 +4: 2488 +4: 2489 +4: 2490 +4: 2491 +4: 2492 +4: 2493 +4: 2494 +4: 2495 +4: 2496 +4: 2497 +4: 2498 +4: 2499 +4: 2500 +4: 2501 +4: 2502 +4: 2503 +4: 2504 +4: 2505 +4: 2506 +4: 2507 +4: 2508 +4: 2509 +4: 2510 +4: 2511 +4: 2512 +4: 2513 +4: 2514 +4: 2515 +4: 2516 +4: 2517 +4: 2518 +4: 2519 +4: 2520 +4: 2521 +4: 2522 +4: 2523 +4: 2524 +4: 2525 +4: 2526 +4: 2527 +4: 2528 +4: 2529 +4: 2530 +4: 2531 +4: 2532 +4: 2533 +4: 2534 +4: 2535 +4: 2536 +4: 2537 +4: 2538 +4: 2539 +4: 2540 +4: 2541 +4: 2542 +4: 2543 +4: 2544 +4: 2545 +4: 2546 +4: 2547 +4: 2548 +4: 2549 +4: 2550 +4: 2551 +4: 2552 +4: 2553 +4: 2554 +4: 2555 +4: 2556 +4: 2557 +4: 2558 +4: 2559 +4: 2560 +4: 2561 +4: 2562 +4: 2563 +4: 2564 +4: 2565 +4: 2566 +4: 2567 +4: 2568 +4: 2569 +4: 2570 +4: 2571 +4: 2572 +4: 2573 +4: 2574 +4: 2575 +4: 2576 +4: 2577 +4: 2578 +4: 2579 +4: 2580 +4: 2581 +4: 2582 +4: 2583 +4: 2584 +4: 2585 +4: 2586 +4: 2587 +4: 2588 +4: 2589 +4: 2590 +4: 2591 +4: 2592 +4: 2593 +4: 2594 +4: 2595 +4: 2596 +4: 2597 +4: 2598 +4: 2599 +4: 2600 +4: 2601 +4: 2602 +4: 2603 +4: 2604 +4: 2605 +4: 2606 +4: 2607 +4: 2608 +4: 2609 +4: 2610 +4: 2611 +4: 2612 +4: 2613 +4: 2614 +4: 2615 +4: 2616 +4: 2617 +4: 2618 +4: 2619 +4: 2620 +4: 2621 +4: 2622 +4: 2623 +4: 2624 +4: 2625 +4: 2626 +4: 2627 +4: 2628 +4: 2629 +4: 2630 +4: 2631 +4: 2632 +4: 2633 +4: 2634 +4: 2635 +4: 2636 +4: 2637 +4: 2638 +4: 2639 +4: 2640 +4: 2641 +4: 2642 +4: 2643 +4: 2644 +4: 2645 +4: 2646 +4: 2647 +4: 2648 +4: 2649 +4: 2650 +4: 2651 +4: 2652 +4: 2653 +4: 2654 +4: 2655 +4: 2656 +4: 2657 +4: 2658 +4: 2659 +4: 2660 +4: 2661 +4: 2662 +4: 2663 +4: 2664 +4: 2665 +4: 2666 +4: 2667 +4: 2668 +4: 2669 +4: 2670 +4: 2671 +4: 2672 +4: 2673 +4: 2674 +4: 2675 +4: 2676 +4: 2677 +4: 2678 +4: 2679 +4: 2680 +4: 2681 +4: 2682 +4: 2683 +4: 2684 +4: 2685 +4: 2686 +4: 2687 +4: 2688 +4: 2689 +4: 2690 +4: 2691 +4: 2692 +4: 2693 +4: 2694 +4: 2695 +4: 2696 +4: 2697 +4: 2698 +4: 2699 +4: 2700 +4: 2701 +4: 2702 +4: 2703 +4: 2704 +4: 2705 +4: 2706 +4: 2707 +4: 2708 +4: 2709 +4: 2710 +4: 2711 +4: 2712 +4: 2713 +4: 2714 +4: 2715 +4: 2716 +4: 2717 +4: 2718 +4: 2719 +4: 2720 +4: 2721 +4: 2722 +4: 2723 +4: 2724 +4: 2725 +4: 2726 +4: 2727 +4: 2728 +4: 2729 +4: 2730 +4: 2731 +4: 2732 +4: 2733 +4: 2734 +4: 2735 +4: 2736 +4: 2737 +4: 2738 +4: 2739 +4: 2740 +4: 2741 +4: 2742 +4: 2743 +4: 2744 +4: 2745 +4: 2746 +4: 2747 +4: 2748 +4: 2749 +4: 2750 +4: 2751 +4: 2752 +5: 2485 +5: 2486 +5: 2487 +5: 2488 +5: 2489 +5: 2490 +5: 2491 +5: 2492 +5: 2493 +5: 2494 +5: 2495 +5: 2496 +5: 2497 +5: 2498 +5: 2499 +5: 2500 +5: 2501 +5: 2502 +5: 2503 +5: 2504 +5: 2505 +5: 2506 +5: 2507 +5: 2508 +5: 2509 +5: 2510 +5: 2511 +5: 2512 +5: 2513 +5: 2514 +5: 2515 +5: 2516 +5: 2517 +5: 2518 +5: 2519 +5: 2520 +5: 2521 +5: 2522 +5: 2523 +5: 2524 +5: 2525 +5: 2526 +5: 2527 +5: 2528 +5: 2529 +5: 2530 +5: 2531 +5: 2532 +5: 2533 +5: 2534 +5: 2535 +5: 2536 +5: 2537 +5: 2538 +5: 2539 +5: 2540 +5: 2541 +5: 2542 +5: 2543 +5: 2544 +5: 2545 +5: 2546 +5: 2547 +5: 2548 +5: 2549 +5: 2550 +5: 2551 +5: 2552 +5: 2553 +5: 2554 +5: 2555 +5: 2556 +5: 2557 +5: 2558 +5: 2559 +5: 2560 +5: 2561 +5: 2562 +5: 2563 +5: 2564 +5: 2565 +5: 2566 +5: 2567 +5: 2568 +5: 2569 +5: 2570 +5: 2571 +5: 2572 +5: 2573 +5: 2574 +5: 2575 +5: 2576 +5: 2577 +5: 2578 +5: 2579 +5: 2580 +5: 2581 +5: 2582 +5: 2583 +5: 2584 +5: 2585 +5: 2586 +5: 2587 +5: 2588 +5: 2589 +5: 2590 +5: 2591 +5: 2592 +5: 2593 +5: 2594 +5: 2595 +5: 2596 +5: 2597 +5: 2598 +5: 2599 +5: 2600 +5: 2601 +5: 2602 +5: 2603 +5: 2604 +5: 2605 +5: 2606 +5: 2607 +5: 2608 +5: 2609 +5: 2610 +5: 2611 +5: 2612 +5: 2613 +5: 2614 +5: 2615 +5: 2616 +5: 2617 +5: 2618 +5: 2619 +5: 2620 +5: 2621 +5: 2622 +5: 2623 +5: 2624 +5: 2625 +5: 2626 +5: 2627 +5: 2628 +5: 2629 +5: 2630 +5: 2631 +5: 2632 +5: 2633 +5: 2634 +5: 2635 +5: 2636 +5: 2637 +5: 2638 +5: 2639 +5: 2640 +5: 2641 +5: 2642 +5: 2643 +5: 2644 +5: 2645 +5: 2646 +5: 2647 +5: 2648 +5: 2649 +5: 2650 +5: 2651 +5: 2652 +5: 2653 +5: 2654 +5: 2655 +5: 2656 +5: 2657 +5: 2658 +5: 2659 +5: 2660 +5: 2661 +5: 2662 +5: 2663 +5: 2664 +5: 2665 +5: 2666 +5: 2667 +5: 2668 +5: 2669 +5: 2670 +5: 2671 +5: 2672 +5: 2673 +5: 2674 +5: 2675 +5: 2676 +5: 2677 +5: 2678 +5: 2679 +5: 2680 +5: 2681 +5: 2682 +5: 2683 +5: 2684 +5: 2685 +5: 2686 +5: 2687 +5: 2688 +5: 2689 +5: 2690 +5: 2691 +5: 2692 +5: 2693 +5: 2694 +5: 2695 +5: 2696 +5: 2697 +5: 2698 +5: 2699 +5: 2700 +5: 2701 +5: 2702 +5: 2703 +5: 2704 +5: 2705 +5: 2706 +5: 2707 +5: 2708 +5: 2709 +5: 2710 +5: 2711 +5: 2712 +5: 2713 +5: 2714 +5: 2715 +5: 2716 +5: 2717 +5: 2718 +5: 2719 +5: 2720 +5: 2721 +5: 2722 +5: 2723 +5: 2724 +5: 2725 +5: 2726 +5: 2727 +5: 2728 +5: 2729 +5: 2730 +5: 2731 +5: 2732 +5: 2733 +5: 2734 +5: 2735 +5: 2736 +5: 2737 +5: 2738 +5: 2739 +5: 2740 +5: 2741 +5: 2742 +5: 2743 +5: 2744 +5: 2745 +5: 2746 +5: 2747 +5: 2748 +5: 2749 +5: 2750 +5: 2751 +5: 2752 +5: 2753 +5: 2754 +5: 2755 +5: 2756 +5: 2757 +5: 2758 +5: 2759 +5: 2760 +5: 2761 +5: 2762 +5: 2763 +5: 2764 +5: 2765 +5: 2766 +5: 2767 +5: 2768 +5: 2769 +5: 2770 +5: 2771 +5: 2772 +5: 2773 +5: 2774 +5: 2775 +5: 2776 +5: 2777 +5: 2778 +5: 2779 +5: 2780 +5: 2781 +5: 2782 +5: 2783 +5: 2784 +5: 2785 +5: 2786 +5: 2787 +5: 2788 +5: 2789 +5: 2790 +5: 2791 +5: 2792 +5: 2793 +5: 2794 +5: 2795 +5: 2796 +5: 2797 +5: 2798 +5: 2799 +5: 2800 +5: 2801 +5: 2802 +5: 2803 +5: 2804 +5: 2805 +5: 2806 +5: 2807 +5: 2808 +5: 2809 +5: 2810 +5: 2811 +5: 2812 +5: 2813 +5: 2814 +5: 2815 +5: 2816 +5: 2817 +5: 2818 +5: 2819 +5: 2820 +5: 2821 +5: 2822 +5: 2823 +5: 2824 +5: 2825 +5: 2826 +5: 2827 +5: 2828 +5: 2829 +5: 2830 +5: 2831 +5: 2832 +5: 2833 +5: 2834 +5: 2835 +5: 2836 +5: 2837 +5: 2838 +5: 2839 +5: 2840 +5: 2841 +5: 2842 +5: 2843 +5: 2844 +5: 2845 +5: 2846 +5: 2847 +5: 2848 +5: 2849 +5: 2850 +5: 2851 +5: 2852 +5: 2853 +5: 2854 +5: 2855 +5: 2856 +5: 2857 +5: 2858 +5: 2859 +5: 2860 +5: 2861 +5: 2862 +5: 2863 +5: 2864 +5: 2865 +5: 2866 +5: 2867 +5: 2868 +5: 2869 +5: 2870 +5: 2871 +5: 2872 +5: 2873 +5: 2874 +5: 2875 +5: 2876 +5: 2877 +5: 2878 +5: 2879 +5: 2880 +5: 2881 +5: 2882 +5: 2883 +5: 2884 +5: 2885 +5: 2886 +5: 2887 +5: 2888 +5: 2889 +5: 2890 +5: 2891 +5: 2892 +5: 2893 +5: 2894 +5: 2895 +5: 2896 +5: 2897 +5: 2898 +5: 2899 +5: 2900 +5: 2901 +5: 2902 +5: 2903 +5: 2904 +5: 2905 +5: 2906 +5: 2907 +5: 2908 +5: 2909 +5: 2910 +5: 2911 +5: 2912 +5: 2913 +5: 2914 +5: 2915 +5: 2916 +5: 2917 +5: 2918 +5: 2919 +5: 2920 +5: 2921 +5: 2922 +5: 2923 +5: 2924 +5: 2925 +4: 2753 +4: 2754 +4: 2755 +4: 2756 +4: 2757 +4: 2758 +4: 2759 +4: 2760 +4: 2761 +4: 2762 +4: 2763 +4: 2764 +4: 2765 +4: 2766 +4: 2767 +4: 2768 +4: 2769 +4: 2770 +4: 2771 +4: 2772 +4: 2773 +4: 2774 +4: 2775 +4: 2776 +4: 2777 +4: 2778 +4: 2779 +4: 2780 +4: 2781 +4: 2782 +4: 2783 +4: 2784 +4: 2785 +4: 2786 +4: 2787 +4: 2788 +4: 2789 +4: 2790 +4: 2791 +4: 2792 +4: 2793 +4: 2794 +4: 2795 +4: 2796 +4: 2797 +4: 2798 +4: 2799 +4: 2800 +4: 2801 +4: 2802 +4: 2803 +4: 2804 +4: 2805 +4: 2806 +4: 2807 +4: 2808 +4: 2809 +4: 2810 +4: 2811 +4: 2812 +4: 2813 +4: 2814 +4: 2815 +4: 2816 +4: 2817 +4: 2818 +4: 2819 +4: 2820 +4: 2821 +4: 2822 +4: 2823 +4: 2824 +4: 2825 +4: 2826 +4: 2827 +4: 2828 +4: 2829 +4: 2830 +4: 2831 +4: 2832 +4: 2833 +4: 2834 +4: 2835 +4: 2836 +4: 2837 +4: 2838 +4: 2839 +4: 2840 +4: 2841 +4: 2842 +4: 2843 +4: 2844 +4: 2845 +4: 2846 +4: 2847 +4: 2848 +4: 2849 +4: 2850 +4: 2851 +4: 2852 +4: 2853 +4: 2854 +4: 2855 +4: 2856 +4: 2857 +4: 2858 +4: 2859 +4: 2860 +4: 2861 +4: 2862 +4: 2863 +4: 2864 +4: 2865 +4: 2866 +4: 2867 +4: 2868 +4: 2869 +4: 2870 +4: 2871 +4: 2872 +4: 2873 +4: 2874 +4: 2875 +4: 2876 +4: 2877 +4: 2878 +4: 2879 +4: 2880 +4: 2881 +4: 2882 +4: 2883 +4: 2884 +4: 2885 +4: 2886 +4: 2887 +4: 2888 +4: 2889 +4: 2890 +4: 2891 +4: 2892 +4: 2893 +4: 2894 +4: 2895 +4: 2896 +4: 2897 +4: 2898 +4: 2899 +4: 2900 +4: 2901 +4: 2902 +4: 2903 +4: 2904 +4: 2905 +4: 2906 +4: 2907 +4: 2908 +4: 2909 +4: 2910 +4: 2911 +4: 2912 +4: 2913 +4: 2914 +4: 2915 +4: 2916 +4: 2917 +4: 2918 +4: 2919 +4: 2920 +4: 2921 +4: 2922 +4: 2923 +4: 2924 +4: 2925 +4: 2926 +4: 2927 +4: 2928 +4: 2929 +4: 2930 +4: 2931 +4: 2932 +4: 2933 +4: 2934 +4: 2935 +4: 2936 +4: 2937 +4: 2938 +4: 2939 +4: 2940 +5: 2926 +5: 2927 +5: 2928 +5: 2929 +5: 2930 +5: 2931 +5: 2932 +5: 2933 +5: 2934 +5: 2935 +5: 2936 +5: 2937 +5: 2938 +5: 2939 +5: 2940 +5: 2941 +5: 2942 +5: 2943 +5: 2944 +5: 2945 +5: 2946 +5: 2947 +5: 2948 +5: 2949 +5: 2950 +5: 2951 +5: 2952 +5: 2953 +5: 2954 +5: 2955 +5: 2956 +5: 2957 +5: 2958 +5: 2959 +5: 2960 +5: 2961 +5: 2962 +5: 2963 +5: 2964 +5: 2965 +5: 2966 +5: 2967 +5: 2968 +5: 2969 +5: 2970 +5: 2971 +5: 2972 +5: 2973 +5: 2974 +5: 2975 +5: 2976 +5: 2977 +5: 2978 +5: 2979 +5: 2980 +5: 2981 +5: 2982 +5: 2983 +5: 2984 +5: 2985 +5: 2986 +5: 2987 +5: 2988 +5: 2989 +5: 2990 +5: 2991 +5: 2992 +5: 2993 +5: 2994 +5: 2995 +5: 2996 +5: 2997 +5: 2998 +5: 2999 +5: 3000 +5: 3001 +5: 3002 +5: 3003 +4: 2941 +4: 2942 +4: 2943 +4: 2944 +4: 2945 +4: 2946 +4: 2947 +4: 2948 +4: 2949 +4: 2950 +4: 2951 +4: 2952 +4: 2953 +4: 2954 +4: 2955 +4: 2956 +4: 2957 +4: 2958 +4: 2959 +4: 2960 +4: 2961 +4: 2962 +4: 2963 +4: 2964 +4: 2965 +4: 2966 +4: 2967 +4: 2968 +4: 2969 +4: 2970 +4: 2971 +4: 2972 +4: 2973 +4: 2974 +4: 2975 +4: 2976 +4: 2977 +4: 2978 +4: 2979 +4: 2980 +4: 2981 +4: 2982 +4: 2983 +4: 2984 +4: 2985 +4: 2986 +4: 2987 +4: 2988 +4: 2989 +4: 2990 +4: 2991 +4: 2992 +4: 2993 +4: 2994 +4: 2995 +4: 2996 +4: 2997 +4: 2998 +4: 2999 +4: 3000 +4: 3001 +4: 3002 +4: 3003 +4: 3004 +4: 3005 +4: 3006 +4: 3007 +4: 3008 +4: 3009 +4: 3010 +4: 3011 +4: 3012 +4: 3013 +4: 3014 +4: 3015 +4: 3016 +4: 3017 +4: 3018 +4: 3019 +4: 3020 +4: 3021 +4: 3022 +4: 3023 +4: 3024 +4: 3025 +5: 3004 +5: 3005 +5: 3006 +5: 3007 +5: 3008 +5: 3009 +5: 3010 +5: 3011 +5: 3012 +5: 3013 +5: 3014 +5: 3015 +5: 3016 +5: 3017 +5: 3018 +5: 3019 +5: 3020 +5: 3021 +5: 3022 +5: 3023 +5: 3024 +5: 3025 +5: 3026 +5: 3027 +5: 3028 +5: 3029 +5: 3030 +5: 3031 +5: 3032 +5: 3033 +5: 3034 +5: 3035 +5: 3036 +5: 3037 +5: 3038 +5: 3039 +5: 3040 +5: 3041 +5: 3042 +5: 3043 +5: 3044 +5: 3045 +5: 3046 +5: 3047 +5: 3048 +5: 3049 +5: 3050 +5: 3051 +5: 3052 +5: 3053 +5: 3054 +5: 3055 +5: 3056 +5: 3057 +5: 3058 +5: 3059 +5: 3060 +5: 3061 +5: 3062 +5: 3063 +5: 3064 +5: 3065 +5: 3066 +5: 3067 +5: 3068 +5: 3069 +5: 3070 +5: 3071 +5: 3072 +5: 3073 +5: 3074 +5: 3075 +5: 3076 +5: 3077 +5: 3078 +5: 3079 +5: 3080 +5: 3081 +5: 3082 +5: 3083 +5: 3084 +5: 3085 +5: 3086 +5: 3087 +5: 3088 +5: 3089 +5: 3090 +5: 3091 +5: 3092 +5: 3093 +5: 3094 +5: 3095 +5: 3096 +5: 3097 +5: 3098 +5: 3099 +5: 3100 +5: 3101 +5: 3102 +5: 3103 +5: 3104 +5: 3105 +5: 3106 +5: 3107 +5: 3108 +5: 3109 +5: 3110 +5: 3111 +5: 3112 +5: 3113 +5: 3114 +5: 3115 +5: 3116 +5: 3117 +5: 3118 +5: 3119 +5: 3120 +5: 3121 +5: 3122 +5: 3123 +5: 3124 +5: 3125 +5: 3126 +5: 3127 +5: 3128 +5: 3129 +5: 3130 +5: 3131 +5: 3132 +5: 3133 +5: 3134 +5: 3135 +5: 3136 +5: 3137 +5: 3138 +5: 3139 +5: 3140 +5: 3141 +5: 3142 +5: 3143 +5: 3144 +5: 3145 +5: 3146 +5: 3147 +5: 3148 +5: 3149 +5: 3150 +5: 3151 +5: 3152 +5: 3153 +5: 3154 +5: 3155 +5: 3156 +5: 3157 +5: 3158 +5: 3159 +5: 3160 +5: 3161 +5: 3162 +5: 3163 +5: 3164 +5: 3165 +5: 3166 +5: 3167 +5: 3168 +5: 3169 +5: 3170 +5: 3171 +5: 3172 +5: 3173 +5: 3174 +5: 3175 +5: 3176 +5: 3177 +5: 3178 +5: 3179 +5: 3180 +5: 3181 +5: 3182 +5: 3183 +5: 3184 +5: 3185 +5: 3186 +5: 3187 +5: 3188 +5: 3189 +5: 3190 +5: 3191 +5: 3192 +5: 3193 +5: 3194 +5: 3195 +5: 3196 +5: 3197 +5: 3198 +5: 3199 +5: 3200 +5: 3201 +5: 3202 +5: 3203 +5: 3204 +5: 3205 +5: 3206 +5: 3207 +5: 3208 +5: 3209 +5: 3210 +5: 3211 +5: 3212 +5: 3213 +5: 3214 +5: 3215 +5: 3216 +5: 3217 +5: 3218 +5: 3219 +5: 3220 +5: 3221 +5: 3222 +5: 3223 +5: 3224 +5: 3225 +5: 3226 +5: 3227 +5: 3228 +5: 3229 +5: 3230 +5: 3231 +5: 3232 +5: 3233 +5: 3234 +5: 3235 +5: 3236 +5: 3237 +5: 3238 +5: 3239 +5: 3240 +5: 3241 +5: 3242 +5: 3243 +5: 3244 +5: 3245 +5: 3246 +5: 3247 +5: 3248 +5: 3249 +5: 3250 +5: 3251 +5: 3252 +5: 3253 +5: 3254 +5: 3255 +5: 3256 +5: 3257 +5: 3258 +5: 3259 +5: 3260 +5: 3261 +5: 3262 +5: 3263 +5: 3264 +5: 3265 +5: 3266 +5: 3267 +5: 3268 +5: 3269 +5: 3270 +5: 3271 +5: 3272 +5: 3273 +5: 3274 +5: 3275 +5: 3276 +5: 3277 +5: 3278 +5: 3279 +5: 3280 +5: 3281 +5: 3282 +5: 3283 +5: 3284 +5: 3285 +5: 3286 +5: 3287 +5: 3288 +5: 3289 +5: 3290 +5: 3291 +5: 3292 +5: 3293 +5: 3294 +5: 3295 +5: 3296 +5: 3297 +5: 3298 +5: 3299 +5: 3300 +5: 3301 +5: 3302 +5: 3303 +5: 3304 +5: 3305 +5: 3306 +5: 3307 +5: 3308 +5: 3309 +5: 3310 +5: 3311 +5: 3312 +5: 3313 +5: 3314 +5: 3315 +5: 3316 +5: 3317 +5: 3318 +5: 3319 +5: 3320 +5: 3321 +5: 3322 +5: 3323 +5: 3324 +5: 3325 +5: 3326 +5: 3327 +5: 3328 +5: 3329 +5: 3330 +5: 3331 +5: 3332 +5: 3333 +5: 3334 +5: 3335 +5: 3336 +5: 3337 +5: 3338 +5: 3339 +5: 3340 +5: 3341 +5: 3342 +5: 3343 +5: 3344 +5: 3345 +5: 3346 +5: 3347 +5: 3348 +5: 3349 +5: 3350 +5: 3351 +5: 3352 +5: 3353 +5: 3354 +5: 3355 +5: 3356 +5: 3357 +5: 3358 +5: 3359 +5: 3360 +5: 3361 +5: 3362 +5: 3363 +5: 3364 +5: 3365 +5: 3366 +5: 3367 +5: 3368 +5: 3369 +5: 3370 +5: 3371 +5: 3372 +5: 3373 +5: 3374 +5: 3375 +5: 3376 +5: 3377 +5: 3378 +5: 3379 +5: 3380 +5: 3381 +4: 3026 +4: 3027 +4: 3028 +4: 3029 +4: 3030 +4: 3031 +4: 3032 +4: 3033 +4: 3034 +4: 3035 +4: 3036 +4: 3037 +4: 3038 +4: 3039 +4: 3040 +4: 3041 +4: 3042 +4: 3043 +4: 3044 +4: 3045 +4: 3046 +4: 3047 +4: 3048 +4: 3049 +4: 3050 +4: 3051 +4: 3052 +4: 3053 +4: 3054 +4: 3055 +4: 3056 +4: 3057 +4: 3058 +4: 3059 +4: 3060 +4: 3061 +4: 3062 +4: 3063 +4: 3064 +4: 3065 +4: 3066 +4: 3067 +4: 3068 +4: 3069 +4: 3070 +4: 3071 +4: 3072 +4: 3073 +4: 3074 +4: 3075 +4: 3076 +4: 3077 +4: 3078 +4: 3079 +4: 3080 +4: 3081 +4: 3082 +4: 3083 +4: 3084 +4: 3085 +4: 3086 +4: 3087 +4: 3088 +4: 3089 +4: 3090 +4: 3091 +4: 3092 +4: 3093 +4: 3094 +4: 3095 +4: 3096 +4: 3097 +4: 3098 +4: 3099 +4: 3100 +4: 3101 +4: 3102 +4: 3103 +4: 3104 +4: 3105 +4: 3106 +4: 3107 +4: 3108 +4: 3109 +4: 3110 +4: 3111 +4: 3112 +4: 3113 +4: 3114 +4: 3115 +4: 3116 +4: 3117 +4: 3118 +4: 3119 +4: 3120 +4: 3121 +4: 3122 +4: 3123 +4: 3124 +4: 3125 +4: 3126 +4: 3127 +4: 3128 +4: 3129 +4: 3130 +4: 3131 +4: 3132 +4: 3133 +4: 3134 +4: 3135 +4: 3136 +4: 3137 +4: 3138 +4: 3139 +4: 3140 +4: 3141 +4: 3142 +4: 3143 +4: 3144 +4: 3145 +4: 3146 +4: 3147 +4: 3148 +4: 3149 +4: 3150 +4: 3151 +4: 3152 +4: 3153 +4: 3154 +4: 3155 +4: 3156 +4: 3157 +4: 3158 +4: 3159 +4: 3160 +4: 3161 +4: 3162 +4: 3163 +4: 3164 +4: 3165 +4: 3166 +4: 3167 +4: 3168 +4: 3169 +4: 3170 +4: 3171 +4: 3172 +4: 3173 +4: 3174 +4: 3175 +4: 3176 +4: 3177 +4: 3178 +4: 3179 +4: 3180 +4: 3181 +4: 3182 +4: 3183 +4: 3184 +4: 3185 +4: 3186 +4: 3187 +4: 3188 +4: 3189 +4: 3190 +4: 3191 +4: 3192 +4: 3193 +4: 3194 +4: 3195 +4: 3196 +4: 3197 +4: 3198 +4: 3199 +4: 3200 +4: 3201 +4: 3202 +4: 3203 +4: 3204 +4: 3205 +4: 3206 +4: 3207 +4: 3208 +4: 3209 +4: 3210 +4: 3211 +4: 3212 +4: 3213 +4: 3214 +4: 3215 +4: 3216 +4: 3217 +4: 3218 +4: 3219 +4: 3220 +4: 3221 +4: 3222 +4: 3223 +4: 3224 +4: 3225 +4: 3226 +4: 3227 +4: 3228 +4: 3229 +4: 3230 +4: 3231 +4: 3232 +4: 3233 +4: 3234 +4: 3235 +4: 3236 +4: 3237 +4: 3238 +4: 3239 +4: 3240 +4: 3241 +4: 3242 +4: 3243 +4: 3244 +4: 3245 +4: 3246 +4: 3247 +4: 3248 +4: 3249 +4: 3250 +4: 3251 +4: 3252 +4: 3253 +4: 3254 +4: 3255 +4: 3256 +4: 3257 +4: 3258 +4: 3259 +4: 3260 +4: 3261 +4: 3262 +4: 3263 +4: 3264 +4: 3265 +4: 3266 +4: 3267 +4: 3268 +4: 3269 +4: 3270 +4: 3271 +4: 3272 +4: 3273 +4: 3274 +4: 3275 +4: 3276 +4: 3277 +4: 3278 +4: 3279 +4: 3280 +4: 3281 +4: 3282 +5: 3382 +5: 3383 +5: 3384 +5: 3385 +5: 3386 +5: 3387 +5: 3388 +5: 3389 +5: 3390 +5: 3391 +5: 3392 +5: 3393 +5: 3394 +5: 3395 +5: 3396 +5: 3397 +5: 3398 +5: 3399 +5: 3400 +5: 3401 +5: 3402 +5: 3403 +5: 3404 +5: 3405 +5: 3406 +5: 3407 +5: 3408 +5: 3409 +5: 3410 +5: 3411 +5: 3412 +5: 3413 +5: 3414 +5: 3415 +5: 3416 +5: 3417 +5: 3418 +5: 3419 +5: 3420 +5: 3421 +5: 3422 +5: 3423 +5: 3424 +5: 3425 +5: 3426 +5: 3427 +5: 3428 +5: 3429 +5: 3430 +5: 3431 +5: 3432 +5: 3433 +5: 3434 +5: 3435 +5: 3436 +5: 3437 +5: 3438 +5: 3439 +5: 3440 +5: 3441 +5: 3442 +5: 3443 +5: 3444 +5: 3445 +5: 3446 +5: 3447 +5: 3448 +5: 3449 +5: 3450 +5: 3451 +5: 3452 +5: 3453 +5: 3454 +5: 3455 +5: 3456 +5: 3457 +5: 3458 +5: 3459 +5: 3460 +5: 3461 +5: 3462 +5: 3463 +5: 3464 +5: 3465 +5: 3466 +5: 3467 +5: 3468 +5: 3469 +5: 3470 +5: 3471 +5: 3472 +5: 3473 +5: 3474 +5: 3475 +5: 3476 +5: 3477 +5: 3478 +5: 3479 +5: 3480 +5: 3481 +5: 3482 +5: 3483 +5: 3484 +5: 3485 +5: 3486 +5: 3487 +5: 3488 +5: 3489 +5: 3490 +5: 3491 +5: 3492 +5: 3493 +5: 3494 +5: 3495 +5: 3496 +5: 3497 +5: 3498 +5: 3499 +5: 3500 +5: 3501 +5: 3502 +5: 3503 +5: 3504 +5: 3505 +5: 3506 +5: 3507 +5: 3508 +5: 3509 +5: 3510 +5: 3511 +5: 3512 +5: 3513 +5: 3514 +5: 3515 +5: 3516 +5: 3517 +5: 3518 +5: 3519 +5: 3520 +5: 3521 +5: 3522 +5: 3523 +5: 3524 +5: 3525 +5: 3526 +5: 3527 +5: 3528 +5: 3529 +5: 3530 +5: 3531 +5: 3532 +5: 3533 +5: 3534 +5: 3535 +5: 3536 +5: 3537 +5: 3538 +5: 3539 +5: 3540 +5: 3541 +5: 3542 +5: 3543 +5: 3544 +5: 3545 +5: 3546 +5: 3547 +5: 3548 +5: 3549 +5: 3550 +5: 3551 +5: 3552 +5: 3553 +5: 3554 +5: 3555 +5: 3556 +5: 3557 +5: 3558 +5: 3559 +5: 3560 +5: 3561 +5: 3562 +5: 3563 +5: 3564 +5: 3565 +5: 3566 +5: 3567 +5: 3568 +5: 3569 +5: 3570 +5: 3571 +5: 3572 +5: 3573 +5: 3574 +5: 3575 +5: 3576 +5: 3577 +5: 3578 +5: 3579 +5: 3580 +5: 3581 +5: 3582 +5: 3583 +5: 3584 +5: 3585 +5: 3586 +5: 3587 +5: 3588 +5: 3589 +5: 3590 +5: 3591 +5: 3592 +5: 3593 +5: 3594 +5: 3595 +5: 3596 +5: 3597 +5: 3598 +5: 3599 +5: 3600 +5: 3601 +5: 3602 +5: 3603 +5: 3604 +5: 3605 +5: 3606 +5: 3607 +5: 3608 +5: 3609 +5: 3610 +5: 3611 +5: 3612 +5: 3613 +5: 3614 +5: 3615 +5: 3616 +5: 3617 +5: 3618 +5: 3619 +5: 3620 +5: 3621 +5: 3622 +5: 3623 +5: 3624 +5: 3625 +5: 3626 +5: 3627 +5: 3628 +5: 3629 +5: 3630 +5: 3631 +5: 3632 +5: 3633 +5: 3634 +5: 3635 +5: 3636 +5: 3637 +5: 3638 +5: 3639 +5: 3640 +5: 3641 +5: 3642 +5: 3643 +5: 3644 +5: 3645 +5: 3646 +5: 3647 +5: 3648 +5: 3649 +5: 3650 +5: 3651 +5: 3652 +5: 3653 +5: 3654 +5: 3655 +5: 3656 +5: 3657 +5: 3658 +5: 3659 +5: 3660 +5: 3661 +5: 3662 +5: 3663 +5: 3664 +5: 3665 +5: 3666 +5: 3667 +5: 3668 +5: 3669 +5: 3670 +5: 3671 +4: 3283 +4: 3284 +4: 3285 +4: 3286 +4: 3287 +4: 3288 +4: 3289 +4: 3290 +4: 3291 +4: 3292 +4: 3293 +4: 3294 +4: 3295 +4: 3296 +4: 3297 +4: 3298 +4: 3299 +4: 3300 +4: 3301 +4: 3302 +4: 3303 +4: 3304 +4: 3305 +4: 3306 +4: 3307 +4: 3308 +4: 3309 +4: 3310 +4: 3311 +4: 3312 +4: 3313 +4: 3314 +4: 3315 +4: 3316 +4: 3317 +4: 3318 +4: 3319 +4: 3320 +4: 3321 +4: 3322 +4: 3323 +4: 3324 +4: 3325 +4: 3326 +4: 3327 +4: 3328 +4: 3329 +4: 3330 +4: 3331 +4: 3332 +4: 3333 +4: 3334 +4: 3335 +4: 3336 +4: 3337 +4: 3338 +4: 3339 +4: 3340 +4: 3341 +4: 3342 +4: 3343 +4: 3344 +4: 3345 +4: 3346 +4: 3347 +4: 3348 +4: 3349 +4: 3350 +4: 3351 +4: 3352 +4: 3353 +4: 3354 +4: 3355 +4: 3356 +4: 3357 +4: 3358 +4: 3359 +4: 3360 +4: 3361 +4: 3362 +4: 3363 +4: 3364 +4: 3365 +4: 3366 +4: 3367 +4: 3368 +4: 3369 +4: 3370 +4: 3371 +4: 3372 +4: 3373 +4: 3374 +4: 3375 +4: 3376 +4: 3377 +4: 3378 +4: 3379 +4: 3380 +4: 3381 +4: 3382 +4: 3383 +4: 3384 +4: 3385 +4: 3386 +4: 3387 +4: 3388 +4: 3389 +4: 3390 +4: 3391 +4: 3392 +4: 3393 +4: 3394 +4: 3395 +4: 3396 +4: 3397 +4: 3398 +4: 3399 +4: 3400 +4: 3401 +4: 3402 +4: 3403 +4: 3404 +4: 3405 +4: 3406 +4: 3407 +4: 3408 +4: 3409 +4: 3410 +4: 3411 +4: 3412 +4: 3413 +4: 3414 +4: 3415 +4: 3416 +4: 3417 +4: 3418 +4: 3419 +4: 3420 +4: 3421 +4: 3422 +4: 3423 +4: 3424 +4: 3425 +4: 3426 +4: 3427 +4: 3428 +4: 3429 +4: 3430 +4: 3431 +4: 3432 +4: 3433 +4: 3434 +4: 3435 +4: 3436 +4: 3437 +4: 3438 +4: 3439 +4: 3440 +4: 3441 +4: 3442 +4: 3443 +4: 3444 +4: 3445 +4: 3446 +4: 3447 +4: 3448 +4: 3449 +4: 3450 +4: 3451 +4: 3452 +4: 3453 +4: 3454 +4: 3455 +4: 3456 +4: 3457 +4: 3458 +4: 3459 +4: 3460 +4: 3461 +4: 3462 +4: 3463 +4: 3464 +4: 3465 +4: 3466 +4: 3467 +4: 3468 +4: 3469 +4: 3470 +4: 3471 +4: 3472 +4: 3473 +4: 3474 +4: 3475 +4: 3476 +4: 3477 +4: 3478 +4: 3479 +4: 3480 +4: 3481 +4: 3482 +4: 3483 +4: 3484 +4: 3485 +4: 3486 +4: 3487 +4: 3488 +4: 3489 +4: 3490 +4: 3491 +4: 3492 +4: 3493 +4: 3494 +4: 3495 +4: 3496 +4: 3497 +4: 3498 +4: 3499 +4: 3500 +4: 3501 +4: 3502 +4: 3503 +4: 3504 +4: 3505 +4: 3506 +4: 3507 +4: 3508 +4: 3509 +4: 3510 +4: 3511 +4: 3512 +4: 3513 +4: 3514 +4: 3515 +4: 3516 +4: 3517 +4: 3518 +4: 3519 +4: 3520 +4: 3521 +4: 3522 +4: 3523 +4: 3524 +4: 3525 +4: 3526 +4: 3527 +4: 3528 +4: 3529 +4: 3530 +4: 3531 +4: 3532 +4: 3533 +4: 3534 +4: 3535 +4: 3536 +4: 3537 +4: 3538 +4: 3539 +4: 3540 +4: 3541 +4: 3542 +4: 3543 +4: 3544 +4: 3545 +4: 3546 +4: 3547 +4: 3548 +4: 3549 +4: 3550 +4: 3551 +4: 3552 +4: 3553 +4: 3554 +4: 3555 +4: 3556 +4: 3557 +4: 3558 +4: 3559 +4: 3560 +4: 3561 +4: 3562 +4: 3563 +4: 3564 +4: 3565 +4: 3566 +4: 3567 +4: 3568 +4: 3569 +4: 3570 +4: 3571 +4: 3572 +4: 3573 +4: 3574 +4: 3575 +4: 3576 +4: 3577 +4: 3578 +4: 3579 +4: 3580 +4: 3581 +4: 3582 +4: 3583 +4: 3584 +4: 3585 +4: 3586 +4: 3587 +4: 3588 +4: 3589 +4: 3590 +4: 3591 +4: 3592 +4: 3593 +4: 3594 +4: 3595 +4: 3596 +4: 3597 +4: 3598 +4: 3599 +4: 3600 +4: 3601 +4: 3602 +4: 3603 +4: 3604 +5: 3672 +5: 3673 +5: 3674 +5: 3675 +5: 3676 +5: 3677 +5: 3678 +5: 3679 +5: 3680 +5: 3681 +5: 3682 +5: 3683 +5: 3684 +5: 3685 +5: 3686 +5: 3687 +5: 3688 +5: 3689 +5: 3690 +5: 3691 +5: 3692 +5: 3693 +5: 3694 +5: 3695 +5: 3696 +5: 3697 +5: 3698 +5: 3699 +5: 3700 +5: 3701 +5: 3702 +5: 3703 +5: 3704 +5: 3705 +5: 3706 +5: 3707 +5: 3708 +5: 3709 +5: 3710 +5: 3711 +5: 3712 +5: 3713 +5: 3714 +5: 3715 +5: 3716 +5: 3717 +5: 3718 +5: 3719 +5: 3720 +5: 3721 +5: 3722 +5: 3723 +5: 3724 +5: 3725 +5: 3726 +5: 3727 +5: 3728 +5: 3729 +5: 3730 +5: 3731 +5: 3732 +5: 3733 +5: 3734 +5: 3735 +5: 3736 +5: 3737 +5: 3738 +5: 3739 +5: 3740 +5: 3741 +5: 3742 +5: 3743 +5: 3744 +5: 3745 +5: 3746 +5: 3747 +5: 3748 +5: 3749 +5: 3750 +5: 3751 +5: 3752 +5: 3753 +5: 3754 +5: 3755 +5: 3756 +5: 3757 +5: 3758 +5: 3759 +5: 3760 +5: 3761 +5: 3762 +5: 3763 +5: 3764 +5: 3765 +5: 3766 +5: 3767 +5: 3768 +5: 3769 +5: 3770 +5: 3771 +5: 3772 +5: 3773 +5: 3774 +5: 3775 +5: 3776 +5: 3777 +5: 3778 +5: 3779 +5: 3780 +5: 3781 +5: 3782 +5: 3783 +5: 3784 +5: 3785 +5: 3786 +5: 3787 +5: 3788 +5: 3789 +5: 3790 +5: 3791 +5: 3792 +5: 3793 +5: 3794 +5: 3795 +5: 3796 +5: 3797 +5: 3798 +5: 3799 +5: 3800 +5: 3801 +5: 3802 +5: 3803 +5: 3804 +5: 3805 +5: 3806 +5: 3807 +5: 3808 +5: 3809 +5: 3810 +5: 3811 +5: 3812 +5: 3813 +5: 3814 +5: 3815 +5: 3816 +5: 3817 +5: 3818 +5: 3819 +5: 3820 +5: 3821 +5: 3822 +5: 3823 +5: 3824 +5: 3825 +5: 3826 +5: 3827 +5: 3828 +5: 3829 +5: 3830 +5: 3831 +5: 3832 +5: 3833 +5: 3834 +5: 3835 +5: 3836 +5: 3837 +5: 3838 +5: 3839 +5: 3840 +5: 3841 +5: 3842 +5: 3843 +5: 3844 +5: 3845 +5: 3846 +5: 3847 +5: 3848 +5: 3849 +5: 3850 +5: 3851 +5: 3852 +5: 3853 +5: 3854 +5: 3855 +5: 3856 +5: 3857 +5: 3858 +5: 3859 +5: 3860 +5: 3861 +5: 3862 +5: 3863 +5: 3864 +5: 3865 +5: 3866 +5: 3867 +5: 3868 +5: 3869 +5: 3870 +5: 3871 +5: 3872 +5: 3873 +5: 3874 +5: 3875 +5: 3876 +5: 3877 +5: 3878 +5: 3879 +5: 3880 +5: 3881 +5: 3882 +5: 3883 +5: 3884 +5: 3885 +5: 3886 +5: 3887 +5: 3888 +5: 3889 +5: 3890 +5: 3891 +5: 3892 +5: 3893 +5: 3894 +5: 3895 +5: 3896 +5: 3897 +5: 3898 +5: 3899 +5: 3900 +5: 3901 +5: 3902 +5: 3903 +5: 3904 +5: 3905 +5: 3906 +5: 3907 +5: 3908 +5: 3909 +5: 3910 +5: 3911 +5: 3912 +5: 3913 +5: 3914 +5: 3915 +5: 3916 +5: 3917 +5: 3918 +5: 3919 +5: 3920 +5: 3921 +5: 3922 +5: 3923 +5: 3924 +5: 3925 +5: 3926 +5: 3927 +5: 3928 +5: 3929 +5: 3930 +5: 3931 +5: 3932 +5: 3933 +5: 3934 +5: 3935 +5: 3936 +5: 3937 +5: 3938 +5: 3939 +5: 3940 +5: 3941 +5: 3942 +5: 3943 +5: 3944 +5: 3945 +5: 3946 +5: 3947 +5: 3948 +5: 3949 +5: 3950 +5: 3951 +5: 3952 +5: 3953 +5: 3954 +5: 3955 +5: 3956 +5: 3957 +5: 3958 +5: 3959 +5: 3960 +5: 3961 +5: 3962 +5: 3963 +5: 3964 +5: 3965 +5: 3966 +5: 3967 +5: 3968 +5: 3969 +5: 3970 +5: 3971 +5: 3972 +5: 3973 +5: 3974 +5: 3975 +5: 3976 +5: 3977 +5: 3978 +5: 3979 +5: 3980 +5: 3981 +5: 3982 +5: 3983 +5: 3984 +5: 3985 +5: 3986 +5: 3987 +5: 3988 +5: 3989 +5: 3990 +5: 3991 +5: 3992 +5: 3993 +5: 3994 +5: 3995 +5: 3996 +5: 3997 +5: 3998 +5: 3999 +5: 4000 +5: 4001 +5: 4002 +5: 4003 +5: 4004 +5: 4005 +5: 4006 +5: 4007 +5: 4008 +5: 4009 +5: 4010 +5: 4011 +5: 4012 +5: 4013 +5: 4014 +5: 4015 +5: 4016 +5: 4017 +5: 4018 +5: 4019 +5: 4020 +5: 4021 +5: 4022 +5: 4023 +5: 4024 +5: 4025 +5: 4026 +5: 4027 +5: 4028 +5: 4029 +5: 4030 +5: 4031 +5: 4032 +5: 4033 +5: 4034 +5: 4035 +5: 4036 +5: 4037 +5: 4038 +5: 4039 +5: 4040 +5: 4041 +5: 4042 +5: 4043 +5: 4044 +5: 4045 +5: 4046 +5: 4047 +5: 4048 +5: 4049 +5: 4050 +5: 4051 +5: 4052 +5: 4053 +5: 4054 +5: 4055 +5: 4056 +5: 4057 +5: 4058 +5: 4059 +5: 4060 +5: 4061 +5: 4062 +5: 4063 +5: 4064 +5: 4065 +5: 4066 +5: 4067 +5: 4068 +5: 4069 +5: 4070 +5: 4071 +5: 4072 +5: 4073 +5: 4074 +5: 4075 +5: 4076 +5: 4077 +5: 4078 +5: 4079 +5: 4080 +5: 4081 +5: 4082 +5: 4083 +5: 4084 +5: 4085 +5: 4086 +5: 4087 +5: 4088 +5: 4089 +5: 4090 +5: 4091 +5: 4092 +5: 4093 +5: 4094 +5: 4095 +5: 4096 +5: 4097 +5: 4098 +5: 4099 +5: 4100 +5: 4101 +5: 4102 +5: 4103 +5: 4104 +5: 4105 +5: 4106 +5: 4107 +5: 4108 +5: 4109 +5: 4110 +5: 4111 +5: 4112 +5: 4113 +5: 4114 +4: 3605 +4: 3606 +4: 3607 +4: 3608 +4: 3609 +4: 3610 +4: 3611 +4: 3612 +4: 3613 +4: 3614 +4: 3615 +4: 3616 +4: 3617 +4: 3618 +4: 3619 +4: 3620 +4: 3621 +4: 3622 +4: 3623 +4: 3624 +4: 3625 +4: 3626 +4: 3627 +4: 3628 +4: 3629 +4: 3630 +4: 3631 +4: 3632 +4: 3633 +4: 3634 +4: 3635 +4: 3636 +4: 3637 +4: 3638 +4: 3639 +4: 3640 +4: 3641 +4: 3642 +4: 3643 +4: 3644 +4: 3645 +4: 3646 +4: 3647 +4: 3648 +4: 3649 +4: 3650 +4: 3651 +4: 3652 +4: 3653 +4: 3654 +4: 3655 +4: 3656 +4: 3657 +4: 3658 +4: 3659 +4: 3660 +4: 3661 +4: 3662 +4: 3663 +4: 3664 +4: 3665 +4: 3666 +4: 3667 +4: 3668 +4: 3669 +4: 3670 +4: 3671 +4: 3672 +4: 3673 +4: 3674 +4: 3675 +4: 3676 +4: 3677 +4: 3678 +4: 3679 +4: 3680 +4: 3681 +4: 3682 +4: 3683 +4: 3684 +4: 3685 +4: 3686 +4: 3687 +4: 3688 +4: 3689 +4: 3690 +4: 3691 +4: 3692 +4: 3693 +4: 3694 +4: 3695 +4: 3696 +4: 3697 +4: 3698 +4: 3699 +4: 3700 +4: 3701 +4: 3702 +4: 3703 +4: 3704 +4: 3705 +4: 3706 +4: 3707 +4: 3708 +4: 3709 +4: 3710 +4: 3711 +4: 3712 +4: 3713 +4: 3714 +4: 3715 +4: 3716 +4: 3717 +4: 3718 +4: 3719 +4: 3720 +4: 3721 +4: 3722 +4: 3723 +4: 3724 +4: 3725 +4: 3726 +4: 3727 +4: 3728 +4: 3729 +4: 3730 +4: 3731 +4: 3732 +4: 3733 +4: 3734 +4: 3735 +4: 3736 +4: 3737 +4: 3738 +4: 3739 +4: 3740 +4: 3741 +4: 3742 +4: 3743 +4: 3744 +4: 3745 +4: 3746 +4: 3747 +4: 3748 +4: 3749 +4: 3750 +4: 3751 +4: 3752 +4: 3753 +4: 3754 +4: 3755 +4: 3756 +4: 3757 +4: 3758 +4: 3759 +4: 3760 +4: 3761 +4: 3762 +4: 3763 +4: 3764 +4: 3765 +4: 3766 +4: 3767 +4: 3768 +4: 3769 +4: 3770 +4: 3771 +4: 3772 +4: 3773 +4: 3774 +4: 3775 +4: 3776 +4: 3777 +4: 3778 +4: 3779 +4: 3780 +4: 3781 +4: 3782 +4: 3783 +4: 3784 +4: 3785 +4: 3786 +4: 3787 +4: 3788 +4: 3789 +4: 3790 +4: 3791 +4: 3792 +4: 3793 +4: 3794 +4: 3795 +4: 3796 +4: 3797 +4: 3798 +4: 3799 +4: 3800 +4: 3801 +4: 3802 +4: 3803 +4: 3804 +4: 3805 +4: 3806 +4: 3807 +4: 3808 +4: 3809 +4: 3810 +4: 3811 +4: 3812 +4: 3813 +4: 3814 +4: 3815 +4: 3816 +4: 3817 +4: 3818 +4: 3819 +4: 3820 +4: 3821 +4: 3822 +4: 3823 +4: 3824 +4: 3825 +4: 3826 +4: 3827 +4: 3828 +4: 3829 +4: 3830 +4: 3831 +4: 3832 +4: 3833 +4: 3834 +4: 3835 +4: 3836 +4: 3837 +4: 3838 +4: 3839 +4: 3840 +4: 3841 +4: 3842 +4: 3843 +4: 3844 +4: 3845 +4: 3846 +4: 3847 +4: 3848 +4: 3849 +4: 3850 +4: 3851 +4: 3852 +4: 3853 +4: 3854 +4: 3855 +4: 3856 +4: 3857 +4: 3858 +4: 3859 +4: 3860 +4: 3861 +4: 3862 +4: 3863 +4: 3864 +4: 3865 +4: 3866 +4: 3867 +4: 3868 +4: 3869 +4: 3870 +4: 3871 +4: 3872 +4: 3873 +4: 3874 +4: 3875 +4: 3876 +4: 3877 +4: 3878 +4: 3879 +4: 3880 +4: 3881 +4: 3882 +4: 3883 +4: 3884 +4: 3885 +4: 3886 +4: 3887 +4: 3888 +4: 3889 +4: 3890 +4: 3891 +4: 3892 +4: 3893 +4: 3894 +4: 3895 +4: 3896 +4: 3897 +4: 3898 +4: 3899 +4: 3900 +4: 3901 +4: 3902 +4: 3903 +4: 3904 +4: 3905 +4: 3906 +4: 3907 +4: 3908 +4: 3909 +4: 3910 +4: 3911 +4: 3912 +4: 3913 +4: 3914 +4: 3915 +4: 3916 +4: 3917 +4: 3918 +4: 3919 +4: 3920 +4: 3921 +4: 3922 +4: 3923 +4: 3924 +4: 3925 +4: 3926 +4: 3927 +4: 3928 +4: 3929 +4: 3930 +4: 3931 +4: 3932 +4: 3933 +4: 3934 +4: 3935 +4: 3936 +4: 3937 +4: 3938 +4: 3939 +4: 3940 +4: 3941 +4: 3942 +4: 3943 +4: 3944 +4: 3945 +4: 3946 +4: 3947 +4: 3948 +4: 3949 +4: 3950 +4: 3951 +4: 3952 +4: 3953 +4: 3954 +4: 3955 +4: 3956 +4: 3957 +4: 3958 +4: 3959 +4: 3960 +4: 3961 +4: 3962 +4: 3963 +4: 3964 +4: 3965 +4: 3966 +4: 3967 +4: 3968 +4: 3969 +4: 3970 +4: 3971 +4: 3972 +4: 3973 +4: 3974 +4: 3975 +4: 3976 +4: 3977 +4: 3978 +4: 3979 +4: 3980 +4: 3981 +4: 3982 +4: 3983 +4: 3984 +4: 3985 +4: 3986 +4: 3987 +4: 3988 +4: 3989 +4: 3990 +4: 3991 +4: 3992 +4: 3993 +4: 3994 +4: 3995 +4: 3996 +4: 3997 +4: 3998 +4: 3999 +4: 4000 +4: 4001 +4: 4002 +4: 4003 +4: 4004 +4: 4005 +4: 4006 +4: 4007 +4: 4008 +4: 4009 +4: 4010 +4: 4011 +4: 4012 +4: 4013 +4: 4014 +4: 4015 +4: 4016 +4: 4017 +4: 4018 +4: 4019 +4: 4020 +5: 4115 +5: 4116 +5: 4117 +5: 4118 +5: 4119 +5: 4120 +5: 4121 +5: 4122 +5: 4123 +5: 4124 +5: 4125 +5: 4126 +5: 4127 +5: 4128 +5: 4129 +5: 4130 +5: 4131 +5: 4132 +5: 4133 +5: 4134 +5: 4135 +5: 4136 +5: 4137 +5: 4138 +5: 4139 +5: 4140 +5: 4141 +5: 4142 +5: 4143 +5: 4144 +5: 4145 +5: 4146 +5: 4147 +5: 4148 +5: 4149 +5: 4150 +5: 4151 +5: 4152 +5: 4153 +5: 4154 +5: 4155 +5: 4156 +5: 4157 +5: 4158 +5: 4159 +5: 4160 +5: 4161 +5: 4162 +5: 4163 +5: 4164 +5: 4165 +5: 4166 +5: 4167 +5: 4168 +5: 4169 +5: 4170 +5: 4171 +5: 4172 +5: 4173 +5: 4174 +5: 4175 +5: 4176 +5: 4177 +5: 4178 +5: 4179 +5: 4180 +5: 4181 +5: 4182 +5: 4183 +5: 4184 +5: 4185 +5: 4186 +5: 4187 +5: 4188 +5: 4189 +5: 4190 +5: 4191 +5: 4192 +5: 4193 +5: 4194 +5: 4195 +5: 4196 +5: 4197 +5: 4198 +5: 4199 +5: 4200 +5: 4201 +5: 4202 +5: 4203 +5: 4204 +5: 4205 +5: 4206 +5: 4207 +5: 4208 +5: 4209 +5: 4210 +5: 4211 +5: 4212 +5: 4213 +5: 4214 +5: 4215 +5: 4216 +5: 4217 +5: 4218 +5: 4219 +5: 4220 +5: 4221 +5: 4222 +5: 4223 +5: 4224 +5: 4225 +5: 4226 +5: 4227 +5: 4228 +5: 4229 +5: 4230 +5: 4231 +5: 4232 +5: 4233 +5: 4234 +5: 4235 +5: 4236 +5: 4237 +5: 4238 +5: 4239 +5: 4240 +5: 4241 +5: 4242 +5: 4243 +5: 4244 +5: 4245 +5: 4246 +5: 4247 +5: 4248 +5: 4249 +5: 4250 +5: 4251 +5: 4252 +5: 4253 +5: 4254 +5: 4255 +5: 4256 +5: 4257 +5: 4258 +5: 4259 +5: 4260 +5: 4261 +5: 4262 +5: 4263 +5: 4264 +5: 4265 +5: 4266 +5: 4267 +5: 4268 +5: 4269 +5: 4270 +5: 4271 +5: 4272 +5: 4273 +5: 4274 +5: 4275 +5: 4276 +5: 4277 +5: 4278 +5: 4279 +5: 4280 +5: 4281 +5: 4282 +5: 4283 +5: 4284 +5: 4285 +5: 4286 +5: 4287 +5: 4288 +5: 4289 +5: 4290 +5: 4291 +5: 4292 +5: 4293 +5: 4294 +5: 4295 +5: 4296 +5: 4297 +5: 4298 +5: 4299 +5: 4300 +5: 4301 +5: 4302 +5: 4303 +5: 4304 +5: 4305 +5: 4306 +5: 4307 +4: 4021 +4: 4022 +4: 4023 +4: 4024 +4: 4025 +4: 4026 +4: 4027 +4: 4028 +4: 4029 +4: 4030 +4: 4031 +4: 4032 +4: 4033 +4: 4034 +4: 4035 +4: 4036 +4: 4037 +4: 4038 +4: 4039 +4: 4040 +4: 4041 +4: 4042 +4: 4043 +4: 4044 +4: 4045 +4: 4046 +4: 4047 +4: 4048 +4: 4049 +4: 4050 +4: 4051 +4: 4052 +4: 4053 +4: 4054 +4: 4055 +4: 4056 +4: 4057 +4: 4058 +4: 4059 +4: 4060 +4: 4061 +4: 4062 +4: 4063 +4: 4064 +4: 4065 +4: 4066 +4: 4067 +4: 4068 +4: 4069 +4: 4070 +4: 4071 +4: 4072 +4: 4073 +4: 4074 +4: 4075 +4: 4076 +4: 4077 +4: 4078 +4: 4079 +4: 4080 +4: 4081 +4: 4082 +4: 4083 +4: 4084 +4: 4085 +4: 4086 +4: 4087 +4: 4088 +4: 4089 +4: 4090 +4: 4091 +4: 4092 +4: 4093 +4: 4094 +4: 4095 +4: 4096 +4: 4097 +4: 4098 +4: 4099 +4: 4100 +4: 4101 +4: 4102 +4: 4103 +4: 4104 +4: 4105 +4: 4106 +4: 4107 +4: 4108 +4: 4109 +4: 4110 +4: 4111 +4: 4112 +4: 4113 +4: 4114 +4: 4115 +4: 4116 +4: 4117 +4: 4118 +4: 4119 +4: 4120 +4: 4121 +4: 4122 +4: 4123 +4: 4124 +4: 4125 +4: 4126 +4: 4127 +4: 4128 +4: 4129 +4: 4130 +4: 4131 +4: 4132 +4: 4133 +4: 4134 +4: 4135 +4: 4136 +4: 4137 +4: 4138 +4: 4139 +4: 4140 +4: 4141 +4: 4142 +4: 4143 +4: 4144 +4: 4145 +4: 4146 +4: 4147 +4: 4148 +4: 4149 +4: 4150 +4: 4151 +4: 4152 +4: 4153 +4: 4154 +4: 4155 +4: 4156 +4: 4157 +4: 4158 +4: 4159 +4: 4160 +4: 4161 +4: 4162 +4: 4163 +4: 4164 +4: 4165 +4: 4166 +4: 4167 +4: 4168 +4: 4169 +4: 4170 +4: 4171 +4: 4172 +4: 4173 +4: 4174 +4: 4175 +4: 4176 +4: 4177 +4: 4178 +4: 4179 +4: 4180 +4: 4181 +4: 4182 +4: 4183 +4: 4184 +4: 4185 +4: 4186 +4: 4187 +4: 4188 +4: 4189 +4: 4190 +4: 4191 +4: 4192 +4: 4193 +4: 4194 +4: 4195 +4: 4196 +4: 4197 +4: 4198 +4: 4199 +4: 4200 +4: 4201 +4: 4202 +4: 4203 +4: 4204 +4: 4205 +4: 4206 +4: 4207 +4: 4208 +4: 4209 +4: 4210 +4: 4211 +4: 4212 +4: 4213 +4: 4214 +4: 4215 +4: 4216 +4: 4217 +4: 4218 +5: 4308 +5: 4309 +5: 4310 +5: 4311 +5: 4312 +5: 4313 +5: 4314 +5: 4315 +5: 4316 +5: 4317 +5: 4318 +5: 4319 +5: 4320 +5: 4321 +5: 4322 +5: 4323 +5: 4324 +5: 4325 +5: 4326 +5: 4327 +5: 4328 +5: 4329 +5: 4330 +5: 4331 +5: 4332 +5: 4333 +5: 4334 +5: 4335 +5: 4336 +5: 4337 +5: 4338 +5: 4339 +5: 4340 +5: 4341 +5: 4342 +5: 4343 +5: 4344 +5: 4345 +5: 4346 +5: 4347 +5: 4348 +5: 4349 +5: 4350 +5: 4351 +5: 4352 +5: 4353 +5: 4354 +5: 4355 +5: 4356 +5: 4357 +5: 4358 +5: 4359 +5: 4360 +5: 4361 +5: 4362 +5: 4363 +5: 4364 +5: 4365 +5: 4366 +5: 4367 +5: 4368 +5: 4369 +5: 4370 +5: 4371 +5: 4372 +5: 4373 +5: 4374 +5: 4375 +5: 4376 +5: 4377 +5: 4378 +5: 4379 +5: 4380 +5: 4381 +5: 4382 +5: 4383 +5: 4384 +5: 4385 +5: 4386 +5: 4387 +5: 4388 +5: 4389 +5: 4390 +5: 4391 +5: 4392 +5: 4393 +5: 4394 +5: 4395 +5: 4396 +5: 4397 +5: 4398 +5: 4399 +5: 4400 +5: 4401 +5: 4402 +5: 4403 +5: 4404 +5: 4405 +4: 4219 +4: 4220 +4: 4221 +4: 4222 +4: 4223 +4: 4224 +4: 4225 +4: 4226 +4: 4227 +4: 4228 +4: 4229 +4: 4230 +4: 4231 +4: 4232 +4: 4233 +4: 4234 +4: 4235 +4: 4236 +4: 4237 +4: 4238 +4: 4239 +4: 4240 +4: 4241 +4: 4242 +4: 4243 +4: 4244 +4: 4245 +4: 4246 +4: 4247 +4: 4248 +4: 4249 +4: 4250 +4: 4251 +4: 4252 +4: 4253 +4: 4254 +4: 4255 +4: 4256 +4: 4257 +4: 4258 +4: 4259 +4: 4260 +4: 4261 +4: 4262 +4: 4263 +4: 4264 +4: 4265 +4: 4266 +4: 4267 +4: 4268 +4: 4269 +4: 4270 +4: 4271 +4: 4272 +4: 4273 +4: 4274 +4: 4275 +4: 4276 +4: 4277 +4: 4278 +4: 4279 +4: 4280 +4: 4281 +4: 4282 +4: 4283 +4: 4284 +4: 4285 +4: 4286 +4: 4287 +4: 4288 +4: 4289 +4: 4290 +4: 4291 +4: 4292 +4: 4293 +4: 4294 +4: 4295 +4: 4296 +4: 4297 +4: 4298 +4: 4299 +4: 4300 +4: 4301 +4: 4302 +4: 4303 +4: 4304 +4: 4305 +4: 4306 +4: 4307 +4: 4308 +4: 4309 +4: 4310 +4: 4311 +4: 4312 +4: 4313 +4: 4314 +4: 4315 +4: 4316 +4: 4317 +4: 4318 +4: 4319 +4: 4320 +4: 4321 +4: 4322 +4: 4323 +4: 4324 +4: 4325 +4: 4326 +4: 4327 +4: 4328 +4: 4329 +4: 4330 +4: 4331 +4: 4332 +4: 4333 +4: 4334 +4: 4335 +4: 4336 +4: 4337 +4: 4338 +4: 4339 +4: 4340 +4: 4341 +4: 4342 +4: 4343 +4: 4344 +4: 4345 +4: 4346 +4: 4347 +4: 4348 +4: 4349 +4: 4350 +4: 4351 +4: 4352 +4: 4353 +4: 4354 +4: 4355 +4: 4356 +4: 4357 +4: 4358 +4: 4359 +4: 4360 +4: 4361 +4: 4362 +4: 4363 +4: 4364 +4: 4365 +4: 4366 +4: 4367 +4: 4368 +4: 4369 +4: 4370 +4: 4371 +4: 4372 +4: 4373 +4: 4374 +4: 4375 +4: 4376 +4: 4377 +4: 4378 +4: 4379 +4: 4380 +4: 4381 +4: 4382 +4: 4383 +4: 4384 +4: 4385 +4: 4386 +4: 4387 +4: 4388 +4: 4389 +4: 4390 +4: 4391 +4: 4392 +4: 4393 +4: 4394 +4: 4395 +4: 4396 +4: 4397 +4: 4398 +4: 4399 +4: 4400 +4: 4401 +4: 4402 +4: 4403 +4: 4404 +4: 4405 +4: 4406 +4: 4407 +4: 4408 +4: 4409 +4: 4410 +4: 4411 +4: 4412 +4: 4413 +4: 4414 +4: 4415 +4: 4416 +4: 4417 +4: 4418 +4: 4419 +4: 4420 +4: 4421 +4: 4422 +4: 4423 +4: 4424 +4: 4425 +4: 4426 +4: 4427 +4: 4428 +4: 4429 +4: 4430 +4: 4431 +4: 4432 +4: 4433 +4: 4434 +4: 4435 +4: 4436 +4: 4437 +4: 4438 +4: 4439 +4: 4440 +4: 4441 +4: 4442 +4: 4443 +4: 4444 +4: 4445 +4: 4446 +4: 4447 +4: 4448 +4: 4449 +4: 4450 +4: 4451 +4: 4452 +4: 4453 +4: 4454 +4: 4455 +4: 4456 +4: 4457 +4: 4458 +4: 4459 +4: 4460 +4: 4461 +4: 4462 +4: 4463 +4: 4464 +4: 4465 +4: 4466 +4: 4467 +4: 4468 +4: 4469 +4: 4470 +4: 4471 +4: 4472 +4: 4473 +4: 4474 +4: 4475 +4: 4476 +4: 4477 +4: 4478 +4: 4479 +4: 4480 +4: 4481 +4: 4482 +4: 4483 +4: 4484 +4: 4485 +4: 4486 +4: 4487 +4: 4488 +4: 4489 +4: 4490 +4: 4491 +4: 4492 +4: 4493 +4: 4494 +4: 4495 +4: 4496 +4: 4497 +4: 4498 +4: 4499 +4: 4500 +4: 4501 +4: 4502 +4: 4503 +4: 4504 +4: 4505 +4: 4506 +4: 4507 +4: 4508 +4: 4509 +4: 4510 +4: 4511 +4: 4512 +4: 4513 +4: 4514 +4: 4515 +4: 4516 +4: 4517 +4: 4518 +4: 4519 +4: 4520 +4: 4521 +4: 4522 +4: 4523 +4: 4524 +4: 4525 +4: 4526 +4: 4527 +4: 4528 +4: 4529 +4: 4530 +4: 4531 +4: 4532 +4: 4533 +4: 4534 +4: 4535 +4: 4536 +4: 4537 +4: 4538 +4: 4539 +4: 4540 +4: 4541 +4: 4542 +4: 4543 +4: 4544 +4: 4545 +4: 4546 +4: 4547 +4: 4548 +5: 4406 +5: 4407 +5: 4408 +5: 4409 +5: 4410 +5: 4411 +5: 4412 +5: 4413 +5: 4414 +5: 4415 +5: 4416 +5: 4417 +5: 4418 +5: 4419 +5: 4420 +5: 4421 +5: 4422 +5: 4423 +5: 4424 +5: 4425 +5: 4426 +5: 4427 +5: 4428 +5: 4429 +5: 4430 +5: 4431 +5: 4432 +5: 4433 +5: 4434 +5: 4435 +5: 4436 +5: 4437 +5: 4438 +5: 4439 +5: 4440 +5: 4441 +5: 4442 +5: 4443 +5: 4444 +5: 4445 +5: 4446 +5: 4447 +5: 4448 +5: 4449 +5: 4450 +5: 4451 +5: 4452 +5: 4453 +5: 4454 +5: 4455 +5: 4456 +5: 4457 +5: 4458 +5: 4459 +5: 4460 +5: 4461 +5: 4462 +5: 4463 +5: 4464 +5: 4465 +5: 4466 +5: 4467 +5: 4468 +5: 4469 +5: 4470 +5: 4471 +5: 4472 +5: 4473 +5: 4474 +5: 4475 +5: 4476 +5: 4477 +5: 4478 +5: 4479 +5: 4480 +5: 4481 +5: 4482 +5: 4483 +5: 4484 +5: 4485 +5: 4486 +5: 4487 +5: 4488 +5: 4489 +5: 4490 +5: 4491 +5: 4492 +5: 4493 +5: 4494 +5: 4495 +5: 4496 +5: 4497 +5: 4498 +5: 4499 +5: 4500 +5: 4501 +5: 4502 +5: 4503 +5: 4504 +5: 4505 +5: 4506 +5: 4507 +5: 4508 +5: 4509 +5: 4510 +5: 4511 +5: 4512 +5: 4513 +5: 4514 +5: 4515 +5: 4516 +5: 4517 +5: 4518 +5: 4519 +5: 4520 +5: 4521 +5: 4522 +5: 4523 +5: 4524 +5: 4525 +5: 4526 +5: 4527 +5: 4528 +5: 4529 +5: 4530 +5: 4531 +5: 4532 +5: 4533 +5: 4534 +5: 4535 +5: 4536 +5: 4537 +5: 4538 +5: 4539 +5: 4540 +5: 4541 +5: 4542 +5: 4543 +5: 4544 +5: 4545 +5: 4546 +5: 4547 +5: 4548 +5: 4549 +5: 4550 +5: 4551 +5: 4552 +5: 4553 +5: 4554 +5: 4555 +5: 4556 +5: 4557 +5: 4558 +5: 4559 +5: 4560 +5: 4561 +5: 4562 +5: 4563 +5: 4564 +5: 4565 +5: 4566 +5: 4567 +5: 4568 +5: 4569 +5: 4570 +5: 4571 +5: 4572 +5: 4573 +5: 4574 +5: 4575 +5: 4576 +5: 4577 +5: 4578 +5: 4579 +5: 4580 +5: 4581 +5: 4582 +5: 4583 +5: 4584 +5: 4585 +5: 4586 +5: 4587 +5: 4588 +5: 4589 +5: 4590 +5: 4591 +5: 4592 +5: 4593 +5: 4594 +5: 4595 +5: 4596 +5: 4597 +5: 4598 +5: 4599 +5: 4600 +5: 4601 +5: 4602 +5: 4603 +5: 4604 +5: 4605 +5: 4606 +5: 4607 +5: 4608 +5: 4609 +5: 4610 +5: 4611 +5: 4612 +5: 4613 +5: 4614 +5: 4615 +5: 4616 +5: 4617 +5: 4618 +5: 4619 +5: 4620 +5: 4621 +5: 4622 +5: 4623 +5: 4624 +5: 4625 +5: 4626 +5: 4627 +5: 4628 +5: 4629 +5: 4630 +5: 4631 +5: 4632 +5: 4633 +5: 4634 +5: 4635 +5: 4636 +5: 4637 +5: 4638 +5: 4639 +5: 4640 +5: 4641 +5: 4642 +5: 4643 +5: 4644 +5: 4645 +5: 4646 +5: 4647 +5: 4648 +5: 4649 +5: 4650 +5: 4651 +5: 4652 +5: 4653 +5: 4654 +5: 4655 +5: 4656 +5: 4657 +5: 4658 +5: 4659 +5: 4660 +5: 4661 +5: 4662 +5: 4663 +5: 4664 +5: 4665 +5: 4666 +5: 4667 +5: 4668 +5: 4669 +5: 4670 +5: 4671 +5: 4672 +5: 4673 +5: 4674 +5: 4675 +5: 4676 +5: 4677 +5: 4678 +5: 4679 +5: 4680 +5: 4681 +5: 4682 +5: 4683 +5: 4684 +5: 4685 +5: 4686 +5: 4687 +5: 4688 +5: 4689 +5: 4690 +5: 4691 +5: 4692 +5: 4693 +5: 4694 +5: 4695 +5: 4696 +5: 4697 +5: 4698 +5: 4699 +5: 4700 +5: 4701 +5: 4702 +5: 4703 +5: 4704 +5: 4705 +5: 4706 +5: 4707 +5: 4708 +5: 4709 +5: 4710 +5: 4711 +5: 4712 +5: 4713 +5: 4714 +5: 4715 +5: 4716 +5: 4717 +5: 4718 +4: 4549 +4: 4550 +4: 4551 +4: 4552 +4: 4553 +4: 4554 +4: 4555 +4: 4556 +4: 4557 +4: 4558 +4: 4559 +4: 4560 +4: 4561 +4: 4562 +4: 4563 +4: 4564 +4: 4565 +4: 4566 +4: 4567 +4: 4568 +4: 4569 +4: 4570 +4: 4571 +4: 4572 +4: 4573 +4: 4574 +4: 4575 +4: 4576 +4: 4577 +4: 4578 +4: 4579 +4: 4580 +4: 4581 +4: 4582 +4: 4583 +4: 4584 +4: 4585 +4: 4586 +4: 4587 +4: 4588 +4: 4589 +4: 4590 +4: 4591 +4: 4592 +4: 4593 +4: 4594 +4: 4595 +4: 4596 +4: 4597 +4: 4598 +4: 4599 +4: 4600 +4: 4601 +4: 4602 +4: 4603 +4: 4604 +4: 4605 +4: 4606 +4: 4607 +4: 4608 +4: 4609 +4: 4610 +4: 4611 +4: 4612 +4: 4613 +4: 4614 +4: 4615 +4: 4616 +4: 4617 +4: 4618 +4: 4619 +4: 4620 +4: 4621 +4: 4622 +4: 4623 +4: 4624 +4: 4625 +4: 4626 +4: 4627 +4: 4628 +4: 4629 +4: 4630 +4: 4631 +4: 4632 +4: 4633 +4: 4634 +4: 4635 +4: 4636 +4: 4637 +4: 4638 +4: 4639 +4: 4640 +4: 4641 +4: 4642 +4: 4643 +4: 4644 +4: 4645 +4: 4646 +4: 4647 +4: 4648 +4: 4649 +4: 4650 +4: 4651 +4: 4652 +4: 4653 +4: 4654 +4: 4655 +4: 4656 +4: 4657 +4: 4658 +4: 4659 +4: 4660 +4: 4661 +4: 4662 +4: 4663 +4: 4664 +4: 4665 +4: 4666 +4: 4667 +4: 4668 +4: 4669 +4: 4670 +4: 4671 +4: 4672 +4: 4673 +4: 4674 +4: 4675 +4: 4676 +4: 4677 +4: 4678 +4: 4679 +4: 4680 +4: 4681 +4: 4682 +4: 4683 +4: 4684 +4: 4685 +4: 4686 +4: 4687 +4: 4688 +4: 4689 +4: 4690 +4: 4691 +4: 4692 +4: 4693 +4: 4694 +4: 4695 +4: 4696 +4: 4697 +4: 4698 +4: 4699 +4: 4700 +4: 4701 +4: 4702 +4: 4703 +4: 4704 +4: 4705 +4: 4706 +4: 4707 +4: 4708 +4: 4709 +4: 4710 +4: 4711 +4: 4712 +4: 4713 +4: 4714 +4: 4715 +4: 4716 +4: 4717 +4: 4718 +4: 4719 +4: 4720 +4: 4721 +4: 4722 +4: 4723 +4: 4724 +4: 4725 +4: 4726 +4: 4727 +4: 4728 +4: 4729 +4: 4730 +4: 4731 +4: 4732 +4: 4733 +4: 4734 +4: 4735 +4: 4736 +4: 4737 +4: 4738 +4: 4739 +4: 4740 +4: 4741 +4: 4742 +4: 4743 +4: 4744 +4: 4745 +4: 4746 +4: 4747 +4: 4748 +4: 4749 +4: 4750 +5: 4719 +5: 4720 +5: 4721 +5: 4722 +5: 4723 +5: 4724 +5: 4725 +5: 4726 +5: 4727 +5: 4728 +5: 4729 +5: 4730 +5: 4731 +5: 4732 +5: 4733 +5: 4734 +5: 4735 +5: 4736 +5: 4737 +5: 4738 +5: 4739 +5: 4740 +5: 4741 +5: 4742 +5: 4743 +5: 4744 +5: 4745 +5: 4746 +5: 4747 +5: 4748 +5: 4749 +5: 4750 +5: 4751 +5: 4752 +5: 4753 +5: 4754 +5: 4755 +5: 4756 +5: 4757 +5: 4758 +5: 4759 +5: 4760 +5: 4761 +5: 4762 +5: 4763 +5: 4764 +5: 4765 +5: 4766 +5: 4767 +5: 4768 +5: 4769 +5: 4770 +5: 4771 +5: 4772 +5: 4773 +5: 4774 +5: 4775 +5: 4776 +5: 4777 +5: 4778 +5: 4779 +5: 4780 +5: 4781 +5: 4782 +5: 4783 +5: 4784 +5: 4785 +5: 4786 +5: 4787 +5: 4788 +5: 4789 +5: 4790 +5: 4791 +5: 4792 +5: 4793 +5: 4794 +5: 4795 +5: 4796 +5: 4797 +5: 4798 +5: 4799 +5: 4800 +5: 4801 +5: 4802 +5: 4803 +5: 4804 +5: 4805 +5: 4806 +5: 4807 +5: 4808 +5: 4809 +5: 4810 +5: 4811 +5: 4812 +5: 4813 +5: 4814 +5: 4815 +5: 4816 +5: 4817 +5: 4818 +5: 4819 +5: 4820 +5: 4821 +5: 4822 +5: 4823 +5: 4824 +5: 4825 +5: 4826 +5: 4827 +5: 4828 +5: 4829 +5: 4830 +5: 4831 +5: 4832 +5: 4833 +5: 4834 +5: 4835 +5: 4836 +5: 4837 +5: 4838 +5: 4839 +5: 4840 +5: 4841 +5: 4842 +5: 4843 +5: 4844 +5: 4845 +5: 4846 +5: 4847 +5: 4848 +5: 4849 +5: 4850 +5: 4851 +5: 4852 +5: 4853 +5: 4854 +5: 4855 +5: 4856 +5: 4857 +5: 4858 +5: 4859 +5: 4860 +5: 4861 +5: 4862 +5: 4863 +5: 4864 +5: 4865 +5: 4866 +5: 4867 +5: 4868 +5: 4869 +5: 4870 +5: 4871 +5: 4872 +5: 4873 +5: 4874 +5: 4875 +5: 4876 +5: 4877 +5: 4878 +5: 4879 +5: 4880 +5: 4881 +5: 4882 +5: 4883 +5: 4884 +5: 4885 +5: 4886 +5: 4887 +5: 4888 +5: 4889 +5: 4890 +5: 4891 +5: 4892 +5: 4893 +5: 4894 +5: 4895 +5: 4896 +5: 4897 +5: 4898 +5: 4899 +5: 4900 +5: 4901 +5: 4902 +5: 4903 +5: 4904 +5: 4905 +5: 4906 +5: 4907 +5: 4908 +5: 4909 +5: 4910 +5: 4911 +5: 4912 +5: 4913 +5: 4914 +5: 4915 +5: 4916 +5: 4917 +5: 4918 +5: 4919 +5: 4920 +5: 4921 +5: 4922 +5: 4923 +5: 4924 +5: 4925 +5: 4926 +5: 4927 +5: 4928 +5: 4929 +5: 4930 +5: 4931 +5: 4932 +5: 4933 +5: 4934 +5: 4935 +5: 4936 +5: 4937 +5: 4938 +5: 4939 +5: 4940 +5: 4941 +5: 4942 +5: 4943 +5: 4944 +5: 4945 +5: 4946 +5: 4947 +5: 4948 +5: 4949 +5: 4950 +5: 4951 +5: 4952 +5: 4953 +5: 4954 +5: 4955 +5: 4956 +5: 4957 +5: 4958 +5: 4959 +5: 4960 +5: 4961 +5: 4962 +5: 4963 +5: 4964 +5: 4965 +5: 4966 +5: 4967 +5: 4968 +5: 4969 +5: 4970 +5: 4971 +5: 4972 +5: 4973 +5: 4974 +5: 4975 +5: 4976 +5: 4977 +5: 4978 +5: 4979 +5: 4980 +5: 4981 +5: 4982 +5: 4983 +5: 4984 +5: 4985 +5: 4986 +5: 4987 +5: 4988 +5: 4989 +5: 4990 +5: 4991 +5: 4992 +5: 4993 +5: 4994 +5: 4995 +5: 4996 +5: 4997 +5: 4998 +5: 4999 +5: 5000 +5: 5001 +5: 5002 +5: 5003 +5: 5004 +4: 4751 +4: 4752 +4: 4753 +4: 4754 +4: 4755 +4: 4756 +4: 4757 +4: 4758 +4: 4759 +4: 4760 +4: 4761 +4: 4762 +4: 4763 +4: 4764 +4: 4765 +4: 4766 +4: 4767 +4: 4768 +4: 4769 +4: 4770 +4: 4771 +4: 4772 +4: 4773 +4: 4774 +4: 4775 +4: 4776 +4: 4777 +4: 4778 +4: 4779 +4: 4780 +4: 4781 +4: 4782 +4: 4783 +4: 4784 +4: 4785 +4: 4786 +4: 4787 +4: 4788 +4: 4789 +4: 4790 +4: 4791 +4: 4792 +4: 4793 +4: 4794 +4: 4795 +4: 4796 +4: 4797 +4: 4798 +4: 4799 +4: 4800 +4: 4801 +4: 4802 +4: 4803 +4: 4804 +4: 4805 +4: 4806 +4: 4807 +4: 4808 +4: 4809 +4: 4810 +4: 4811 +4: 4812 +4: 4813 +4: 4814 +4: 4815 +4: 4816 +4: 4817 +4: 4818 +4: 4819 +4: 4820 +4: 4821 +4: 4822 +4: 4823 +4: 4824 +4: 4825 +4: 4826 +4: 4827 +4: 4828 +4: 4829 +4: 4830 +4: 4831 +4: 4832 +4: 4833 +4: 4834 +4: 4835 +4: 4836 +4: 4837 +4: 4838 +4: 4839 +4: 4840 +4: 4841 +4: 4842 +4: 4843 +4: 4844 +4: 4845 +4: 4846 +4: 4847 +4: 4848 +4: 4849 +4: 4850 +4: 4851 +4: 4852 +4: 4853 +4: 4854 +4: 4855 +4: 4856 +4: 4857 +4: 4858 +4: 4859 +4: 4860 +4: 4861 +4: 4862 +4: 4863 +4: 4864 +4: 4865 +4: 4866 +4: 4867 +4: 4868 +4: 4869 +4: 4870 +4: 4871 +4: 4872 +4: 4873 +4: 4874 +4: 4875 +4: 4876 +4: 4877 +4: 4878 +4: 4879 +4: 4880 +4: 4881 +4: 4882 +4: 4883 +4: 4884 +4: 4885 +4: 4886 +4: 4887 +4: 4888 +4: 4889 +4: 4890 +4: 4891 +4: 4892 +4: 4893 +4: 4894 +4: 4895 +4: 4896 +4: 4897 +4: 4898 +4: 4899 +4: 4900 +4: 4901 +4: 4902 +4: 4903 +4: 4904 +4: 4905 +4: 4906 +4: 4907 +4: 4908 +4: 4909 +4: 4910 +4: 4911 +4: 4912 +4: 4913 +4: 4914 +4: 4915 +4: 4916 +4: 4917 +4: 4918 +4: 4919 +4: 4920 +4: 4921 +4: 4922 +4: 4923 +4: 4924 +4: 4925 +4: 4926 +4: 4927 +4: 4928 +4: 4929 +4: 4930 +4: 4931 +4: 4932 +4: 4933 +4: 4934 +4: 4935 +4: 4936 +4: 4937 +4: 4938 +4: 4939 +4: 4940 +4: 4941 +4: 4942 +4: 4943 +4: 4944 +4: 4945 +4: 4946 +4: 4947 +4: 4948 +4: 4949 +4: 4950 +4: 4951 +4: 4952 +4: 4953 +4: 4954 +4: 4955 +4: 4956 +4: 4957 +4: 4958 +4: 4959 +4: 4960 +4: 4961 +4: 4962 +4: 4963 +4: 4964 +4: 4965 +4: 4966 +4: 4967 +4: 4968 +4: 4969 +4: 4970 +4: 4971 +4: 4972 +4: 4973 +4: 4974 +4: 4975 +4: 4976 +4: 4977 +4: 4978 +4: 4979 +4: 4980 +4: 4981 +4: 4982 +4: 4983 +4: 4984 +4: 4985 +4: 4986 +4: 4987 +4: 4988 +4: 4989 +4: 4990 +4: 4991 +4: 4992 +4: 4993 +4: 4994 +4: 4995 +4: 4996 +4: 4997 +4: 4998 +4: 4999 +4: 5000 +5: 5005 +5: 5006 +5: 5007 +5: 5008 +5: 5009 +5: 5010 +5: 5011 +5: 5012 +5: 5013 +5: 5014 +5: 5015 +5: 5016 +5: 5017 +5: 5018 +5: 5019 +5: 5020 +5: 5021 +5: 5022 +5: 5023 +5: 5024 +5: 5025 +5: 5026 +5: 5027 +5: 5028 +5: 5029 +5: 5030 +5: 5031 +5: 5032 +5: 5033 +5: 5034 +5: 5035 +5: 5036 +5: 5037 +5: 5038 +5: 5039 +5: 5040 +5: 5041 +5: 5042 +5: 5043 +5: 5044 +5: 5045 +5: 5046 +5: 5047 +5: 5048 +5: 5049 +5: 5050 +5: 5051 +5: 5052 +5: 5053 +5: 5054 +5: 5055 +5: 5056 +5: 5057 +5: 5058 +5: 5059 +5: 5060 +5: 5061 +5: 5062 +5: 5063 +5: 5064 +5: 5065 +5: 5066 +5: 5067 +5: 5068 +5: 5069 +5: 5070 +5: 5071 +5: 5072 +5: 5073 +5: 5074 +5: 5075 +5: 5076 +5: 5077 +5: 5078 +5: 5079 +5: 5080 +5: 5081 +5: 5082 +5: 5083 +5: 5084 +5: 5085 +5: 5086 +5: 5087 +5: 5088 +5: 5089 +5: 5090 +5: 5091 +5: 5092 +5: 5093 +5: 5094 +5: 5095 +5: 5096 +5: 5097 +5: 5098 +5: 5099 +5: 5100 +5: 5101 +5: 5102 +5: 5103 +5: 5104 +5: 5105 +5: 5106 +5: 5107 +5: 5108 +5: 5109 +5: 5110 +5: 5111 +5: 5112 +5: 5113 +5: 5114 +5: 5115 +5: 5116 +5: 5117 +5: 5118 +5: 5119 +5: 5120 +5: 5121 +5: 5122 +5: 5123 +5: 5124 +5: 5125 +5: 5126 +5: 5127 +5: 5128 +5: 5129 +5: 5130 +5: 5131 +5: 5132 +5: 5133 +5: 5134 +5: 5135 +5: 5136 +5: 5137 +5: 5138 +5: 5139 +5: 5140 +5: 5141 +5: 5142 +5: 5143 +5: 5144 +5: 5145 +5: 5146 +5: 5147 +5: 5148 +5: 5149 +5: 5150 +5: 5151 +5: 5152 +5: 5153 +5: 5154 +5: 5155 +5: 5156 +5: 5157 +5: 5158 +5: 5159 +5: 5160 +5: 5161 +5: 5162 +5: 5163 +5: 5164 +5: 5165 +5: 5166 +5: 5167 +5: 5168 +5: 5169 +5: 5170 +5: 5171 +5: 5172 +5: 5173 +5: 5174 +5: 5175 +5: 5176 +5: 5177 +5: 5178 +5: 5179 +5: 5180 +5: 5181 +5: 5182 +5: 5183 +5: 5184 +5: 5185 +5: 5186 +5: 5187 +5: 5188 +5: 5189 +5: 5190 +5: 5191 +5: 5192 +5: 5193 +5: 5194 +5: 5195 +5: 5196 +5: 5197 +5: 5198 +5: 5199 +5: 5200 +5: 5201 +5: 5202 +5: 5203 +5: 5204 +5: 5205 +5: 5206 +5: 5207 +5: 5208 +5: 5209 +5: 5210 +5: 5211 +5: 5212 +5: 5213 +5: 5214 +5: 5215 +5: 5216 +5: 5217 +5: 5218 +5: 5219 +5: 5220 +5: 5221 +5: 5222 +5: 5223 +5: 5224 +5: 5225 +5: 5226 +5: 5227 +5: 5228 +5: 5229 +5: 5230 +5: 5231 +5: 5232 +5: 5233 +5: 5234 +5: 5235 +5: 5236 +5: 5237 +5: 5238 +5: 5239 +5: 5240 +5: 5241 +5: 5242 +5: 5243 +5: 5244 +5: 5245 +5: 5246 +5: 5247 +5: 5248 +5: 5249 +5: 5250 +5: 5251 +5: 5252 +5: 5253 +5: 5254 +5: 5255 +5: 5256 +5: 5257 +5: 5258 +5: 5259 +5: 5260 +5: 5261 +5: 5262 +5: 5263 +5: 5264 +5: 5265 +5: 5266 +5: 5267 +5: 5268 +5: 5269 +5: 5270 +5: 5271 +5: 5272 +5: 5273 +5: 5274 +5: 5275 +5: 5276 +5: 5277 +5: 5278 +5: 5279 +5: 5280 +5: 5281 +5: 5282 +5: 5283 +5: 5284 +5: 5285 +5: 5286 +5: 5287 +5: 5288 +5: 5289 +5: 5290 +5: 5291 +5: 5292 +5: 5293 +5: 5294 +5: 5295 +5: 5296 +5: 5297 +5: 5298 +5: 5299 +5: 5300 +5: 5301 +5: 5302 +5: 5303 +5: 5304 +5: 5305 +5: 5306 +5: 5307 +5: 5308 +5: 5309 +5: 5310 +5: 5311 +5: 5312 +5: 5313 +5: 5314 +5: 5315 +5: 5316 +5: 5317 +5: 5318 +5: 5319 +5: 5320 +5: 5321 +5: 5322 +5: 5323 +5: 5324 +5: 5325 +5: 5326 +5: 5327 +5: 5328 +5: 5329 +5: 5330 +5: 5331 +5: 5332 +5: 5333 +5: 5334 +5: 5335 +5: 5336 +5: 5337 +5: 5338 +5: 5339 +5: 5340 +5: 5341 +5: 5342 +5: 5343 +5: 5344 +5: 5345 +5: 5346 +5: 5347 +5: 5348 +5: 5349 +5: 5350 +5: 5351 +5: 5352 +5: 5353 +5: 5354 +5: 5355 +5: 5356 +5: 5357 +5: 5358 +5: 5359 +5: 5360 +5: 5361 +5: 5362 +5: 5363 +5: 5364 +5: 5365 +5: 5366 +5: 5367 +5: 5368 +5: 5369 +5: 5370 +5: 5371 +5: 5372 +5: 5373 +5: 5374 +5: 5375 +5: 5376 +5: 5377 +5: 5378 +5: 5379 +5: 5380 +5: 5381 +5: 5382 +5: 5383 +5: 5384 +5: 5385 +5: 5386 +5: 5387 +5: 5388 +5: 5389 +5: 5390 +5: 5391 +5: 5392 +5: 5393 +5: 5394 +5: 5395 +5: 5396 +5: 5397 +5: 5398 +5: 5399 +5: 5400 +5: 5401 +5: 5402 +5: 5403 +5: 5404 +5: 5405 +5: 5406 +5: 5407 +5: 5408 +5: 5409 +5: 5410 +5: 5411 +5: 5412 +5: 5413 +5: 5414 +5: 5415 +5: 5416 +5: 5417 +5: 5418 +5: 5419 +5: 5420 +5: 5421 +5: 5422 +5: 5423 +5: 5424 +5: 5425 +5: 5426 +5: 5427 +5: 5428 +5: 5429 +5: 5430 +5: 5431 +5: 5432 +5: 5433 +5: 5434 +5: 5435 +5: 5436 +5: 5437 +5: 5438 +5: 5439 +5: 5440 +5: 5441 +5: 5442 +5: 5443 +5: 5444 +5: 5445 +5: 5446 +5: 5447 +5: 5448 +5: 5449 +5: 5450 +5: 5451 +5: 5452 +5: 5453 +5: 5454 +5: 5455 +5: 5456 +5: 5457 +5: 5458 +5: 5459 +5: 5460 +5: 5461 +5: 5462 +5: 5463 +5: 5464 +5: 5465 +5: 5466 +5: 5467 +5: 5468 +5: 5469 +5: 5470 +5: 5471 +5: 5472 +5: 5473 +5: 5474 +5: 5475 +5: 5476 +5: 5477 +5: 5478 +5: 5479 +5: 5480 +5: 5481 +5: 5482 +5: 5483 +5: 5484 +5: 5485 +5: 5486 +5: 5487 +5: 5488 +5: 5489 +5: 5490 +5: 5491 +5: 5492 +5: 5493 +5: 5494 +5: 5495 +5: 5496 +5: 5497 +5: 5498 +5: 5499 +5: 5500 +5: 5501 +5: 5502 +5: 5503 +5: 5504 +5: 5505 +5: 5506 +5: 5507 +5: 5508 +5: 5509 +5: 5510 +5: 5511 +5: 5512 +5: 5513 +5: 5514 +5: 5515 +5: 5516 +5: 5517 diff --git a/threads/script.example02 b/threads/script.example02 new file mode 100644 index 0000000..5db87b5 --- /dev/null +++ b/threads/script.example02 @@ -0,0 +1,10000 @@ +4: 1 +4: 2 +4: 3 +4: 4 +4: 5 +4: 6 +4: 7 +4: 8 +4: 9 +4: 10 +4: 11 +4: 12 +4: 13 +4: 14 +4: 15 +4: 16 +4: 17 +4: 18 +4: 19 +4: 20 +4: 21 +4: 22 +4: 23 +4: 24 +4: 25 +4: 26 +4: 27 +4: 28 +4: 29 +4: 30 +4: 31 +4: 32 +4: 33 +4: 34 +4: 35 +4: 36 +4: 37 +4: 38 +4: 39 +4: 40 +4: 41 +4: 42 +4: 43 +4: 44 +4: 45 +4: 46 +4: 47 +4: 48 +4: 49 +4: 50 +4: 51 +4: 52 +4: 53 +4: 54 +4: 55 +4: 56 +4: 57 +4: 58 +4: 59 +4: 60 +4: 61 +4: 62 +4: 63 +4: 64 +4: 65 +4: 66 +4: 67 +4: 68 +4: 69 +4: 70 +4: 71 +4: 72 +4: 73 +4: 74 +4: 75 +4: 76 +4: 77 +4: 78 +4: 79 +4: 80 +4: 81 +4: 82 +4: 83 +4: 84 +4: 85 +4: 86 +4: 87 +4: 88 +4: 89 +4: 90 +4: 91 +4: 92 +4: 93 +4: 94 +4: 95 +4: 96 +4: 97 +4: 98 +4: 99 +4: 100 +4: 101 +4: 102 +4: 103 +4: 104 +4: 105 +4: 106 +4: 107 +4: 108 +4: 109 +4: 110 +4: 111 +4: 112 +4: 113 +4: 114 +4: 115 +4: 116 +4: 117 +4: 118 +4: 119 +4: 120 +4: 121 +4: 122 +4: 123 +4: 124 +4: 125 +4: 126 +4: 127 +4: 128 +4: 129 +4: 130 +4: 131 +4: 132 +4: 133 +4: 134 +4: 135 +4: 136 +4: 137 +4: 138 +4: 139 +4: 140 +4: 141 +4: 142 +4: 143 +4: 144 +4: 145 +4: 146 +4: 147 +4: 148 +4: 149 +4: 150 +4: 151 +4: 152 +4: 153 +4: 154 +4: 155 +4: 156 +4: 157 +4: 158 +4: 159 +4: 160 +4: 161 +4: 162 +4: 163 +4: 164 +4: 165 +4: 166 +4: 167 +4: 168 +4: 169 +4: 170 +4: 171 +4: 172 +4: 173 +4: 174 +4: 175 +4: 176 +4: 177 +4: 178 +4: 179 +4: 180 +4: 181 +4: 182 +4: 183 +4: 184 +4: 185 +4: 186 +4: 187 +4: 188 +4: 189 +4: 190 +4: 191 +4: 192 +4: 193 +4: 194 +4: 195 +4: 196 +4: 197 +4: 198 +4: 199 +4: 200 +4: 201 +4: 202 +4: 203 +4: 204 +4: 205 +4: 206 +4: 207 +4: 208 +4: 209 +4: 210 +4: 211 +4: 212 +4: 213 +4: 214 +4: 215 +4: 216 +4: 217 +4: 218 +4: 219 +4: 220 +4: 221 +4: 222 +4: 223 +4: 224 +4: 225 +4: 226 +4: 227 +4: 228 +4: 229 +4: 230 +4: 231 +4: 232 +4: 233 +4: 234 +4: 235 +4: 236 +4: 237 +4: 238 +4: 239 +4: 240 +4: 241 +4: 242 +4: 243 +4: 244 +4: 245 +4: 246 +4: 247 +4: 248 +4: 249 +4: 250 +4: 251 +4: 252 +4: 253 +4: 254 +4: 255 +4: 256 +4: 257 +4: 258 +4: 259 +4: 260 +4: 261 +4: 262 +4: 263 +4: 264 +4: 265 +4: 266 +4: 267 +4: 268 +4: 269 +4: 270 +4: 271 +4: 272 +4: 273 +4: 274 +4: 275 +4: 276 +4: 277 +4: 278 +4: 279 +4: 280 +4: 281 +4: 282 +4: 283 +4: 284 +4: 285 +4: 286 +4: 287 +4: 288 +4: 289 +4: 290 +4: 291 +4: 292 +4: 293 +4: 294 +4: 295 +4: 296 +4: 297 +4: 298 +4: 299 +4: 300 +4: 301 +4: 302 +4: 303 +4: 304 +4: 305 +4: 306 +4: 307 +4: 308 +4: 309 +4: 310 +4: 311 +4: 312 +4: 313 +4: 314 +4: 315 +4: 316 +4: 317 +4: 318 +4: 319 +4: 320 +4: 321 +4: 322 +4: 323 +4: 324 +4: 325 +4: 326 +4: 327 +4: 328 +4: 329 +4: 330 +4: 331 +4: 332 +4: 333 +4: 334 +4: 335 +4: 336 +4: 337 +4: 338 +4: 339 +4: 340 +4: 341 +4: 342 +4: 343 +4: 344 +4: 345 +4: 346 +4: 347 +4: 348 +4: 349 +4: 350 +4: 351 +4: 352 +4: 353 +4: 354 +4: 355 +4: 356 +4: 357 +4: 358 +4: 359 +4: 360 +4: 361 +4: 362 +4: 363 +4: 364 +4: 365 +4: 366 +4: 367 +4: 368 +4: 369 +4: 370 +4: 371 +4: 372 +4: 373 +4: 374 +4: 375 +4: 376 +4: 377 +4: 378 +4: 379 +4: 380 +4: 381 +4: 382 +4: 383 +4: 384 +4: 385 +4: 386 +4: 387 +4: 388 +4: 389 +4: 390 +4: 391 +4: 392 +4: 393 +4: 394 +4: 395 +4: 396 +4: 397 +4: 398 +4: 399 +4: 400 +4: 401 +4: 402 +4: 403 +4: 404 +4: 405 +4: 406 +4: 407 +4: 408 +4: 409 +4: 410 +4: 411 +4: 412 +4: 413 +4: 414 +4: 415 +4: 416 +4: 417 +4: 418 +4: 419 +4: 420 +4: 421 +4: 422 +4: 423 +4: 424 +4: 425 +4: 426 +4: 427 +4: 428 +4: 429 +4: 430 +4: 431 +4: 432 +4: 433 +4: 434 +4: 435 +4: 436 +4: 437 +4: 438 +4: 439 +4: 440 +4: 441 +4: 442 +4: 443 +4: 444 +4: 445 +4: 446 +4: 447 +4: 448 +4: 449 +4: 450 +4: 451 +4: 452 +4: 453 +4: 454 +4: 455 +4: 456 +4: 457 +4: 458 +4: 459 +4: 460 +4: 461 +4: 462 +4: 463 +4: 464 +4: 465 +4: 466 +4: 467 +4: 468 +4: 469 +4: 470 +4: 471 +4: 472 +4: 473 +4: 474 +4: 475 +4: 476 +4: 477 +4: 478 +4: 479 +4: 480 +4: 481 +4: 482 +4: 483 +4: 484 +4: 485 +4: 486 +4: 487 +4: 488 +4: 489 +4: 490 +4: 491 +4: 492 +4: 493 +4: 494 +4: 495 +4: 496 +4: 497 +4: 498 +4: 499 +4: 500 +4: 501 +4: 502 +4: 503 +4: 504 +4: 505 +4: 506 +4: 507 +4: 508 +4: 509 +4: 510 +4: 511 +4: 512 +4: 513 +4: 514 +4: 515 +4: 516 +4: 517 +4: 518 +4: 519 +4: 520 +4: 521 +4: 522 +4: 523 +4: 524 +4: 525 +4: 526 +4: 527 +4: 528 +4: 529 +4: 530 +4: 531 +4: 532 +4: 533 +4: 534 +4: 535 +4: 536 +4: 537 +4: 538 +4: 539 +4: 540 +4: 541 +4: 542 +4: 543 +4: 544 +4: 545 +4: 546 +4: 547 +4: 548 +4: 549 +4: 550 +4: 551 +4: 552 +4: 553 +4: 554 +4: 555 +4: 556 +4: 557 +4: 558 +4: 559 +4: 560 +4: 561 +4: 562 +4: 563 +4: 564 +4: 565 +4: 566 +4: 567 +4: 568 +4: 569 +4: 570 +4: 571 +4: 572 +4: 573 +4: 574 +4: 575 +4: 576 +4: 577 +4: 578 +4: 579 +4: 580 +4: 581 +4: 582 +4: 583 +4: 584 +4: 585 +4: 586 +4: 587 +4: 588 +4: 589 +4: 590 +4: 591 +4: 592 +4: 593 +4: 594 +4: 595 +4: 596 +4: 597 +4: 598 +4: 599 +4: 600 +4: 601 +4: 602 +4: 603 +4: 604 +4: 605 +4: 606 +4: 607 +4: 608 +4: 609 +4: 610 +4: 611 +4: 612 +4: 613 +4: 614 +4: 615 +4: 616 +4: 617 +4: 618 +4: 619 +4: 620 +4: 621 +4: 622 +4: 623 +4: 624 +4: 625 +4: 626 +4: 627 +4: 628 +4: 629 +4: 630 +4: 631 +4: 632 +4: 633 +4: 634 +4: 635 +4: 636 +4: 637 +4: 638 +4: 639 +4: 640 +4: 641 +4: 642 +4: 643 +4: 644 +4: 645 +4: 646 +4: 647 +4: 648 +4: 649 +4: 650 +4: 651 +4: 652 +4: 653 +4: 654 +4: 655 +4: 656 +4: 657 +4: 658 +4: 659 +4: 660 +4: 661 +4: 662 +4: 663 +4: 664 +4: 665 +4: 666 +4: 667 +4: 668 +4: 669 +4: 670 +4: 671 +4: 672 +4: 673 +4: 674 +4: 675 +4: 676 +4: 677 +4: 678 +4: 679 +4: 680 +4: 681 +4: 682 +4: 683 +4: 684 +4: 685 +4: 686 +4: 687 +4: 688 +4: 689 +4: 690 +4: 691 +4: 692 +4: 693 +4: 694 +4: 695 +4: 696 +4: 697 +4: 698 +4: 699 +4: 700 +4: 701 +4: 702 +4: 703 +4: 704 +4: 705 +4: 706 +4: 707 +4: 708 +4: 709 +4: 710 +4: 711 +4: 712 +4: 713 +4: 714 +4: 715 +4: 716 +4: 717 +4: 718 +4: 719 +4: 720 +4: 721 +4: 722 +4: 723 +4: 724 +4: 725 +4: 726 +4: 727 +4: 728 +4: 729 +4: 730 +4: 731 +4: 732 +4: 733 +4: 734 +4: 735 +4: 736 +4: 737 +4: 738 +4: 739 +4: 740 +4: 741 +4: 742 +4: 743 +4: 744 +4: 745 +4: 746 +4: 747 +4: 748 +4: 749 +4: 750 +4: 751 +4: 752 +4: 753 +4: 754 +4: 755 +4: 756 +4: 757 +4: 758 +4: 759 +4: 760 +4: 761 +4: 762 +4: 763 +4: 764 +4: 765 +4: 766 +4: 767 +4: 768 +4: 769 +4: 770 +4: 771 +4: 772 +4: 773 +4: 774 +4: 775 +4: 776 +4: 777 +4: 778 +4: 779 +4: 780 +4: 781 +4: 782 +5: 783 +5: 784 +5: 785 +5: 786 +5: 787 +5: 788 +5: 789 +5: 790 +5: 791 +5: 792 +5: 793 +5: 794 +5: 795 +5: 796 +5: 797 +5: 798 +5: 799 +5: 800 +5: 801 +5: 802 +5: 803 +5: 804 +5: 805 +5: 806 +5: 807 +5: 808 +5: 809 +5: 810 +5: 811 +5: 812 +5: 813 +5: 814 +5: 815 +5: 816 +5: 817 +5: 818 +5: 819 +5: 820 +5: 821 +5: 822 +5: 823 +5: 824 +5: 825 +5: 826 +5: 827 +5: 828 +5: 829 +5: 830 +5: 831 +5: 832 +5: 833 +5: 834 +5: 835 +5: 836 +5: 837 +5: 838 +5: 839 +5: 840 +5: 841 +5: 842 +5: 843 +5: 844 +5: 845 +5: 846 +5: 847 +5: 848 +5: 849 +5: 850 +5: 851 +5: 852 +5: 853 +5: 854 +5: 855 +5: 856 +5: 857 +5: 858 +5: 859 +5: 860 +5: 861 +5: 862 +5: 863 +5: 864 +5: 865 +5: 866 +5: 867 +5: 868 +5: 869 +5: 870 +5: 871 +5: 872 +5: 873 +5: 874 +5: 875 +5: 876 +5: 877 +5: 878 +5: 879 +5: 880 +5: 881 +5: 882 +5: 883 +5: 884 +5: 885 +5: 886 +5: 887 +5: 888 +5: 889 +5: 890 +5: 891 +5: 892 +5: 893 +5: 894 +5: 895 +5: 896 +5: 897 +5: 898 +5: 899 +5: 900 +5: 901 +5: 902 +5: 903 +5: 904 +5: 905 +5: 906 +5: 907 +5: 908 +5: 909 +5: 910 +5: 911 +5: 912 +5: 913 +5: 914 +5: 915 +5: 916 +5: 917 +5: 918 +5: 919 +5: 920 +5: 921 +5: 922 +5: 923 +5: 924 +5: 925 +5: 926 +5: 927 +5: 928 +5: 929 +5: 930 +5: 931 +5: 932 +5: 933 +5: 934 +5: 935 +5: 936 +5: 937 +5: 938 +5: 939 +5: 940 +5: 941 +5: 942 +5: 943 +5: 944 +5: 945 +5: 946 +5: 947 +5: 948 +5: 949 +5: 950 +5: 951 +5: 952 +5: 953 +5: 954 +5: 955 +5: 956 +5: 957 +5: 958 +5: 959 +5: 960 +5: 961 +5: 962 +5: 963 +5: 964 +5: 965 +5: 966 +5: 967 +5: 968 +5: 969 +5: 970 +5: 971 +5: 972 +5: 973 +5: 974 +5: 975 +5: 976 +5: 977 +5: 978 +5: 979 +5: 980 +5: 981 +5: 982 +5: 983 +5: 984 +5: 985 +5: 986 +5: 987 +5: 988 +5: 989 +5: 990 +5: 991 +5: 992 +5: 993 +5: 994 +5: 995 +5: 996 +5: 997 +5: 998 +5: 999 +5: 1000 +5: 1001 +5: 1002 +5: 1003 +5: 1004 +5: 1005 +5: 1006 +5: 1007 +5: 1008 +5: 1009 +5: 1010 +5: 1011 +5: 1012 +5: 1013 +5: 1014 +5: 1015 +5: 1016 +5: 1017 +5: 1018 +5: 1019 +5: 1020 +5: 1021 +5: 1022 +5: 1023 +5: 1024 +5: 1025 +5: 1026 +5: 1027 +5: 1028 +5: 1029 +5: 1030 +5: 1031 +5: 1032 +5: 1033 +5: 1034 +5: 1035 +5: 1036 +5: 1037 +5: 1038 +5: 1039 +5: 1040 +5: 1041 +5: 1042 +5: 1043 +5: 1044 +5: 1045 +5: 1046 +5: 1047 +5: 1048 +5: 1049 +5: 1050 +5: 1051 +5: 1052 +5: 1053 +5: 1054 +5: 1055 +5: 1056 +5: 1057 +5: 1058 +5: 1059 +5: 1060 +5: 1061 +5: 1062 +5: 1063 +5: 1064 +5: 1065 +5: 1066 +5: 1067 +5: 1068 +5: 1069 +5: 1070 +5: 1071 +5: 1072 +5: 1073 +5: 1074 +5: 1075 +5: 1076 +5: 1077 +5: 1078 +5: 1079 +5: 1080 +5: 1081 +5: 1082 +5: 1083 +5: 1084 +5: 1085 +5: 1086 +5: 1087 +5: 1088 +5: 1089 +5: 1090 +5: 1091 +5: 1092 +5: 1093 +5: 1094 +5: 1095 +5: 1096 +5: 1097 +5: 1098 +5: 1099 +5: 1100 +5: 1101 +5: 1102 +5: 1103 +5: 1104 +5: 1105 +5: 1106 +5: 1107 +5: 1108 +5: 1109 +5: 1110 +5: 1111 +5: 1112 +5: 1113 +5: 1114 +5: 1115 +5: 1116 +5: 1117 +5: 1118 +5: 1119 +5: 1120 +5: 1121 +5: 1122 +5: 1123 +5: 1124 +5: 1125 +5: 1126 +5: 1127 +5: 1128 +5: 1129 +5: 1130 +5: 1131 +5: 1132 +5: 1133 +5: 1134 +5: 1135 +5: 1136 +5: 1137 +5: 1138 +5: 1139 +5: 1140 +5: 1141 +5: 1142 +5: 1143 +5: 1144 +5: 1145 +5: 1146 +5: 1147 +5: 1148 +5: 1149 +5: 1150 +5: 1151 +5: 1152 +5: 1153 +5: 1154 +5: 1155 +5: 1156 +5: 1157 +5: 1158 +5: 1159 +5: 1160 +5: 1161 +5: 1162 +5: 1163 +5: 1164 +5: 1165 +5: 1166 +5: 1167 +5: 1168 +5: 1169 +5: 1170 +5: 1171 +5: 1172 +5: 1173 +5: 1174 +5: 1175 +5: 1176 +5: 1177 +5: 1178 +5: 1179 +5: 1180 +5: 1181 +4: 1182 +4: 1183 +4: 1184 +4: 1185 +4: 1186 +4: 1187 +4: 1188 +4: 1189 +4: 1190 +4: 1191 +4: 1192 +4: 1193 +4: 1194 +4: 1195 +4: 1196 +4: 1197 +4: 1198 +4: 1199 +4: 1200 +4: 1201 +4: 1202 +4: 1203 +4: 1204 +4: 1205 +4: 1206 +4: 1207 +4: 1208 +4: 1209 +4: 1210 +4: 1211 +4: 1212 +4: 1213 +4: 1214 +4: 1215 +4: 1216 +4: 1217 +4: 1218 +4: 1219 +4: 1220 +4: 1221 +4: 1222 +4: 1223 +4: 1224 +4: 1225 +4: 1226 +4: 1227 +4: 1228 +4: 1229 +4: 1230 +4: 1231 +4: 1232 +4: 1233 +4: 1234 +4: 1235 +4: 1236 +4: 1237 +4: 1238 +4: 1239 +4: 1240 +4: 1241 +4: 1242 +5: 1243 +5: 1244 +5: 1245 +5: 1246 +5: 1247 +5: 1248 +5: 1249 +5: 1250 +5: 1251 +5: 1252 +5: 1253 +5: 1254 +5: 1255 +5: 1256 +5: 1257 +5: 1258 +5: 1259 +5: 1260 +5: 1261 +5: 1262 +5: 1263 +5: 1264 +5: 1265 +5: 1266 +5: 1267 +5: 1268 +5: 1269 +5: 1270 +5: 1271 +5: 1272 +5: 1273 +5: 1274 +5: 1275 +5: 1276 +5: 1277 +5: 1278 +5: 1279 +5: 1280 +5: 1281 +5: 1282 +5: 1283 +5: 1284 +5: 1285 +5: 1286 +5: 1287 +5: 1288 +5: 1289 +5: 1290 +5: 1291 +5: 1292 +5: 1293 +5: 1294 +5: 1295 +5: 1296 +5: 1297 +5: 1298 +5: 1299 +5: 1300 +5: 1301 +5: 1302 +5: 1303 +5: 1304 +5: 1305 +5: 1306 +5: 1307 +5: 1308 +5: 1309 +5: 1310 +5: 1311 +5: 1312 +5: 1313 +5: 1314 +5: 1315 +5: 1316 +5: 1317 +5: 1318 +5: 1319 +5: 1320 +5: 1321 +5: 1322 +5: 1323 +5: 1324 +5: 1325 +5: 1326 +5: 1327 +5: 1328 +5: 1329 +5: 1330 +5: 1331 +5: 1332 +5: 1333 +5: 1334 +5: 1335 +5: 1336 +5: 1337 +5: 1338 +5: 1339 +5: 1340 +5: 1341 +5: 1342 +5: 1343 +5: 1344 +5: 1345 +5: 1346 +5: 1347 +5: 1348 +5: 1349 +5: 1350 +5: 1351 +5: 1352 +5: 1353 +5: 1354 +5: 1355 +5: 1356 +5: 1357 +5: 1358 +5: 1359 +5: 1360 +5: 1361 +5: 1362 +5: 1363 +5: 1364 +5: 1365 +5: 1366 +5: 1367 +5: 1368 +5: 1369 +5: 1370 +5: 1371 +5: 1372 +5: 1373 +5: 1374 +5: 1375 +5: 1376 +5: 1377 +5: 1378 +5: 1379 +5: 1380 +5: 1381 +5: 1382 +5: 1383 +5: 1384 +5: 1385 +5: 1386 +5: 1387 +5: 1388 +5: 1389 +5: 1390 +5: 1391 +5: 1392 +5: 1393 +5: 1394 +5: 1395 +5: 1396 +5: 1397 +5: 1398 +5: 1399 +5: 1400 +5: 1401 +5: 1402 +5: 1403 +5: 1404 +5: 1405 +5: 1406 +5: 1407 +5: 1408 +5: 1409 +5: 1410 +5: 1411 +5: 1412 +5: 1413 +5: 1414 +5: 1415 +5: 1416 +5: 1417 +5: 1418 +5: 1419 +5: 1420 +5: 1421 +5: 1422 +5: 1423 +5: 1424 +5: 1425 +5: 1426 +5: 1427 +5: 1428 +5: 1429 +5: 1430 +5: 1431 +5: 1432 +5: 1433 +5: 1434 +5: 1435 +5: 1436 +5: 1437 +5: 1438 +5: 1439 +5: 1440 +5: 1441 +5: 1442 +5: 1443 +5: 1444 +5: 1445 +5: 1446 +5: 1447 +5: 1448 +5: 1449 +5: 1450 +5: 1451 +5: 1452 +5: 1453 +5: 1454 +5: 1455 +5: 1456 +5: 1457 +5: 1458 +5: 1459 +5: 1460 +5: 1461 +5: 1462 +5: 1463 +5: 1464 +5: 1465 +5: 1466 +5: 1467 +5: 1468 +5: 1469 +5: 1470 +5: 1471 +5: 1472 +5: 1473 +5: 1474 +5: 1475 +5: 1476 +5: 1477 +5: 1478 +5: 1479 +5: 1480 +5: 1481 +5: 1482 +5: 1483 +5: 1484 +5: 1485 +5: 1486 +5: 1487 +5: 1488 +5: 1489 +5: 1490 +5: 1491 +5: 1492 +5: 1493 +5: 1494 +5: 1495 +5: 1496 +5: 1497 +5: 1498 +5: 1499 +5: 1500 +5: 1501 +5: 1502 +5: 1503 +5: 1504 +5: 1505 +5: 1506 +5: 1507 +5: 1508 +5: 1509 +5: 1510 +5: 1511 +5: 1512 +5: 1513 +5: 1514 +5: 1515 +5: 1516 +5: 1517 +5: 1518 +5: 1519 +5: 1520 +5: 1521 +5: 1522 +5: 1523 +5: 1524 +5: 1525 +5: 1526 +5: 1527 +5: 1528 +5: 1529 +5: 1530 +5: 1531 +5: 1532 +5: 1533 +5: 1534 +5: 1535 +5: 1536 +5: 1537 +5: 1538 +5: 1539 +5: 1540 +5: 1541 +4: 1542 +4: 1543 +4: 1544 +4: 1545 +4: 1546 +4: 1547 +4: 1548 +4: 1549 +4: 1550 +4: 1551 +4: 1552 +4: 1553 +4: 1554 +4: 1555 +4: 1556 +4: 1557 +4: 1558 +4: 1559 +4: 1560 +4: 1561 +4: 1562 +4: 1563 +4: 1564 +4: 1565 +4: 1566 +4: 1567 +4: 1568 +4: 1569 +4: 1570 +4: 1571 +4: 1572 +4: 1573 +4: 1574 +4: 1575 +4: 1576 +4: 1577 +4: 1578 +4: 1579 +4: 1580 +4: 1581 +4: 1582 +4: 1583 +4: 1584 +4: 1585 +4: 1586 +4: 1587 +4: 1588 +4: 1589 +4: 1590 +4: 1591 +4: 1592 +4: 1593 +4: 1594 +4: 1595 +4: 1596 +4: 1597 +4: 1598 +4: 1599 +4: 1600 +4: 1601 +4: 1602 +4: 1603 +4: 1604 +4: 1605 +4: 1606 +4: 1607 +4: 1608 +4: 1609 +4: 1610 +4: 1611 +4: 1612 +4: 1613 +4: 1614 +4: 1615 +4: 1616 +4: 1617 +4: 1618 +4: 1619 +4: 1620 +4: 1621 +4: 1622 +4: 1623 +4: 1624 +4: 1625 +4: 1626 +4: 1627 +4: 1628 +4: 1629 +4: 1630 +4: 1631 +4: 1632 +4: 1633 +4: 1634 +4: 1635 +4: 1636 +4: 1637 +4: 1638 +4: 1639 +4: 1640 +4: 1641 +4: 1642 +4: 1643 +4: 1644 +4: 1645 +4: 1646 +4: 1647 +4: 1648 +4: 1649 +4: 1650 +4: 1651 +4: 1652 +4: 1653 +4: 1654 +4: 1655 +4: 1656 +4: 1657 +4: 1658 +4: 1659 +4: 1660 +4: 1661 +4: 1662 +4: 1663 +4: 1664 +4: 1665 +4: 1666 +4: 1667 +4: 1668 +4: 1669 +4: 1670 +4: 1671 +4: 1672 +4: 1673 +4: 1674 +4: 1675 +4: 1676 +4: 1677 +4: 1678 +4: 1679 +4: 1680 +4: 1681 +4: 1682 +4: 1683 +4: 1684 +4: 1685 +4: 1686 +4: 1687 +4: 1688 +4: 1689 +4: 1690 +4: 1691 +4: 1692 +4: 1693 +4: 1694 +4: 1695 +4: 1696 +4: 1697 +4: 1698 +4: 1699 +4: 1700 +4: 1701 +4: 1702 +4: 1703 +4: 1704 +4: 1705 +4: 1706 +4: 1707 +4: 1708 +4: 1709 +4: 1710 +4: 1711 +4: 1712 +4: 1713 +4: 1714 +4: 1715 +4: 1716 +4: 1717 +4: 1718 +4: 1719 +4: 1720 +4: 1721 +4: 1722 +4: 1723 +4: 1724 +4: 1725 +4: 1726 +4: 1727 +4: 1728 +4: 1729 +4: 1730 +4: 1731 +4: 1732 +4: 1733 +4: 1734 +4: 1735 +4: 1736 +4: 1737 +4: 1738 +4: 1739 +4: 1740 +4: 1741 +4: 1742 +4: 1743 +4: 1744 +4: 1745 +4: 1746 +4: 1747 +4: 1748 +4: 1749 +4: 1750 +4: 1751 +4: 1752 +4: 1753 +4: 1754 +4: 1755 +4: 1756 +4: 1757 +4: 1758 +4: 1759 +4: 1760 +4: 1761 +4: 1762 +4: 1763 +4: 1764 +4: 1765 +4: 1766 +4: 1767 +4: 1768 +4: 1769 +4: 1770 +4: 1771 +4: 1772 +4: 1773 +4: 1774 +4: 1775 +4: 1776 +4: 1777 +4: 1778 +4: 1779 +4: 1780 +4: 1781 +4: 1782 +4: 1783 +4: 1784 +4: 1785 +4: 1786 +4: 1787 +4: 1788 +4: 1789 +4: 1790 +4: 1791 +4: 1792 +4: 1793 +4: 1794 +4: 1795 +4: 1796 +4: 1797 +4: 1798 +4: 1799 +4: 1800 +4: 1801 +4: 1802 +4: 1803 +4: 1804 +4: 1805 +4: 1806 +4: 1807 +4: 1808 +4: 1809 +4: 1810 +4: 1811 +4: 1812 +4: 1813 +4: 1814 +4: 1815 +4: 1816 +4: 1817 +4: 1818 +4: 1819 +4: 1820 +4: 1821 +4: 1822 +4: 1823 +4: 1824 +4: 1825 +4: 1826 +4: 1827 +4: 1828 +4: 1829 +4: 1830 +4: 1831 +5: 1832 +5: 1833 +5: 1834 +5: 1835 +5: 1836 +5: 1837 +5: 1838 +5: 1839 +5: 1840 +5: 1841 +5: 1842 +5: 1843 +5: 1844 +5: 1845 +5: 1846 +5: 1847 +5: 1848 +5: 1849 +5: 1850 +5: 1851 +5: 1852 +5: 1853 +5: 1854 +5: 1855 +5: 1856 +5: 1857 +5: 1858 +5: 1859 +5: 1860 +5: 1861 +5: 1862 +5: 1863 +5: 1864 +5: 1865 +5: 1866 +5: 1867 +5: 1868 +5: 1869 +5: 1870 +5: 1871 +5: 1872 +5: 1873 +5: 1874 +5: 1875 +5: 1876 +5: 1877 +5: 1878 +5: 1879 +5: 1880 +5: 1881 +5: 1882 +5: 1883 +5: 1884 +5: 1885 +5: 1886 +5: 1887 +5: 1888 +5: 1889 +5: 1890 +5: 1891 +5: 1892 +5: 1893 +5: 1894 +5: 1895 +5: 1896 +5: 1897 +5: 1898 +5: 1899 +5: 1900 +5: 1901 +5: 1902 +5: 1903 +5: 1904 +5: 1905 +5: 1906 +5: 1907 +5: 1908 +5: 1909 +5: 1910 +5: 1911 +5: 1912 +5: 1913 +5: 1914 +5: 1915 +5: 1916 +5: 1917 +5: 1918 +5: 1919 +5: 1920 +5: 1921 +5: 1922 +5: 1923 +5: 1924 +5: 1925 +5: 1926 +5: 1927 +5: 1928 +5: 1929 +5: 1930 +5: 1931 +5: 1932 +5: 1933 +5: 1934 +5: 1935 +5: 1936 +5: 1937 +5: 1938 +5: 1939 +5: 1940 +5: 1941 +5: 1942 +5: 1943 +5: 1944 +5: 1945 +5: 1946 +5: 1947 +5: 1948 +5: 1949 +5: 1950 +5: 1951 +5: 1952 +5: 1953 +5: 1954 +5: 1955 +5: 1956 +5: 1957 +5: 1958 +5: 1959 +5: 1960 +5: 1961 +5: 1962 +5: 1963 +5: 1964 +5: 1965 +5: 1966 +5: 1967 +5: 1968 +5: 1969 +5: 1970 +5: 1971 +5: 1972 +5: 1973 +5: 1974 +5: 1975 +5: 1976 +5: 1977 +5: 1978 +5: 1979 +5: 1980 +5: 1981 +5: 1982 +5: 1983 +5: 1984 +5: 1985 +5: 1986 +5: 1987 +5: 1988 +5: 1989 +5: 1990 +5: 1991 +5: 1992 +5: 1993 +5: 1994 +5: 1995 +5: 1996 +5: 1997 +5: 1998 +5: 1999 +5: 2000 +5: 2001 +5: 2002 +5: 2003 +5: 2004 +5: 2005 +5: 2006 +5: 2007 +5: 2008 +5: 2009 +5: 2010 +5: 2011 +5: 2012 +5: 2013 +5: 2014 +5: 2015 +5: 2016 +5: 2017 +5: 2018 +5: 2019 +5: 2020 +5: 2021 +5: 2022 +5: 2023 +5: 2024 +5: 2025 +5: 2026 +5: 2027 +5: 2028 +5: 2029 +5: 2030 +5: 2031 +5: 2032 +5: 2033 +5: 2034 +5: 2035 +5: 2036 +5: 2037 +5: 2038 +5: 2039 +5: 2040 +5: 2041 +5: 2042 +5: 2043 +5: 2044 +5: 2045 +5: 2046 +5: 2047 +5: 2048 +5: 2049 +5: 2050 +5: 2051 +5: 2052 +5: 2053 +5: 2054 +5: 2055 +5: 2056 +5: 2057 +5: 2058 +5: 2059 +5: 2060 +5: 2061 +5: 2062 +5: 2063 +5: 2064 +5: 2065 +5: 2066 +5: 2067 +5: 2068 +5: 2069 +5: 2070 +5: 2071 +5: 2072 +5: 2073 +5: 2074 +5: 2075 +5: 2076 +5: 2077 +5: 2078 +5: 2079 +5: 2080 +5: 2081 +5: 2082 +5: 2083 +5: 2084 +5: 2085 +5: 2086 +5: 2087 +5: 2088 +5: 2089 +5: 2090 +5: 2091 +5: 2092 +5: 2093 +5: 2094 +5: 2095 +5: 2096 +5: 2097 +5: 2098 +5: 2099 +5: 2100 +5: 2101 +5: 2102 +5: 2103 +5: 2104 +5: 2105 +5: 2106 +5: 2107 +5: 2108 +5: 2109 +5: 2110 +5: 2111 +5: 2112 +5: 2113 +5: 2114 +5: 2115 +5: 2116 +5: 2117 +5: 2118 +5: 2119 +5: 2120 +5: 2121 +5: 2122 +5: 2123 +5: 2124 +5: 2125 +5: 2126 +5: 2127 +5: 2128 +5: 2129 +5: 2130 +5: 2131 +5: 2132 +5: 2133 +5: 2134 +5: 2135 +5: 2136 +5: 2137 +5: 2138 +5: 2139 +5: 2140 +5: 2141 +5: 2142 +5: 2143 +5: 2144 +5: 2145 +5: 2146 +5: 2147 +5: 2148 +5: 2149 +5: 2150 +5: 2151 +5: 2152 +5: 2153 +5: 2154 +5: 2155 +5: 2156 +5: 2157 +5: 2158 +5: 2159 +5: 2160 +5: 2161 +5: 2162 +5: 2163 +5: 2164 +5: 2165 +5: 2166 +5: 2167 +5: 2168 +5: 2169 +5: 2170 +5: 2171 +5: 2172 +5: 2173 +5: 2174 +5: 2175 +5: 2176 +5: 2177 +5: 2178 +5: 2179 +5: 2180 +5: 2181 +5: 2182 +5: 2183 +5: 2184 +5: 2185 +5: 2186 +5: 2187 +5: 2188 +5: 2189 +5: 2190 +5: 2191 +5: 2192 +5: 2193 +5: 2194 +5: 2195 +5: 2196 +5: 2197 +5: 2198 +5: 2199 +5: 2200 +5: 2201 +5: 2202 +5: 2203 +5: 2204 +5: 2205 +5: 2206 +5: 2207 +5: 2208 +5: 2209 +5: 2210 +5: 2211 +5: 2212 +5: 2213 +5: 2214 +5: 2215 +5: 2216 +5: 2217 +5: 2218 +5: 2219 +5: 2220 +5: 2221 +5: 2222 +5: 2223 +5: 2224 +5: 2225 +5: 2226 +5: 2227 +5: 2228 +5: 2229 +5: 2230 +5: 2231 +5: 2232 +5: 2233 +5: 2234 +5: 2235 +5: 2236 +5: 2237 +5: 2238 +5: 2239 +5: 2240 +5: 2241 +5: 2242 +5: 2243 +5: 2244 +5: 2245 +5: 2246 +5: 2247 +5: 2248 +5: 2249 +5: 2250 +5: 2251 +5: 2252 +5: 2253 +5: 2254 +5: 2255 +5: 2256 +5: 2257 +5: 2258 +5: 2259 +5: 2260 +5: 2261 +5: 2262 +5: 2263 +5: 2264 +5: 2265 +5: 2266 +5: 2267 +5: 2268 +5: 2269 +5: 2270 +5: 2271 +5: 2272 +5: 2273 +5: 2274 +5: 2275 +5: 2276 +5: 2277 +5: 2278 +5: 2279 +5: 2280 +5: 2281 +5: 2282 +5: 2283 +5: 2284 +5: 2285 +5: 2286 +5: 2287 +5: 2288 +5: 2289 +5: 2290 +5: 2291 +5: 2292 +5: 2293 +5: 2294 +5: 2295 +5: 2296 +5: 2297 +5: 2298 +5: 2299 +5: 2300 +5: 2301 +5: 2302 +5: 2303 +5: 2304 +5: 2305 +5: 2306 +5: 2307 +5: 2308 +5: 2309 +5: 2310 +5: 2311 +5: 2312 +5: 2313 +5: 2314 +5: 2315 +5: 2316 +5: 2317 +5: 2318 +5: 2319 +5: 2320 +5: 2321 +5: 2322 +5: 2323 +5: 2324 +5: 2325 +5: 2326 +5: 2327 +5: 2328 +5: 2329 +5: 2330 +5: 2331 +5: 2332 +5: 2333 +5: 2334 +5: 2335 +5: 2336 +5: 2337 +5: 2338 +5: 2339 +5: 2340 +5: 2341 +5: 2342 +4: 2343 +4: 2344 +4: 2345 +4: 2346 +4: 2347 +4: 2348 +4: 2349 +4: 2350 +4: 2351 +4: 2352 +4: 2353 +4: 2354 +4: 2355 +4: 2356 +4: 2357 +4: 2358 +4: 2359 +4: 2360 +4: 2361 +4: 2362 +4: 2363 +4: 2364 +4: 2365 +4: 2366 +4: 2367 +4: 2368 +4: 2369 +4: 2370 +4: 2371 +4: 2372 +4: 2373 +4: 2374 +4: 2375 +4: 2376 +4: 2377 +4: 2378 +4: 2379 +4: 2380 +4: 2381 +4: 2382 +4: 2383 +4: 2384 +4: 2385 +4: 2386 +4: 2387 +4: 2388 +4: 2389 +4: 2390 +4: 2391 +4: 2392 +4: 2393 +4: 2394 +4: 2395 +4: 2396 +4: 2397 +4: 2398 +4: 2399 +4: 2400 +4: 2401 +4: 2402 +4: 2403 +4: 2404 +4: 2405 +4: 2406 +4: 2407 +4: 2408 +4: 2409 +4: 2410 +4: 2411 +4: 2412 +4: 2413 +4: 2414 +4: 2415 +4: 2416 +4: 2417 +4: 2418 +4: 2419 +4: 2420 +4: 2421 +4: 2422 +4: 2423 +4: 2424 +4: 2425 +4: 2426 +4: 2427 +4: 2428 +4: 2429 +4: 2430 +4: 2431 +4: 2432 +4: 2433 +4: 2434 +4: 2435 +4: 2436 +4: 2437 +4: 2438 +4: 2439 +4: 2440 +4: 2441 +4: 2442 +4: 2443 +4: 2444 +4: 2445 +4: 2446 +4: 2447 +4: 2448 +4: 2449 +4: 2450 +4: 2451 +4: 2452 +4: 2453 +4: 2454 +4: 2455 +4: 2456 +4: 2457 +4: 2458 +4: 2459 +4: 2460 +4: 2461 +4: 2462 +4: 2463 +4: 2464 +4: 2465 +4: 2466 +4: 2467 +4: 2468 +4: 2469 +4: 2470 +4: 2471 +4: 2472 +4: 2473 +4: 2474 +4: 2475 +4: 2476 +4: 2477 +4: 2478 +4: 2479 +4: 2480 +4: 2481 +4: 2482 +4: 2483 +4: 2484 +4: 2485 +4: 2486 +4: 2487 +4: 2488 +4: 2489 +4: 2490 +4: 2491 +4: 2492 +4: 2493 +4: 2494 +4: 2495 +4: 2496 +4: 2497 +4: 2498 +4: 2499 +4: 2500 +4: 2501 +4: 2502 +4: 2503 +4: 2504 +4: 2505 +4: 2506 +4: 2507 +4: 2508 +4: 2509 +4: 2510 +4: 2511 +4: 2512 +4: 2513 +4: 2514 +4: 2515 +4: 2516 +4: 2517 +4: 2518 +4: 2519 +4: 2520 +4: 2521 +4: 2522 +4: 2523 +4: 2524 +4: 2525 +4: 2526 +4: 2527 +4: 2528 +4: 2529 +4: 2530 +4: 2531 +4: 2532 +4: 2533 +4: 2534 +4: 2535 +4: 2536 +4: 2537 +4: 2538 +4: 2539 +4: 2540 +4: 2541 +4: 2542 +4: 2543 +4: 2544 +4: 2545 +4: 2546 +4: 2547 +4: 2548 +4: 2549 +4: 2550 +4: 2551 +4: 2552 +4: 2553 +4: 2554 +4: 2555 +4: 2556 +4: 2557 +4: 2558 +4: 2559 +4: 2560 +4: 2561 +4: 2562 +4: 2563 +4: 2564 +4: 2565 +4: 2566 +4: 2567 +4: 2568 +4: 2569 +4: 2570 +4: 2571 +4: 2572 +4: 2573 +4: 2574 +4: 2575 +4: 2576 +4: 2577 +4: 2578 +4: 2579 +4: 2580 +4: 2581 +4: 2582 +4: 2583 +4: 2584 +4: 2585 +4: 2586 +4: 2587 +4: 2588 +4: 2589 +4: 2590 +4: 2591 +4: 2592 +4: 2593 +4: 2594 +4: 2595 +4: 2596 +4: 2597 +4: 2598 +4: 2599 +4: 2600 +4: 2601 +4: 2602 +4: 2603 +4: 2604 +4: 2605 +4: 2606 +4: 2607 +4: 2608 +4: 2609 +4: 2610 +4: 2611 +4: 2612 +4: 2613 +4: 2614 +4: 2615 +4: 2616 +4: 2617 +4: 2618 +4: 2619 +4: 2620 +4: 2621 +4: 2622 +4: 2623 +4: 2624 +4: 2625 +4: 2626 +4: 2627 +4: 2628 +4: 2629 +4: 2630 +4: 2631 +4: 2632 +4: 2633 +4: 2634 +4: 2635 +4: 2636 +4: 2637 +4: 2638 +4: 2639 +4: 2640 +4: 2641 +4: 2642 +4: 2643 +4: 2644 +4: 2645 +4: 2646 +4: 2647 +4: 2648 +4: 2649 +4: 2650 +4: 2651 +4: 2652 +4: 2653 +4: 2654 +4: 2655 +4: 2656 +4: 2657 +4: 2658 +4: 2659 +4: 2660 +4: 2661 +4: 2662 +4: 2663 +4: 2664 +4: 2665 +4: 2666 +4: 2667 +4: 2668 +4: 2669 +4: 2670 +4: 2671 +4: 2672 +4: 2673 +4: 2674 +4: 2675 +4: 2676 +4: 2677 +4: 2678 +4: 2679 +4: 2680 +4: 2681 +4: 2682 +4: 2683 +4: 2684 +4: 2685 +4: 2686 +4: 2687 +4: 2688 +4: 2689 +4: 2690 +4: 2691 +4: 2692 +4: 2693 +4: 2694 +4: 2695 +4: 2696 +4: 2697 +4: 2698 +4: 2699 +4: 2700 +5: 2701 +5: 2702 +5: 2703 +5: 2704 +5: 2705 +5: 2706 +5: 2707 +5: 2708 +5: 2709 +5: 2710 +5: 2711 +5: 2712 +5: 2713 +5: 2714 +5: 2715 +5: 2716 +5: 2717 +5: 2718 +5: 2719 +5: 2720 +5: 2721 +5: 2722 +5: 2723 +5: 2724 +5: 2725 +5: 2726 +5: 2727 +5: 2728 +5: 2729 +5: 2730 +5: 2731 +5: 2732 +5: 2733 +5: 2734 +5: 2735 +5: 2736 +5: 2737 +5: 2738 +5: 2739 +5: 2740 +5: 2741 +5: 2742 +5: 2743 +5: 2744 +5: 2745 +5: 2746 +5: 2747 +5: 2748 +5: 2749 +5: 2750 +5: 2751 +5: 2752 +5: 2753 +5: 2754 +5: 2755 +5: 2756 +5: 2757 +5: 2758 +5: 2759 +5: 2760 +5: 2761 +5: 2762 +5: 2763 +5: 2764 +5: 2765 +5: 2766 +5: 2767 +5: 2768 +5: 2769 +5: 2770 +5: 2771 +5: 2772 +5: 2773 +5: 2774 +5: 2775 +5: 2776 +5: 2777 +5: 2778 +5: 2779 +5: 2780 +5: 2781 +5: 2782 +5: 2783 +5: 2784 +5: 2785 +5: 2786 +5: 2787 +5: 2788 +5: 2789 +5: 2790 +5: 2791 +5: 2792 +5: 2793 +5: 2794 +5: 2795 +5: 2796 +5: 2797 +5: 2798 +5: 2799 +5: 2800 +5: 2801 +5: 2802 +5: 2803 +5: 2804 +5: 2805 +5: 2806 +5: 2807 +5: 2808 +5: 2809 +5: 2810 +5: 2811 +5: 2812 +5: 2813 +5: 2814 +5: 2815 +5: 2816 +5: 2817 +5: 2818 +5: 2819 +5: 2820 +5: 2821 +5: 2822 +5: 2823 +5: 2824 +5: 2825 +5: 2826 +5: 2827 +5: 2828 +5: 2829 +5: 2830 +5: 2831 +5: 2832 +5: 2833 +5: 2834 +5: 2835 +5: 2836 +5: 2837 +5: 2838 +5: 2839 +5: 2840 +5: 2841 +5: 2842 +5: 2843 +5: 2844 +5: 2845 +5: 2846 +5: 2847 +5: 2848 +5: 2849 +5: 2850 +5: 2851 +5: 2852 +5: 2853 +5: 2854 +5: 2855 +5: 2856 +5: 2857 +5: 2858 +5: 2859 +5: 2860 +5: 2861 +5: 2862 +5: 2863 +5: 2864 +5: 2865 +5: 2866 +5: 2867 +5: 2868 +5: 2869 +5: 2870 +5: 2871 +5: 2872 +5: 2873 +5: 2874 +5: 2875 +5: 2876 +5: 2877 +5: 2878 +5: 2879 +5: 2880 +5: 2881 +5: 2882 +5: 2883 +5: 2884 +5: 2885 +5: 2886 +5: 2887 +5: 2888 +5: 2889 +5: 2890 +5: 2891 +5: 2892 +5: 2893 +5: 2894 +5: 2895 +5: 2896 +5: 2897 +5: 2898 +5: 2899 +5: 2900 +5: 2901 +5: 2902 +5: 2903 +5: 2904 +5: 2905 +5: 2906 +5: 2907 +5: 2908 +5: 2909 +5: 2910 +5: 2911 +5: 2912 +5: 2913 +5: 2914 +5: 2915 +5: 2916 +5: 2917 +5: 2918 +5: 2919 +5: 2920 +5: 2921 +5: 2922 +5: 2923 +5: 2924 +5: 2925 +5: 2926 +5: 2927 +5: 2928 +5: 2929 +5: 2930 +5: 2931 +5: 2932 +5: 2933 +5: 2934 +5: 2935 +5: 2936 +5: 2937 +5: 2938 +5: 2939 +5: 2940 +5: 2941 +5: 2942 +5: 2943 +5: 2944 +5: 2945 +5: 2946 +5: 2947 +5: 2948 +5: 2949 +5: 2950 +5: 2951 +5: 2952 +5: 2953 +5: 2954 +5: 2955 +5: 2956 +5: 2957 +5: 2958 +5: 2959 +5: 2960 +5: 2961 +5: 2962 +5: 2963 +5: 2964 +5: 2965 +5: 2966 +5: 2967 +5: 2968 +5: 2969 +5: 2970 +5: 2971 +5: 2972 +5: 2973 +5: 2974 +5: 2975 +5: 2976 +5: 2977 +5: 2978 +5: 2979 +5: 2980 +5: 2981 +5: 2982 +5: 2983 +5: 2984 +5: 2985 +5: 2986 +5: 2987 +5: 2988 +5: 2989 +5: 2990 +5: 2991 +5: 2992 +5: 2993 +5: 2994 +5: 2995 +5: 2996 +5: 2997 +5: 2998 +5: 2999 +5: 3000 +5: 3001 +5: 3002 +5: 3003 +5: 3004 +5: 3005 +5: 3006 +5: 3007 +5: 3008 +5: 3009 +5: 3010 +5: 3011 +5: 3012 +5: 3013 +5: 3014 +5: 3015 +5: 3016 +5: 3017 +5: 3018 +5: 3019 +5: 3020 +5: 3021 +5: 3022 +5: 3023 +5: 3024 +5: 3025 +5: 3026 +5: 3027 +5: 3028 +5: 3029 +5: 3030 +5: 3031 +5: 3032 +5: 3033 +5: 3034 +5: 3035 +5: 3036 +5: 3037 +5: 3038 +5: 3039 +5: 3040 +5: 3041 +5: 3042 +5: 3043 +5: 3044 +5: 3045 +5: 3046 +5: 3047 +5: 3048 +5: 3049 +5: 3050 +5: 3051 +5: 3052 +5: 3053 +5: 3054 +5: 3055 +5: 3056 +5: 3057 +5: 3058 +5: 3059 +5: 3060 +5: 3061 +5: 3062 +5: 3063 +5: 3064 +5: 3065 +5: 3066 +5: 3067 +5: 3068 +5: 3069 +5: 3070 +5: 3071 +5: 3072 +5: 3073 +5: 3074 +5: 3075 +5: 3076 +5: 3077 +5: 3078 +5: 3079 +5: 3080 +5: 3081 +5: 3082 +5: 3083 +5: 3084 +5: 3085 +5: 3086 +5: 3087 +5: 3088 +5: 3089 +5: 3090 +5: 3091 +5: 3092 +5: 3093 +5: 3094 +5: 3095 +5: 3096 +5: 3097 +5: 3098 +5: 3099 +5: 3100 +5: 3101 +5: 3102 +5: 3103 +5: 3104 +5: 3105 +5: 3106 +5: 3107 +5: 3108 +5: 3109 +5: 3110 +5: 3111 +5: 3112 +5: 3113 +5: 3114 +5: 3115 +5: 3116 +5: 3117 +5: 3118 +5: 3119 +5: 3120 +5: 3121 +5: 3122 +5: 3123 +5: 3124 +5: 3125 +5: 3126 +5: 3127 +5: 3128 +5: 3129 +5: 3130 +5: 3131 +5: 3132 +5: 3133 +5: 3134 +5: 3135 +5: 3136 +5: 3137 +5: 3138 +5: 3139 +5: 3140 +5: 3141 +5: 3142 +5: 3143 +5: 3144 +5: 3145 +5: 3146 +5: 3147 +5: 3148 +5: 3149 +5: 3150 +5: 3151 +5: 3152 +5: 3153 +5: 3154 +5: 3155 +5: 3156 +5: 3157 +5: 3158 +5: 3159 +5: 3160 +5: 3161 +5: 3162 +5: 3163 +5: 3164 +5: 3165 +5: 3166 +5: 3167 +5: 3168 +5: 3169 +5: 3170 +5: 3171 +5: 3172 +5: 3173 +5: 3174 +5: 3175 +5: 3176 +5: 3177 +5: 3178 +5: 3179 +5: 3180 +5: 3181 +5: 3182 +5: 3183 +5: 3184 +5: 3185 +5: 3186 +5: 3187 +5: 3188 +5: 3189 +5: 3190 +5: 3191 +5: 3192 +5: 3193 +5: 3194 +5: 3195 +5: 3196 +5: 3197 +5: 3198 +5: 3199 +5: 3200 +5: 3201 +5: 3202 +5: 3203 +5: 3204 +5: 3205 +5: 3206 +5: 3207 +5: 3208 +5: 3209 +5: 3210 +5: 3211 +5: 3212 +5: 3213 +5: 3214 +5: 3215 +5: 3216 +5: 3217 +5: 3218 +5: 3219 +5: 3220 +4: 3221 +4: 3222 +4: 3223 +4: 3224 +4: 3225 +4: 3226 +4: 3227 +4: 3228 +4: 3229 +4: 3230 +4: 3231 +4: 3232 +4: 3233 +4: 3234 +4: 3235 +4: 3236 +4: 3237 +4: 3238 +4: 3239 +4: 3240 +4: 3241 +4: 3242 +4: 3243 +4: 3244 +4: 3245 +4: 3246 +4: 3247 +4: 3248 +4: 3249 +4: 3250 +4: 3251 +4: 3252 +4: 3253 +4: 3254 +4: 3255 +4: 3256 +4: 3257 +4: 3258 +4: 3259 +4: 3260 +4: 3261 +4: 3262 +4: 3263 +4: 3264 +4: 3265 +4: 3266 +4: 3267 +4: 3268 +4: 3269 +4: 3270 +4: 3271 +4: 3272 +4: 3273 +4: 3274 +4: 3275 +4: 3276 +4: 3277 +4: 3278 +4: 3279 +4: 3280 +4: 3281 +4: 3282 +4: 3283 +4: 3284 +4: 3285 +4: 3286 +4: 3287 +4: 3288 +4: 3289 +4: 3290 +4: 3291 +4: 3292 +4: 3293 +4: 3294 +4: 3295 +4: 3296 +4: 3297 +4: 3298 +4: 3299 +4: 3300 +4: 3301 +4: 3302 +4: 3303 +4: 3304 +4: 3305 +4: 3306 +4: 3307 +4: 3308 +4: 3309 +4: 3310 +4: 3311 +4: 3312 +4: 3313 +4: 3314 +4: 3315 +4: 3316 +4: 3317 +4: 3318 +4: 3319 +4: 3320 +4: 3321 +4: 3322 +4: 3323 +4: 3324 +4: 3325 +4: 3326 +4: 3327 +4: 3328 +4: 3329 +4: 3330 +4: 3331 +4: 3332 +4: 3333 +4: 3334 +4: 3335 +4: 3336 +4: 3337 +4: 3338 +4: 3339 +4: 3340 +4: 3341 +4: 3342 +4: 3343 +4: 3344 +4: 3345 +4: 3346 +4: 3347 +4: 3348 +4: 3349 +4: 3350 +4: 3351 +4: 3352 +4: 3353 +4: 3354 +4: 3355 +4: 3356 +4: 3357 +4: 3358 +4: 3359 +4: 3360 +4: 3361 +4: 3362 +4: 3363 +4: 3364 +4: 3365 +4: 3366 +4: 3367 +4: 3368 +4: 3369 +4: 3370 +4: 3371 +4: 3372 +4: 3373 +4: 3374 +4: 3375 +4: 3376 +4: 3377 +4: 3378 +4: 3379 +4: 3380 +4: 3381 +4: 3382 +4: 3383 +4: 3384 +4: 3385 +4: 3386 +4: 3387 +4: 3388 +4: 3389 +4: 3390 +4: 3391 +4: 3392 +4: 3393 +4: 3394 +4: 3395 +4: 3396 +4: 3397 +4: 3398 +4: 3399 +4: 3400 +4: 3401 +4: 3402 +4: 3403 +4: 3404 +4: 3405 +4: 3406 +4: 3407 +4: 3408 +4: 3409 +4: 3410 +4: 3411 +4: 3412 +4: 3413 +4: 3414 +4: 3415 +4: 3416 +4: 3417 +4: 3418 +4: 3419 +4: 3420 +4: 3421 +4: 3422 +4: 3423 +4: 3424 +4: 3425 +4: 3426 +4: 3427 +4: 3428 +4: 3429 +4: 3430 +4: 3431 +4: 3432 +4: 3433 +4: 3434 +4: 3435 +4: 3436 +4: 3437 +4: 3438 +4: 3439 +4: 3440 +4: 3441 +4: 3442 +4: 3443 +4: 3444 +4: 3445 +4: 3446 +4: 3447 +4: 3448 +4: 3449 +4: 3450 +4: 3451 +4: 3452 +4: 3453 +4: 3454 +4: 3455 +4: 3456 +4: 3457 +4: 3458 +4: 3459 +4: 3460 +4: 3461 +4: 3462 +4: 3463 +4: 3464 +4: 3465 +4: 3466 +4: 3467 +4: 3468 +4: 3469 +4: 3470 +4: 3471 +4: 3472 +4: 3473 +4: 3474 +4: 3475 +4: 3476 +4: 3477 +4: 3478 +4: 3479 +4: 3480 +4: 3481 +4: 3482 +4: 3483 +4: 3484 +4: 3485 +4: 3486 +4: 3487 +4: 3488 +4: 3489 +4: 3490 +4: 3491 +4: 3492 +4: 3493 +4: 3494 +4: 3495 +4: 3496 +4: 3497 +4: 3498 +4: 3499 +4: 3500 +4: 3501 +4: 3502 +4: 3503 +4: 3504 +4: 3505 +4: 3506 +4: 3507 +4: 3508 +4: 3509 +4: 3510 +4: 3511 +4: 3512 +4: 3513 +4: 3514 +4: 3515 +4: 3516 +4: 3517 +4: 3518 +4: 3519 +4: 3520 +4: 3521 +4: 3522 +4: 3523 +4: 3524 +4: 3525 +4: 3526 +4: 3527 +4: 3528 +4: 3529 +4: 3530 +4: 3531 +4: 3532 +4: 3533 +4: 3534 +4: 3535 +4: 3536 +4: 3537 +4: 3538 +4: 3539 +4: 3540 +4: 3541 +4: 3542 +4: 3543 +4: 3544 +4: 3545 +4: 3546 +4: 3547 +4: 3548 +4: 3549 +4: 3550 +4: 3551 +4: 3552 +4: 3553 +4: 3554 +4: 3555 +4: 3556 +4: 3557 +4: 3558 +4: 3559 +4: 3560 +4: 3561 +4: 3562 +4: 3563 +4: 3564 +4: 3565 +4: 3566 +4: 3567 +4: 3568 +4: 3569 +4: 3570 +4: 3571 +4: 3572 +4: 3573 +4: 3574 +4: 3575 +4: 3576 +4: 3577 +4: 3578 +4: 3579 +4: 3580 +4: 3581 +4: 3582 +4: 3583 +4: 3584 +4: 3585 +4: 3586 +4: 3587 +4: 3588 +4: 3589 +4: 3590 +4: 3591 +4: 3592 +4: 3593 +4: 3594 +4: 3595 +4: 3596 +4: 3597 +4: 3598 +4: 3599 +4: 3600 +4: 3601 +4: 3602 +4: 3603 +4: 3604 +4: 3605 +4: 3606 +4: 3607 +4: 3608 +4: 3609 +4: 3610 +4: 3611 +4: 3612 +4: 3613 +4: 3614 +4: 3615 +4: 3616 +4: 3617 +4: 3618 +4: 3619 +4: 3620 +4: 3621 +4: 3622 +4: 3623 +4: 3624 +4: 3625 +4: 3626 +4: 3627 +4: 3628 +4: 3629 +4: 3630 +4: 3631 +4: 3632 +4: 3633 +4: 3634 +4: 3635 +4: 3636 +4: 3637 +4: 3638 +4: 3639 +4: 3640 +4: 3641 +4: 3642 +4: 3643 +4: 3644 +4: 3645 +4: 3646 +4: 3647 +4: 3648 +4: 3649 +4: 3650 +4: 3651 +4: 3652 +4: 3653 +4: 3654 +4: 3655 +4: 3656 +4: 3657 +4: 3658 +4: 3659 +4: 3660 +4: 3661 +4: 3662 +4: 3663 +4: 3664 +4: 3665 +4: 3666 +4: 3667 +4: 3668 +4: 3669 +4: 3670 +4: 3671 +4: 3672 +4: 3673 +4: 3674 +4: 3675 +4: 3676 +4: 3677 +4: 3678 +4: 3679 +4: 3680 +4: 3681 +4: 3682 +4: 3683 +4: 3684 +4: 3685 +4: 3686 +4: 3687 +4: 3688 +4: 3689 +4: 3690 +4: 3691 +4: 3692 +4: 3693 +4: 3694 +4: 3695 +4: 3696 +4: 3697 +4: 3698 +4: 3699 +4: 3700 +4: 3701 +4: 3702 +4: 3703 +4: 3704 +4: 3705 +4: 3706 +4: 3707 +4: 3708 +4: 3709 +4: 3710 +4: 3711 +4: 3712 +5: 3713 +5: 3714 +5: 3715 +5: 3716 +5: 3717 +5: 3718 +5: 3719 +5: 3720 +5: 3721 +5: 3722 +5: 3723 +5: 3724 +5: 3725 +5: 3726 +5: 3727 +5: 3728 +5: 3729 +5: 3730 +5: 3731 +5: 3732 +5: 3733 +5: 3734 +5: 3735 +5: 3736 +5: 3737 +5: 3738 +5: 3739 +5: 3740 +5: 3741 +5: 3742 +5: 3743 +5: 3744 +5: 3745 +5: 3746 +5: 3747 +5: 3748 +5: 3749 +5: 3750 +5: 3751 +5: 3752 +5: 3753 +5: 3754 +5: 3755 +5: 3756 +5: 3757 +5: 3758 +5: 3759 +5: 3760 +5: 3761 +5: 3762 +5: 3763 +5: 3764 +5: 3765 +5: 3766 +5: 3767 +5: 3768 +5: 3769 +5: 3770 +5: 3771 +5: 3772 +5: 3773 +5: 3774 +5: 3775 +5: 3776 +5: 3777 +5: 3778 +5: 3779 +5: 3780 +5: 3781 +5: 3782 +5: 3783 +5: 3784 +5: 3785 +5: 3786 +5: 3787 +5: 3788 +5: 3789 +5: 3790 +5: 3791 +5: 3792 +5: 3793 +5: 3794 +5: 3795 +5: 3796 +5: 3797 +5: 3798 +5: 3799 +5: 3800 +5: 3801 +5: 3802 +5: 3803 +5: 3804 +5: 3805 +5: 3806 +5: 3807 +5: 3808 +5: 3809 +5: 3810 +5: 3811 +5: 3812 +5: 3813 +5: 3814 +5: 3815 +5: 3816 +5: 3817 +5: 3818 +5: 3819 +5: 3820 +5: 3821 +5: 3822 +5: 3823 +5: 3824 +5: 3825 +5: 3826 +5: 3827 +5: 3828 +5: 3829 +5: 3830 +5: 3831 +5: 3832 +5: 3833 +5: 3834 +5: 3835 +5: 3836 +5: 3837 +5: 3838 +5: 3839 +5: 3840 +5: 3841 +5: 3842 +5: 3843 +5: 3844 +5: 3845 +5: 3846 +5: 3847 +5: 3848 +5: 3849 +5: 3850 +5: 3851 +5: 3852 +5: 3853 +5: 3854 +5: 3855 +5: 3856 +5: 3857 +5: 3858 +5: 3859 +5: 3860 +5: 3861 +5: 3862 +5: 3863 +5: 3864 +5: 3865 +5: 3866 +5: 3867 +5: 3868 +5: 3869 +5: 3870 +5: 3871 +5: 3872 +5: 3873 +5: 3874 +5: 3875 +5: 3876 +5: 3877 +5: 3878 +5: 3879 +5: 3880 +5: 3881 +5: 3882 +5: 3883 +5: 3884 +5: 3885 +5: 3886 +5: 3887 +5: 3888 +5: 3889 +5: 3890 +5: 3891 +5: 3892 +5: 3893 +5: 3894 +5: 3895 +5: 3896 +5: 3897 +5: 3898 +5: 3899 +5: 3900 +5: 3901 +5: 3902 +5: 3903 +5: 3904 +5: 3905 +5: 3906 +5: 3907 +5: 3908 +5: 3909 +5: 3910 +5: 3911 +5: 3912 +5: 3913 +5: 3914 +5: 3915 +5: 3916 +5: 3917 +5: 3918 +5: 3919 +5: 3920 +5: 3921 +5: 3922 +5: 3923 +5: 3924 +5: 3925 +5: 3926 +5: 3927 +5: 3928 +5: 3929 +5: 3930 +5: 3931 +5: 3932 +5: 3933 +5: 3934 +5: 3935 +5: 3936 +5: 3937 +5: 3938 +5: 3939 +5: 3940 +5: 3941 +5: 3942 +5: 3943 +5: 3944 +5: 3945 +5: 3946 +5: 3947 +5: 3948 +5: 3949 +5: 3950 +5: 3951 +5: 3952 +5: 3953 +5: 3954 +5: 3955 +5: 3956 +5: 3957 +5: 3958 +5: 3959 +5: 3960 +5: 3961 +5: 3962 +5: 3963 +5: 3964 +5: 3965 +5: 3966 +5: 3967 +5: 3968 +5: 3969 +5: 3970 +5: 3971 +5: 3972 +5: 3973 +5: 3974 +5: 3975 +5: 3976 +5: 3977 +5: 3978 +5: 3979 +5: 3980 +5: 3981 +5: 3982 +5: 3983 +5: 3984 +5: 3985 +5: 3986 +5: 3987 +5: 3988 +5: 3989 +5: 3990 +5: 3991 +5: 3992 +5: 3993 +5: 3994 +5: 3995 +5: 3996 +5: 3997 +5: 3998 +5: 3999 +5: 4000 +5: 4001 +5: 4002 +5: 4003 +5: 4004 +4: 4005 +4: 4006 +4: 4007 +4: 4008 +4: 4009 +4: 4010 +4: 4011 +4: 4012 +4: 4013 +4: 4014 +4: 4015 +4: 4016 +4: 4017 +4: 4018 +4: 4019 +4: 4020 +4: 4021 +4: 4022 +4: 4023 +4: 4024 +4: 4025 +4: 4026 +4: 4027 +4: 4028 +4: 4029 +4: 4030 +4: 4031 +4: 4032 +4: 4033 +4: 4034 +4: 4035 +4: 4036 +4: 4037 +4: 4038 +4: 4039 +4: 4040 +4: 4041 +4: 4042 +4: 4043 +4: 4044 +4: 4045 +4: 4046 +4: 4047 +4: 4048 +4: 4049 +4: 4050 +4: 4051 +4: 4052 +4: 4053 +4: 4054 +4: 4055 +4: 4056 +4: 4057 +4: 4058 +4: 4059 +4: 4060 +4: 4061 +4: 4062 +4: 4063 +4: 4064 +4: 4065 +4: 4066 +4: 4067 +4: 4068 +4: 4069 +4: 4070 +4: 4071 +4: 4072 +4: 4073 +4: 4074 +4: 4075 +4: 4076 +4: 4077 +4: 4078 +4: 4079 +4: 4080 +4: 4081 +4: 4082 +4: 4083 +4: 4084 +4: 4085 +4: 4086 +4: 4087 +4: 4088 +4: 4089 +4: 4090 +4: 4091 +4: 4092 +4: 4093 +4: 4094 +4: 4095 +4: 4096 +4: 4097 +4: 4098 +4: 4099 +4: 4100 +4: 4101 +4: 4102 +4: 4103 +4: 4104 +4: 4105 +4: 4106 +4: 4107 +4: 4108 +4: 4109 +4: 4110 +4: 4111 +4: 4112 +4: 4113 +4: 4114 +4: 4115 +4: 4116 +4: 4117 +4: 4118 +4: 4119 +4: 4120 +4: 4121 +4: 4122 +4: 4123 +4: 4124 +4: 4125 +4: 4126 +4: 4127 +4: 4128 +4: 4129 +4: 4130 +4: 4131 +4: 4132 +4: 4133 +4: 4134 +4: 4135 +4: 4136 +4: 4137 +4: 4138 +4: 4139 +4: 4140 +4: 4141 +4: 4142 +4: 4143 +4: 4144 +4: 4145 +4: 4146 +4: 4147 +4: 4148 +4: 4149 +4: 4150 +4: 4151 +4: 4152 +4: 4153 +4: 4154 +4: 4155 +4: 4156 +4: 4157 +4: 4158 +4: 4159 +4: 4160 +4: 4161 +4: 4162 +4: 4163 +4: 4164 +4: 4165 +4: 4166 +4: 4167 +4: 4168 +4: 4169 +4: 4170 +4: 4171 +4: 4172 +4: 4173 +4: 4174 +4: 4175 +4: 4176 +4: 4177 +4: 4178 +4: 4179 +4: 4180 +4: 4181 +4: 4182 +4: 4183 +4: 4184 +4: 4185 +4: 4186 +4: 4187 +4: 4188 +4: 4189 +4: 4190 +4: 4191 +4: 4192 +4: 4193 +4: 4194 +4: 4195 +4: 4196 +4: 4197 +4: 4198 +4: 4199 +4: 4200 +4: 4201 +4: 4202 +4: 4203 +4: 4204 +4: 4205 +4: 4206 +4: 4207 +4: 4208 +4: 4209 +4: 4210 +4: 4211 +4: 4212 +4: 4213 +4: 4214 +4: 4215 +4: 4216 +4: 4217 +4: 4218 +4: 4219 +4: 4220 +4: 4221 +4: 4222 +4: 4223 +4: 4224 +4: 4225 +4: 4226 +4: 4227 +4: 4228 +4: 4229 +4: 4230 +4: 4231 +4: 4232 +4: 4233 +4: 4234 +4: 4235 +4: 4236 +4: 4237 +4: 4238 +4: 4239 +4: 4240 +4: 4241 +4: 4242 +4: 4243 +4: 4244 +4: 4245 +4: 4246 +4: 4247 +4: 4248 +4: 4249 +4: 4250 +4: 4251 +4: 4252 +4: 4253 +4: 4254 +4: 4255 +4: 4256 +4: 4257 +4: 4258 +4: 4259 +4: 4260 +4: 4261 +4: 4262 +4: 4263 +4: 4264 +4: 4265 +4: 4266 +4: 4267 +4: 4268 +4: 4269 +4: 4270 +4: 4271 +4: 4272 +4: 4273 +4: 4274 +4: 4275 +4: 4276 +4: 4277 +4: 4278 +4: 4279 +4: 4280 +4: 4281 +4: 4282 +4: 4283 +4: 4284 +4: 4285 +4: 4286 +4: 4287 +4: 4288 +4: 4289 +4: 4290 +4: 4291 +4: 4292 +4: 4293 +4: 4294 +4: 4295 +4: 4296 +4: 4297 +4: 4298 +4: 4299 +4: 4300 +4: 4301 +4: 4302 +4: 4303 +4: 4304 +4: 4305 +4: 4306 +4: 4307 +4: 4308 +4: 4309 +4: 4310 +4: 4311 +4: 4312 +4: 4313 +4: 4314 +4: 4315 +4: 4316 +4: 4317 +4: 4318 +4: 4319 +4: 4320 +4: 4321 +5: 4322 +5: 4323 +5: 4324 +5: 4325 +5: 4326 +5: 4327 +5: 4328 +5: 4329 +5: 4330 +5: 4331 +5: 4332 +5: 4333 +5: 4334 +5: 4335 +5: 4336 +5: 4337 +5: 4338 +5: 4339 +5: 4340 +5: 4341 +5: 4342 +5: 4343 +5: 4344 +5: 4345 +5: 4346 +5: 4347 +5: 4348 +5: 4349 +5: 4350 +5: 4351 +5: 4352 +5: 4353 +5: 4354 +5: 4355 +5: 4356 +5: 4357 +5: 4358 +5: 4359 +5: 4360 +5: 4361 +5: 4362 +5: 4363 +5: 4364 +5: 4365 +5: 4366 +5: 4367 +5: 4368 +5: 4369 +5: 4370 +5: 4371 +5: 4372 +5: 4373 +5: 4374 +5: 4375 +5: 4376 +5: 4377 +5: 4378 +5: 4379 +5: 4380 +5: 4381 +5: 4382 +5: 4383 +5: 4384 +5: 4385 +5: 4386 +5: 4387 +5: 4388 +5: 4389 +5: 4390 +5: 4391 +5: 4392 +5: 4393 +5: 4394 +5: 4395 +5: 4396 +5: 4397 +5: 4398 +5: 4399 +5: 4400 +5: 4401 +5: 4402 +5: 4403 +5: 4404 +5: 4405 +5: 4406 +5: 4407 +5: 4408 +5: 4409 +5: 4410 +5: 4411 +5: 4412 +5: 4413 +5: 4414 +5: 4415 +5: 4416 +5: 4417 +5: 4418 +5: 4419 +5: 4420 +5: 4421 +5: 4422 +5: 4423 +5: 4424 +5: 4425 +5: 4426 +5: 4427 +5: 4428 +5: 4429 +5: 4430 +5: 4431 +5: 4432 +5: 4433 +5: 4434 +5: 4435 +5: 4436 +5: 4437 +5: 4438 +5: 4439 +5: 4440 +5: 4441 +5: 4442 +5: 4443 +5: 4444 +5: 4445 +5: 4446 +5: 4447 +5: 4448 +5: 4449 +5: 4450 +5: 4451 +5: 4452 +5: 4453 +5: 4454 +5: 4455 +5: 4456 +5: 4457 +5: 4458 +5: 4459 +5: 4460 +5: 4461 +5: 4462 +5: 4463 +5: 4464 +5: 4465 +5: 4466 +5: 4467 +5: 4468 +5: 4469 +5: 4470 +5: 4471 +5: 4472 +5: 4473 +5: 4474 +5: 4475 +5: 4476 +5: 4477 +5: 4478 +5: 4479 +5: 4480 +5: 4481 +5: 4482 +5: 4483 +5: 4484 +5: 4485 +5: 4486 +5: 4487 +5: 4488 +5: 4489 +5: 4490 +5: 4491 +5: 4492 +5: 4493 +5: 4494 +5: 4495 +5: 4496 +5: 4497 +5: 4498 +5: 4499 +5: 4500 +5: 4501 +5: 4502 +5: 4503 +5: 4504 +5: 4505 +5: 4506 +5: 4507 +5: 4508 +5: 4509 +5: 4510 +5: 4511 +5: 4512 +5: 4513 +5: 4514 +5: 4515 +5: 4516 +5: 4517 +5: 4518 +5: 4519 +5: 4520 +5: 4521 +5: 4522 +5: 4523 +5: 4524 +5: 4525 +5: 4526 +5: 4527 +5: 4528 +5: 4529 +5: 4530 +5: 4531 +5: 4532 +5: 4533 +5: 4534 +5: 4535 +5: 4536 +5: 4537 +5: 4538 +5: 4539 +5: 4540 +5: 4541 +5: 4542 +5: 4543 +5: 4544 +5: 4545 +5: 4546 +5: 4547 +5: 4548 +5: 4549 +5: 4550 +5: 4551 +5: 4552 +5: 4553 +5: 4554 +5: 4555 +5: 4556 +5: 4557 +5: 4558 +5: 4559 +5: 4560 +5: 4561 +5: 4562 +5: 4563 +5: 4564 +5: 4565 +5: 4566 +5: 4567 +5: 4568 +5: 4569 +5: 4570 +5: 4571 +5: 4572 +5: 4573 +5: 4574 +5: 4575 +5: 4576 +5: 4577 +5: 4578 +5: 4579 +5: 4580 +5: 4581 +5: 4582 +5: 4583 +5: 4584 +5: 4585 +5: 4586 +5: 4587 +5: 4588 +5: 4589 +5: 4590 +5: 4591 +5: 4592 +5: 4593 +5: 4594 +5: 4595 +5: 4596 +5: 4597 +5: 4598 +5: 4599 +5: 4600 +5: 4601 +5: 4602 +5: 4603 +5: 4604 +5: 4605 +5: 4606 +5: 4607 +5: 4608 +5: 4609 +5: 4610 +5: 4611 +5: 4612 +5: 4613 +5: 4614 +5: 4615 +5: 4616 +5: 4617 +5: 4618 +5: 4619 +5: 4620 +5: 4621 +5: 4622 +5: 4623 +5: 4624 +5: 4625 +5: 4626 +5: 4627 +5: 4628 +5: 4629 +5: 4630 +5: 4631 +5: 4632 +5: 4633 +5: 4634 +5: 4635 +5: 4636 +5: 4637 +5: 4638 +5: 4639 +5: 4640 +5: 4641 +5: 4642 +5: 4643 +5: 4644 +5: 4645 +5: 4646 +5: 4647 +5: 4648 +5: 4649 +5: 4650 +5: 4651 +5: 4652 +5: 4653 +5: 4654 +5: 4655 +5: 4656 +5: 4657 +5: 4658 +5: 4659 +5: 4660 +5: 4661 +5: 4662 +5: 4663 +5: 4664 +5: 4665 +5: 4666 +5: 4667 +5: 4668 +5: 4669 +5: 4670 +5: 4671 +5: 4672 +5: 4673 +5: 4674 +5: 4675 +5: 4676 +5: 4677 +5: 4678 +5: 4679 +5: 4680 +5: 4681 +5: 4682 +5: 4683 +5: 4684 +5: 4685 +5: 4686 +5: 4687 +5: 4688 +5: 4689 +5: 4690 +5: 4691 +5: 4692 +5: 4693 +5: 4694 +5: 4695 +5: 4696 +5: 4697 +5: 4698 +5: 4699 +5: 4700 +5: 4701 +5: 4702 +5: 4703 +5: 4704 +5: 4705 +5: 4706 +5: 4707 +5: 4708 +5: 4709 +5: 4710 +5: 4711 +5: 4712 +5: 4713 +5: 4714 +5: 4715 +5: 4716 +5: 4717 +5: 4718 +5: 4719 +5: 4720 +5: 4721 +5: 4722 +5: 4723 +5: 4724 +5: 4725 +5: 4726 +5: 4727 +5: 4728 +5: 4729 +5: 4730 +5: 4731 +5: 4732 +5: 4733 +5: 4734 +5: 4735 +5: 4736 +5: 4737 +5: 4738 +5: 4739 +5: 4740 +5: 4741 +5: 4742 +5: 4743 +5: 4744 +5: 4745 +5: 4746 +5: 4747 +5: 4748 +5: 4749 +5: 4750 +5: 4751 +5: 4752 +5: 4753 +5: 4754 +5: 4755 +5: 4756 +5: 4757 +5: 4758 +5: 4759 +5: 4760 +5: 4761 +5: 4762 +5: 4763 +5: 4764 +5: 4765 +5: 4766 +5: 4767 +5: 4768 +5: 4769 +5: 4770 +5: 4771 +5: 4772 +5: 4773 +5: 4774 +5: 4775 +5: 4776 +5: 4777 +5: 4778 +5: 4779 +5: 4780 +5: 4781 +5: 4782 +5: 4783 +5: 4784 +5: 4785 +5: 4786 +5: 4787 +5: 4788 +5: 4789 +5: 4790 +5: 4791 +5: 4792 +5: 4793 +5: 4794 +5: 4795 +5: 4796 +5: 4797 +5: 4798 +5: 4799 +5: 4800 +5: 4801 +5: 4802 +5: 4803 +5: 4804 +5: 4805 +5: 4806 +5: 4807 +5: 4808 +5: 4809 +5: 4810 +5: 4811 +5: 4812 +5: 4813 +5: 4814 +5: 4815 +5: 4816 +5: 4817 +5: 4818 +5: 4819 +5: 4820 +5: 4821 +5: 4822 +5: 4823 +5: 4824 +5: 4825 +5: 4826 +5: 4827 +5: 4828 +5: 4829 +5: 4830 +5: 4831 +5: 4832 +5: 4833 +5: 4834 +5: 4835 +5: 4836 +5: 4837 +5: 4838 +5: 4839 +5: 4840 +5: 4841 +5: 4842 +5: 4843 +5: 4844 +5: 4845 +5: 4846 +5: 4847 +5: 4848 +5: 4849 +5: 4850 +5: 4851 +5: 4852 +5: 4853 +5: 4854 +5: 4855 +5: 4856 +5: 4857 +5: 4858 +5: 4859 +5: 4860 +5: 4861 +5: 4862 +5: 4863 +5: 4864 +5: 4865 +5: 4866 +5: 4867 +5: 4868 +5: 4869 +5: 4870 +5: 4871 +5: 4872 +5: 4873 +5: 4874 +5: 4875 +5: 4876 +5: 4877 +5: 4878 +5: 4879 +5: 4880 +5: 4881 +5: 4882 +5: 4883 +5: 4884 +5: 4885 +5: 4886 +5: 4887 +5: 4888 +5: 4889 +5: 4890 +5: 4891 +5: 4892 +5: 4893 +5: 4894 +5: 4895 +5: 4896 +5: 4897 +5: 4898 +5: 4899 +5: 4900 +5: 4901 +5: 4902 +5: 4903 +5: 4904 +5: 4905 +5: 4906 +5: 4907 +5: 4908 +5: 4909 +5: 4910 +5: 4911 +5: 4912 +5: 4913 +5: 4914 +5: 4915 +5: 4916 +5: 4917 +5: 4918 +5: 4919 +5: 4920 +5: 4921 +5: 4922 +5: 4923 +5: 4924 +5: 4925 +5: 4926 +5: 4927 +5: 4928 +5: 4929 +5: 4930 +5: 4931 +5: 4932 +5: 4933 +5: 4934 +5: 4935 +5: 4936 +5: 4937 +5: 4938 +5: 4939 +5: 4940 +5: 4941 +5: 4942 +5: 4943 +5: 4944 +5: 4945 +5: 4946 +5: 4947 +5: 4948 +5: 4949 +5: 4950 +5: 4951 +5: 4952 +5: 4953 +5: 4954 +5: 4955 +5: 4956 +5: 4957 +5: 4958 +5: 4959 +5: 4960 +5: 4961 +5: 4962 +5: 4963 +5: 4964 +5: 4965 +5: 4966 +5: 4967 +5: 4968 +5: 4969 +5: 4970 +5: 4971 +5: 4972 +5: 4973 +5: 4974 +5: 4975 +5: 4976 +5: 4977 +5: 4978 +5: 4979 +5: 4980 +5: 4981 +5: 4982 +5: 4983 +5: 4984 +4: 4985 +4: 4986 +4: 4987 +4: 4988 +4: 4989 +4: 4990 +4: 4991 +4: 4992 +4: 4993 +4: 4994 +4: 4995 +4: 4996 +4: 4997 +4: 4998 +4: 4999 +4: 5000 +4: 5001 +4: 5002 +4: 5003 +4: 5004 +4: 5005 +4: 5006 +4: 5007 +4: 5008 +4: 5009 +4: 5010 +4: 5011 +4: 5012 +4: 5013 +4: 5014 +4: 5015 +4: 5016 +4: 5017 +4: 5018 +4: 5019 +4: 5020 +4: 5021 +4: 5022 +4: 5023 +4: 5024 +4: 5025 +4: 5026 +4: 5027 +4: 5028 +4: 5029 +4: 5030 +4: 5031 +4: 5032 +4: 5033 +4: 5034 +4: 5035 +4: 5036 +4: 5037 +4: 5038 +4: 5039 +4: 5040 +4: 5041 +4: 5042 +4: 5043 +4: 5044 +4: 5045 +4: 5046 +4: 5047 +4: 5048 +4: 5049 +4: 5050 +4: 5051 +4: 5052 +4: 5053 +4: 5054 +4: 5055 +4: 5056 +4: 5057 +4: 5058 +4: 5059 +4: 5060 +4: 5061 +4: 5062 +4: 5063 +4: 5064 +4: 5065 +4: 5066 +4: 5067 +4: 5068 +4: 5069 +4: 5070 +4: 5071 +4: 5072 +4: 5073 +4: 5074 +4: 5075 +4: 5076 +4: 5077 +4: 5078 +4: 5079 +4: 5080 +4: 5081 +4: 5082 +4: 5083 +4: 5084 +4: 5085 +4: 5086 +4: 5087 +4: 5088 +4: 5089 +4: 5090 +4: 5091 +4: 5092 +4: 5093 +4: 5094 +4: 5095 +4: 5096 +4: 5097 +4: 5098 +4: 5099 +4: 5100 +4: 5101 +4: 5102 +4: 5103 +4: 5104 +4: 5105 +4: 5106 +4: 5107 +4: 5108 +4: 5109 +4: 5110 +4: 5111 +4: 5112 +4: 5113 +4: 5114 +4: 5115 +4: 5116 +4: 5117 +4: 5118 +4: 5119 +4: 5120 +4: 5121 +4: 5122 +4: 5123 +4: 5124 +4: 5125 +4: 5126 +4: 5127 +4: 5128 +4: 5129 +4: 5130 +4: 5131 +4: 5132 +4: 5133 +4: 5134 +4: 5135 +4: 5136 +4: 5137 +4: 5138 +4: 5139 +4: 5140 +4: 5141 +4: 5142 +4: 5143 +4: 5144 +4: 5145 +4: 5146 +4: 5147 +4: 5148 +4: 5149 +4: 5150 +4: 5151 +4: 5152 +4: 5153 +4: 5154 +4: 5155 +4: 5156 +4: 5157 +4: 5158 +4: 5159 +4: 5160 +4: 5161 +4: 5162 +4: 5163 +4: 5164 +4: 5165 +4: 5166 +4: 5167 +4: 5168 +4: 5169 +4: 5170 +4: 5171 +4: 5172 +4: 5173 +4: 5174 +4: 5175 +4: 5176 +4: 5177 +4: 5178 +4: 5179 +4: 5180 +4: 5181 +4: 5182 +4: 5183 +4: 5184 +4: 5185 +4: 5186 +4: 5187 +4: 5188 +4: 5189 +4: 5190 +4: 5191 +4: 5192 +4: 5193 +4: 5194 +4: 5195 +4: 5196 +4: 5197 +4: 5198 +4: 5199 +4: 5200 +4: 5201 +4: 5202 +4: 5203 +4: 5204 +4: 5205 +4: 5206 +4: 5207 +4: 5208 +4: 5209 +4: 5210 +4: 5211 +4: 5212 +4: 5213 +4: 5214 +4: 5215 +4: 5216 +4: 5217 +4: 5218 +4: 5219 +4: 5220 +4: 5221 +4: 5222 +4: 5223 +4: 5224 +4: 5225 +4: 5226 +4: 5227 +4: 5228 +4: 5229 +4: 5230 +4: 5231 +4: 5232 +4: 5233 +4: 5234 +4: 5235 +4: 5236 +4: 5237 +4: 5238 +4: 5239 +4: 5240 +4: 5241 +4: 5242 +4: 5243 +4: 5244 +4: 5245 +4: 5246 +4: 5247 +4: 5248 +4: 5249 +4: 5250 +4: 5251 +4: 5252 +4: 5253 +4: 5254 +4: 5255 +4: 5256 +4: 5257 +4: 5258 +4: 5259 +4: 5260 +4: 5261 +5: 5262 +5: 5263 +5: 5264 +5: 5265 +5: 5266 +5: 5267 +5: 5268 +5: 5269 +5: 5270 +5: 5271 +5: 5272 +5: 5273 +5: 5274 +5: 5275 +5: 5276 +5: 5277 +5: 5278 +5: 5279 +5: 5280 +5: 5281 +5: 5282 +5: 5283 +5: 5284 +5: 5285 +5: 5286 +5: 5287 +5: 5288 +5: 5289 +5: 5290 +5: 5291 +5: 5292 +5: 5293 +5: 5294 +5: 5295 +5: 5296 +5: 5297 +5: 5298 +5: 5299 +5: 5300 +5: 5301 +5: 5302 +5: 5303 +5: 5304 +5: 5305 +5: 5306 +5: 5307 +5: 5308 +5: 5309 +5: 5310 +5: 5311 +5: 5312 +5: 5313 +5: 5314 +5: 5315 +5: 5316 +5: 5317 +5: 5318 +5: 5319 +5: 5320 +5: 5321 +5: 5322 +5: 5323 +5: 5324 +5: 5325 +5: 5326 +5: 5327 +5: 5328 +5: 5329 +5: 5330 +5: 5331 +5: 5332 +5: 5333 +5: 5334 +5: 5335 +5: 5336 +5: 5337 +5: 5338 +5: 5339 +5: 5340 +5: 5341 +5: 5342 +5: 5343 +5: 5344 +5: 5345 +5: 5346 +5: 5347 +5: 5348 +5: 5349 +5: 5350 +5: 5351 +5: 5352 +5: 5353 +5: 5354 +5: 5355 +5: 5356 +5: 5357 +5: 5358 +5: 5359 +5: 5360 +5: 5361 +5: 5362 +5: 5363 +5: 5364 +5: 5365 +5: 5366 +5: 5367 +5: 5368 +5: 5369 +5: 5370 +5: 5371 +5: 5372 +5: 5373 +5: 5374 +5: 5375 +5: 5376 +5: 5377 +5: 5378 +5: 5379 +5: 5380 +5: 5381 +5: 5382 +5: 5383 +5: 5384 +5: 5385 +5: 5386 +5: 5387 +5: 5388 +5: 5389 +5: 5390 +5: 5391 +5: 5392 +5: 5393 +5: 5394 +5: 5395 +5: 5396 +5: 5397 +5: 5398 +5: 5399 +5: 5400 +5: 5401 +5: 5402 +5: 5403 +5: 5404 +5: 5405 +5: 5406 +5: 5407 +5: 5408 +5: 5409 +5: 5410 +5: 5411 +5: 5412 +5: 5413 +5: 5414 +5: 5415 +5: 5416 +5: 5417 +5: 5418 +5: 5419 +5: 5420 +5: 5421 +5: 5422 +5: 5423 +5: 5424 +5: 5425 +5: 5426 +5: 5427 +5: 5428 +5: 5429 +5: 5430 +5: 5431 +5: 5432 +5: 5433 +5: 5434 +5: 5435 +5: 5436 +5: 5437 +5: 5438 +5: 5439 +5: 5440 +5: 5441 +5: 5442 +5: 5443 +5: 5444 +5: 5445 +5: 5446 +5: 5447 +5: 5448 +5: 5449 +5: 5450 +5: 5451 +5: 5452 +5: 5453 +5: 5454 +5: 5455 +5: 5456 +5: 5457 +5: 5458 +5: 5459 +5: 5460 +5: 5461 +5: 5462 +5: 5463 +5: 5464 +5: 5465 +5: 5466 +5: 5467 +5: 5468 +5: 5469 +5: 5470 +5: 5471 +5: 5472 +5: 5473 +5: 5474 +5: 5475 +5: 5476 +5: 5477 +5: 5478 +5: 5479 +5: 5480 +5: 5481 +5: 5482 +5: 5483 +5: 5484 +5: 5485 +5: 5486 +5: 5487 +5: 5488 +5: 5489 +5: 5490 +5: 5491 +5: 5492 +5: 5493 +5: 5494 +5: 5495 +5: 5496 +5: 5497 +5: 5498 +5: 5499 +5: 5500 +5: 5501 +5: 5502 +5: 5503 +5: 5504 +5: 5505 +5: 5506 +5: 5507 +5: 5508 +5: 5509 +5: 5510 +5: 5511 +5: 5512 +5: 5513 +5: 5514 +5: 5515 +5: 5516 +5: 5517 +5: 5518 +5: 5519 +5: 5520 +5: 5521 +5: 5522 +5: 5523 +5: 5524 +5: 5525 +5: 5526 +5: 5527 +5: 5528 +5: 5529 +5: 5530 +5: 5531 +5: 5532 +5: 5533 +5: 5534 +5: 5535 +5: 5536 +5: 5537 +5: 5538 +5: 5539 +5: 5540 +5: 5541 +5: 5542 +5: 5543 +5: 5544 +5: 5545 +5: 5546 +5: 5547 +5: 5548 +5: 5549 +5: 5550 +5: 5551 +5: 5552 +5: 5553 +5: 5554 +5: 5555 +5: 5556 +5: 5557 +5: 5558 +5: 5559 +5: 5560 +5: 5561 +5: 5562 +5: 5563 +5: 5564 +5: 5565 +5: 5566 +5: 5567 +5: 5568 +5: 5569 +5: 5570 +5: 5571 +5: 5572 +5: 5573 +5: 5574 +5: 5575 +5: 5576 +5: 5577 +5: 5578 +5: 5579 +5: 5580 +5: 5581 +5: 5582 +5: 5583 +5: 5584 +5: 5585 +5: 5586 +5: 5587 +5: 5588 +5: 5589 +5: 5590 +5: 5591 +5: 5592 +5: 5593 +5: 5594 +5: 5595 +5: 5596 +5: 5597 +5: 5598 +5: 5599 +5: 5600 +5: 5601 +5: 5602 +4: 5603 +4: 5604 +4: 5605 +4: 5606 +4: 5607 +4: 5608 +4: 5609 +4: 5610 +4: 5611 +4: 5612 +4: 5613 +4: 5614 +4: 5615 +4: 5616 +4: 5617 +4: 5618 +4: 5619 +4: 5620 +4: 5621 +4: 5622 +4: 5623 +4: 5624 +4: 5625 +4: 5626 +4: 5627 +4: 5628 +4: 5629 +4: 5630 +4: 5631 +4: 5632 +4: 5633 +4: 5634 +4: 5635 +4: 5636 +4: 5637 +4: 5638 +4: 5639 +4: 5640 +4: 5641 +4: 5642 +4: 5643 +4: 5644 +4: 5645 +4: 5646 +4: 5647 +4: 5648 +4: 5649 +4: 5650 +4: 5651 +4: 5652 +4: 5653 +4: 5654 +4: 5655 +4: 5656 +4: 5657 +4: 5658 +4: 5659 +4: 5660 +4: 5661 +4: 5662 +4: 5663 +4: 5664 +4: 5665 +4: 5666 +4: 5667 +4: 5668 +4: 5669 +4: 5670 +4: 5671 +4: 5672 +4: 5673 +4: 5674 +4: 5675 +4: 5676 +4: 5677 +4: 5678 +4: 5679 +4: 5680 +4: 5681 +4: 5682 +4: 5683 +4: 5684 +4: 5685 +4: 5686 +4: 5687 +4: 5688 +4: 5689 +4: 5690 +4: 5691 +4: 5692 +4: 5693 +4: 5694 +4: 5695 +4: 5696 +4: 5697 +4: 5698 +4: 5699 +4: 5700 +4: 5701 +4: 5702 +4: 5703 +4: 5704 +4: 5705 +4: 5706 +4: 5707 +4: 5708 +4: 5709 +4: 5710 +4: 5711 +4: 5712 +4: 5713 +4: 5714 +4: 5715 +4: 5716 +4: 5717 +4: 5718 +4: 5719 +4: 5720 +4: 5721 +4: 5722 +4: 5723 +4: 5724 +4: 5725 +4: 5726 +4: 5727 +4: 5728 +4: 5729 +4: 5730 +4: 5731 +4: 5732 +4: 5733 +4: 5734 +4: 5735 +4: 5736 +4: 5737 +4: 5738 +4: 5739 +4: 5740 +4: 5741 +4: 5742 +4: 5743 +4: 5744 +4: 5745 +4: 5746 +4: 5747 +4: 5748 +4: 5749 +4: 5750 +4: 5751 +4: 5752 +4: 5753 +4: 5754 +4: 5755 +4: 5756 +4: 5757 +4: 5758 +4: 5759 +4: 5760 +4: 5761 +4: 5762 +4: 5763 +4: 5764 +4: 5765 +4: 5766 +4: 5767 +4: 5768 +4: 5769 +4: 5770 +4: 5771 +4: 5772 +4: 5773 +4: 5774 +4: 5775 +4: 5776 +4: 5777 +4: 5778 +4: 5779 +4: 5780 +4: 5781 +4: 5782 +4: 5783 +4: 5784 +4: 5785 +4: 5786 +4: 5787 +4: 5788 +4: 5789 +4: 5790 +4: 5791 +4: 5792 +4: 5793 +4: 5794 +4: 5795 +4: 5796 +4: 5797 +4: 5798 +4: 5799 +4: 5800 +4: 5801 +4: 5802 +4: 5803 +4: 5804 +4: 5805 +4: 5806 +4: 5807 +4: 5808 +4: 5809 +4: 5810 +4: 5811 +4: 5812 +4: 5813 +4: 5814 +4: 5815 +4: 5816 +4: 5817 +4: 5818 +4: 5819 +4: 5820 +4: 5821 +4: 5822 +4: 5823 +4: 5824 +4: 5825 +4: 5826 +4: 5827 +4: 5828 +4: 5829 +4: 5830 +4: 5831 +4: 5832 +4: 5833 +4: 5834 +4: 5835 +4: 5836 +4: 5837 +4: 5838 +4: 5839 +4: 5840 +4: 5841 +4: 5842 +4: 5843 +4: 5844 +4: 5845 +4: 5846 +4: 5847 +4: 5848 +4: 5849 +4: 5850 +4: 5851 +4: 5852 +4: 5853 +4: 5854 +4: 5855 +4: 5856 +4: 5857 +4: 5858 +4: 5859 +4: 5860 +4: 5861 +4: 5862 +4: 5863 +4: 5864 +4: 5865 +4: 5866 +4: 5867 +4: 5868 +4: 5869 +4: 5870 +4: 5871 +4: 5872 +4: 5873 +4: 5874 +4: 5875 +4: 5876 +4: 5877 +4: 5878 +4: 5879 +4: 5880 +4: 5881 +4: 5882 +4: 5883 +4: 5884 +4: 5885 +4: 5886 +4: 5887 +4: 5888 +4: 5889 +4: 5890 +4: 5891 +4: 5892 +4: 5893 +4: 5894 +4: 5895 +4: 5896 +4: 5897 +4: 5898 +4: 5899 +4: 5900 +4: 5901 +4: 5902 +4: 5903 +4: 5904 +4: 5905 +4: 5906 +4: 5907 +4: 5908 +4: 5909 +4: 5910 +4: 5911 +4: 5912 +4: 5913 +4: 5914 +4: 5915 +4: 5916 +4: 5917 +4: 5918 +4: 5919 +4: 5920 +4: 5921 +4: 5922 +4: 5923 +4: 5924 +4: 5925 +4: 5926 +4: 5927 +4: 5928 +4: 5929 +4: 5930 +4: 5931 +4: 5932 +4: 5933 +4: 5934 +4: 5935 +4: 5936 +4: 5937 +4: 5938 +4: 5939 +4: 5940 +4: 5941 +4: 5942 +4: 5943 +4: 5944 +4: 5945 +4: 5946 +4: 5947 +4: 5948 +4: 5949 +4: 5950 +4: 5951 +4: 5952 +4: 5953 +4: 5954 +4: 5955 +4: 5956 +4: 5957 +4: 5958 +4: 5959 +4: 5960 +4: 5961 +4: 5962 +4: 5963 +4: 5964 +4: 5965 +4: 5966 +4: 5967 +4: 5968 +4: 5969 +4: 5970 +4: 5971 +4: 5972 +4: 5973 +4: 5974 +4: 5975 +4: 5976 +4: 5977 +4: 5978 +4: 5979 +4: 5980 +4: 5981 +4: 5982 +4: 5983 +4: 5984 +4: 5985 +4: 5986 +4: 5987 +4: 5988 +4: 5989 +4: 5990 +4: 5991 +4: 5992 +4: 5993 +4: 5994 +4: 5995 +4: 5996 +4: 5997 +4: 5998 +4: 5999 +4: 6000 +4: 6001 +4: 6002 +4: 6003 +4: 6004 +4: 6005 +4: 6006 +4: 6007 +4: 6008 +4: 6009 +4: 6010 +4: 6011 +4: 6012 +4: 6013 +4: 6014 +4: 6015 +4: 6016 +4: 6017 +4: 6018 +4: 6019 +4: 6020 +4: 6021 +4: 6022 +4: 6023 +4: 6024 +4: 6025 +4: 6026 +4: 6027 +4: 6028 +4: 6029 +4: 6030 +4: 6031 +4: 6032 +4: 6033 +4: 6034 +4: 6035 +4: 6036 +4: 6037 +4: 6038 +4: 6039 +4: 6040 +4: 6041 +4: 6042 +4: 6043 +4: 6044 +4: 6045 +4: 6046 +4: 6047 +4: 6048 +4: 6049 +4: 6050 +4: 6051 +4: 6052 +4: 6053 +4: 6054 +4: 6055 +4: 6056 +4: 6057 +4: 6058 +4: 6059 +4: 6060 +4: 6061 +4: 6062 +4: 6063 +4: 6064 +4: 6065 +4: 6066 +4: 6067 +4: 6068 +4: 6069 +4: 6070 +4: 6071 +4: 6072 +4: 6073 +4: 6074 +4: 6075 +4: 6076 +4: 6077 +4: 6078 +4: 6079 +4: 6080 +4: 6081 +4: 6082 +4: 6083 +4: 6084 +4: 6085 +4: 6086 +4: 6087 +4: 6088 +4: 6089 +4: 6090 +4: 6091 +4: 6092 +4: 6093 +4: 6094 +4: 6095 +4: 6096 +4: 6097 +4: 6098 +4: 6099 +4: 6100 +4: 6101 +4: 6102 +4: 6103 +4: 6104 +4: 6105 +4: 6106 +4: 6107 +4: 6108 +4: 6109 +4: 6110 +4: 6111 +4: 6112 +4: 6113 +4: 6114 +4: 6115 +4: 6116 +4: 6117 +4: 6118 +4: 6119 +4: 6120 +4: 6121 +4: 6122 +4: 6123 +4: 6124 +4: 6125 +4: 6126 +4: 6127 +4: 6128 +4: 6129 +4: 6130 +4: 6131 +4: 6132 +4: 6133 +4: 6134 +4: 6135 +4: 6136 +4: 6137 +4: 6138 +4: 6139 +4: 6140 +4: 6141 +4: 6142 +4: 6143 +4: 6144 +4: 6145 +4: 6146 +4: 6147 +4: 6148 +4: 6149 +4: 6150 +4: 6151 +4: 6152 +4: 6153 +4: 6154 +4: 6155 +4: 6156 +4: 6157 +4: 6158 +4: 6159 +4: 6160 +4: 6161 +4: 6162 +4: 6163 +4: 6164 +4: 6165 +4: 6166 +4: 6167 +4: 6168 +4: 6169 +4: 6170 +4: 6171 +4: 6172 +4: 6173 +4: 6174 +4: 6175 +4: 6176 +4: 6177 +4: 6178 +4: 6179 +4: 6180 +4: 6181 +4: 6182 +4: 6183 +4: 6184 +4: 6185 +4: 6186 +4: 6187 +4: 6188 +5: 6189 +5: 6190 +5: 6191 +5: 6192 +5: 6193 +5: 6194 +5: 6195 +5: 6196 +5: 6197 +5: 6198 +5: 6199 +5: 6200 +5: 6201 +5: 6202 +5: 6203 +5: 6204 +5: 6205 +5: 6206 +5: 6207 +5: 6208 +5: 6209 +5: 6210 +5: 6211 +5: 6212 +5: 6213 +5: 6214 +5: 6215 +5: 6216 +5: 6217 +5: 6218 +5: 6219 +5: 6220 +5: 6221 +5: 6222 +5: 6223 +5: 6224 +5: 6225 +5: 6226 +5: 6227 +5: 6228 +5: 6229 +5: 6230 +5: 6231 +5: 6232 +5: 6233 +5: 6234 +5: 6235 +5: 6236 +5: 6237 +5: 6238 +5: 6239 +5: 6240 +5: 6241 +5: 6242 +5: 6243 +5: 6244 +5: 6245 +5: 6246 +5: 6247 +5: 6248 +5: 6249 +5: 6250 +5: 6251 +5: 6252 +5: 6253 +5: 6254 +5: 6255 +5: 6256 +5: 6257 +5: 6258 +5: 6259 +5: 6260 +5: 6261 +5: 6262 +5: 6263 +5: 6264 +5: 6265 +5: 6266 +5: 6267 +5: 6268 +5: 6269 +5: 6270 +5: 6271 +5: 6272 +5: 6273 +5: 6274 +5: 6275 +5: 6276 +5: 6277 +5: 6278 +5: 6279 +5: 6280 +5: 6281 +5: 6282 +5: 6283 +5: 6284 +5: 6285 +5: 6286 +5: 6287 +5: 6288 +5: 6289 +5: 6290 +5: 6291 +5: 6292 +5: 6293 +5: 6294 +5: 6295 +5: 6296 +5: 6297 +5: 6298 +5: 6299 +5: 6300 +5: 6301 +5: 6302 +5: 6303 +5: 6304 +5: 6305 +5: 6306 +5: 6307 +5: 6308 +5: 6309 +5: 6310 +5: 6311 +5: 6312 +5: 6313 +5: 6314 +5: 6315 +5: 6316 +5: 6317 +5: 6318 +5: 6319 +5: 6320 +5: 6321 +5: 6322 +5: 6323 +5: 6324 +5: 6325 +5: 6326 +5: 6327 +5: 6328 +5: 6329 +5: 6330 +5: 6331 +5: 6332 +5: 6333 +5: 6334 +5: 6335 +5: 6336 +5: 6337 +5: 6338 +5: 6339 +5: 6340 +5: 6341 +5: 6342 +5: 6343 +5: 6344 +5: 6345 +5: 6346 +5: 6347 +5: 6348 +5: 6349 +5: 6350 +5: 6351 +5: 6352 +5: 6353 +5: 6354 +5: 6355 +5: 6356 +5: 6357 +5: 6358 +5: 6359 +5: 6360 +5: 6361 +5: 6362 +5: 6363 +5: 6364 +5: 6365 +5: 6366 +5: 6367 +5: 6368 +5: 6369 +5: 6370 +5: 6371 +5: 6372 +5: 6373 +5: 6374 +5: 6375 +5: 6376 +5: 6377 +5: 6378 +5: 6379 +5: 6380 +5: 6381 +5: 6382 +5: 6383 +5: 6384 +5: 6385 +5: 6386 +5: 6387 +5: 6388 +5: 6389 +5: 6390 +5: 6391 +5: 6392 +5: 6393 +5: 6394 +5: 6395 +5: 6396 +5: 6397 +5: 6398 +5: 6399 +5: 6400 +5: 6401 +5: 6402 +5: 6403 +5: 6404 +5: 6405 +5: 6406 +5: 6407 +5: 6408 +5: 6409 +5: 6410 +5: 6411 +5: 6412 +5: 6413 +5: 6414 +5: 6415 +5: 6416 +5: 6417 +5: 6418 +5: 6419 +5: 6420 +5: 6421 +5: 6422 +5: 6423 +5: 6424 +5: 6425 +5: 6426 +5: 6427 +5: 6428 +5: 6429 +5: 6430 +5: 6431 +5: 6432 +5: 6433 +5: 6434 +5: 6435 +5: 6436 +5: 6437 +5: 6438 +5: 6439 +5: 6440 +5: 6441 +5: 6442 +5: 6443 +5: 6444 +5: 6445 +5: 6446 +5: 6447 +5: 6448 +5: 6449 +5: 6450 +5: 6451 +5: 6452 +5: 6453 +5: 6454 +5: 6455 +5: 6456 +5: 6457 +5: 6458 +5: 6459 +5: 6460 +5: 6461 +5: 6462 +5: 6463 +5: 6464 +5: 6465 +5: 6466 +5: 6467 +5: 6468 +5: 6469 +5: 6470 +5: 6471 +5: 6472 +5: 6473 +5: 6474 +5: 6475 +5: 6476 +5: 6477 +5: 6478 +5: 6479 +5: 6480 +5: 6481 +5: 6482 +5: 6483 +5: 6484 +5: 6485 +5: 6486 +5: 6487 +5: 6488 +5: 6489 +5: 6490 +5: 6491 +5: 6492 +5: 6493 +5: 6494 +5: 6495 +5: 6496 +5: 6497 +5: 6498 +5: 6499 +5: 6500 +5: 6501 +5: 6502 +5: 6503 +5: 6504 +5: 6505 +5: 6506 +5: 6507 +5: 6508 +5: 6509 +5: 6510 +5: 6511 +5: 6512 +5: 6513 +5: 6514 +5: 6515 +5: 6516 +5: 6517 +5: 6518 +5: 6519 +5: 6520 +5: 6521 +5: 6522 +5: 6523 +5: 6524 +5: 6525 +5: 6526 +5: 6527 +5: 6528 +5: 6529 +5: 6530 +5: 6531 +5: 6532 +5: 6533 +5: 6534 +5: 6535 +5: 6536 +5: 6537 +5: 6538 +5: 6539 +5: 6540 +5: 6541 +5: 6542 +5: 6543 +5: 6544 +5: 6545 +5: 6546 +5: 6547 +5: 6548 +5: 6549 +5: 6550 +5: 6551 +5: 6552 +5: 6553 +5: 6554 +5: 6555 +5: 6556 +5: 6557 +5: 6558 +5: 6559 +5: 6560 +5: 6561 +5: 6562 +5: 6563 +5: 6564 +5: 6565 +5: 6566 +4: 6567 +4: 6568 +4: 6569 +4: 6570 +4: 6571 +4: 6572 +4: 6573 +4: 6574 +4: 6575 +4: 6576 +4: 6577 +4: 6578 +4: 6579 +4: 6580 +4: 6581 +4: 6582 +4: 6583 +4: 6584 +4: 6585 +4: 6586 +4: 6587 +4: 6588 +4: 6589 +4: 6590 +4: 6591 +4: 6592 +4: 6593 +4: 6594 +4: 6595 +4: 6596 +4: 6597 +4: 6598 +4: 6599 +4: 6600 +4: 6601 +4: 6602 +4: 6603 +4: 6604 +4: 6605 +4: 6606 +4: 6607 +4: 6608 +4: 6609 +4: 6610 +4: 6611 +4: 6612 +4: 6613 +4: 6614 +4: 6615 +4: 6616 +4: 6617 +4: 6618 +4: 6619 +4: 6620 +4: 6621 +4: 6622 +4: 6623 +4: 6624 +4: 6625 +4: 6626 +4: 6627 +4: 6628 +4: 6629 +4: 6630 +4: 6631 +4: 6632 +4: 6633 +4: 6634 +4: 6635 +4: 6636 +4: 6637 +4: 6638 +4: 6639 +4: 6640 +4: 6641 +4: 6642 +4: 6643 +4: 6644 +4: 6645 +4: 6646 +4: 6647 +4: 6648 +4: 6649 +4: 6650 +4: 6651 +4: 6652 +4: 6653 +4: 6654 +4: 6655 +4: 6656 +4: 6657 +4: 6658 +4: 6659 +4: 6660 +4: 6661 +4: 6662 +4: 6663 +4: 6664 +4: 6665 +4: 6666 +4: 6667 +4: 6668 +4: 6669 +4: 6670 +4: 6671 +4: 6672 +4: 6673 +4: 6674 +4: 6675 +4: 6676 +4: 6677 +4: 6678 +4: 6679 +4: 6680 +4: 6681 +4: 6682 +4: 6683 +4: 6684 +4: 6685 +4: 6686 +4: 6687 +4: 6688 +4: 6689 +4: 6690 +4: 6691 +4: 6692 +4: 6693 +4: 6694 +4: 6695 +4: 6696 +4: 6697 +4: 6698 +4: 6699 +4: 6700 +4: 6701 +4: 6702 +4: 6703 +4: 6704 +4: 6705 +4: 6706 +4: 6707 +4: 6708 +4: 6709 +4: 6710 +4: 6711 +4: 6712 +4: 6713 +4: 6714 +4: 6715 +4: 6716 +4: 6717 +4: 6718 +4: 6719 +4: 6720 +4: 6721 +4: 6722 +4: 6723 +4: 6724 +4: 6725 +4: 6726 +4: 6727 +4: 6728 +4: 6729 +4: 6730 +4: 6731 +4: 6732 +4: 6733 +4: 6734 +4: 6735 +4: 6736 +4: 6737 +4: 6738 +4: 6739 +4: 6740 +4: 6741 +4: 6742 +4: 6743 +4: 6744 +4: 6745 +4: 6746 +4: 6747 +4: 6748 +4: 6749 +4: 6750 +4: 6751 +4: 6752 +4: 6753 +4: 6754 +4: 6755 +4: 6756 +4: 6757 +4: 6758 +4: 6759 +4: 6760 +4: 6761 +4: 6762 +4: 6763 +4: 6764 +4: 6765 +4: 6766 +4: 6767 +4: 6768 +4: 6769 +4: 6770 +4: 6771 +4: 6772 +4: 6773 +4: 6774 +4: 6775 +4: 6776 +4: 6777 +4: 6778 +4: 6779 +4: 6780 +4: 6781 +4: 6782 +4: 6783 +4: 6784 +4: 6785 +4: 6786 +4: 6787 +4: 6788 +4: 6789 +4: 6790 +4: 6791 +4: 6792 +4: 6793 +4: 6794 +4: 6795 +4: 6796 +4: 6797 +4: 6798 +4: 6799 +4: 6800 +4: 6801 +4: 6802 +4: 6803 +4: 6804 +4: 6805 +4: 6806 +4: 6807 +4: 6808 +4: 6809 +4: 6810 +4: 6811 +4: 6812 +4: 6813 +4: 6814 +4: 6815 +4: 6816 +4: 6817 +4: 6818 +4: 6819 +4: 6820 +4: 6821 +4: 6822 +4: 6823 +4: 6824 +4: 6825 +4: 6826 +4: 6827 +4: 6828 +4: 6829 +4: 6830 +4: 6831 +4: 6832 +4: 6833 +4: 6834 +4: 6835 +4: 6836 +4: 6837 +4: 6838 +4: 6839 +4: 6840 +4: 6841 +4: 6842 +4: 6843 +4: 6844 +4: 6845 +4: 6846 +4: 6847 +4: 6848 +4: 6849 +4: 6850 +4: 6851 +4: 6852 +4: 6853 +4: 6854 +4: 6855 +4: 6856 +4: 6857 +4: 6858 +4: 6859 +4: 6860 +4: 6861 +4: 6862 +4: 6863 +4: 6864 +4: 6865 +4: 6866 +4: 6867 +4: 6868 +4: 6869 +4: 6870 +4: 6871 +4: 6872 +4: 6873 +4: 6874 +4: 6875 +4: 6876 +4: 6877 +4: 6878 +4: 6879 +4: 6880 +4: 6881 +4: 6882 +4: 6883 +4: 6884 +4: 6885 +4: 6886 +4: 6887 +4: 6888 +4: 6889 +4: 6890 +4: 6891 +4: 6892 +4: 6893 +4: 6894 +4: 6895 +4: 6896 +4: 6897 +4: 6898 +4: 6899 +4: 6900 +4: 6901 +4: 6902 +4: 6903 +4: 6904 +4: 6905 +4: 6906 +4: 6907 +4: 6908 +4: 6909 +4: 6910 +4: 6911 +4: 6912 +4: 6913 +4: 6914 +4: 6915 +4: 6916 +4: 6917 +4: 6918 +4: 6919 +4: 6920 +4: 6921 +4: 6922 +4: 6923 +4: 6924 +4: 6925 +4: 6926 +4: 6927 +4: 6928 +4: 6929 +4: 6930 +4: 6931 +4: 6932 +4: 6933 +4: 6934 +4: 6935 +4: 6936 +4: 6937 +4: 6938 +4: 6939 +4: 6940 +4: 6941 +4: 6942 +4: 6943 +4: 6944 +4: 6945 +4: 6946 +4: 6947 +4: 6948 +4: 6949 +4: 6950 +4: 6951 +4: 6952 +4: 6953 +4: 6954 +4: 6955 +4: 6956 +4: 6957 +4: 6958 +4: 6959 +4: 6960 +4: 6961 +4: 6962 +4: 6963 +4: 6964 +4: 6965 +4: 6966 +4: 6967 +4: 6968 +4: 6969 +4: 6970 +4: 6971 +4: 6972 +4: 6973 +4: 6974 +4: 6975 +4: 6976 +4: 6977 +4: 6978 +4: 6979 +4: 6980 +4: 6981 +4: 6982 +4: 6983 +4: 6984 +4: 6985 +4: 6986 +4: 6987 +4: 6988 +4: 6989 +4: 6990 +4: 6991 +4: 6992 +4: 6993 +4: 6994 +4: 6995 +4: 6996 +4: 6997 +4: 6998 +4: 6999 +4: 7000 +4: 7001 +4: 7002 +4: 7003 +4: 7004 +4: 7005 +4: 7006 +4: 7007 +4: 7008 +4: 7009 +4: 7010 +4: 7011 +4: 7012 +4: 7013 +4: 7014 +4: 7015 +4: 7016 +4: 7017 +4: 7018 +4: 7019 +4: 7020 +4: 7021 +4: 7022 +4: 7023 +4: 7024 +4: 7025 +4: 7026 +4: 7027 +4: 7028 +4: 7029 +4: 7030 +4: 7031 +4: 7032 +4: 7033 +4: 7034 +4: 7035 +4: 7036 +4: 7037 +4: 7038 +4: 7039 +4: 7040 +4: 7041 +4: 7042 +4: 7043 +4: 7044 +4: 7045 +4: 7046 +4: 7047 +4: 7048 +4: 7049 +4: 7050 +4: 7051 +4: 7052 +4: 7053 +4: 7054 +4: 7055 +4: 7056 +4: 7057 +4: 7058 +4: 7059 +4: 7060 +4: 7061 +4: 7062 +4: 7063 +4: 7064 +4: 7065 +4: 7066 +4: 7067 +4: 7068 +4: 7069 +4: 7070 +4: 7071 +4: 7072 +4: 7073 +4: 7074 +4: 7075 +4: 7076 +4: 7077 +4: 7078 +4: 7079 +4: 7080 +4: 7081 +4: 7082 +4: 7083 +4: 7084 +4: 7085 +4: 7086 +4: 7087 +5: 7088 +5: 7089 +5: 7090 +5: 7091 +5: 7092 +5: 7093 +5: 7094 +5: 7095 +5: 7096 +5: 7097 +5: 7098 +5: 7099 +5: 7100 +5: 7101 +5: 7102 +5: 7103 +5: 7104 +5: 7105 +5: 7106 +5: 7107 +5: 7108 +5: 7109 +5: 7110 +5: 7111 +5: 7112 +5: 7113 +5: 7114 +5: 7115 +5: 7116 +5: 7117 +5: 7118 +5: 7119 +5: 7120 +5: 7121 +5: 7122 +5: 7123 +5: 7124 +5: 7125 +5: 7126 +5: 7127 +5: 7128 +5: 7129 +5: 7130 +5: 7131 +5: 7132 +5: 7133 +5: 7134 +5: 7135 +5: 7136 +5: 7137 +5: 7138 +5: 7139 +5: 7140 +5: 7141 +5: 7142 +5: 7143 +5: 7144 +5: 7145 +5: 7146 +5: 7147 +5: 7148 +5: 7149 +5: 7150 +5: 7151 +5: 7152 +5: 7153 +5: 7154 +5: 7155 +5: 7156 +5: 7157 +5: 7158 +5: 7159 +5: 7160 +5: 7161 +5: 7162 +5: 7163 +5: 7164 +5: 7165 +5: 7166 +5: 7167 +5: 7168 +5: 7169 +5: 7170 +5: 7171 +5: 7172 +5: 7173 +5: 7174 +5: 7175 +5: 7176 +5: 7177 +5: 7178 +5: 7179 +5: 7180 +5: 7181 +5: 7182 +5: 7183 +5: 7184 +5: 7185 +5: 7186 +5: 7187 +5: 7188 +5: 7189 +5: 7190 +5: 7191 +5: 7192 +5: 7193 +5: 7194 +5: 7195 +5: 7196 +5: 7197 +5: 7198 +5: 7199 +5: 7200 +5: 7201 +5: 7202 +5: 7203 +5: 7204 +5: 7205 +5: 7206 +5: 7207 +5: 7208 +5: 7209 +5: 7210 +5: 7211 +5: 7212 +5: 7213 +5: 7214 +5: 7215 +5: 7216 +5: 7217 +5: 7218 +5: 7219 +5: 7220 +5: 7221 +5: 7222 +5: 7223 +5: 7224 +5: 7225 +5: 7226 +5: 7227 +5: 7228 +5: 7229 +5: 7230 +5: 7231 +5: 7232 +5: 7233 +5: 7234 +5: 7235 +5: 7236 +5: 7237 +5: 7238 +5: 7239 +5: 7240 +5: 7241 +5: 7242 +5: 7243 +5: 7244 +5: 7245 +5: 7246 +5: 7247 +5: 7248 +5: 7249 +5: 7250 +5: 7251 +5: 7252 +5: 7253 +5: 7254 +5: 7255 +5: 7256 +5: 7257 +5: 7258 +5: 7259 +5: 7260 +5: 7261 +5: 7262 +5: 7263 +5: 7264 +5: 7265 +5: 7266 +5: 7267 +5: 7268 +5: 7269 +5: 7270 +5: 7271 +5: 7272 +5: 7273 +5: 7274 +5: 7275 +5: 7276 +5: 7277 +5: 7278 +5: 7279 +5: 7280 +5: 7281 +5: 7282 +5: 7283 +5: 7284 +5: 7285 +5: 7286 +5: 7287 +5: 7288 +5: 7289 +5: 7290 +5: 7291 +5: 7292 +5: 7293 +5: 7294 +5: 7295 +5: 7296 +5: 7297 +5: 7298 +5: 7299 +5: 7300 +5: 7301 +5: 7302 +5: 7303 +5: 7304 +5: 7305 +5: 7306 +5: 7307 +5: 7308 +5: 7309 +5: 7310 +5: 7311 +5: 7312 +5: 7313 +5: 7314 +5: 7315 +5: 7316 +5: 7317 +5: 7318 +5: 7319 +5: 7320 +5: 7321 +5: 7322 +5: 7323 +5: 7324 +5: 7325 +5: 7326 +5: 7327 +5: 7328 +5: 7329 +5: 7330 +5: 7331 +5: 7332 +5: 7333 +5: 7334 +5: 7335 +5: 7336 +5: 7337 +5: 7338 +5: 7339 +5: 7340 +5: 7341 +5: 7342 +5: 7343 +5: 7344 +5: 7345 +5: 7346 +5: 7347 +5: 7348 +5: 7349 +5: 7350 +5: 7351 +5: 7352 +5: 7353 +5: 7354 +5: 7355 +5: 7356 +5: 7357 +5: 7358 +5: 7359 +5: 7360 +5: 7361 +5: 7362 +5: 7363 +5: 7364 +5: 7365 +5: 7366 +5: 7367 +5: 7368 +5: 7369 +5: 7370 +5: 7371 +5: 7372 +5: 7373 +5: 7374 +5: 7375 +5: 7376 +5: 7377 +5: 7378 +5: 7379 +5: 7380 +5: 7381 +5: 7382 +5: 7383 +5: 7384 +5: 7385 +5: 7386 +5: 7387 +5: 7388 +5: 7389 +5: 7390 +5: 7391 +5: 7392 +5: 7393 +5: 7394 +5: 7395 +5: 7396 +5: 7397 +5: 7398 +5: 7399 +5: 7400 +5: 7401 +5: 7402 +5: 7403 +5: 7404 +5: 7405 +5: 7406 +5: 7407 +5: 7408 +5: 7409 +5: 7410 +5: 7411 +5: 7412 +5: 7413 +5: 7414 +5: 7415 +5: 7416 +5: 7417 +5: 7418 +5: 7419 +5: 7420 +5: 7421 +5: 7422 +5: 7423 +5: 7424 +5: 7425 +5: 7426 +5: 7427 +5: 7428 +5: 7429 +5: 7430 +5: 7431 +5: 7432 +5: 7433 +5: 7434 +5: 7435 +5: 7436 +5: 7437 +5: 7438 +5: 7439 +5: 7440 +5: 7441 +5: 7442 +5: 7443 +5: 7444 +5: 7445 +5: 7446 +5: 7447 +5: 7448 +5: 7449 +5: 7450 +5: 7451 +5: 7452 +5: 7453 +5: 7454 +5: 7455 +5: 7456 +5: 7457 +5: 7458 +5: 7459 +5: 7460 +5: 7461 +5: 7462 +5: 7463 +5: 7464 +5: 7465 +5: 7466 +5: 7467 +5: 7468 +5: 7469 +5: 7470 +5: 7471 +5: 7472 +5: 7473 +5: 7474 +5: 7475 +5: 7476 +5: 7477 +5: 7478 +5: 7479 +5: 7480 +5: 7481 +5: 7482 +5: 7483 +5: 7484 +5: 7485 +5: 7486 +5: 7487 +5: 7488 +5: 7489 +5: 7490 +5: 7491 +5: 7492 +5: 7493 +5: 7494 +5: 7495 +5: 7496 +5: 7497 +5: 7498 +5: 7499 +5: 7500 +5: 7501 +5: 7502 +5: 7503 +5: 7504 +5: 7505 +5: 7506 +5: 7507 +5: 7508 +5: 7509 +5: 7510 +5: 7511 +5: 7512 +5: 7513 +5: 7514 +5: 7515 +5: 7516 +5: 7517 +5: 7518 +5: 7519 +5: 7520 +5: 7521 +5: 7522 +5: 7523 +5: 7524 +5: 7525 +5: 7526 +5: 7527 +5: 7528 +5: 7529 +5: 7530 +5: 7531 +5: 7532 +5: 7533 +5: 7534 +5: 7535 +5: 7536 +5: 7537 +5: 7538 +5: 7539 +5: 7540 +5: 7541 +5: 7542 +5: 7543 +5: 7544 +5: 7545 +5: 7546 +5: 7547 +5: 7548 +5: 7549 +5: 7550 +5: 7551 +5: 7552 +5: 7553 +5: 7554 +5: 7555 +5: 7556 +5: 7557 +5: 7558 +5: 7559 +5: 7560 +5: 7561 +5: 7562 +5: 7563 +5: 7564 +5: 7565 +5: 7566 +5: 7567 +5: 7568 +5: 7569 +5: 7570 +5: 7571 +5: 7572 +5: 7573 +5: 7574 +5: 7575 +5: 7576 +5: 7577 +5: 7578 +5: 7579 +5: 7580 +5: 7581 +5: 7582 +5: 7583 +5: 7584 +5: 7585 +5: 7586 +5: 7587 +5: 7588 +5: 7589 +5: 7590 +5: 7591 +5: 7592 +5: 7593 +5: 7594 +5: 7595 +5: 7596 +5: 7597 +5: 7598 +5: 7599 +5: 7600 +5: 7601 +5: 7602 +5: 7603 +5: 7604 +5: 7605 +5: 7606 +5: 7607 +5: 7608 +5: 7609 +5: 7610 +5: 7611 +5: 7612 +5: 7613 +5: 7614 +5: 7615 +5: 7616 +5: 7617 +5: 7618 +5: 7619 +5: 7620 +5: 7621 +5: 7622 +5: 7623 +5: 7624 +5: 7625 +5: 7626 +5: 7627 +5: 7628 +5: 7629 +5: 7630 +5: 7631 +5: 7632 +5: 7633 +5: 7634 +5: 7635 +5: 7636 +5: 7637 +5: 7638 +5: 7639 +5: 7640 +5: 7641 +5: 7642 +5: 7643 +5: 7644 +5: 7645 +5: 7646 +5: 7647 +5: 7648 +5: 7649 +5: 7650 +5: 7651 +5: 7652 +5: 7653 +5: 7654 +5: 7655 +5: 7656 +5: 7657 +5: 7658 +5: 7659 +5: 7660 +5: 7661 +5: 7662 +5: 7663 +5: 7664 +5: 7665 +5: 7666 +5: 7667 +5: 7668 +5: 7669 +5: 7670 +5: 7671 +5: 7672 +5: 7673 +5: 7674 +5: 7675 +5: 7676 +5: 7677 +5: 7678 +5: 7679 +5: 7680 +5: 7681 +5: 7682 +5: 7683 +5: 7684 +5: 7685 +5: 7686 +5: 7687 +5: 7688 +5: 7689 +5: 7690 +5: 7691 +5: 7692 +5: 7693 +5: 7694 +5: 7695 +5: 7696 +5: 7697 +5: 7698 +5: 7699 +5: 7700 +5: 7701 +5: 7702 +5: 7703 +5: 7704 +5: 7705 +5: 7706 +5: 7707 +5: 7708 +5: 7709 +5: 7710 +5: 7711 +5: 7712 +5: 7713 +5: 7714 +5: 7715 +5: 7716 +5: 7717 +5: 7718 +5: 7719 +5: 7720 +5: 7721 +5: 7722 +5: 7723 +5: 7724 +5: 7725 +5: 7726 +5: 7727 +5: 7728 +5: 7729 +5: 7730 +5: 7731 +5: 7732 +5: 7733 +5: 7734 +5: 7735 +5: 7736 +5: 7737 +5: 7738 +5: 7739 +5: 7740 +5: 7741 +5: 7742 +5: 7743 +5: 7744 +5: 7745 +5: 7746 +5: 7747 +5: 7748 +5: 7749 +5: 7750 +5: 7751 +5: 7752 +5: 7753 +5: 7754 +5: 7755 +5: 7756 +5: 7757 +5: 7758 +5: 7759 +5: 7760 +5: 7761 +5: 7762 +5: 7763 +5: 7764 +5: 7765 +5: 7766 +5: 7767 +5: 7768 +5: 7769 +5: 7770 +5: 7771 +5: 7772 +5: 7773 +5: 7774 +5: 7775 +5: 7776 +5: 7777 +5: 7778 +5: 7779 +5: 7780 +5: 7781 +5: 7782 +5: 7783 +5: 7784 +5: 7785 +5: 7786 +5: 7787 +5: 7788 +5: 7789 +5: 7790 +5: 7791 +5: 7792 +5: 7793 +5: 7794 +5: 7795 +5: 7796 +5: 7797 +5: 7798 +5: 7799 +5: 7800 +5: 7801 +5: 7802 +5: 7803 +5: 7804 +5: 7805 +5: 7806 +5: 7807 +5: 7808 +5: 7809 +5: 7810 +5: 7811 +5: 7812 +5: 7813 +5: 7814 +5: 7815 +5: 7816 +5: 7817 +5: 7818 +5: 7819 +4: 7820 +4: 7821 +4: 7822 +4: 7823 +4: 7824 +4: 7825 +4: 7826 +4: 7827 +4: 7828 +4: 7829 +4: 7830 +4: 7831 +4: 7832 +4: 7833 +4: 7834 +4: 7835 +4: 7836 +4: 7837 +4: 7838 +4: 7839 +4: 7840 +4: 7841 +4: 7842 +4: 7843 +4: 7844 +4: 7845 +4: 7846 +4: 7847 +4: 7848 +4: 7849 +4: 7850 +4: 7851 +4: 7852 +4: 7853 +4: 7854 +4: 7855 +4: 7856 +4: 7857 +4: 7858 +4: 7859 +4: 7860 +4: 7861 +4: 7862 +4: 7863 +4: 7864 +4: 7865 +4: 7866 +4: 7867 +4: 7868 +4: 7869 +4: 7870 +4: 7871 +4: 7872 +4: 7873 +4: 7874 +4: 7875 +4: 7876 +4: 7877 +4: 7878 +4: 7879 +4: 7880 +4: 7881 +4: 7882 +4: 7883 +4: 7884 +4: 7885 +4: 7886 +4: 7887 +4: 7888 +4: 7889 +4: 7890 +4: 7891 +4: 7892 +4: 7893 +4: 7894 +4: 7895 +4: 7896 +4: 7897 +4: 7898 +4: 7899 +4: 7900 +4: 7901 +4: 7902 +4: 7903 +4: 7904 +4: 7905 +4: 7906 +4: 7907 +4: 7908 +4: 7909 +4: 7910 +4: 7911 +4: 7912 +4: 7913 +4: 7914 +4: 7915 +4: 7916 +4: 7917 +4: 7918 +4: 7919 +4: 7920 +4: 7921 +4: 7922 +4: 7923 +4: 7924 +4: 7925 +4: 7926 +4: 7927 +4: 7928 +4: 7929 +4: 7930 +4: 7931 +4: 7932 +4: 7933 +4: 7934 +4: 7935 +4: 7936 +4: 7937 +4: 7938 +4: 7939 +4: 7940 +4: 7941 +4: 7942 +4: 7943 +4: 7944 +4: 7945 +4: 7946 +4: 7947 +4: 7948 +4: 7949 +4: 7950 +4: 7951 +4: 7952 +4: 7953 +4: 7954 +4: 7955 +4: 7956 +4: 7957 +4: 7958 +4: 7959 +4: 7960 +4: 7961 +4: 7962 +4: 7963 +4: 7964 +4: 7965 +4: 7966 +4: 7967 +4: 7968 +4: 7969 +4: 7970 +4: 7971 +4: 7972 +4: 7973 +4: 7974 +4: 7975 +4: 7976 +4: 7977 +4: 7978 +4: 7979 +4: 7980 +4: 7981 +4: 7982 +4: 7983 +4: 7984 +4: 7985 +4: 7986 +4: 7987 +4: 7988 +4: 7989 +4: 7990 +4: 7991 +4: 7992 +4: 7993 +4: 7994 +4: 7995 +4: 7996 +4: 7997 +4: 7998 +4: 7999 +4: 8000 +4: 8001 +4: 8002 +4: 8003 +4: 8004 +4: 8005 +4: 8006 +4: 8007 +4: 8008 +4: 8009 +4: 8010 +4: 8011 +4: 8012 +4: 8013 +4: 8014 +4: 8015 +4: 8016 +4: 8017 +4: 8018 +4: 8019 +4: 8020 +4: 8021 +4: 8022 +4: 8023 +4: 8024 +4: 8025 +4: 8026 +4: 8027 +4: 8028 +4: 8029 +4: 8030 +4: 8031 +4: 8032 +4: 8033 +4: 8034 +4: 8035 +4: 8036 +4: 8037 +4: 8038 +4: 8039 +4: 8040 +4: 8041 +4: 8042 +4: 8043 +4: 8044 +4: 8045 +4: 8046 +4: 8047 +4: 8048 +4: 8049 +4: 8050 +4: 8051 +4: 8052 +4: 8053 +4: 8054 +4: 8055 +4: 8056 +4: 8057 +4: 8058 +4: 8059 +4: 8060 +4: 8061 +4: 8062 +4: 8063 +4: 8064 +4: 8065 +4: 8066 +4: 8067 +4: 8068 +4: 8069 +5: 8070 +5: 8071 +5: 8072 +5: 8073 +5: 8074 +5: 8075 +5: 8076 +5: 8077 +5: 8078 +5: 8079 +5: 8080 +5: 8081 +5: 8082 +5: 8083 +5: 8084 +5: 8085 +5: 8086 +5: 8087 +5: 8088 +5: 8089 +5: 8090 +5: 8091 +5: 8092 +5: 8093 +5: 8094 +5: 8095 +5: 8096 +5: 8097 +5: 8098 +5: 8099 +5: 8100 +5: 8101 +5: 8102 +5: 8103 +5: 8104 +5: 8105 +5: 8106 +5: 8107 +5: 8108 +5: 8109 +5: 8110 +5: 8111 +5: 8112 +5: 8113 +5: 8114 +5: 8115 +5: 8116 +5: 8117 +5: 8118 +5: 8119 +5: 8120 +5: 8121 +5: 8122 +5: 8123 +5: 8124 +5: 8125 +5: 8126 +5: 8127 +5: 8128 +5: 8129 +5: 8130 +5: 8131 +5: 8132 +5: 8133 +5: 8134 +5: 8135 +5: 8136 +5: 8137 +5: 8138 +5: 8139 +5: 8140 +5: 8141 +5: 8142 +5: 8143 +5: 8144 +5: 8145 +5: 8146 +5: 8147 +5: 8148 +5: 8149 +5: 8150 +5: 8151 +5: 8152 +5: 8153 +5: 8154 +5: 8155 +5: 8156 +5: 8157 +5: 8158 +5: 8159 +5: 8160 +5: 8161 +5: 8162 +5: 8163 +5: 8164 +5: 8165 +5: 8166 +5: 8167 +5: 8168 +5: 8169 +5: 8170 +5: 8171 +5: 8172 +5: 8173 +5: 8174 +5: 8175 +5: 8176 +5: 8177 +5: 8178 +5: 8179 +5: 8180 +5: 8181 +5: 8182 +5: 8183 +5: 8184 +5: 8185 +5: 8186 +5: 8187 +5: 8188 +5: 8189 +5: 8190 +5: 8191 +5: 8192 +5: 8193 +5: 8194 +5: 8195 +5: 8196 +5: 8197 +5: 8198 +5: 8199 +5: 8200 +5: 8201 +5: 8202 +5: 8203 +5: 8204 +5: 8205 +5: 8206 +5: 8207 +5: 8208 +5: 8209 +5: 8210 +5: 8211 +5: 8212 +5: 8213 +5: 8214 +5: 8215 +5: 8216 +5: 8217 +5: 8218 +5: 8219 +5: 8220 +5: 8221 +5: 8222 +5: 8223 +5: 8224 +5: 8225 +5: 8226 +5: 8227 +5: 8228 +5: 8229 +5: 8230 +5: 8231 +5: 8232 +5: 8233 +5: 8234 +5: 8235 +5: 8236 +5: 8237 +5: 8238 +5: 8239 +5: 8240 +5: 8241 +5: 8242 +5: 8243 +5: 8244 +5: 8245 +5: 8246 +5: 8247 +5: 8248 +5: 8249 +5: 8250 +5: 8251 +5: 8252 +5: 8253 +5: 8254 +5: 8255 +5: 8256 +5: 8257 +5: 8258 +5: 8259 +5: 8260 +5: 8261 +5: 8262 +5: 8263 +5: 8264 +5: 8265 +5: 8266 +5: 8267 +5: 8268 +5: 8269 +5: 8270 +5: 8271 +5: 8272 +5: 8273 +5: 8274 +5: 8275 +5: 8276 +5: 8277 +5: 8278 +5: 8279 +5: 8280 +5: 8281 +5: 8282 +5: 8283 +5: 8284 +5: 8285 +5: 8286 +5: 8287 +5: 8288 +5: 8289 +5: 8290 +5: 8291 +5: 8292 +5: 8293 +5: 8294 +5: 8295 +5: 8296 +5: 8297 +5: 8298 +5: 8299 +5: 8300 +5: 8301 +5: 8302 +5: 8303 +5: 8304 +5: 8305 +5: 8306 +5: 8307 +5: 8308 +5: 8309 +5: 8310 +5: 8311 +5: 8312 +5: 8313 +5: 8314 +5: 8315 +5: 8316 +5: 8317 +5: 8318 +5: 8319 +5: 8320 +5: 8321 +5: 8322 +5: 8323 +5: 8324 +5: 8325 +5: 8326 +5: 8327 +5: 8328 +5: 8329 +5: 8330 +5: 8331 +5: 8332 +5: 8333 +5: 8334 +5: 8335 +5: 8336 +5: 8337 +5: 8338 +5: 8339 +5: 8340 +5: 8341 +5: 8342 +5: 8343 +5: 8344 +5: 8345 +5: 8346 +5: 8347 +5: 8348 +5: 8349 +5: 8350 +5: 8351 +5: 8352 +5: 8353 +5: 8354 +5: 8355 +5: 8356 +5: 8357 +5: 8358 +5: 8359 +5: 8360 +5: 8361 +5: 8362 +5: 8363 +5: 8364 +5: 8365 +5: 8366 +5: 8367 +5: 8368 +5: 8369 +5: 8370 +5: 8371 +5: 8372 +5: 8373 +5: 8374 +5: 8375 +5: 8376 +5: 8377 +5: 8378 +5: 8379 +5: 8380 +5: 8381 +5: 8382 +5: 8383 +5: 8384 +5: 8385 +5: 8386 +5: 8387 +5: 8388 +5: 8389 +5: 8390 +5: 8391 +5: 8392 +5: 8393 +5: 8394 +5: 8395 +5: 8396 +5: 8397 +5: 8398 +5: 8399 +5: 8400 +5: 8401 +5: 8402 +5: 8403 +5: 8404 +5: 8405 +5: 8406 +5: 8407 +5: 8408 +5: 8409 +5: 8410 +5: 8411 +5: 8412 +5: 8413 +5: 8414 +5: 8415 +5: 8416 +5: 8417 +5: 8418 +5: 8419 +5: 8420 +5: 8421 +5: 8422 +5: 8423 +5: 8424 +5: 8425 +5: 8426 +5: 8427 +5: 8428 +5: 8429 +5: 8430 +5: 8431 +5: 8432 +5: 8433 +5: 8434 +5: 8435 +5: 8436 +5: 8437 +5: 8438 +5: 8439 +5: 8440 +5: 8441 +5: 8442 +5: 8443 +5: 8444 +5: 8445 +5: 8446 +5: 8447 +5: 8448 +5: 8449 +5: 8450 +5: 8451 +5: 8452 +5: 8453 +5: 8454 +5: 8455 +5: 8456 +5: 8457 +5: 8458 +5: 8459 +5: 8460 +5: 8461 +5: 8462 +5: 8463 +5: 8464 +5: 8465 +5: 8466 +5: 8467 +5: 8468 +5: 8469 +5: 8470 +5: 8471 +5: 8472 +5: 8473 +5: 8474 +5: 8475 +5: 8476 +5: 8477 +5: 8478 +5: 8479 +5: 8480 +5: 8481 +5: 8482 +5: 8483 +5: 8484 +5: 8485 +5: 8486 +5: 8487 +5: 8488 +5: 8489 +5: 8490 +5: 8491 +5: 8492 +5: 8493 +5: 8494 +5: 8495 +5: 8496 +5: 8497 +5: 8498 +5: 8499 +5: 8500 +5: 8501 +5: 8502 +5: 8503 +5: 8504 +5: 8505 +5: 8506 +5: 8507 +5: 8508 +5: 8509 +5: 8510 +5: 8511 +5: 8512 +5: 8513 +5: 8514 +5: 8515 +5: 8516 +5: 8517 +5: 8518 +5: 8519 +5: 8520 +5: 8521 +5: 8522 +5: 8523 +5: 8524 +5: 8525 +5: 8526 +5: 8527 +5: 8528 +5: 8529 +5: 8530 +5: 8531 +5: 8532 +5: 8533 +5: 8534 +5: 8535 +5: 8536 +5: 8537 +5: 8538 +5: 8539 +5: 8540 +5: 8541 +5: 8542 +5: 8543 +5: 8544 +5: 8545 +5: 8546 +5: 8547 +5: 8548 +5: 8549 +5: 8550 +5: 8551 +5: 8552 +5: 8553 +5: 8554 +5: 8555 +5: 8556 +5: 8557 +5: 8558 +5: 8559 +5: 8560 +5: 8561 +5: 8562 +5: 8563 +5: 8564 +5: 8565 +5: 8566 +5: 8567 +5: 8568 +5: 8569 +5: 8570 +4: 8571 +4: 8572 +4: 8573 +4: 8574 +4: 8575 +4: 8576 +4: 8577 +4: 8578 +4: 8579 +4: 8580 +4: 8581 +4: 8582 +4: 8583 +4: 8584 +4: 8585 +4: 8586 +4: 8587 +4: 8588 +4: 8589 +4: 8590 +4: 8591 +4: 8592 +4: 8593 +4: 8594 +4: 8595 +4: 8596 +4: 8597 +4: 8598 +4: 8599 +4: 8600 +4: 8601 +4: 8602 +4: 8603 +4: 8604 +4: 8605 +4: 8606 +4: 8607 +4: 8608 +4: 8609 +4: 8610 +4: 8611 +4: 8612 +4: 8613 +4: 8614 +4: 8615 +4: 8616 +4: 8617 +4: 8618 +4: 8619 +4: 8620 +4: 8621 +4: 8622 +4: 8623 +4: 8624 +4: 8625 +4: 8626 +4: 8627 +4: 8628 +4: 8629 +4: 8630 +4: 8631 +4: 8632 +4: 8633 +4: 8634 +4: 8635 +4: 8636 +4: 8637 +4: 8638 +4: 8639 +4: 8640 +4: 8641 +4: 8642 +4: 8643 +4: 8644 +4: 8645 +4: 8646 +4: 8647 +4: 8648 +4: 8649 +4: 8650 +4: 8651 +4: 8652 +4: 8653 +4: 8654 +4: 8655 +4: 8656 +4: 8657 +4: 8658 +4: 8659 +4: 8660 +4: 8661 +4: 8662 +4: 8663 +4: 8664 +4: 8665 +4: 8666 +4: 8667 +4: 8668 +4: 8669 +4: 8670 +4: 8671 +4: 8672 +4: 8673 +4: 8674 +4: 8675 +4: 8676 +4: 8677 +4: 8678 +4: 8679 +4: 8680 +4: 8681 +4: 8682 +4: 8683 +4: 8684 +4: 8685 +4: 8686 +4: 8687 +4: 8688 +4: 8689 +4: 8690 +4: 8691 +4: 8692 +4: 8693 +4: 8694 +4: 8695 +4: 8696 +4: 8697 +4: 8698 +4: 8699 +4: 8700 +4: 8701 +4: 8702 +4: 8703 +4: 8704 +4: 8705 +4: 8706 +4: 8707 +4: 8708 +4: 8709 +4: 8710 +4: 8711 +4: 8712 +4: 8713 +4: 8714 +4: 8715 +4: 8716 +4: 8717 +4: 8718 +4: 8719 +4: 8720 +4: 8721 +4: 8722 +4: 8723 +4: 8724 +4: 8725 +4: 8726 +4: 8727 +4: 8728 +4: 8729 +4: 8730 +4: 8731 +4: 8732 +4: 8733 +4: 8734 +4: 8735 +4: 8736 +4: 8737 +4: 8738 +4: 8739 +4: 8740 +4: 8741 +4: 8742 +4: 8743 +4: 8744 +4: 8745 +4: 8746 +4: 8747 +4: 8748 +4: 8749 +4: 8750 +4: 8751 +4: 8752 +4: 8753 +4: 8754 +4: 8755 +4: 8756 +4: 8757 +4: 8758 +4: 8759 +4: 8760 +4: 8761 +4: 8762 +4: 8763 +4: 8764 +4: 8765 +4: 8766 +4: 8767 +4: 8768 +4: 8769 +4: 8770 +4: 8771 +4: 8772 +4: 8773 +4: 8774 +4: 8775 +4: 8776 +4: 8777 +4: 8778 +4: 8779 +4: 8780 +4: 8781 +4: 8782 +4: 8783 +4: 8784 +4: 8785 +4: 8786 +4: 8787 +4: 8788 +4: 8789 +4: 8790 +4: 8791 +4: 8792 +4: 8793 +4: 8794 +4: 8795 +4: 8796 +4: 8797 +4: 8798 +4: 8799 +4: 8800 +4: 8801 +4: 8802 +4: 8803 +4: 8804 +4: 8805 +4: 8806 +4: 8807 +4: 8808 +4: 8809 +4: 8810 +4: 8811 +4: 8812 +4: 8813 +4: 8814 +4: 8815 +4: 8816 +4: 8817 +4: 8818 +4: 8819 +4: 8820 +4: 8821 +4: 8822 +4: 8823 +4: 8824 +4: 8825 +4: 8826 +4: 8827 +4: 8828 +4: 8829 +4: 8830 +4: 8831 +4: 8832 +4: 8833 +4: 8834 +4: 8835 +4: 8836 +4: 8837 +4: 8838 +4: 8839 +4: 8840 +4: 8841 +4: 8842 +4: 8843 +4: 8844 +4: 8845 +4: 8846 +4: 8847 +4: 8848 +4: 8849 +4: 8850 +4: 8851 +4: 8852 +4: 8853 +4: 8854 +4: 8855 +4: 8856 +4: 8857 +4: 8858 +4: 8859 +4: 8860 +4: 8861 +4: 8862 +4: 8863 +4: 8864 +4: 8865 +4: 8866 +4: 8867 +4: 8868 +4: 8869 +4: 8870 +4: 8871 +4: 8872 +4: 8873 +4: 8874 +4: 8875 +4: 8876 +4: 8877 +4: 8878 +4: 8879 +4: 8880 +4: 8881 +4: 8882 +4: 8883 +4: 8884 +4: 8885 +4: 8886 +4: 8887 +4: 8888 +4: 8889 +4: 8890 +4: 8891 +4: 8892 +4: 8893 +4: 8894 +4: 8895 +4: 8896 +4: 8897 +4: 8898 +4: 8899 +4: 8900 +4: 8901 +4: 8902 +4: 8903 +4: 8904 +4: 8905 +4: 8906 +4: 8907 +4: 8908 +4: 8909 +4: 8910 +4: 8911 +4: 8912 +4: 8913 +4: 8914 +4: 8915 +4: 8916 +4: 8917 +4: 8918 +4: 8919 +4: 8920 +4: 8921 +4: 8922 +4: 8923 +4: 8924 +4: 8925 +4: 8926 +4: 8927 +4: 8928 +4: 8929 +4: 8930 +4: 8931 +4: 8932 +4: 8933 +4: 8934 +4: 8935 +4: 8936 +4: 8937 +4: 8938 +4: 8939 +4: 8940 +4: 8941 +4: 8942 +4: 8943 +4: 8944 +4: 8945 +4: 8946 +4: 8947 +4: 8948 +4: 8949 +4: 8950 +4: 8951 +4: 8952 +4: 8953 +4: 8954 +4: 8955 +4: 8956 +4: 8957 +4: 8958 +4: 8959 +4: 8960 +4: 8961 +4: 8962 +4: 8963 +4: 8964 +4: 8965 +4: 8966 +4: 8967 +4: 8968 +4: 8969 +4: 8970 +4: 8971 +4: 8972 +4: 8973 +4: 8974 +4: 8975 +4: 8976 +4: 8977 +4: 8978 +4: 8979 +4: 8980 +4: 8981 +4: 8982 +4: 8983 +4: 8984 +4: 8985 +4: 8986 +4: 8987 +4: 8988 +4: 8989 +4: 8990 +4: 8991 +4: 8992 +4: 8993 +4: 8994 +4: 8995 +4: 8996 +4: 8997 +4: 8998 +4: 8999 +4: 9000 +4: 9001 +4: 9002 +4: 9003 +4: 9004 +4: 9005 +4: 9006 +4: 9007 +4: 9008 +4: 9009 +4: 9010 +4: 9011 +4: 9012 +4: 9013 +4: 9014 +4: 9015 +4: 9016 +4: 9017 +4: 9018 +4: 9019 +4: 9020 +4: 9021 +4: 9022 +4: 9023 +4: 9024 +4: 9025 +4: 9026 +4: 9027 +4: 9028 +4: 9029 +4: 9030 +4: 9031 +4: 9032 +4: 9033 +4: 9034 +4: 9035 +4: 9036 +4: 9037 +4: 9038 +4: 9039 +4: 9040 +4: 9041 +4: 9042 +4: 9043 +4: 9044 +4: 9045 +4: 9046 +4: 9047 +4: 9048 +4: 9049 +4: 9050 +4: 9051 +4: 9052 +4: 9053 +4: 9054 +4: 9055 +4: 9056 +4: 9057 +4: 9058 +4: 9059 +4: 9060 +4: 9061 +4: 9062 +4: 9063 +4: 9064 +4: 9065 +4: 9066 +4: 9067 +4: 9068 +4: 9069 +4: 9070 +4: 9071 +4: 9072 +4: 9073 +4: 9074 +4: 9075 +4: 9076 +4: 9077 +4: 9078 +4: 9079 +4: 9080 +4: 9081 +4: 9082 +4: 9083 +4: 9084 +4: 9085 +4: 9086 +4: 9087 +4: 9088 +4: 9089 +4: 9090 +4: 9091 +4: 9092 +4: 9093 +4: 9094 +4: 9095 +4: 9096 +4: 9097 +4: 9098 +4: 9099 +4: 9100 +4: 9101 +4: 9102 +4: 9103 +4: 9104 +4: 9105 +4: 9106 +4: 9107 +4: 9108 +4: 9109 +4: 9110 +4: 9111 +4: 9112 +4: 9113 +4: 9114 +4: 9115 +4: 9116 +4: 9117 +4: 9118 +4: 9119 +4: 9120 +4: 9121 +4: 9122 +4: 9123 +4: 9124 +4: 9125 +4: 9126 +4: 9127 +4: 9128 +4: 9129 +4: 9130 +4: 9131 +4: 9132 +4: 9133 +4: 9134 +4: 9135 +4: 9136 +4: 9137 +4: 9138 +4: 9139 +4: 9140 +4: 9141 +4: 9142 +4: 9143 +4: 9144 +4: 9145 +4: 9146 +4: 9147 +4: 9148 +4: 9149 +4: 9150 +4: 9151 +4: 9152 +4: 9153 +4: 9154 +4: 9155 +4: 9156 +4: 9157 +4: 9158 +4: 9159 +4: 9160 +4: 9161 +4: 9162 +4: 9163 +4: 9164 +4: 9165 +4: 9166 +4: 9167 +4: 9168 +4: 9169 +4: 9170 +4: 9171 +4: 9172 +4: 9173 +4: 9174 +4: 9175 +4: 9176 +4: 9177 +4: 9178 +4: 9179 +4: 9180 +4: 9181 +4: 9182 +4: 9183 +4: 9184 +4: 9185 +4: 9186 +4: 9187 +4: 9188 +4: 9189 +4: 9190 +4: 9191 +4: 9192 +4: 9193 +4: 9194 +4: 9195 +4: 9196 +4: 9197 +4: 9198 +4: 9199 +4: 9200 +4: 9201 +4: 9202 +4: 9203 +4: 9204 +4: 9205 +4: 9206 +4: 9207 +4: 9208 +4: 9209 +4: 9210 +4: 9211 +4: 9212 +4: 9213 +4: 9214 +4: 9215 +4: 9216 +4: 9217 +4: 9218 +5: 9219 +5: 9220 +5: 9221 +5: 9222 +5: 9223 +5: 9224 +5: 9225 +5: 9226 +5: 9227 +5: 9228 +5: 9229 +5: 9230 +5: 9231 +5: 9232 +5: 9233 +5: 9234 +5: 9235 +5: 9236 +5: 9237 +5: 9238 +5: 9239 +5: 9240 +5: 9241 +5: 9242 +5: 9243 +5: 9244 +5: 9245 +5: 9246 +5: 9247 +5: 9248 +5: 9249 +5: 9250 +5: 9251 +5: 9252 +5: 9253 +5: 9254 +5: 9255 +5: 9256 +5: 9257 +5: 9258 +5: 9259 +5: 9260 +5: 9261 +5: 9262 +5: 9263 +5: 9264 +5: 9265 +5: 9266 +5: 9267 +5: 9268 +5: 9269 +5: 9270 +5: 9271 +5: 9272 +5: 9273 +5: 9274 +5: 9275 +5: 9276 +5: 9277 +5: 9278 +5: 9279 +5: 9280 +5: 9281 +5: 9282 +5: 9283 +5: 9284 +5: 9285 +5: 9286 +5: 9287 +5: 9288 +5: 9289 +5: 9290 +5: 9291 +5: 9292 +5: 9293 +5: 9294 +5: 9295 +5: 9296 +5: 9297 +5: 9298 +5: 9299 +5: 9300 +5: 9301 +5: 9302 +5: 9303 +5: 9304 +5: 9305 +5: 9306 +5: 9307 +5: 9308 +5: 9309 +5: 9310 +5: 9311 +5: 9312 +5: 9313 +5: 9314 +5: 9315 +5: 9316 +5: 9317 +5: 9318 +5: 9319 +5: 9320 +5: 9321 +5: 9322 +5: 9323 +5: 9324 +5: 9325 +5: 9326 +5: 9327 +5: 9328 +5: 9329 +5: 9330 +5: 9331 +5: 9332 +5: 9333 +5: 9334 +5: 9335 +5: 9336 +5: 9337 +5: 9338 +5: 9339 +5: 9340 +5: 9341 +5: 9342 +5: 9343 +5: 9344 +5: 9345 +5: 9346 +5: 9347 +5: 9348 +5: 9349 +5: 9350 +5: 9351 +5: 9352 +5: 9353 +5: 9354 +5: 9355 +5: 9356 +5: 9357 +5: 9358 +5: 9359 +5: 9360 +5: 9361 +5: 9362 +5: 9363 +5: 9364 +5: 9365 +5: 9366 +5: 9367 +5: 9368 +5: 9369 +5: 9370 +5: 9371 +5: 9372 +5: 9373 +5: 9374 +5: 9375 +5: 9376 +5: 9377 +5: 9378 +5: 9379 +5: 9380 +5: 9381 +5: 9382 +5: 9383 +5: 9384 +5: 9385 +5: 9386 +5: 9387 +5: 9388 +5: 9389 +5: 9390 +5: 9391 +5: 9392 +5: 9393 +5: 9394 +5: 9395 +5: 9396 +5: 9397 +5: 9398 +5: 9399 +5: 9400 +5: 9401 +5: 9402 +5: 9403 +5: 9404 +5: 9405 +5: 9406 +5: 9407 +5: 9408 +5: 9409 +5: 9410 +5: 9411 +5: 9412 +5: 9413 +5: 9414 +5: 9415 +5: 9416 +5: 9417 +5: 9418 +5: 9419 +5: 9420 +5: 9421 +5: 9422 +5: 9423 +5: 9424 +5: 9425 +5: 9426 +5: 9427 +5: 9428 +5: 9429 +5: 9430 +5: 9431 +5: 9432 +5: 9433 +5: 9434 +5: 9435 +5: 9436 +5: 9437 +5: 9438 +5: 9439 +5: 9440 +5: 9441 +5: 9442 +5: 9443 +5: 9444 +5: 9445 +5: 9446 +5: 9447 +5: 9448 +5: 9449 +5: 9450 +5: 9451 +5: 9452 +5: 9453 +5: 9454 +5: 9455 +5: 9456 +5: 9457 +5: 9458 +5: 9459 +5: 9460 +5: 9461 +5: 9462 +5: 9463 +5: 9464 +5: 9465 +5: 9466 +5: 9467 +5: 9468 +5: 9469 +5: 9470 +5: 9471 +5: 9472 +5: 9473 +5: 9474 +5: 9475 +5: 9476 +5: 9477 +5: 9478 +5: 9479 +5: 9480 +4: 9481 +4: 9482 +4: 9483 +4: 9484 +4: 9485 +4: 9486 +4: 9487 +4: 9488 +4: 9489 +4: 9490 +4: 9491 +4: 9492 +4: 9493 +4: 9494 +4: 9495 +4: 9496 +4: 9497 +4: 9498 +4: 9499 +4: 9500 +4: 9501 +4: 9502 +4: 9503 +4: 9504 +4: 9505 +4: 9506 +4: 9507 +4: 9508 +4: 9509 +4: 9510 +4: 9511 +4: 9512 +4: 9513 +4: 9514 +4: 9515 +4: 9516 +4: 9517 +4: 9518 +4: 9519 +4: 9520 +4: 9521 +4: 9522 +4: 9523 +4: 9524 +4: 9525 +4: 9526 +4: 9527 +4: 9528 +4: 9529 +4: 9530 +4: 9531 +4: 9532 +4: 9533 +4: 9534 +4: 9535 +4: 9536 +4: 9537 +4: 9538 +4: 9539 +4: 9540 +4: 9541 +4: 9542 +4: 9543 +4: 9544 +4: 9545 +4: 9546 +4: 9547 +4: 9548 +4: 9549 +4: 9550 +4: 9551 +4: 9552 +4: 9553 +4: 9554 +4: 9555 +4: 9556 +4: 9557 +4: 9558 +4: 9559 +4: 9560 +4: 9561 +4: 9562 +4: 9563 +4: 9564 +4: 9565 +4: 9566 +4: 9567 +4: 9568 +4: 9569 +4: 9570 +4: 9571 +4: 9572 +4: 9573 +4: 9574 +4: 9575 +4: 9576 +4: 9577 +4: 9578 +4: 9579 +4: 9580 +4: 9581 +4: 9582 +4: 9583 +4: 9584 +4: 9585 +4: 9586 +4: 9587 +4: 9588 +4: 9589 +4: 9590 +4: 9591 +4: 9592 +4: 9593 +4: 9594 +4: 9595 +4: 9596 +4: 9597 +4: 9598 +4: 9599 +4: 9600 +4: 9601 +4: 9602 +4: 9603 +4: 9604 +4: 9605 +4: 9606 +4: 9607 +4: 9608 +4: 9609 +4: 9610 +4: 9611 +4: 9612 +4: 9613 +4: 9614 +4: 9615 +4: 9616 +4: 9617 +4: 9618 +4: 9619 +4: 9620 +4: 9621 +4: 9622 +4: 9623 +4: 9624 +4: 9625 +4: 9626 +4: 9627 +4: 9628 +4: 9629 +4: 9630 +4: 9631 +4: 9632 +4: 9633 +4: 9634 +4: 9635 +4: 9636 +4: 9637 +4: 9638 +4: 9639 +4: 9640 +4: 9641 +4: 9642 +4: 9643 +4: 9644 +4: 9645 +4: 9646 +4: 9647 +4: 9648 +4: 9649 +4: 9650 +4: 9651 +4: 9652 +4: 9653 +4: 9654 +4: 9655 +4: 9656 +4: 9657 +4: 9658 +4: 9659 +4: 9660 +4: 9661 +4: 9662 +4: 9663 +4: 9664 +4: 9665 +4: 9666 +4: 9667 +4: 9668 +4: 9669 +4: 9670 +4: 9671 +4: 9672 +4: 9673 +4: 9674 +4: 9675 +4: 9676 +4: 9677 +4: 9678 +4: 9679 +4: 9680 +4: 9681 +4: 9682 +4: 9683 +4: 9684 +4: 9685 +4: 9686 +4: 9687 +4: 9688 +4: 9689 +4: 9690 +4: 9691 +4: 9692 +4: 9693 +4: 9694 +4: 9695 +4: 9696 +4: 9697 +4: 9698 +4: 9699 +4: 9700 +4: 9701 +4: 9702 +4: 9703 +4: 9704 +4: 9705 +4: 9706 +4: 9707 +4: 9708 +4: 9709 +4: 9710 +4: 9711 +4: 9712 +4: 9713 +4: 9714 +4: 9715 +4: 9716 +4: 9717 +4: 9718 +4: 9719 +4: 9720 +4: 9721 +4: 9722 +4: 9723 +4: 9724 +4: 9725 +4: 9726 +4: 9727 +4: 9728 +4: 9729 +4: 9730 +4: 9731 +4: 9732 +4: 9733 +4: 9734 +4: 9735 +4: 9736 +4: 9737 +4: 9738 +4: 9739 +4: 9740 +4: 9741 +4: 9742 +4: 9743 +4: 9744 +4: 9745 +4: 9746 +4: 9747 +4: 9748 +4: 9749 +4: 9750 +4: 9751 +4: 9752 +4: 9753 +4: 9754 +4: 9755 +4: 9756 +4: 9757 +4: 9758 +4: 9759 +4: 9760 +4: 9761 +4: 9762 +4: 9763 +4: 9764 +4: 9765 +4: 9766 +4: 9767 +4: 9768 +4: 9769 +4: 9770 +4: 9771 +4: 9772 +4: 9773 +4: 9774 +4: 9775 +4: 9776 +4: 9777 +4: 9778 +4: 9779 +4: 9780 +4: 9781 +4: 9782 +4: 9783 +4: 9784 +4: 9785 +4: 9786 +4: 9787 +4: 9788 +4: 9789 +4: 9790 +4: 9791 +4: 9792 +4: 9793 +4: 9794 +4: 9795 +4: 9796 +4: 9797 +4: 9798 +4: 9799 +4: 9800 +4: 9801 +4: 9802 +4: 9803 +4: 9804 +4: 9805 +4: 9806 +4: 9807 +4: 9808 +4: 9809 +4: 9810 +4: 9811 +4: 9812 +4: 9813 +4: 9814 +4: 9815 +4: 9816 +4: 9817 +4: 9818 +4: 9819 +4: 9820 +4: 9821 +4: 9822 +4: 9823 +4: 9824 +4: 9825 +4: 9826 +4: 9827 +4: 9828 +4: 9829 +4: 9830 +4: 9831 +4: 9832 +4: 9833 +4: 9834 +4: 9835 +4: 9836 +4: 9837 +4: 9838 +4: 9839 +4: 9840 +4: 9841 +4: 9842 +4: 9843 +4: 9844 +4: 9845 +4: 9846 +4: 9847 +4: 9848 +4: 9849 +4: 9850 +4: 9851 +4: 9852 +4: 9853 +4: 9854 +4: 9855 +4: 9856 +4: 9857 +4: 9858 +4: 9859 +4: 9860 +4: 9861 +4: 9862 +4: 9863 +4: 9864 +4: 9865 +4: 9866 +4: 9867 +4: 9868 +4: 9869 +4: 9870 +4: 9871 +4: 9872 +4: 9873 +4: 9874 +4: 9875 +4: 9876 +4: 9877 +4: 9878 +4: 9879 +4: 9880 +4: 9881 +4: 9882 +4: 9883 +4: 9884 +4: 9885 +4: 9886 +4: 9887 +4: 9888 +4: 9889 +4: 9890 +4: 9891 +4: 9892 +4: 9893 +4: 9894 +4: 9895 +4: 9896 +4: 9897 +4: 9898 +5: 9899 +5: 9900 +5: 9901 +5: 9902 +5: 9903 +5: 9904 +5: 9905 +5: 9906 +5: 9907 +5: 9908 +5: 9909 +5: 9910 +5: 9911 +5: 9912 +5: 9913 +5: 9914 +5: 9915 +5: 9916 +5: 9917 +5: 9918 +5: 9919 +5: 9920 +5: 9921 +5: 9922 +5: 9923 +5: 9924 +5: 9925 +5: 9926 +5: 9927 +5: 9928 +5: 9929 +5: 9930 +5: 9931 +5: 9932 +5: 9933 +5: 9934 +5: 9935 +5: 9936 +5: 9937 +5: 9938 +5: 9939 +5: 9940 +5: 9941 +5: 9942 +5: 9943 +5: 9944 +5: 9945 +5: 9946 +5: 9947 +5: 9948 +5: 9949 +5: 9950 +5: 9951 +5: 9952 +5: 9953 +5: 9954 +5: 9955 +5: 9956 +5: 9957 +5: 9958 +5: 9959 +5: 9960 +5: 9961 +5: 9962 +5: 9963 +5: 9964 +5: 9965 +5: 9966 +5: 9967 +5: 9968 +5: 9969 +5: 9970 +5: 9971 +5: 9972 +5: 9973 +5: 9974 +5: 9975 +5: 9976 +5: 9977 +5: 9978 +5: 9979 +5: 9980 +5: 9981 +5: 9982 +5: 9983 +5: 9984 +5: 9985 +5: 9986 +5: 9987 +5: 9988 +5: 9989 +5: 9990 +5: 9991 +5: 9992 +5: 9993 +5: 9994 +5: 9995 +5: 9996 +5: 9997 +5: 9998 +5: 9999 +5: 10000 diff --git a/threads/strclithread.c b/threads/strclithread.c new file mode 100644 index 0000000..22dd4db --- /dev/null +++ b/threads/strclithread.c @@ -0,0 +1,35 @@ +#include "unpthread.h" + +void *copyto(void *); + +static int sockfd; /* global for both threads to access */ +static FILE *fp; + +void +str_cli(FILE *fp_arg, int sockfd_arg) +{ + char recvline[MAXLINE]; + pthread_t tid; + + sockfd = sockfd_arg; /* copy arguments to externals */ + fp = fp_arg; + + Pthread_create(&tid, NULL, copyto, NULL); + + while (Readline(sockfd, recvline, MAXLINE) > 0) + Fputs(recvline, stdout); +} + +void * +copyto(void *arg) +{ + char sendline[MAXLINE]; + + while (Fgets(sendline, MAXLINE, fp) != NULL) + Writen(sockfd, sendline, strlen(sendline)); + + Shutdown(sockfd, SHUT_WR); /* EOF on stdin, send FIN */ + + return(NULL); + /* 4return (i.e., thread terminates) when EOF on stdin */ +} diff --git a/threads/strclithread.lc b/threads/strclithread.lc new file mode 100644 index 0000000..58bf087 --- /dev/null +++ b/threads/strclithread.lc @@ -0,0 +1,35 @@ +#include "unpthread.h"## 1 ##src/threads/strclithread.c## + +void *copyto(void *);## 2 ##src/threads/strclithread.c## + +static int sockfd; /* global for both threads to access */## 3 ##src/threads/strclithread.c## +static FILE *fp;## 4 ##src/threads/strclithread.c## + +void## 5 ##src/threads/strclithread.c## +str_cli(FILE *fp_arg, int sockfd_arg)## 6 ##src/threads/strclithread.c## +{## 7 ##src/threads/strclithread.c## + char recvline[MAXLINE];## 8 ##src/threads/strclithread.c## + pthread_t tid;## 9 ##src/threads/strclithread.c## + + sockfd = sockfd_arg; /* copy arguments to externals */## 10 ##src/threads/strclithread.c## + fp = fp_arg;## 11 ##src/threads/strclithread.c## + + Pthread_create(&tid, NULL, copyto, NULL);## 12 ##src/threads/strclithread.c## + + while (Readline(sockfd, recvline, MAXLINE) > 0)## 13 ##src/threads/strclithread.c## + Fputs(recvline, stdout);## 14 ##src/threads/strclithread.c## +}## 15 ##src/threads/strclithread.c## + +void *## 16 ##src/threads/strclithread.c## +copyto(void *arg)## 17 ##src/threads/strclithread.c## +{## 18 ##src/threads/strclithread.c## + char sendline[MAXLINE];## 19 ##src/threads/strclithread.c## + + while (Fgets(sendline, MAXLINE, fp) != NULL)## 20 ##src/threads/strclithread.c## + Writen(sockfd, sendline, strlen(sendline));## 21 ##src/threads/strclithread.c## + + Shutdown(sockfd, SHUT_WR); /* EOF on stdin, send FIN */## 22 ##src/threads/strclithread.c## + + return (NULL);## 23 ##src/threads/strclithread.c## + /* 4return (i.e., thread terminates) when end-of-file on stdin */## 24 ##src/threads/strclithread.c## +}## 25 ##src/threads/strclithread.c## diff --git a/threads/strclithread2.c b/threads/strclithread2.c new file mode 100644 index 0000000..2fb624e --- /dev/null +++ b/threads/strclithread2.c @@ -0,0 +1,40 @@ +#include "unpthread.h" + +void *copyto(void *); + +static int sockfd; +static FILE *fp; +static int done; + +void +str_cli(FILE *fp_arg, int sockfd_arg) +{ + char recvline[MAXLINE]; + pthread_t tid; + + sockfd = sockfd_arg; /* copy arguments to externals */ + fp = fp_arg; + + Pthread_create(&tid, NULL, copyto, NULL); + + while (Readline(sockfd, recvline, MAXLINE) > 0) + Fputs(recvline, stdout); + + if (done == 0) + err_quit("server terminated prematurely"); +} + +void * +copyto(void *arg) +{ + char sendline[MAXLINE]; + + while (Fgets(sendline, MAXLINE, fp) != NULL) + Writen(sockfd, sendline, strlen(sendline)); + + Shutdown(sockfd, SHUT_WR); /* EOF on stdin, send FIN */ + + done = 1; + return(NULL); + /* return (i.e., thread terminates) when end-of-file on stdin */ +} diff --git a/threads/tcpcli01.c b/threads/tcpcli01.c new file mode 100644 index 0000000..aa1300e --- /dev/null +++ b/threads/tcpcli01.c @@ -0,0 +1,16 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + + if (argc != 3) + err_quit("usage: tcpcli "); + + sockfd = Tcp_connect(argv[1], argv[2]); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/threads/tcpcli02.c b/threads/tcpcli02.c new file mode 100644 index 0000000..aa1300e --- /dev/null +++ b/threads/tcpcli02.c @@ -0,0 +1,16 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + + if (argc != 3) + err_quit("usage: tcpcli "); + + sockfd = Tcp_connect(argv[1], argv[2]); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/threads/tcpserv01.c b/threads/tcpserv01.c new file mode 100644 index 0000000..5bd1346 --- /dev/null +++ b/threads/tcpserv01.c @@ -0,0 +1,36 @@ +#include "unpthread.h" + +static void *doit(void *); /* each thread executes this function */ + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + pthread_t tid; + socklen_t addrlen, len; + struct sockaddr *cliaddr; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: tcpserv01 [ ] "); + + cliaddr = Malloc(addrlen); + + for ( ; ; ) { + len = addrlen; + connfd = Accept(listenfd, cliaddr, &len); + Pthread_create(&tid, NULL, &doit, (void *) connfd); + } +} + +static void * +doit(void *arg) +{ + Pthread_detach(pthread_self()); + str_echo((int) arg); /* same function as before */ + Close((int) arg); /* done with connected socket */ + return(NULL); +} diff --git a/threads/tcpserv02.c b/threads/tcpserv02.c new file mode 100644 index 0000000..b8da350 --- /dev/null +++ b/threads/tcpserv02.c @@ -0,0 +1,42 @@ +#include "unpthread.h" + +static void *doit(void *); /* each thread executes this function */ + +int +main(int argc, char **argv) +{ + int listenfd, *iptr; + thread_t tid; + socklen_t addrlen, len; + struct sockaddr *cliaddr; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: tcpserv01 [ ] "); + + cliaddr = Malloc(addrlen); + + for ( ; ; ) { + len = addrlen; + iptr = Malloc(sizeof(int)); + *iptr = Accept(listenfd, cliaddr, &len); + Pthread_create(&tid, NULL, &doit, iptr); + } +} + +static void * +doit(void *arg) +{ + int connfd; + + connfd = *((int *) arg); + free(arg); + + Pthread_detach(pthread_self()); + str_echo(connfd); /* same function as before */ + Close(connfd); /* done with connected socket */ + return(NULL); +} diff --git a/threads/test01.c b/threads/test01.c new file mode 100644 index 0000000..bbb3e2c --- /dev/null +++ b/threads/test01.c @@ -0,0 +1,29 @@ +#include "unpthread.h" + +void * +myfunc(void *ptr) +{ + pause(); +} + +int +main(int argc, char **argv) +{ + pthread_t tid; + int n; + + /* Let's see what the return value is and what errno is after a error. */ + for ( ; ; ) { + errno = 0; + if ( (n = pthread_create(&tid, NULL, myfunc, NULL)) != 0) { + printf("pthread_create returned %d, errno = %d\n", n, errno); + + errno = 0; + n = pthread_join(777777, NULL); + printf("pthread_join returned %d, errno = %d\n", n, errno); + + exit(0); + } + printf("created tid %d\n", tid); + } +} diff --git a/threads/test02.c b/threads/test02.c new file mode 100644 index 0000000..a4e4ba5 --- /dev/null +++ b/threads/test02.c @@ -0,0 +1,34 @@ +#include "unpthread.h" + +void * +myfunc(void *ptr) +{ + int val; + + printf("thread ID of myfunc: %d\n", pthread_self()); + + val = *((int *) ptr); + printf("val = %d\n", val); + sleep(10); + val = *((int *) ptr); + printf("val = %d\n", val); +} + +int +main(int argc, char **argv) +{ + pthread_t tid; + int n, val; + + printf("thread ID of main: %d\n", pthread_self()); + + /* Let's verify that the value pointed to the thread's argument is + modifiable */ + val = 123; + if ( (n = pthread_create(&tid, NULL, myfunc, &val)) != 0) + errno = n, err_sys("pthread_create error"); + sleep(5); + val = 789; + sleep(20); + exit(0); +} diff --git a/threads/test03.c b/threads/test03.c new file mode 100644 index 0000000..a266e90 --- /dev/null +++ b/threads/test03.c @@ -0,0 +1,47 @@ +/* test pthread_cond_timedwait() */ + +#include "unpthread.h" + +int ndone; +pthread_mutex_t ndone_mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t ndone_cond = PTHREAD_COND_INITIALIZER; + +void * +myfunc(void *ptr) +{ + int val; + + sleep(100); /* do not set ndone, do not cond_signal() */ + return(NULL); +} + +int +main(int argc, char **argv) +{ + pthread_t tid; + int n, val; + struct timeval tv; + struct timespec ts; + + if ( (n = pthread_create(&tid, NULL, myfunc, &val)) != 0) + errno = n, err_sys("pthread_create error"); + + if (gettimeofday(&tv, NULL) < 0) + err_sys("gettimeofday error"); + ts.tv_sec = tv.tv_sec + 5; /* 5 seconds in future */ + ts.tv_nsec = tv.tv_usec * 1000; + + if ( (n = pthread_mutex_lock(&ndone_mutex)) != 0) + errno = n, err_sys("pthread_mutex_lock error"); + while (ndone == 0) + if ( (n = pthread_cond_timedwait(&ndone_cond, &ndone_mutex, &ts)) != 0){ + if (n == ETIME) + err_quit("timewait timed out"); + errno = n, err_sys("pthread_cond_timedwait error"); + } + + if ( (n = pthread_mutex_unlock(&ndone_mutex)) != 0) + errno = n, err_sys("pthread_mutex_unlock error"); + + exit(0); +} diff --git a/threads/test04.c b/threads/test04.c new file mode 100644 index 0000000..993198d --- /dev/null +++ b/threads/test04.c @@ -0,0 +1,50 @@ +/* test readline() */ + +#include "unpthread.h" + +static char *infile; /* from argv[1]; read-only by threads */ + +void * +myfunc(void *ptr) +{ + int i, fdin; + char buf[MAXLINE]; + FILE *fpout; + + snprintf(buf, sizeof(buf), "temp.%d", pthread_self()); + fpout = Fopen(buf, "w+"); + /* printf("created %s\n", buf); */ + + for (i = 0; i < 5; i++) { + fdin = Open(infile, O_RDONLY, 0); + + while (Readline(fdin, buf, sizeof(buf)) > 0) { + fputs(buf, fpout); + } + Close(fdin); + } + Fclose(fpout); + + printf("thread %d done\n", pthread_self()); + return(NULL); +} + +int +main(int argc, char **argv) +{ + int i, nthreads; + pthread_t tid; + + if (argc != 3) + err_quit("usage: test04 <#threads>"); + infile = argv[1]; + nthreads = atoi(argv[2]); + + for (i = 0; i < nthreads; i++) { + Pthread_create(&tid, NULL, myfunc, NULL); + } + + pause(); + + exit(0); +} diff --git a/threads/test05.c b/threads/test05.c new file mode 100644 index 0000000..7d5aa02 --- /dev/null +++ b/threads/test05.c @@ -0,0 +1,33 @@ +/* See what the implementation returns for TSD keys */ + +#include "unpthread.h" + +pthread_key_t my_key; + +int +main(int argc, char **argv) +{ + int *iptr; + + Pthread_key_create(&my_key, NULL); + printf("first key = %d\n", my_key); + + Pthread_key_create(&my_key, NULL); + printf("second key = %d\n", my_key); + + Pthread_key_create(&my_key, NULL); + printf("third key = %d\n", my_key); + + if ( (iptr = pthread_getspecific((pthread_key_t) 0)) == NULL) + printf("key 0 pointer is NULL\n"); + else + printf("value in key 0 = %d\n", *iptr); + + errno = 67; + if ( (iptr = pthread_getspecific((pthread_key_t) 0)) == NULL) + printf("key 0 pointer is NULL\n"); + else + printf("value in key 0 = %d\n", *iptr); + + exit(0); +} diff --git a/threads/unpthread.h b/threads/unpthread.h new file mode 100644 index 0000000..e79b779 --- /dev/null +++ b/threads/unpthread.h @@ -0,0 +1,31 @@ +/* Our own header for the programs that use threads. + Include this file, instead of "unp.h". */ + +#ifndef __unp_pthread_h +#define __unp_pthread_h + +#include "unp.h" + +void Pthread_create(pthread_t *, const pthread_attr_t *, + void * (*)(void *), void *); +void Pthread_join(pthread_t, void **); +void Pthread_detach(pthread_t); +void Pthread_kill(pthread_t, int); + +void Pthread_mutexattr_init(pthread_mutexattr_t *); +void Pthread_mutexattr_setpshared(pthread_mutexattr_t *, int); +void Pthread_mutex_init(pthread_mutex_t *, pthread_mutexattr_t *); +void Pthread_mutex_lock(pthread_mutex_t *); +void Pthread_mutex_unlock(pthread_mutex_t *); + +void Pthread_cond_broadcast(pthread_cond_t *); +void Pthread_cond_signal(pthread_cond_t *); +void Pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); +void Pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *, + const struct timespec *); + +void Pthread_key_create(pthread_key_t *, void (*)(void *)); +void Pthread_setspecific(pthread_key_t, const void *); +void Pthread_once(pthread_once_t *, void (*)(void)); + +#endif /* __unp_pthread_h */ diff --git a/threads/web01.c b/threads/web01.c new file mode 100644 index 0000000..adc9bba --- /dev/null +++ b/threads/web01.c @@ -0,0 +1,149 @@ +/* include web1 */ +#include "unpthread.h" +#include /* Solaris threads */ + +#define MAXFILES 20 +#define SERV "80" /* port number or service name */ + +struct file { + char *f_name; /* filename */ + char *f_host; /* hostname or IP address */ + int f_fd; /* descriptor */ + int f_flags; /* F_xxx below */ + pthread_t f_tid; /* thread ID */ +} file[MAXFILES]; +#define F_CONNECTING 1 /* connect() in progress */ +#define F_READING 2 /* connect() complete; now reading */ +#define F_DONE 4 /* all done */ + +#define GET_CMD "GET %s HTTP/1.0\r\n\r\n" + +int nconn, nfiles, nlefttoconn, nlefttoread; + +void *do_get_read(void *); +void home_page(const char *, const char *); +void write_get_cmd(struct file *); + +int +main(int argc, char **argv) +{ + int i, n, maxnconn; + pthread_t tid; + struct file *fptr; + + if (argc < 5) + err_quit("usage: web <#conns> file1 ..."); + maxnconn = atoi(argv[1]); + + nfiles = min(argc - 4, MAXFILES); + for (i = 0; i < nfiles; i++) { + file[i].f_name = argv[i + 4]; + file[i].f_host = argv[2]; + file[i].f_flags = 0; + } + printf("nfiles = %d\n", nfiles); + + home_page(argv[2], argv[3]); + + nlefttoread = nlefttoconn = nfiles; + nconn = 0; +/* end web1 */ +/* include web2 */ + while (nlefttoread > 0) { + while (nconn < maxnconn && nlefttoconn > 0) { + /* 4find a file to read */ + for (i = 0 ; i < nfiles; i++) + if (file[i].f_flags == 0) + break; + if (i == nfiles) + err_quit("nlefttoconn = %d but nothing found", nlefttoconn); + + file[i].f_flags = F_CONNECTING; + Pthread_create(&tid, NULL, &do_get_read, &file[i]); + file[i].f_tid = tid; + nconn++; + nlefttoconn--; + } + + if ( (n = thr_join(0, &tid, (void **) &fptr)) != 0) + errno = n, err_sys("thr_join error"); + + nconn--; + nlefttoread--; + printf("thread id %d for %s done\n", tid, fptr->f_name); + } + + exit(0); +} +/* end web2 */ + +/* include do_get_read */ +void * +do_get_read(void *vptr) +{ + int fd, n; + char line[MAXLINE]; + struct file *fptr; + + fptr = (struct file *) vptr; + + fd = Tcp_connect(fptr->f_host, SERV); + fptr->f_fd = fd; + printf("do_get_read for %s, fd %d, thread %d\n", + fptr->f_name, fd, fptr->f_tid); + + write_get_cmd(fptr); /* write() the GET command */ + + /* 4Read server's reply */ + for ( ; ; ) { + if ( (n = Read(fd, line, MAXLINE)) == 0) + break; /* server closed connection */ + + printf("read %d bytes from %s\n", n, fptr->f_name); + } + printf("end-of-file on %s\n", fptr->f_name); + Close(fd); + fptr->f_flags = F_DONE; /* clears F_READING */ + + return(fptr); /* terminate thread */ +} +/* end do_get_read */ + +/* include write_get_cmd */ +void +write_get_cmd(struct file *fptr) +{ + int n; + char line[MAXLINE]; + + n = snprintf(line, sizeof(line), GET_CMD, fptr->f_name); + Writen(fptr->f_fd, line, n); + printf("wrote %d bytes for %s\n", n, fptr->f_name); + + fptr->f_flags = F_READING; /* clears F_CONNECTING */ +} +/* end write_get_cmd */ + +/* include home_page */ +void +home_page(const char *host, const char *fname) +{ + int fd, n; + char line[MAXLINE]; + + fd = Tcp_connect(host, SERV); /* blocking connect() */ + + n = snprintf(line, sizeof(line), GET_CMD, fname); + Writen(fd, line, n); + + for ( ; ; ) { + if ( (n = Read(fd, line, MAXLINE)) == 0) + break; /* server closed connection */ + + printf("read %d bytes of home page\n", n); + /* do whatever with data */ + } + printf("end-of-file on home page\n"); + Close(fd); +} +/* end home_page */ diff --git a/threads/web01.lc b/threads/web01.lc new file mode 100644 index 0000000..162fedd --- /dev/null +++ b/threads/web01.lc @@ -0,0 +1,149 @@ +/* include web1 */ +#include "unpthread.h"## 1 ##src/threads/web01.c## +#include /* Solaris threads */## 2 ##src/threads/web01.c## + +#define MAXFILES 20## 3 ##src/threads/web01.c## +#define SERV "80" /* port number or service name */## 4 ##src/threads/web01.c## + +struct file {## 5 ##src/threads/web01.c## + char *f_name; /* filename */## 6 ##src/threads/web01.c## + char *f_host; /* hostname or IP address */## 7 ##src/threads/web01.c## + int f_fd; /* descriptor */## 8 ##src/threads/web01.c## + int f_flags; /* F_xxx below */## 9 ##src/threads/web01.c## + pthread_t f_tid; /* thread ID */## 10 ##src/threads/web01.c## +} file[MAXFILES];## 11 ##src/threads/web01.c## +#define F_CONNECTING 1 /* connect() in progress */## 12 ##src/threads/web01.c## +#define F_READING 2 /* connect() complete; now reading */## 13 ##src/threads/web01.c## +#define F_DONE 4 /* all done */## 14 ##src/threads/web01.c## + +#define GET_CMD "GET %s HTTP/1.0\r\n\r\n"## 15 ##src/threads/web01.c## + +int nconn, nfiles, nlefttoconn, nlefttoread;## 16 ##src/threads/web01.c## + +void *do_get_read(void *);## 17 ##src/threads/web01.c## +void home_page(const char *, const char *);## 18 ##src/threads/web01.c## +void write_get_cmd(struct file *);## 19 ##src/threads/web01.c## + +int## 20 ##src/threads/web01.c## +main(int argc, char **argv)## 21 ##src/threads/web01.c## +{## 22 ##src/threads/web01.c## + int i, n, maxnconn;## 23 ##src/threads/web01.c## + pthread_t tid;## 24 ##src/threads/web01.c## + struct file *fptr;## 25 ##src/threads/web01.c## + + if (argc < 5)## 26 ##src/threads/web01.c## + err_quit("usage: web <#conns> file1 ...");## 27 ##src/threads/web01.c## + maxnconn = atoi(argv[1]);## 28 ##src/threads/web01.c## + + nfiles = min(argc - 4, MAXFILES);## 29 ##src/threads/web01.c## + for (i = 0; i < nfiles; i++) {## 30 ##src/threads/web01.c## + file[i].f_name = argv[i + 4];## 31 ##src/threads/web01.c## + file[i].f_host = argv[2];## 32 ##src/threads/web01.c## + file[i].f_flags = 0;## 33 ##src/threads/web01.c## + }## 34 ##src/threads/web01.c## + printf("nfiles = %d\n", nfiles);## 35 ##src/threads/web01.c## + + home_page(argv[2], argv[3]);## 36 ##src/threads/web01.c## + + nlefttoread = nlefttoconn = nfiles;## 37 ##src/threads/web01.c## + nconn = 0;## 38 ##src/threads/web01.c## +/* end web1 */ +/* include web2 */ + while (nlefttoread > 0) {## 39 ##src/threads/web01.c## + while (nconn < maxnconn && nlefttoconn > 0) {## 40 ##src/threads/web01.c## + /* 4find a file to read */## 41 ##src/threads/web01.c## + for (i = 0; i < nfiles; i++)## 42 ##src/threads/web01.c## + if (file[i].f_flags == 0)## 43 ##src/threads/web01.c## + break;## 44 ##src/threads/web01.c## + if (i == nfiles)## 45 ##src/threads/web01.c## + err_quit("nlefttoconn = %d but nothing found", nlefttoconn);## 46 ##src/threads/web01.c## + + file[i].f_flags = F_CONNECTING;## 47 ##src/threads/web01.c## + Pthread_create(&tid, NULL, &do_get_read, &file[i]);## 48 ##src/threads/web01.c## + file[i].f_tid = tid;## 49 ##src/threads/web01.c## + nconn++;## 50 ##src/threads/web01.c## + nlefttoconn--;## 51 ##src/threads/web01.c## + }## 52 ##src/threads/web01.c## + + if ((n = thr_join(0, &tid, (void **) &fptr)) != 0)## 53 ##src/threads/web01.c## + errno = n, err_sys("thr_join error");## 54 ##src/threads/web01.c## + + nconn--;## 55 ##src/threads/web01.c## + nlefttoread--;## 56 ##src/threads/web01.c## + printf("thread id %d for %s done\n", tid, fptr->f_name);## 57 ##src/threads/web01.c## + }## 58 ##src/threads/web01.c## + + exit(0);## 59 ##src/threads/web01.c## +}## 60 ##src/threads/web01.c## +/* end web2 */ + +/* include do_get_read */ +void *## 61 ##src/threads/web01.c## +do_get_read(void *vptr)## 62 ##src/threads/web01.c## +{## 63 ##src/threads/web01.c## + int fd, n;## 64 ##src/threads/web01.c## + char line[MAXLINE];## 65 ##src/threads/web01.c## + struct file *fptr;## 66 ##src/threads/web01.c## + + fptr = (struct file *) vptr;## 67 ##src/threads/web01.c## + + fd = Tcp_connect(fptr->f_host, SERV);## 68 ##src/threads/web01.c## + fptr->f_fd = fd;## 69 ##src/threads/web01.c## + printf("do_get_read for %s, fd %d, thread %d\n",## 70 ##src/threads/web01.c## + fptr->f_name, fd, fptr->f_tid);## 71 ##src/threads/web01.c## + + write_get_cmd(fptr); /* write() the GET command */## 72 ##src/threads/web01.c## + + /* 4Read server's reply */## 73 ##src/threads/web01.c## + for (;;) {## 74 ##src/threads/web01.c## + if ((n = Read(fd, line, MAXLINE)) == 0)## 75 ##src/threads/web01.c## + break; /* server closed connection */## 76 ##src/threads/web01.c## + + printf("read %d bytes from %s\n", n, fptr->f_name);## 77 ##src/threads/web01.c## + }## 78 ##src/threads/web01.c## + printf("end-of-file on %s\n", fptr->f_name);## 79 ##src/threads/web01.c## + Close(fd);## 80 ##src/threads/web01.c## + fptr->f_flags = F_DONE; /* clears F_READING */## 81 ##src/threads/web01.c## + + return (fptr); /* terminate thread */## 82 ##src/threads/web01.c## +}## 83 ##src/threads/web01.c## +/* end do_get_read */ + +/* include write_get_cmd */ +void## 84 ##src/threads/web01.c## +write_get_cmd(struct file *fptr)## 85 ##src/threads/web01.c## +{## 86 ##src/threads/web01.c## + int n;## 87 ##src/threads/web01.c## + char line[MAXLINE];## 88 ##src/threads/web01.c## + + n = snprintf(line, sizeof(line), GET_CMD, fptr->f_name);## 89 ##src/threads/web01.c## + Writen(fptr->f_fd, line, n);## 90 ##src/threads/web01.c## + printf("wrote %d bytes for %s\n", n, fptr->f_name);## 91 ##src/threads/web01.c## + + fptr->f_flags = F_READING; /* clears F_CONNECTING */## 92 ##src/threads/web01.c## +}## 93 ##src/threads/web01.c## +/* end write_get_cmd */ + +/* include home_page */ +void## 94 ##src/threads/web01.c## +home_page(const char *host, const char *fname)## 95 ##src/threads/web01.c## +{## 96 ##src/threads/web01.c## + int fd, n;## 97 ##src/threads/web01.c## + char line[MAXLINE];## 98 ##src/threads/web01.c## + + fd = Tcp_connect(host, SERV); /* blocking connect() */## 99 ##src/threads/web01.c## + + n = snprintf(line, sizeof(line), GET_CMD, fname);##100 ##src/threads/web01.c## + Writen(fd, line, n);##101 ##src/threads/web01.c## + + for (;;) {##102 ##src/threads/web01.c## + if ((n = Read(fd, line, MAXLINE)) == 0)##103 ##src/threads/web01.c## + break; /* server closed connection */##104 ##src/threads/web01.c## + + printf("read %d bytes of home page\n", n);##105 ##src/threads/web01.c## + /* do whatever with data */##106 ##src/threads/web01.c## + }##107 ##src/threads/web01.c## + printf("end-of-file on home page\n");##108 ##src/threads/web01.c## + Close(fd);##109 ##src/threads/web01.c## +}##110 ##src/threads/web01.c## +/* end home_page */ diff --git a/threads/web02.c b/threads/web02.c new file mode 100644 index 0000000..cb7d7ba --- /dev/null +++ b/threads/web02.c @@ -0,0 +1,184 @@ +/* Doesn't work right. Main thread sucks up all the CPU time polling unless + we call thr_yield(). */ +#include "unpthread.h" +#include /* Solaris threads */ + +#define MAXFILES 20 +#define SERV "80" /* port number or service name */ + +struct file { + char *f_name; /* filename */ + char *f_host; /* hostname or IP address */ + int f_fd; /* descriptor */ + int f_flags; /* F_xxx below */ + pthread_t f_tid; /* thread ID */ +} file[MAXFILES]; +#define F_CONNECTING 1 /* connect() in progress */ +#define F_READING 2 /* connect() complete; now reading */ +#define F_DONE 4 /* all done */ +#define F_JOINED 8 /* main has pthread_join'ed */ + +int nconn, nfiles, nlefttoconn, nlefttoread; +char get[] = "GET / HTTP/1.0\r\n\r\n"; /* for home page */ + +int ndone; /* number of terminated threads & mutex */ +pthread_mutex_t ndone_mutex = PTHREAD_MUTEX_INITIALIZER; + +void *do_get_read(void *); +void home_page(const char *, const char *); +void write_get_cmd(struct file *); + +int +main(int argc, char **argv) +{ + int i, n, maxnconn; + pthread_t tid; + struct file *fptr; + + if (argc < 5) + err_quit("usage: web <#conns> file1 ..."); + maxnconn = atoi(argv[1]); + + nfiles = min(argc - 4, MAXFILES); + for (i = 0; i < nfiles; i++) { + file[i].f_name = argv[i + 4]; + file[i].f_host = argv[2]; + file[i].f_flags = 0; + } + printf("nfiles = %d\n", nfiles); + + home_page(argv[2], argv[3]); + + nlefttoread = nlefttoconn = nfiles; + nconn = 0; + while (nlefttoread > 0) { +/* printf("nconn = %d, nlefttoconn = %d\n", nconn, nlefttoconn); */ + while (nconn < maxnconn && nlefttoconn > 0) { + /* find a file to read */ + for (i = 0 ; i < nfiles; i++) + if (file[i].f_flags == 0) + break; + if (i == nfiles) + err_quit("nlefttoconn = %d but nothing found", nlefttoconn); + + if ( (n = pthread_create(&tid, NULL, &do_get_read, &file[i])) != 0) + errno = n, err_sys("pthread_create error"); +printf("created thread %d\n", tid); + file[i].f_tid = tid; + file[i].f_flags = F_CONNECTING; + nconn++; + nlefttoconn--; + } +thr_yield(); + + /* See if one of the threads is done */ + if ( (n = pthread_mutex_lock(&ndone_mutex)) != 0) + errno = n, err_sys("pthread_mutex_lock error"); + if (ndone > 0) { + for (i = 0; i < nfiles; i++) { + if (file[i].f_flags & F_DONE) { + if ( (n = pthread_join(file[i].f_tid, (void **) &fptr)) != 0) + errno = n, err_sys("pthread_join error"); + + if (&file[i] != fptr) + err_quit("file[i] != fptr"); + fptr->f_flags = F_JOINED; /* clears F_DONE */ + ndone--; + nconn--; + nlefttoread--; + printf("thread id %d for %s done\n", + file[i].f_tid, fptr->f_name); + } + } + } + if ( (n = pthread_mutex_unlock(&ndone_mutex)) != 0) + errno = n, err_sys("pthread_mutex_unlock error"); + } + + exit(0); +} + +void * +do_get_read(void *vptr) +{ + int fd, n; + char line[MAXLINE]; + struct file *fptr; + + fptr = (struct file *) vptr; + + fd = Tcp_connect(fptr->f_host, SERV); + fptr->f_fd = fd; + printf("do_get_read for %s, fd %d, thread %d\n", + fptr->f_name, fd, fptr->f_tid); + + write_get_cmd(fptr); /* write() the GET command */ + + /* Read server's reply */ + for ( ; ; ) { + if ( (n = read(fd, line, MAXLINE)) <= 0) { + if (n == 0) + break; /* server closed connection */ + else + err_sys("read error"); + } + printf("read %d bytes from %s\n", n, fptr->f_name); + } + printf("end-of-file on %s\n", fptr->f_name); + close(fd); + fptr->f_flags = F_DONE; /* clears F_READING */ + + if ( (n = pthread_mutex_lock(&ndone_mutex)) != 0) + errno = n, err_sys("pthread_mutex_lock error"); + ndone++; + if ( (n = pthread_mutex_unlock(&ndone_mutex)) != 0) + errno = n, err_sys("pthread_mutex_unlock error"); + + return(fptr); /* terminate thread */ +} + +void +write_get_cmd(struct file *fptr) +{ + int n; + char line[MAXLINE]; + + strcpy(line, "GET "); + strcat(line, fptr->f_name); + strcat(line, " HTTP/1.0\r\n\r\n"); + n = strlen(line); + if (writen(fptr->f_fd, line, n) != n) + err_sys("writen error"); + printf("wrote %d bytes for %s\n", n, fptr->f_name); + + fptr->f_flags = F_READING; /* clears F_CONNECTING */ +} + +void +home_page(const char *host, const char *fname) +{ + int fd, n; + char line[MAXLINE]; + + fd = Tcp_connect(host, SERV); + + strcpy(line, "GET "); + strcat(line, fname); + strcat(line, " HTTP/1.0\r\n\r\n"); + n = strlen(line); + if (writen(fd, line, n) != n) + err_sys("writen error"); + + for ( ; ; ) { + if ( (n = read(fd, line, MAXLINE)) <= 0) { + if (n == 0) + break; /* server closed connection */ + else + err_sys("read error"); + } + printf("read %d bytes of home page\n", n); + /* do whatever with data */ + } + printf("end-of-file on home page\n"); + close(fd); +} diff --git a/threads/web03.c b/threads/web03.c new file mode 100644 index 0000000..ee87391 --- /dev/null +++ b/threads/web03.c @@ -0,0 +1,164 @@ +#include "unpthread.h" +#include /* Solaris threads */ + +#define MAXFILES 20 +#define SERV "80" /* port number or service name */ + +struct file { + char *f_name; /* filename */ + char *f_host; /* hostname or IP address */ + int f_fd; /* descriptor */ + int f_flags; /* F_xxx below */ + pthread_t f_tid; /* thread ID */ +} file[MAXFILES]; +#define F_CONNECTING 1 /* connect() in progress */ +#define F_READING 2 /* connect() complete; now reading */ +#define F_DONE 4 /* all done */ +#define F_JOINED 8 /* main has pthread_join'ed */ + +#define GET_CMD "GET %s HTTP/1.0\r\n\r\n" + +int nconn, nfiles, nlefttoconn, nlefttoread; + +int ndone; /* number of terminated threads */ +pthread_mutex_t ndone_mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t ndone_cond = PTHREAD_COND_INITIALIZER; + +void *do_get_read(void *); +void home_page(const char *, const char *); +void write_get_cmd(struct file *); + +int +main(int argc, char **argv) +{ + int i, maxnconn; + pthread_t tid; + struct file *fptr; + + if (argc < 5) + err_quit("usage: web <#conns> file1 ..."); + maxnconn = atoi(argv[1]); + + nfiles = min(argc - 4, MAXFILES); + for (i = 0; i < nfiles; i++) { + file[i].f_name = argv[i + 4]; + file[i].f_host = argv[2]; + file[i].f_flags = 0; + } + printf("nfiles = %d\n", nfiles); + + home_page(argv[2], argv[3]); + + nlefttoread = nlefttoconn = nfiles; + nconn = 0; +/* include web2 */ + while (nlefttoread > 0) { + while (nconn < maxnconn && nlefttoconn > 0) { + /* 4find a file to read */ + for (i = 0 ; i < nfiles; i++) + if (file[i].f_flags == 0) + break; + if (i == nfiles) + err_quit("nlefttoconn = %d but nothing found", nlefttoconn); + + file[i].f_flags = F_CONNECTING; + Pthread_create(&tid, NULL, &do_get_read, &file[i]); + file[i].f_tid = tid; + nconn++; + nlefttoconn--; + } + + /* 4Wait for thread to terminate */ + Pthread_mutex_lock(&ndone_mutex); + while (ndone == 0) + Pthread_cond_wait(&ndone_cond, &ndone_mutex); + + for (i = 0; i < nfiles; i++) { + if (file[i].f_flags & F_DONE) { + Pthread_join(file[i].f_tid, (void **) &fptr); + + if (&file[i] != fptr) + err_quit("file[i] != fptr"); + fptr->f_flags = F_JOINED; /* clears F_DONE */ + ndone--; + nconn--; + nlefttoread--; + printf("thread %d for %s done\n", fptr->f_tid, fptr->f_name); + } + } + Pthread_mutex_unlock(&ndone_mutex); + } + + exit(0); +} +/* end web2 */ + +void * +do_get_read(void *vptr) +{ + int fd, n; + char line[MAXLINE]; + struct file *fptr; + + fptr = (struct file *) vptr; + + fd = Tcp_connect(fptr->f_host, SERV); + fptr->f_fd = fd; + printf("do_get_read for %s, fd %d, thread %d\n", + fptr->f_name, fd, fptr->f_tid); + + write_get_cmd(fptr); /* write() the GET command */ + + /* 4Read server's reply */ + for ( ; ; ) { + if ( (n = Read(fd, line, MAXLINE)) == 0) + break; /* server closed connection */ + + printf("read %d bytes from %s\n", n, fptr->f_name); + } + printf("end-of-file on %s\n", fptr->f_name); + Close(fd); + fptr->f_flags = F_DONE; /* clears F_READING */ + + Pthread_mutex_lock(&ndone_mutex); + ndone++; + Pthread_cond_signal(&ndone_cond); + Pthread_mutex_unlock(&ndone_mutex); + + return(fptr); /* terminate thread */ +} + +void +write_get_cmd(struct file *fptr) +{ + int n; + char line[MAXLINE]; + + n = snprintf(line, sizeof(line), GET_CMD, fptr->f_name); + Writen(fptr->f_fd, line, n); + printf("wrote %d bytes for %s\n", n, fptr->f_name); + + fptr->f_flags = F_READING; /* clears F_CONNECTING */ +} + +void +home_page(const char *host, const char *fname) +{ + int fd, n; + char line[MAXLINE]; + + fd = Tcp_connect(host, SERV); /* blocking connect() */ + + n = snprintf(line, sizeof(line), GET_CMD, fname); + Writen(fd, line, n); + + for ( ; ; ) { + if ( (n = Read(fd, line, MAXLINE)) == 0) + break; /* server closed connection */ + + printf("read %d bytes of home page\n", n); + /* do whatever with data */ + } + printf("end-of-file on home page\n"); + Close(fd); +} diff --git a/threads/web03.lc b/threads/web03.lc new file mode 100644 index 0000000..6b260b2 --- /dev/null +++ b/threads/web03.lc @@ -0,0 +1,164 @@ +#include "unpthread.h"## 1 ##src/threads/web03.c## +#include /* Solaris threads */## 2 ##src/threads/web03.c## + +#define MAXFILES 20## 3 ##src/threads/web03.c## +#define SERV "80" /* port number or service name */## 4 ##src/threads/web03.c## + +struct file {## 5 ##src/threads/web03.c## + char *f_name; /* filename */## 6 ##src/threads/web03.c## + char *f_host; /* hostname or IP address */## 7 ##src/threads/web03.c## + int f_fd; /* descriptor */## 8 ##src/threads/web03.c## + int f_flags; /* F_xxx below */## 9 ##src/threads/web03.c## + pthread_t f_tid; /* thread ID */## 10 ##src/threads/web03.c## +} file[MAXFILES];## 11 ##src/threads/web03.c## +#define F_CONNECTING 1 /* connect() in progress */## 12 ##src/threads/web03.c## +#define F_READING 2 /* connect() complete; now reading */## 13 ##src/threads/web03.c## +#define F_DONE 4 /* all done */## 14 ##src/threads/web03.c## +#define F_JOINED 8 /* main has pthread_join'ed */## 15 ##src/threads/web03.c## + +#define GET_CMD "GET %s HTTP/1.0\r\n\r\n"## 16 ##src/threads/web03.c## + +int nconn, nfiles, nlefttoconn, nlefttoread;## 17 ##src/threads/web03.c## + +int ndone; /* number of terminated threads */## 18 ##src/threads/web03.c## +pthread_mutex_t ndone_mutex = PTHREAD_MUTEX_INITIALIZER;## 19 ##src/threads/web03.c## +pthread_cond_t ndone_cond = PTHREAD_COND_INITIALIZER;## 20 ##src/threads/web03.c## + +void *do_get_read(void *);## 21 ##src/threads/web03.c## +void home_page(const char *, const char *);## 22 ##src/threads/web03.c## +void write_get_cmd(struct file *);## 23 ##src/threads/web03.c## + +int## 24 ##src/threads/web03.c## +main(int argc, char **argv)## 25 ##src/threads/web03.c## +{## 26 ##src/threads/web03.c## + int i, maxnconn;## 27 ##src/threads/web03.c## + pthread_t tid;## 28 ##src/threads/web03.c## + struct file *fptr;## 29 ##src/threads/web03.c## + + if (argc < 5)## 30 ##src/threads/web03.c## + err_quit("usage: web <#conns> file1 ...");## 31 ##src/threads/web03.c## + maxnconn = atoi(argv[1]);## 32 ##src/threads/web03.c## + + nfiles = min(argc - 4, MAXFILES);## 33 ##src/threads/web03.c## + for (i = 0; i < nfiles; i++) {## 34 ##src/threads/web03.c## + file[i].f_name = argv[i + 4];## 35 ##src/threads/web03.c## + file[i].f_host = argv[2];## 36 ##src/threads/web03.c## + file[i].f_flags = 0;## 37 ##src/threads/web03.c## + }## 38 ##src/threads/web03.c## + printf("nfiles = %d\n", nfiles);## 39 ##src/threads/web03.c## + + home_page(argv[2], argv[3]);## 40 ##src/threads/web03.c## + + nlefttoread = nlefttoconn = nfiles;## 41 ##src/threads/web03.c## + nconn = 0;## 42 ##src/threads/web03.c## +/* include web2 */ + while (nlefttoread > 0) {## 43 ##src/threads/web03.c## + while (nconn < maxnconn && nlefttoconn > 0) {## 44 ##src/threads/web03.c## + /* 4find a file to read */## 45 ##src/threads/web03.c## + for (i = 0; i < nfiles; i++)## 46 ##src/threads/web03.c## + if (file[i].f_flags == 0)## 47 ##src/threads/web03.c## + break;## 48 ##src/threads/web03.c## + if (i == nfiles)## 49 ##src/threads/web03.c## + err_quit("nlefttoconn = %d but nothing found", nlefttoconn);## 50 ##src/threads/web03.c## + + file[i].f_flags = F_CONNECTING;## 51 ##src/threads/web03.c## + Pthread_create(&tid, NULL, &do_get_read, &file[i]);## 52 ##src/threads/web03.c## + file[i].f_tid = tid;## 53 ##src/threads/web03.c## + nconn++;## 54 ##src/threads/web03.c## + nlefttoconn--;## 55 ##src/threads/web03.c## + }## 56 ##src/threads/web03.c## + + /* 4Wait for one of the threads to terminate */## 57 ##src/threads/web03.c## + Pthread_mutex_lock(&ndone_mutex);## 58 ##src/threads/web03.c## + while (ndone == 0)## 59 ##src/threads/web03.c## + Pthread_cond_wait(&ndone_cond, &ndone_mutex);## 60 ##src/threads/web03.c## + + for (i = 0; i < nfiles; i++) {## 61 ##src/threads/web03.c## + if (file[i].f_flags & F_DONE) {## 62 ##src/threads/web03.c## + Pthread_join(file[i].f_tid, (void **) &fptr);## 63 ##src/threads/web03.c## + + if (&file[i] != fptr)## 64 ##src/threads/web03.c## + err_quit("file[i] != fptr");## 65 ##src/threads/web03.c## + fptr->f_flags = F_JOINED; /* clears F_DONE */## 66 ##src/threads/web03.c## + ndone--;## 67 ##src/threads/web03.c## + nconn--;## 68 ##src/threads/web03.c## + nlefttoread--;## 69 ##src/threads/web03.c## + printf("thread %d for %s done\n", fptr->f_tid, fptr->f_name);## 70 ##src/threads/web03.c## + }## 71 ##src/threads/web03.c## + }## 72 ##src/threads/web03.c## + Pthread_mutex_unlock(&ndone_mutex);## 73 ##src/threads/web03.c## + }## 74 ##src/threads/web03.c## + + exit(0);## 75 ##src/threads/web03.c## +}## 76 ##src/threads/web03.c## +/* end web2 */ + +void *## 77 ##src/threads/web03.c## +do_get_read(void *vptr)## 78 ##src/threads/web03.c## +{## 79 ##src/threads/web03.c## + int fd, n;## 80 ##src/threads/web03.c## + char line[MAXLINE];## 81 ##src/threads/web03.c## + struct file *fptr;## 82 ##src/threads/web03.c## + + fptr = (struct file *) vptr;## 83 ##src/threads/web03.c## + + fd = Tcp_connect(fptr->f_host, SERV);## 84 ##src/threads/web03.c## + fptr->f_fd = fd;## 85 ##src/threads/web03.c## + printf("do_get_read for %s, fd %d, thread %d\n",## 86 ##src/threads/web03.c## + fptr->f_name, fd, fptr->f_tid);## 87 ##src/threads/web03.c## + + write_get_cmd(fptr); /* write() the GET command */## 88 ##src/threads/web03.c## + + /* 4Read server's reply */## 89 ##src/threads/web03.c## + for (;;) {## 90 ##src/threads/web03.c## + if ((n = Read(fd, line, MAXLINE)) == 0)## 91 ##src/threads/web03.c## + break; /* server closed connection */## 92 ##src/threads/web03.c## + + printf("read %d bytes from %s\n", n, fptr->f_name);## 93 ##src/threads/web03.c## + }## 94 ##src/threads/web03.c## + printf("end-of-file on %s\n", fptr->f_name);## 95 ##src/threads/web03.c## + Close(fd);## 96 ##src/threads/web03.c## + fptr->f_flags = F_DONE; /* clears F_READING */## 97 ##src/threads/web03.c## + + Pthread_mutex_lock(&ndone_mutex);## 98 ##src/threads/web03.c## + ndone++;## 99 ##src/threads/web03.c## + Pthread_cond_signal(&ndone_cond);##100 ##src/threads/web03.c## + Pthread_mutex_unlock(&ndone_mutex);##101 ##src/threads/web03.c## + + return (fptr); /* terminate thread */##102 ##src/threads/web03.c## +}##103 ##src/threads/web03.c## + +void##104 ##src/threads/web03.c## +write_get_cmd(struct file *fptr)##105 ##src/threads/web03.c## +{##106 ##src/threads/web03.c## + int n;##107 ##src/threads/web03.c## + char line[MAXLINE];##108 ##src/threads/web03.c## + + n = snprintf(line, sizeof(line), GET_CMD, fptr->f_name);##109 ##src/threads/web03.c## + Writen(fptr->f_fd, line, n);##110 ##src/threads/web03.c## + printf("wrote %d bytes for %s\n", n, fptr->f_name);##111 ##src/threads/web03.c## + + fptr->f_flags = F_READING; /* clears F_CONNECTING */##112 ##src/threads/web03.c## +}##113 ##src/threads/web03.c## + +void##114 ##src/threads/web03.c## +home_page(const char *host, const char *fname)##115 ##src/threads/web03.c## +{##116 ##src/threads/web03.c## + int fd, n;##117 ##src/threads/web03.c## + char line[MAXLINE];##118 ##src/threads/web03.c## + + fd = Tcp_connect(host, SERV); /* blocking connect() */##119 ##src/threads/web03.c## + + n = snprintf(line, sizeof(line), GET_CMD, fname);##120 ##src/threads/web03.c## + Writen(fd, line, n);##121 ##src/threads/web03.c## + + for (;;) {##122 ##src/threads/web03.c## + if ((n = Read(fd, line, MAXLINE)) == 0)##123 ##src/threads/web03.c## + break; /* server closed connection */##124 ##src/threads/web03.c## + + printf("read %d bytes of home page\n", n);##125 ##src/threads/web03.c## + /* do whatever with data */##126 ##src/threads/web03.c## + }##127 ##src/threads/web03.c## + printf("end-of-file on home page\n");##128 ##src/threads/web03.c## + Close(fd);##129 ##src/threads/web03.c## +}##130 ##src/threads/web03.c## diff --git a/traceroute/Makefile b/traceroute/Makefile new file mode 100644 index 0000000..348c627 --- /dev/null +++ b/traceroute/Makefile @@ -0,0 +1,13 @@ +include ../Make.defines + +OBJS = main.o icmpcode_v4.o icmpcode_v6.o recv_v4.o recv_v6.o \ + sig_alrm.o traceloop.o tv_sub.o +PROGS = traceroute + +all: ${PROGS} + +traceroute: ${OBJS} + ${CC} ${CFLAGS} -o $@ ${OBJS} ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/traceroute/icmpcode_v4.c b/traceroute/icmpcode_v4.c new file mode 100644 index 0000000..27dde74 --- /dev/null +++ b/traceroute/icmpcode_v4.c @@ -0,0 +1,27 @@ +#include "trace.h" + +const char * +icmpcode_v4(int code) +{ + static char errbuf[100]; + switch (code) { + case 0: return("network unreachable"); + case 1: return("host unreachable"); + case 2: return("protocol unreachable"); + case 3: return("port unreachable"); + case 4: return("fragmentation required but DF bit set"); + case 5: return("source route failed"); + case 6: return("destination network unknown"); + case 7: return("destination host unknown"); + case 8: return("source host isolated (obsolete)"); + case 9: return("destination network administratively prohibited"); + case 10: return("destination host administratively prohibited"); + case 11: return("network unreachable for TOS"); + case 12: return("host unreachable for TOS"); + case 13: return("communication administratively prohibited by filtering"); + case 14: return("host recedence violation"); + case 15: return("precedence cutoff in effect"); + default: sprintf(errbuf, "[unknown code %d]", code); + return errbuf; + } +} diff --git a/traceroute/icmpcode_v6.c b/traceroute/icmpcode_v6.c new file mode 100644 index 0000000..a42cdbc --- /dev/null +++ b/traceroute/icmpcode_v6.c @@ -0,0 +1,24 @@ +#include "trace.h" + +const char * +icmpcode_v6(int code) +{ +#ifdef IPV6 + static char errbuf[100]; + switch (code) { + case ICMP6_DST_UNREACH_NOROUTE: + return("no route to host"); + case ICMP6_DST_UNREACH_ADMIN: + return("administratively prohibited"); + case ICMP6_DST_UNREACH_NOTNEIGHBOR: + return("not a neighbor"); + case ICMP6_DST_UNREACH_ADDR: + return("address unreachable"); + case ICMP6_DST_UNREACH_NOPORT: + return("port unreachable"); + default: + sprintf(errbuf, "[unknown code %d]", code); + return errbuf; + } +#endif +} diff --git a/traceroute/main.c b/traceroute/main.c new file mode 100644 index 0000000..2ddecde --- /dev/null +++ b/traceroute/main.c @@ -0,0 +1,75 @@ +#include "trace.h" + +struct proto proto_v4 = { icmpcode_v4, recv_v4, NULL, NULL, NULL, NULL, 0, + IPPROTO_ICMP, IPPROTO_IP, IP_TTL }; + +#ifdef IPV6 +struct proto proto_v6 = { icmpcode_v6, recv_v6, NULL, NULL, NULL, NULL, 0, + IPPROTO_ICMPV6, IPPROTO_IPV6, IPV6_UNICAST_HOPS }; +#endif + +int datalen = sizeof(struct rec); /* defaults */ +int max_ttl = 30; +int nprobes = 3; +u_short dport = 32768 + 666; + +int +main(int argc, char **argv) +{ + int c; + struct addrinfo *ai; + char *h; + + opterr = 0; /* don't want getopt() writing to stderr */ + while ( (c = getopt(argc, argv, "m:v")) != -1) { + switch (c) { + case 'm': + if ( (max_ttl = atoi(optarg)) <= 1) + err_quit("invalid -m value"); + break; + + case 'v': + verbose++; + break; + + case '?': + err_quit("unrecognized option: %c", c); + } + } + + if (optind != argc-1) + err_quit("usage: traceroute [ -m -v ] "); + host = argv[optind]; + + pid = getpid(); + Signal(SIGALRM, sig_alrm); + + ai = Host_serv(host, NULL, 0, 0); + + h = Sock_ntop_host(ai->ai_addr, ai->ai_addrlen); + printf("traceroute to %s (%s): %d hops max, %d data bytes\n", + ai->ai_canonname ? ai->ai_canonname : h, + h, max_ttl, datalen); + + /* initialize according to protocol */ + if (ai->ai_family == AF_INET) { + pr = &proto_v4; +#ifdef IPV6 + } else if (ai->ai_family == AF_INET6) { + pr = &proto_v6; + if (IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr))) + err_quit("cannot traceroute IPv4-mapped IPv6 address"); +#endif + } else + err_quit("unknown address family %d", ai->ai_family); + + pr->sasend = ai->ai_addr; /* contains destination address */ + pr->sarecv = Calloc(1, ai->ai_addrlen); + pr->salast = Calloc(1, ai->ai_addrlen); + pr->sabind = Calloc(1, ai->ai_addrlen); + pr->salen = ai->ai_addrlen; + + traceloop(); + + exit(0); +} diff --git a/traceroute/main.lc b/traceroute/main.lc new file mode 100644 index 0000000..518f14f --- /dev/null +++ b/traceroute/main.lc @@ -0,0 +1,76 @@ +#include "trace.h"## 1 ##src/traceroute/main.c## + +struct proto proto_v4 = { icmpcode_v4, recv_v4, NULL, NULL, NULL, NULL, 0,## 2 ##src/traceroute/main.c## + IPPROTO_ICMP, IPPROTO_IP, IP_TTL## 3 ##src/traceroute/main.c## +};## 4 ##src/traceroute/main.c## + +#ifdef IPV6## 5 ##src/traceroute/main.c## +struct proto proto_v6 = { icmpcode_v6, recv_v6, NULL, NULL, NULL, NULL, 0,## 6 ##src/traceroute/main.c## + IPPROTO_ICMPV6, IPPROTO_IPV6, IPV6_UNICAST_HOPS## 7 ##src/traceroute/main.c## +};## 8 ##src/traceroute/main.c## +#endif## 9 ##src/traceroute/main.c## + +int datalen = sizeof(struct rec); /* defaults */## 10 ##src/traceroute/main.c## +int max_ttl = 30;## 11 ##src/traceroute/main.c## +int nprobes = 3;## 12 ##src/traceroute/main.c## +u_short dport = 32768 + 666;## 13 ##src/traceroute/main.c## + +int## 14 ##src/traceroute/main.c## +main(int argc, char **argv)## 15 ##src/traceroute/main.c## +{## 16 ##src/traceroute/main.c## + int c;## 17 ##src/traceroute/main.c## + struct addrinfo *ai;## 18 ##src/traceroute/main.c## + + opterr = 0; /* don't want getopt() writing to stderr */## 19 ##src/traceroute/main.c## + while ((c = getopt(argc, argv, "m:v")) != -1) {## 20 ##src/traceroute/main.c## + switch (c) {## 21 ##src/traceroute/main.c## + case 'm':## 22 ##src/traceroute/main.c## + if ((max_ttl = atoi(optarg)) <= 1)## 23 ##src/traceroute/main.c## + err_quit("invalid -m value");## 24 ##src/traceroute/main.c## + break;## 25 ##src/traceroute/main.c## + + case 'v':## 26 ##src/traceroute/main.c## + verbose++;## 27 ##src/traceroute/main.c## + break;## 28 ##src/traceroute/main.c## + + case '?':## 29 ##src/traceroute/main.c## + err_quit("unrecognized option: %c", c);## 30 ##src/traceroute/main.c## + }## 31 ##src/traceroute/main.c## + }## 32 ##src/traceroute/main.c## + + if (optind != argc - 1)## 33 ##src/traceroute/main.c## + err_quit("usage: traceroute [ -m -v ] ");## 34 ##src/traceroute/main.c## + host = argv[optind];## 35 ##src/traceroute/main.c## + + pid = getpid();## 36 ##src/traceroute/main.c## + Signal(SIGALRM, sig_alrm);## 37 ##src/traceroute/main.c## + + ai = Host_serv(host, NULL, 0, 0);## 38 ##src/traceroute/main.c## + + printf("traceroute to %s (%s): %d hops max, %d data bytes\n",## 39 ##src/traceroute/main.c## + ai->ai_canonname,## 40 ##src/traceroute/main.c## + Sock_ntop_host(ai->ai_addr, ai->ai_addrlen), max_ttl, datalen);## 41 ##src/traceroute/main.c## + + /* initialize according to protocol */## 42 ##src/traceroute/main.c## + if (ai->ai_family == AF_INET) {## 43 ##src/traceroute/main.c## + pr = &proto_v4;## 44 ##src/traceroute/main.c## +#ifdef IPV6## 45 ##src/traceroute/main.c## + } else if (ai->ai_family == AF_INET6) {## 46 ##src/traceroute/main.c## + pr = &proto_v6;## 47 ##src/traceroute/main.c## + if (IN6_IS_ADDR_V4MAPPED## 48 ##src/traceroute/main.c## + (&(((struct sockaddr_in6 *) ai->ai_addr)->sin6_addr)))## 49 ##src/traceroute/main.c## + err_quit("cannot traceroute IPv4-mapped IPv6 address");## 50 ##src/traceroute/main.c## +#endif## 51 ##src/traceroute/main.c## + } else## 52 ##src/traceroute/main.c## + err_quit("unknown address family %d", ai->ai_family);## 53 ##src/traceroute/main.c## + + pr->sasend = ai->ai_addr; /* contains destination address */## 54 ##src/traceroute/main.c## + pr->sarecv = Calloc(1, ai->ai_addrlen);## 55 ##src/traceroute/main.c## + pr->salast = Calloc(1, ai->ai_addrlen);## 56 ##src/traceroute/main.c## + pr->sabind = Calloc(1, ai->ai_addrlen);## 57 ##src/traceroute/main.c## + pr->salen = ai->ai_addrlen;## 58 ##src/traceroute/main.c## + + traceloop();## 59 ##src/traceroute/main.c## + + exit(0);## 60 ##src/traceroute/main.c## +}## 61 ##src/traceroute/main.c## diff --git a/traceroute/recv_v4.c b/traceroute/recv_v4.c new file mode 100644 index 0000000..e7ec19c --- /dev/null +++ b/traceroute/recv_v4.c @@ -0,0 +1,91 @@ +#include "trace.h" + +extern int gotalarm; + +/* + * Return: -3 on timeout + * -2 on ICMP time exceeded in transit (caller keeps going) + * -1 on ICMP port unreachable (caller is done) + * >= 0 return value is some other ICMP unreachable code + */ + +int +recv_v4(int seq, struct timeval *tv) +{ + int hlen1, hlen2, icmplen, ret; + socklen_t len; + ssize_t n; + struct ip *ip, *hip; + struct icmp *icmp; + struct udphdr *udp; + + gotalarm = 0; + alarm(3); + for ( ; ; ) { + if (gotalarm) + return(-3); /* alarm expired */ + len = pr->salen; + n = recvfrom(recvfd, recvbuf, sizeof(recvbuf), 0, pr->sarecv, &len); + if (n < 0) { + if (errno == EINTR) + continue; + else + err_sys("recvfrom error"); + } + + ip = (struct ip *) recvbuf; /* start of IP header */ + hlen1 = ip->ip_hl << 2; /* length of IP header */ + + icmp = (struct icmp *) (recvbuf + hlen1); /* start of ICMP header */ + if ( (icmplen = n - hlen1) < 8) + continue; /* not enough to look at ICMP header */ + + if (icmp->icmp_type == ICMP_TIMXCEED && + icmp->icmp_code == ICMP_TIMXCEED_INTRANS) { + if (icmplen < 8 + sizeof(struct ip)) + continue; /* not enough data to look at inner IP */ + + hip = (struct ip *) (recvbuf + hlen1 + 8); + hlen2 = hip->ip_hl << 2; + if (icmplen < 8 + hlen2 + 4) + continue; /* not enough data to look at UDP ports */ + + udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2); + if (hip->ip_p == IPPROTO_UDP && + udp->uh_sport == htons(sport) && + udp->uh_dport == htons(dport + seq)) { + ret = -2; /* we hit an intermediate router */ + break; + } + + } else if (icmp->icmp_type == ICMP_UNREACH) { + if (icmplen < 8 + sizeof(struct ip)) + continue; /* not enough data to look at inner IP */ + + hip = (struct ip *) (recvbuf + hlen1 + 8); + hlen2 = hip->ip_hl << 2; + if (icmplen < 8 + hlen2 + 4) + continue; /* not enough data to look at UDP ports */ + + udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2); + if (hip->ip_p == IPPROTO_UDP && + udp->uh_sport == htons(sport) && + udp->uh_dport == htons(dport + seq)) { + if (icmp->icmp_code == ICMP_UNREACH_PORT) + ret = -1; /* have reached destination */ + else + ret = icmp->icmp_code; /* 0, 1, 2, ... */ + break; + } + } + if (verbose) { + printf(" (from %s: type = %d, code = %d)\n", + Sock_ntop_host(pr->sarecv, pr->salen), + icmp->icmp_type, icmp->icmp_code); + } + /* Some other ICMP error, recvfrom() again */ + } + alarm(0); /* don't leave alarm running */ + Gettimeofday(tv, NULL); /* get time of packet arrival */ + return(ret); +} diff --git a/traceroute/recv_v4.lc b/traceroute/recv_v4.lc new file mode 100644 index 0000000..461ecb5 --- /dev/null +++ b/traceroute/recv_v4.lc @@ -0,0 +1,74 @@ +#include "trace.h"## 1 ##src/traceroute/recv_v4.c## + +/*## 2 ##src/traceroute/recv_v4.c## + * Return: -3 on timeout## 3 ##src/traceroute/recv_v4.c## + * -2 on ICMP time exceeded in transit (caller keeps going)## 4 ##src/traceroute/recv_v4.c## + * -1 on ICMP port unreachable (caller is done)## 5 ##src/traceroute/recv_v4.c## + * >= 0 return value is some other ICMP unreachable code## 6 ##src/traceroute/recv_v4.c## + */## 7 ##src/traceroute/recv_v4.c## + +int## 8 ##src/traceroute/recv_v4.c## +recv_v4(int seq, struct timeval *tv)## 9 ##src/traceroute/recv_v4.c## +{## 10 ##src/traceroute/recv_v4.c## + int hlen1, hlen2, icmplen;## 11 ##src/traceroute/recv_v4.c## + socklen_t len;## 12 ##src/traceroute/recv_v4.c## + ssize_t n;## 13 ##src/traceroute/recv_v4.c## + struct ip *ip, *hip;## 14 ##src/traceroute/recv_v4.c## + struct icmp *icmp;## 15 ##src/traceroute/recv_v4.c## + struct udphdr *udp;## 16 ##src/traceroute/recv_v4.c## + + alarm(3);## 17 ##src/traceroute/recv_v4.c## + for (;;) {## 18 ##src/traceroute/recv_v4.c## + len = pr->salen;## 19 ##src/traceroute/recv_v4.c## + n = recvfrom(recvfd, recvbuf, sizeof(recvbuf), 0, pr->sarecv, &len);## 20 ##src/traceroute/recv_v4.c## + if (n < 0) {## 21 ##src/traceroute/recv_v4.c## + if (errno == EINTR)## 22 ##src/traceroute/recv_v4.c## + return (-3); /* alarm expired */## 23 ##src/traceroute/recv_v4.c## + else## 24 ##src/traceroute/recv_v4.c## + err_sys("recvfrom error");## 25 ##src/traceroute/recv_v4.c## + }## 26 ##src/traceroute/recv_v4.c## + Gettimeofday(tv, NULL); /* get time of packet arrival */## 27 ##src/traceroute/recv_v4.c## + + ip = (struct ip *) recvbuf; /* start of IP header */## 28 ##src/traceroute/recv_v4.c## + hlen1 = ip->ip_hl << 2; /* length of IP header */## 29 ##src/traceroute/recv_v4.c## + + icmp = (struct icmp *) (recvbuf + hlen1); /* start of ICMP header */## 30 ##src/traceroute/recv_v4.c## + if ((icmplen = n - hlen1) < 8)## 31 ##src/traceroute/recv_v4.c## + err_quit("icmplen (%d) < 8", icmplen);## 32 ##src/traceroute/recv_v4.c## + + if (icmp->icmp_type == ICMP_TIMXCEED &&## 33 ##src/traceroute/recv_v4.c## + icmp->icmp_code == ICMP_TIMXCEED_INTRANS) {## 34 ##src/traceroute/recv_v4.c## + if (icmplen < 8 + 20 + 8)## 35 ##src/traceroute/recv_v4.c## + err_quit("icmplen (%d) < 8 + 20 + 8", icmplen);## 36 ##src/traceroute/recv_v4.c## + + hip = (struct ip *) (recvbuf + hlen1 + 8);## 37 ##src/traceroute/recv_v4.c## + hlen2 = hip->ip_hl << 2;## 38 ##src/traceroute/recv_v4.c## + udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2);## 39 ##src/traceroute/recv_v4.c## + if (hip->ip_p == IPPROTO_UDP &&## 40 ##src/traceroute/recv_v4.c## + udp->uh_sport == htons(sport) &&## 41 ##src/traceroute/recv_v4.c## + udp->uh_dport == htons(dport + seq))## 42 ##src/traceroute/recv_v4.c## + return (-2); /* we hit an intermediate router */## 43 ##src/traceroute/recv_v4.c## + + } else if (icmp->icmp_type == ICMP_UNREACH) {## 44 ##src/traceroute/recv_v4.c## + if (icmplen < 8 + 20 + 8)## 45 ##src/traceroute/recv_v4.c## + err_quit("icmplen (%d) < 8 + 20 + 8", icmplen);## 46 ##src/traceroute/recv_v4.c## + + hip = (struct ip *) (recvbuf + hlen1 + 8);## 47 ##src/traceroute/recv_v4.c## + hlen2 = hip->ip_hl << 2;## 48 ##src/traceroute/recv_v4.c## + udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2);## 49 ##src/traceroute/recv_v4.c## + if (hip->ip_p == IPPROTO_UDP &&## 50 ##src/traceroute/recv_v4.c## + udp->uh_sport == htons(sport) &&## 51 ##src/traceroute/recv_v4.c## + udp->uh_dport == htons(dport + seq)) {## 52 ##src/traceroute/recv_v4.c## + if (icmp->icmp_code == ICMP_UNREACH_PORT)## 53 ##src/traceroute/recv_v4.c## + return (-1); /* have reached destination */## 54 ##src/traceroute/recv_v4.c## + else## 55 ##src/traceroute/recv_v4.c## + return (icmp->icmp_code); /* 0, 1, 2, ... */## 56 ##src/traceroute/recv_v4.c## + }## 57 ##src/traceroute/recv_v4.c## + } else if (verbose) {## 58 ##src/traceroute/recv_v4.c## + printf(" (from %s: type = %d, code = %d)\n",## 59 ##src/traceroute/recv_v4.c## + Sock_ntop_host(pr->sarecv, pr->salen),## 60 ##src/traceroute/recv_v4.c## + icmp->icmp_type, icmp->icmp_code);## 61 ##src/traceroute/recv_v4.c## + }## 62 ##src/traceroute/recv_v4.c## + /* Some other ICMP error, recvfrom() again */## 63 ##src/traceroute/recv_v4.c## + }## 64 ##src/traceroute/recv_v4.c## +}## 65 ##src/traceroute/recv_v4.c## diff --git a/traceroute/recv_v6.c b/traceroute/recv_v6.c new file mode 100644 index 0000000..f84011a --- /dev/null +++ b/traceroute/recv_v6.c @@ -0,0 +1,82 @@ +#include "trace.h" + +extern int gotalarm; + +/* + * Return: -3 on timeout + * -2 on ICMP time exceeded in transit (caller keeps going) + * -1 on ICMP port unreachable (caller is done) + * >= 0 return value is some other ICMP unreachable code + */ + +int +recv_v6(int seq, struct timeval *tv) +{ +#ifdef IPV6 + int hlen2, icmp6len, ret; + ssize_t n; + socklen_t len; + struct ip6_hdr *hip6; + struct icmp6_hdr *icmp6; + struct udphdr *udp; + + gotalarm = 0; + alarm(3); + for ( ; ; ) { + if (gotalarm) + return(-3); /* alarm expired */ + len = pr->salen; + n = recvfrom(recvfd, recvbuf, sizeof(recvbuf), 0, pr->sarecv, &len); + if (n < 0) { + if (errno == EINTR) + continue; + else + err_sys("recvfrom error"); + } + + icmp6 = (struct icmp6_hdr *) recvbuf; /* ICMP header */ + if ( ( icmp6len = n ) < 8) + continue; /* not enough to look at ICMP header */ + + if (icmp6->icmp6_type == ICMP6_TIME_EXCEEDED && + icmp6->icmp6_code == ICMP6_TIME_EXCEED_TRANSIT) { + if (icmp6len < 8 + sizeof(struct ip6_hdr) + 4) + continue; /* not enough data to look at inner header */ + + hip6 = (struct ip6_hdr *) (recvbuf + 8); + hlen2 = sizeof(struct ip6_hdr); + udp = (struct udphdr *) (recvbuf + 8 + hlen2); + if (hip6->ip6_nxt == IPPROTO_UDP && + udp->uh_sport == htons(sport) && + udp->uh_dport == htons(dport + seq)) + ret = -2; /* we hit an intermediate router */ + break; + + } else if (icmp6->icmp6_type == ICMP6_DST_UNREACH) { + if (icmp6len < 8 + sizeof(struct ip6_hdr) + 4) + continue; /* not enough data to look at inner header */ + + hip6 = (struct ip6_hdr *) (recvbuf + 8); + hlen2 = sizeof(struct ip6_hdr); + udp = (struct udphdr *) (recvbuf + 8 + hlen2); + if (hip6->ip6_nxt == IPPROTO_UDP && + udp->uh_sport == htons(sport) && + udp->uh_dport == htons(dport + seq)) { + if (icmp6->icmp6_code == ICMP6_DST_UNREACH_NOPORT) + ret = -1; /* have reached destination */ + else + ret = icmp6->icmp6_code; /* 0, 1, 2, ... */ + break; + } + } else if (verbose) { + printf(" (from %s: type = %d, code = %d)\n", + Sock_ntop_host(pr->sarecv, pr->salen), + icmp6->icmp6_type, icmp6->icmp6_code); + } + /* Some other ICMP error, recvfrom() again */ + } + alarm(0); /* don't leave alarm running */ + Gettimeofday(tv, NULL); /* get time of packet arrival */ + return(ret); +#endif +} diff --git a/traceroute/recv_v6.lc b/traceroute/recv_v6.lc new file mode 100644 index 0000000..4154066 --- /dev/null +++ b/traceroute/recv_v6.lc @@ -0,0 +1,76 @@ +#include "trace.h"## 1 ##src/traceroute/recv_v6.c## + +/*## 2 ##src/traceroute/recv_v6.c## + * Return: -3 on timeout## 3 ##src/traceroute/recv_v6.c## + * -2 on ICMP time exceeded in transit (caller keeps going)## 4 ##src/traceroute/recv_v6.c## + * -1 on ICMP port unreachable (caller is done)## 5 ##src/traceroute/recv_v6.c## + * >= 0 return value is some other ICMP unreachable code## 6 ##src/traceroute/recv_v6.c## + */## 7 ##src/traceroute/recv_v6.c## + +int## 8 ##src/traceroute/recv_v6.c## +recv_v6(int seq, struct timeval *tv)## 9 ##src/traceroute/recv_v6.c## +{## 10 ##src/traceroute/recv_v6.c## +#ifdef IPV6## 11 ##src/traceroute/recv_v6.c## + int hlen1, hlen2, icmp6len;## 12 ##src/traceroute/recv_v6.c## + ssize_t n;## 13 ##src/traceroute/recv_v6.c## + socklen_t len;## 14 ##src/traceroute/recv_v6.c## + struct ip6_hdr *ip6, *hip6;## 15 ##src/traceroute/recv_v6.c## + struct icmp6_hdr *icmp6;## 16 ##src/traceroute/recv_v6.c## + struct udphdr *udp;## 17 ##src/traceroute/recv_v6.c## + + alarm(3);## 18 ##src/traceroute/recv_v6.c## + for (;;) {## 19 ##src/traceroute/recv_v6.c## + len = pr->salen;## 20 ##src/traceroute/recv_v6.c## + n = recvfrom(recvfd, recvbuf, sizeof(recvbuf), 0, pr->sarecv, &len);## 21 ##src/traceroute/recv_v6.c## + if (n < 0) {## 22 ##src/traceroute/recv_v6.c## + if (errno == EINTR)## 23 ##src/traceroute/recv_v6.c## + return (-3); /* alarm expired */## 24 ##src/traceroute/recv_v6.c## + else## 25 ##src/traceroute/recv_v6.c## + err_sys("recvfrom error");## 26 ##src/traceroute/recv_v6.c## + }## 27 ##src/traceroute/recv_v6.c## + Gettimeofday(tv, NULL); /* get time of packet arrival */## 28 ##src/traceroute/recv_v6.c## + + ip6 = (struct ip6_hdr *) recvbuf; /* start of IPv6 header */## 29 ##src/traceroute/recv_v6.c## + hlen1 = sizeof(struct ip6_hdr);## 30 ##src/traceroute/recv_v6.c## + + icmp6 = (struct icmp6_hdr *) (recvbuf + hlen1); /* ICMP hdr */## 31 ##src/traceroute/recv_v6.c## + if ((icmp6len = n - hlen1) < 8)## 32 ##src/traceroute/recv_v6.c## + err_quit("icmp6len (%d) < 8", icmp6len);## 33 ##src/traceroute/recv_v6.c## + + if (icmp6->icmp6_type == ICMP6_TIME_EXCEEDED &&## 34 ##src/traceroute/recv_v6.c## + icmp6->icmp6_code == ICMP6_TIME_EXCEED_TRANSIT) {## 35 ##src/traceroute/recv_v6.c## + if (icmp6len < 8 + 40 + 8)## 36 ##src/traceroute/recv_v6.c## + err_quit("icmp6len (%d) < 8 + 40 + 8", icmp6len);## 37 ##src/traceroute/recv_v6.c## + + hip6 = (struct ip6_hdr *) (recvbuf + hlen1 + 8);## 38 ##src/traceroute/recv_v6.c## + hlen2 = sizeof(struct ip6_hdr);## 39 ##src/traceroute/recv_v6.c## + udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2);## 40 ##src/traceroute/recv_v6.c## + if (hip6->ip6_nxt == IPPROTO_UDP &&## 41 ##src/traceroute/recv_v6.c## + udp->uh_sport == htons(sport) &&## 42 ##src/traceroute/recv_v6.c## + udp->uh_dport == htons(dport + seq))## 43 ##src/traceroute/recv_v6.c## + return (-2); /* we hit an intermediate router */## 44 ##src/traceroute/recv_v6.c## + + } else if (icmp6->icmp6_type == ICMP6_DST_UNREACH) {## 45 ##src/traceroute/recv_v6.c## + if (icmp6len < 8 + 40 + 8)## 46 ##src/traceroute/recv_v6.c## + err_quit("icmp6len (%d) < 8 + 40 + 8", icmp6len);## 47 ##src/traceroute/recv_v6.c## + + hip6 = (struct ip6_hdr *) (recvbuf + hlen1 + 8);## 48 ##src/traceroute/recv_v6.c## + hlen2 = 40;## 49 ##src/traceroute/recv_v6.c## + udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2);## 50 ##src/traceroute/recv_v6.c## + if (hip6->ip6_nxt == IPPROTO_UDP &&## 51 ##src/traceroute/recv_v6.c## + udp->uh_sport == htons(sport) &&## 52 ##src/traceroute/recv_v6.c## + udp->uh_dport == htons(dport + seq)) {## 53 ##src/traceroute/recv_v6.c## + if (icmp6->icmp6_code == ICMP6_DST_UNREACH_NOPORT)## 54 ##src/traceroute/recv_v6.c## + return (-1); /* have reached destination */## 55 ##src/traceroute/recv_v6.c## + else## 56 ##src/traceroute/recv_v6.c## + return (icmp6->icmp6_code); /* 0, 1, 2, ... */## 57 ##src/traceroute/recv_v6.c## + }## 58 ##src/traceroute/recv_v6.c## + } else if (verbose) {## 59 ##src/traceroute/recv_v6.c## + printf(" (from %s: type = %d, code = %d)\n",## 60 ##src/traceroute/recv_v6.c## + Sock_ntop_host(pr->sarecv, pr->salen),## 61 ##src/traceroute/recv_v6.c## + icmp6->icmp6_type, icmp6->icmp6_code);## 62 ##src/traceroute/recv_v6.c## + }## 63 ##src/traceroute/recv_v6.c## + /* Some other ICMP error, recvfrom() again */## 64 ##src/traceroute/recv_v6.c## + }## 65 ##src/traceroute/recv_v6.c## +#endif## 66 ##src/traceroute/recv_v6.c## +}## 67 ##src/traceroute/recv_v6.c## diff --git a/traceroute/sig_alrm.c b/traceroute/sig_alrm.c new file mode 100644 index 0000000..db4eee5 --- /dev/null +++ b/traceroute/sig_alrm.c @@ -0,0 +1,10 @@ +#include "trace.h" + +int gotalarm; + +void +sig_alrm(int signo) +{ + gotalarm = 1; /* set flag to note that alarm occurred */ + return; /* and interrupt the recvfrom() */ +} diff --git a/traceroute/trace.h b/traceroute/trace.h new file mode 100644 index 0000000..f339e97 --- /dev/null +++ b/traceroute/trace.h @@ -0,0 +1,56 @@ +#include "unp.h" +#include +#include +#include +#include + +#define BUFSIZE 1500 + +struct rec { /* format of outgoing UDP data */ + u_short rec_seq; /* sequence number */ + u_short rec_ttl; /* TTL packet left with */ + struct timeval rec_tv; /* time packet left */ +}; + + /* globals */ +char recvbuf[BUFSIZE]; +char sendbuf[BUFSIZE]; + +int datalen; /* # bytes of data following ICMP header */ +char *host; +u_short sport, dport; +int nsent; /* add 1 for each sendto() */ +pid_t pid; /* our PID */ +int probe, nprobes; +int sendfd, recvfd; /* send on UDP sock, read on raw ICMP sock */ +int ttl, max_ttl; +int verbose; + + /* function prototypes */ +const char *icmpcode_v4(int); +const char *icmpcode_v6(int); +int recv_v4(int, struct timeval *); +int recv_v6(int, struct timeval *); +void sig_alrm(int); +void traceloop(void); +void tv_sub(struct timeval *, struct timeval *); + +struct proto { + const char *(*icmpcode)(int); + int (*recv)(int, struct timeval *); + struct sockaddr *sasend; /* sockaddr{} for send, from getaddrinfo */ + struct sockaddr *sarecv; /* sockaddr{} for receiving */ + struct sockaddr *salast; /* last sockaddr{} for receiving */ + struct sockaddr *sabind; /* sockaddr{} for binding source port */ + socklen_t salen; /* length of sockaddr{}s */ + int icmpproto; /* IPPROTO_xxx value for ICMP */ + int ttllevel; /* setsockopt() level to set TTL */ + int ttloptname; /* setsockopt() name to set TTL */ +} *pr; + +#ifdef IPV6 + +#include +#include + +#endif diff --git a/traceroute/trace.lh b/traceroute/trace.lh new file mode 100644 index 0000000..fdb837f --- /dev/null +++ b/traceroute/trace.lh @@ -0,0 +1,56 @@ +#include "unp.h"## 1 ##src/traceroute/trace.h## +#include ## 2 ##src/traceroute/trace.h## +#include ## 3 ##src/traceroute/trace.h## +#include ## 4 ##src/traceroute/trace.h## +#include ## 5 ##src/traceroute/trace.h## + +#define BUFSIZE 1500## 6 ##src/traceroute/trace.h## + +struct rec { /* of outgoing UDP data */## 7 ##src/traceroute/trace.h## + u_short rec_seq; /* sequence number */## 8 ##src/traceroute/trace.h## + u_short rec_ttl; /* TTL packet left with */## 9 ##src/traceroute/trace.h## + struct timeval rec_tv; /* time packet left */## 10 ##src/traceroute/trace.h## +};## 11 ##src/traceroute/trace.h## + + /* globals */## 12 ##src/traceroute/trace.h## +char recvbuf[BUFSIZE];## 13 ##src/traceroute/trace.h## +char sendbuf[BUFSIZE];## 14 ##src/traceroute/trace.h## + +int datalen; /* #bytes of data, following ICMP header */## 15 ##src/traceroute/trace.h## +char *host;## 16 ##src/traceroute/trace.h## +u_short sport, dport;## 17 ##src/traceroute/trace.h## +int nsent; /* add 1 for each sendto() */## 18 ##src/traceroute/trace.h## +pid_t pid; /* our PID */## 19 ##src/traceroute/trace.h## +int probe, nprobes;## 20 ##src/traceroute/trace.h## +int sendfd, recvfd; /* send on UDP sock, read on raw ICMP sock */## 21 ##src/traceroute/trace.h## +int ttl, max_ttl;## 22 ##src/traceroute/trace.h## +int verbose;## 23 ##src/traceroute/trace.h## + + /* function prototypes */## 24 ##src/traceroute/trace.h## +const char *icmpcode_v4(int);## 25 ##src/traceroute/trace.h## +const char *icmpcode_v6(int);## 26 ##src/traceroute/trace.h## +int recv_v4(int, struct timeval *);## 27 ##src/traceroute/trace.h## +int recv_v6(int, struct timeval *);## 28 ##src/traceroute/trace.h## +void sig_alrm(int);## 29 ##src/traceroute/trace.h## +void traceloop(void);## 30 ##src/traceroute/trace.h## +void tv_sub(struct timeval *, struct timeval *);## 31 ##src/traceroute/trace.h## + +struct proto {## 32 ##src/traceroute/trace.h## + const char *(*icmpcode) (int);## 33 ##src/traceroute/trace.h## + int (*recv) (int, struct timeval *);## 34 ##src/traceroute/trace.h## + struct sockaddr *sasend; /* sockaddr{} for send, from getaddrinfo */## 35 ##src/traceroute/trace.h## + struct sockaddr *sarecv; /* sockaddr{} for receiving */## 36 ##src/traceroute/trace.h## + struct sockaddr *salast; /* last sockaddr{} for receiving */## 37 ##src/traceroute/trace.h## + struct sockaddr *sabind; /* sockaddr{} for binding source port */## 38 ##src/traceroute/trace.h## + socklen_t salen; /* length of sockaddr{}s */## 39 ##src/traceroute/trace.h## + int icmpproto; /* IPPROTO_xxx value for ICMP */## 40 ##src/traceroute/trace.h## + int ttllevel; /* setsockopt() level to set TTL */## 41 ##src/traceroute/trace.h## + int ttloptname; /* setsockopt() name to set TTL */## 42 ##src/traceroute/trace.h## +} *pr;## 43 ##src/traceroute/trace.h## + +#ifdef IPV6## 44 ##src/traceroute/trace.h## + +#include ## 45 ##src/traceroute/trace.h## +#include ## 46 ##src/traceroute/trace.h## + +#endif## 47 ##src/traceroute/trace.h## diff --git a/traceroute/traceloop.c b/traceroute/traceloop.c new file mode 100644 index 0000000..a78b509 --- /dev/null +++ b/traceroute/traceloop.c @@ -0,0 +1,80 @@ +#include "trace.h" + +void +traceloop(void) +{ + int seq, code, done; + double rtt; + struct rec *rec; + struct timeval tvrecv; + + recvfd = Socket(pr->sasend->sa_family, SOCK_RAW, pr->icmpproto); + setuid(getuid()); /* don't need special permissions anymore */ + +#ifdef IPV6 + if (pr->sasend->sa_family == AF_INET6 && verbose == 0) { + struct icmp6_filter myfilt; + ICMP6_FILTER_SETBLOCKALL(&myfilt); + ICMP6_FILTER_SETPASS(ICMP6_TIME_EXCEEDED, &myfilt); + ICMP6_FILTER_SETPASS(ICMP6_DST_UNREACH, &myfilt); + setsockopt(recvfd, IPPROTO_IPV6, ICMP6_FILTER, + &myfilt, sizeof(myfilt)); + } +#endif + + sendfd = Socket(pr->sasend->sa_family, SOCK_DGRAM, 0); + + pr->sabind->sa_family = pr->sasend->sa_family; + sport = (getpid() & 0xffff) | 0x8000; /* our source UDP port # */ + sock_set_port(pr->sabind, pr->salen, htons(sport)); + Bind(sendfd, pr->sabind, pr->salen); + + sig_alrm(SIGALRM); + + seq = 0; + done = 0; + for (ttl = 1; ttl <= max_ttl && done == 0; ttl++) { + Setsockopt(sendfd, pr->ttllevel, pr->ttloptname, &ttl, sizeof(int)); + bzero(pr->salast, pr->salen); + + printf("%2d ", ttl); + fflush(stdout); + + for (probe = 0; probe < nprobes; probe++) { + rec = (struct rec *) sendbuf; + rec->rec_seq = ++seq; + rec->rec_ttl = ttl; + Gettimeofday(&rec->rec_tv, NULL); + + sock_set_port(pr->sasend, pr->salen, htons(dport + seq)); + Sendto(sendfd, sendbuf, datalen, 0, pr->sasend, pr->salen); + + if ( (code = (*pr->recv)(seq, &tvrecv)) == -3) + printf(" *"); /* timeout, no reply */ + else { + char str[NI_MAXHOST]; + + if (sock_cmp_addr(pr->sarecv, pr->salast, pr->salen) != 0) { + if (getnameinfo(pr->sarecv, pr->salen, str, sizeof(str), + NULL, 0, 0) == 0) + printf(" %s (%s)", str, + Sock_ntop_host(pr->sarecv, pr->salen)); + else + printf(" %s", + Sock_ntop_host(pr->sarecv, pr->salen)); + memcpy(pr->salast, pr->sarecv, pr->salen); + } + tv_sub(&tvrecv, &rec->rec_tv); + rtt = tvrecv.tv_sec * 1000.0 + tvrecv.tv_usec / 1000.0; + printf(" %.3f ms", rtt); + + if (code == -1) /* port unreachable; at destination */ + done++; + else if (code >= 0) + printf(" (ICMP %s)", (*pr->icmpcode)(code)); + } + fflush(stdout); + } + printf("\n"); + } +} diff --git a/traceroute/traceloop.lc b/traceroute/traceloop.lc new file mode 100644 index 0000000..dbd20ab --- /dev/null +++ b/traceroute/traceloop.lc @@ -0,0 +1,79 @@ +#include "trace.h"## 1 ##src/traceroute/traceloop.c## + +void## 2 ##src/traceroute/traceloop.c## +traceloop(void)## 3 ##src/traceroute/traceloop.c## +{## 4 ##src/traceroute/traceloop.c## + int seq, code, done;## 5 ##src/traceroute/traceloop.c## + double rtt;## 6 ##src/traceroute/traceloop.c## + struct rec *rec;## 7 ##src/traceroute/traceloop.c## + struct timeval tvrecv;## 8 ##src/traceroute/traceloop.c## + + recvfd = Socket(pr->sasend->sa_family, SOCK_RAW, pr->icmpproto);## 9 ##src/traceroute/traceloop.c## + setuid(getuid()); /* don't need special permissions any more */## 10 ##src/traceroute/traceloop.c## + +#ifdef IPV6## 11 ##src/traceroute/traceloop.c## + if (pr->sasend->sa_family == AF_INET && verbose == 0) {## 12 ##src/traceroute/traceloop.c## + struct icmp6_filter myfilt;## 13 ##src/traceroute/traceloop.c## + ICMP6_FILTER_SETBLOCKALL(&myfilt);## 14 ##src/traceroute/traceloop.c## + ICMP6_FILTER_SETPASS(ICMP6_TIME_EXCEEDED, &myfilt);## 15 ##src/traceroute/traceloop.c## + ICMP6_FILTER_SETPASS(ICMP6_DST_UNREACH, &myfilt);## 16 ##src/traceroute/traceloop.c## + setsockopt(recvfd, IPPROTO_IPV6, ICMP6_FILTER,## 17 ##src/traceroute/traceloop.c## + &myfilt, sizeof(myfilt));## 18 ##src/traceroute/traceloop.c## + }## 19 ##src/traceroute/traceloop.c## +#endif## 20 ##src/traceroute/traceloop.c## + + sendfd = Socket(pr->sasend->sa_family, SOCK_DGRAM, 0);## 21 ##src/traceroute/traceloop.c## + + pr->sabind->sa_family = pr->sasend->sa_family;## 22 ##src/traceroute/traceloop.c## + sport = (getpid() & 0xffff) | 0x8000; /* our source UDP port# */## 23 ##src/traceroute/traceloop.c## + sock_set_port(pr->sabind, pr->salen, htons(sport));## 24 ##src/traceroute/traceloop.c## + Bind(sendfd, pr->sabind, pr->salen);## 25 ##src/traceroute/traceloop.c## + + sig_alrm(SIGALRM);## 26 ##src/traceroute/traceloop.c## + + seq = 0;## 27 ##src/traceroute/traceloop.c## + done = 0;## 28 ##src/traceroute/traceloop.c## + for (ttl = 1; ttl <= max_ttl && done == 0; ttl++) {## 29 ##src/traceroute/traceloop.c## + Setsockopt(sendfd, pr->ttllevel, pr->ttloptname, &ttl, sizeof(int));## 30 ##src/traceroute/traceloop.c## + bzero(pr->salast, pr->salen);## 31 ##src/traceroute/traceloop.c## + + printf("%2d ", ttl);## 32 ##src/traceroute/traceloop.c## + fflush(stdout);## 33 ##src/traceroute/traceloop.c## + + for (probe = 0; probe < nprobes; probe++) {## 34 ##src/traceroute/traceloop.c## + rec = (struct rec *) sendbuf;## 35 ##src/traceroute/traceloop.c## + rec->rec_seq = ++seq;## 36 ##src/traceroute/traceloop.c## + rec->rec_ttl = ttl;## 37 ##src/traceroute/traceloop.c## + Gettimeofday(&rec->rec_tv, NULL);## 38 ##src/traceroute/traceloop.c## + + sock_set_port(pr->sasend, pr->salen, htons(dport + seq));## 39 ##src/traceroute/traceloop.c## + Sendto(sendfd, sendbuf, datalen, 0, pr->sasend, pr->salen);## 40 ##src/traceroute/traceloop.c## + + if ((code = (*pr->recv) (seq, &tvrecv)) == -3)## 41 ##src/traceroute/traceloop.c## + printf(" *"); /* timeout, no reply */## 42 ##src/traceroute/traceloop.c## + else {## 43 ##src/traceroute/traceloop.c## + char str[NI_MAXHOST];## 44 ##src/traceroute/traceloop.c## + + if (sock_cmp_addr(pr->sarecv, pr->salast, pr->salen) != 0) {## 45 ##src/traceroute/traceloop.c## + if (getnameinfo(pr->sarecv, pr->salen, str, sizeof(str),## 46 ##src/traceroute/traceloop.c## + NULL, 0, 0) == 0)## 47 ##src/traceroute/traceloop.c## + printf(" %s (%s)", str,## 48 ##src/traceroute/traceloop.c## + Sock_ntop_host(pr->sarecv, pr->salen));## 49 ##src/traceroute/traceloop.c## + else## 50 ##src/traceroute/traceloop.c## + printf(" %s", Sock_ntop_host(pr->sarecv, pr->salen));## 51 ##src/traceroute/traceloop.c## + memcpy(pr->salast, pr->sarecv, pr->salen);## 52 ##src/traceroute/traceloop.c## + }## 53 ##src/traceroute/traceloop.c## + tv_sub(&tvrecv, &rec->rec_tv);## 54 ##src/traceroute/traceloop.c## + rtt = tvrecv.tv_sec * 1000.0 + tvrecv.tv_usec / 1000.0;## 55 ##src/traceroute/traceloop.c## + printf(" %.3f ms", rtt);## 56 ##src/traceroute/traceloop.c## + + if (code == -1) /* port unreachable; at destination */## 57 ##src/traceroute/traceloop.c## + done++;## 58 ##src/traceroute/traceloop.c## + else if (code >= 0)## 59 ##src/traceroute/traceloop.c## + printf(" (ICMP %s)", (*pr->icmpcode) (code));## 60 ##src/traceroute/traceloop.c## + }## 61 ##src/traceroute/traceloop.c## + fflush(stdout);## 62 ##src/traceroute/traceloop.c## + }## 63 ##src/traceroute/traceloop.c## + printf("\n");## 64 ##src/traceroute/traceloop.c## + }## 65 ##src/traceroute/traceloop.c## +}## 66 ##src/traceroute/traceloop.c## diff --git a/traceroute/tv_sub.c b/traceroute/tv_sub.c new file mode 100644 index 0000000..7ad7830 --- /dev/null +++ b/traceroute/tv_sub.c @@ -0,0 +1,11 @@ +#include "unp.h" + +void +tv_sub(struct timeval *out, struct timeval *in) +{ + if ( (out->tv_usec -= in->tv_usec) < 0) { /* out -= in */ + --out->tv_sec; + out->tv_usec += 1000000; + } + out->tv_sec -= in->tv_sec; +} diff --git a/udpcksum/Makefile b/udpcksum/Makefile new file mode 100644 index 0000000..3d7de4c --- /dev/null +++ b/udpcksum/Makefile @@ -0,0 +1,21 @@ +include ../Make.defines + +OBJS = main.o cleanup.o pcap.o udpcksum.o senddnsquery-raw.o udpread.o udpwrite.o +OBJSNET = main.o cleanup.o pcap.o udpcksum.o senddnsquery-libnet.o udpread.o +PROGS = udpcksum udpcksum-libnet + +all: ${PROGS} + +udpcksum: ${OBJS} + ${CC} ${CFLAGS} -o $@ ${OBJS} -L/usr/local/lib -lpcap ${LIBS} + +# Include special linking flags from libnet-config program +udpcksum-libnet: ${OBJSNET} + ${CC} ${CFLAGS} -o $@ ${OBJSNET} -L/usr/local/lib -lpcap ${LIBS} `libnet-config --libs` + +# Include special compilation flags from libnet-config program +senddnsquery-libnet.o: senddnsquery-libnet.c + ${CC} ${CFLAGS} `libnet-config --defines --cflags` -c -o $@ $< + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/udpcksum/cleanup.c b/udpcksum/cleanup.c new file mode 100644 index 0000000..97743ec --- /dev/null +++ b/udpcksum/cleanup.c @@ -0,0 +1,20 @@ +#include "udpcksum.h" + +/* include cleanup */ +void +cleanup(int signo) +{ + struct pcap_stat stat; + + putc('\n', stdout); + + if (verbose) { + if (pcap_stats(pd, &stat) < 0) + err_quit("pcap_stats: %s\n", pcap_geterr(pd)); + printf("%d packets received by filter\n", stat.ps_recv); + printf("%d packets dropped by kernel\n", stat.ps_drop); + } + + exit(0); +} +/* end cleanup */ diff --git a/udpcksum/cleanup.lc b/udpcksum/cleanup.lc new file mode 100644 index 0000000..9cffc80 --- /dev/null +++ b/udpcksum/cleanup.lc @@ -0,0 +1,21 @@ +#include "udpcksum.h"## 1 ##src/udpcksum/cleanup.c## + +/* include cleanup */ +void## 2 ##src/udpcksum/cleanup.c## +cleanup(int signo)## 3 ##src/udpcksum/cleanup.c## +{## 4 ##src/udpcksum/cleanup.c## + struct pcap_stat stat;## 5 ##src/udpcksum/cleanup.c## + + fflush(stdout);## 6 ##src/udpcksum/cleanup.c## + putc('\n', stdout);## 7 ##src/udpcksum/cleanup.c## + + if (verbose) {## 8 ##src/udpcksum/cleanup.c## + if (pcap_stats(pd, &stat) < 0)## 9 ##src/udpcksum/cleanup.c## + err_quit("pcap_stats: %s\n", pcap_geterr(pd));## 10 ##src/udpcksum/cleanup.c## + printf("%d packets received by filter\n", stat.ps_recv);## 11 ##src/udpcksum/cleanup.c## + printf("%d packets dropped by kernel\n", stat.ps_drop);## 12 ##src/udpcksum/cleanup.c## + }## 13 ##src/udpcksum/cleanup.c## + + exit(0);## 14 ##src/udpcksum/cleanup.c## +}## 15 ##src/udpcksum/cleanup.c## +/* end cleanup */ diff --git a/udpcksum/main.c b/udpcksum/main.c new file mode 100644 index 0000000..45b33d3 --- /dev/null +++ b/udpcksum/main.c @@ -0,0 +1,124 @@ +/* include main1 */ +#include "udpcksum.h" + + /* DefinE global variables */ +struct sockaddr *dest, *local; +struct sockaddr_in locallookup; +socklen_t destlen, locallen; + +int datalink; /* from pcap_datalink(), in */ +char *device; /* pcap device */ +pcap_t *pd; /* packet capture struct pointer */ +int rawfd; /* raw socket to write on */ +int snaplen = 200; /* amount of data to capture */ +int verbose; +int zerosum; /* send UDP query with no checksum */ + +static void usage(const char *); + +int +main(int argc, char *argv[]) +{ + int c, lopt=0; + char *ptr, localname[1024], *localport; + struct addrinfo *aip; +/* end main1 */ + +/* include main2 */ + opterr = 0; /* don't want getopt() writing to stderr */ + while ( (c = getopt(argc, argv, "0i:l:v")) != -1) { + switch (c) { + + case '0': + zerosum = 1; + break; + + case 'i': + device = optarg; /* pcap device */ + break; + + case 'l': /* local IP address and port #: a.b.c.d.p */ + if ( (ptr = strrchr(optarg, '.')) == NULL) + usage("invalid -l option"); + + *ptr++ = 0; /* null replaces final period */ + localport = ptr; /* service name or port number */ + strncpy(localname, optarg, sizeof(localname)); + lopt = 1; + break; + + case 'v': + verbose = 1; + break; + + case '?': + usage("unrecognized option"); + } + } +/* end main2 */ +/* include main3 */ + if (optind != argc-2) + usage("missing and/or "); + + /* 4convert destination name and service */ + aip = Host_serv(argv[optind], argv[optind+1], AF_INET, SOCK_DGRAM); + dest = aip->ai_addr; /* don't freeaddrinfo() */ + destlen = aip->ai_addrlen; + + /* + * Need local IP address for source IP address for UDP datagrams. + * Can't specify 0 and let IP choose, as we need to know it for + * the pseudoheader to calculate the UDP checksum. + * If -l option supplied, then use those values; otherwise, + * connect a UDP socket to the destination to determine the right + * source address. + */ + if (lopt) { + /* 4convert local name and service */ + aip = Host_serv(localname, localport, AF_INET, SOCK_DGRAM); + local = aip->ai_addr; /* don't freeaddrinfo() */ + locallen = aip->ai_addrlen; + } else { + int s; + s = Socket(AF_INET, SOCK_DGRAM, 0); + Connect(s, dest, destlen); + /* kernel chooses correct local address for dest */ + locallen = sizeof(locallookup); + local = (struct sockaddr *)&locallookup; + Getsockname(s, local, &locallen); + if (locallookup.sin_addr.s_addr == htonl(INADDR_ANY)) + err_quit("Can't determine local address - use -l\n"); + close(s); + } + + open_output(); /* open output, either raw socket or libnet */ + + open_pcap(); /* open packet capture device */ + + setuid(getuid()); /* don't need superuser privileges anymore */ + + Signal(SIGTERM, cleanup); + Signal(SIGINT, cleanup); + Signal(SIGHUP, cleanup); + + test_udp(); + + cleanup(0); +} +/* end main3 */ + +static void +usage(const char *msg) +{ + err_msg( +"usage: udpcksum [ options ] \n" +"options: -0 send UDP datagram with checksum set to 0\n" +" -i s packet capture device\n" +" -l a.b.c.d.p local IP=a.b.c.d, local port=p\n" +" -v verbose output" +); + + if (msg[0] != 0) + err_quit("%s", msg); + exit(1); +} diff --git a/udpcksum/main.lc b/udpcksum/main.lc new file mode 100644 index 0000000..3ebe718 --- /dev/null +++ b/udpcksum/main.lc @@ -0,0 +1,125 @@ +/* include main1 */ +#include "udpcksum.h"## 1 ##src/udpcksum/main.c## + + /* define global variables */## 2 ##src/udpcksum/main.c## +struct sockaddr *dest, *local;## 3 ##src/udpcksum/main.c## +struct sockaddr_in locallookup;## 4 ##src/udpcksum/main.c## +socklen_t destlen, locallen;## 5 ##src/udpcksum/main.c## + +int datalink; /* from pcap_datalink(), in */## 6 ##src/udpcksum/main.c## +char *device; /* pcap device */## 7 ##src/udpcksum/main.c## +pcap_t *pd; /* packet capture struct pointer */## 8 ##src/udpcksum/main.c## +int rawfd; /* raw socket to write on */## 9 ##src/udpcksum/main.c## +int snaplen = 200; /* amount of data to capture */## 10 ##src/udpcksum/main.c## +int verbose;## 11 ##src/udpcksum/main.c## +int zerosum; /* send UDP query with no checksum */## 12 ##src/udpcksum/main.c## + +static void usage(const char *);## 13 ##src/udpcksum/main.c## + +int## 14 ##src/udpcksum/main.c## +main(int argc, char *argv[])## 15 ##src/udpcksum/main.c## +{## 16 ##src/udpcksum/main.c## + int c, lopt = 0;## 17 ##src/udpcksum/main.c## + char *ptr, localname[1024], *localport;## 18 ##src/udpcksum/main.c## + struct addrinfo *aip;## 19 ##src/udpcksum/main.c## + + if (argc < 2)## 20 ##src/udpcksum/main.c## + usage("");## 21 ##src/udpcksum/main.c## +/* end main1 */ + +/* include main2 */ + opterr = 0; /* don't want getopt() writing to stderr */## 22 ##src/udpcksum/main.c## + while ((c = getopt(argc, argv, "0i:l:v")) != -1) {## 23 ##src/udpcksum/main.c## + switch (c) {## 24 ##src/udpcksum/main.c## + + case '0':## 25 ##src/udpcksum/main.c## + zerosum = 1;## 26 ##src/udpcksum/main.c## + break;## 27 ##src/udpcksum/main.c## + + case 'i':## 28 ##src/udpcksum/main.c## + device = optarg; /* pcap device */## 29 ##src/udpcksum/main.c## + break;## 30 ##src/udpcksum/main.c## + + case 'l': /* local IP address and port#: a.b.c.d.p */## 31 ##src/udpcksum/main.c## + if ((ptr = strrchr(optarg, '.')) == NULL)## 32 ##src/udpcksum/main.c## + usage("invalid -l option");## 33 ##src/udpcksum/main.c## + + *ptr++ = 0; /* null replaces final period */## 34 ##src/udpcksum/main.c## + localport = ptr; /* service name or port number */## 35 ##src/udpcksum/main.c## + strncpy(localname, optarg, sizeof(localname));## 36 ##src/udpcksum/main.c## + lopt = 1;## 37 ##src/udpcksum/main.c## + break;## 38 ##src/udpcksum/main.c## + + case 'v':## 39 ##src/udpcksum/main.c## + verbose = 1;## 40 ##src/udpcksum/main.c## + break;## 41 ##src/udpcksum/main.c## + + case '?':## 42 ##src/udpcksum/main.c## + usage("unrecognized option");## 43 ##src/udpcksum/main.c## + }## 44 ##src/udpcksum/main.c## + }## 45 ##src/udpcksum/main.c## +/* end main2 */ +/* include main3 */ + if (optind != argc - 2)## 46 ##src/udpcksum/main.c## + usage("missing and/or ");## 47 ##src/udpcksum/main.c## + + /* 4convert destination name and service */## 48 ##src/udpcksum/main.c## + aip = Host_serv(argv[optind], argv[optind + 1], AF_INET, SOCK_DGRAM);## 49 ##src/udpcksum/main.c## + dest = aip->ai_addr; /* don't freeaddrinfo() */## 50 ##src/udpcksum/main.c## + destlen = aip->ai_addrlen;## 51 ##src/udpcksum/main.c## + + /* ## 52 ##src/udpcksum/main.c## + * Need local IP address for source IP address for UDP datagrams.## 53 ##src/udpcksum/main.c## + * Can't specify 0 and let IP choose, as we need to know it for## 54 ##src/udpcksum/main.c## + * the pseudo-header to calculate the UDP checksum.## 55 ##src/udpcksum/main.c## + * If -l option supplied, then use those values; otherwise,## 56 ##src/udpcksum/main.c## + * connect a UDP socket to the destination to determine the right## 57 ##src/udpcksum/main.c## + * source address.## 58 ##src/udpcksum/main.c## + */## 59 ##src/udpcksum/main.c## + if (lopt) {## 60 ##src/udpcksum/main.c## + /* 4convert local name and service */## 61 ##src/udpcksum/main.c## + aip = Host_serv(localname, localport, AF_INET, SOCK_DGRAM);## 62 ##src/udpcksum/main.c## + local = aip->ai_addr; /* don't freeaddrinfo() */## 63 ##src/udpcksum/main.c## + locallen = aip->ai_addrlen;## 64 ##src/udpcksum/main.c## + } else {## 65 ##src/udpcksum/main.c## + int s;## 66 ##src/udpcksum/main.c## + s = Socket(AF_INET, SOCK_DGRAM, 0);## 67 ##src/udpcksum/main.c## + Connect(s, dest, destlen);## 68 ##src/udpcksum/main.c## + /* the kernel chooses the correct local address for dest */## 69 ##src/udpcksum/main.c## + locallen = sizeof(locallookup);## 70 ##src/udpcksum/main.c## + local = (struct sockaddr *) &locallookup;## 71 ##src/udpcksum/main.c## + Getsockname(s, local, &locallen);## 72 ##src/udpcksum/main.c## + if (locallookup.sin_addr.s_addr == htonl(INADDR_ANY))## 73 ##src/udpcksum/main.c## + err_quit("Can't determine local address - use -l\n");## 74 ##src/udpcksum/main.c## + close(s);## 75 ##src/udpcksum/main.c## + }## 76 ##src/udpcksum/main.c## + + open_output(); /* open output, either raw socket or libnet */## 77 ##src/udpcksum/main.c## + + open_pcap(); /* open packet capture device */## 78 ##src/udpcksum/main.c## + + setuid(getuid()); /* don't need superuser privileges any more */## 79 ##src/udpcksum/main.c## + + Signal(SIGTERM, cleanup);## 80 ##src/udpcksum/main.c## + Signal(SIGINT, cleanup);## 81 ##src/udpcksum/main.c## + Signal(SIGHUP, cleanup);## 82 ##src/udpcksum/main.c## + + test_udp();## 83 ##src/udpcksum/main.c## + + cleanup(0);## 84 ##src/udpcksum/main.c## +}## 85 ##src/udpcksum/main.c## +/* end main3 */ + +static void## 86 ##src/udpcksum/main.c## +usage(const char *msg)## 87 ##src/udpcksum/main.c## +{## 88 ##src/udpcksum/main.c## + err_msg("usage: udpcksum [ options ] \n"## 89 ##src/udpcksum/main.c## + "options: -0 send UDP datagram with checksum set to 0\n"## 90 ##src/udpcksum/main.c## + " -i s packet capture device\n"## 91 ##src/udpcksum/main.c## + " -l a.b.c.d.p local IP=a.b.c.d, local port=p\n"## 92 ##src/udpcksum/main.c## + " -v verbose output");## 93 ##src/udpcksum/main.c## + + if (msg[0] != 0)## 94 ##src/udpcksum/main.c## + err_quit("%s", msg);## 95 ##src/udpcksum/main.c## + exit(1);## 96 ##src/udpcksum/main.c## +}## 97 ##src/udpcksum/main.c## diff --git a/udpcksum/pcap.c b/udpcksum/pcap.c new file mode 100644 index 0000000..a88cc43 --- /dev/null +++ b/udpcksum/pcap.c @@ -0,0 +1,63 @@ +/* include open_pcap */ +#include "udpcksum.h" + +#define CMD "udp and src host %s and src port %d" + +void +open_pcap(void) +{ + uint32_t localnet, netmask; + char cmd[MAXLINE], errbuf[PCAP_ERRBUF_SIZE], + str1[INET_ADDRSTRLEN], str2[INET_ADDRSTRLEN]; + struct bpf_program fcode; + + if (device == NULL) { + if ( (device = pcap_lookupdev(errbuf)) == NULL) + err_quit("pcap_lookup: %s", errbuf); + } + printf("device = %s\n", device); + + /* 4hardcode: promisc=0, to_ms=500 */ + if ( (pd = pcap_open_live(device, snaplen, 0, 500, errbuf)) == NULL) + err_quit("pcap_open_live: %s", errbuf); + + if (pcap_lookupnet(device, &localnet, &netmask, errbuf) < 0) + err_quit("pcap_lookupnet: %s", errbuf); + if (verbose) + printf("localnet = %s, netmask = %s\n", + Inet_ntop(AF_INET, &localnet, str1, sizeof(str1)), + Inet_ntop(AF_INET, &netmask, str2, sizeof(str2))); + + snprintf(cmd, sizeof(cmd), CMD, + Sock_ntop_host(dest, destlen), + ntohs(sock_get_port(dest, destlen))); + if (verbose) + printf("cmd = %s\n", cmd); + if (pcap_compile(pd, &fcode, cmd, 0, netmask) < 0) + err_quit("pcap_compile: %s", pcap_geterr(pd)); + + if (pcap_setfilter(pd, &fcode) < 0) + err_quit("pcap_setfilter: %s", pcap_geterr(pd)); + + if ( (datalink = pcap_datalink(pd)) < 0) + err_quit("pcap_datalink: %s", pcap_geterr(pd)); + if (verbose) + printf("datalink = %d\n", datalink); +} +/* end open_pcap */ + +/* include next_pcap */ +char * +next_pcap(int *len) +{ + char *ptr; + struct pcap_pkthdr hdr; + + /* 4keep looping until packet ready */ + while ( (ptr = (char *) pcap_next(pd, &hdr)) == NULL) + ; + + *len = hdr.caplen; /* captured length */ + return(ptr); +} +/* end next_pcap */ diff --git a/udpcksum/pcap.lc b/udpcksum/pcap.lc new file mode 100644 index 0000000..cd77a78 --- /dev/null +++ b/udpcksum/pcap.lc @@ -0,0 +1,62 @@ +/* include open_pcap */ +#include "udpcksum.h"## 1 ##src/udpcksum/pcap.c## + +#define CMD "udp and src host %s and src port %d"## 2 ##src/udpcksum/pcap.c## + +void## 3 ##src/udpcksum/pcap.c## +open_pcap(void)## 4 ##src/udpcksum/pcap.c## +{## 5 ##src/udpcksum/pcap.c## + uint32_t localnet, netmask;## 6 ##src/udpcksum/pcap.c## + char cmd[MAXLINE], errbuf[PCAP_ERRBUF_SIZE],## 7 ##src/udpcksum/pcap.c## + str1[INET_ADDRSTRLEN], str2[INET_ADDRSTRLEN];## 8 ##src/udpcksum/pcap.c## + struct bpf_program fcode;## 9 ##src/udpcksum/pcap.c## + + if (device == NULL) {## 10 ##src/udpcksum/pcap.c## + if ((device = pcap_lookupdev(errbuf)) == NULL)## 11 ##src/udpcksum/pcap.c## + err_quit("pcap_lookup: %s", errbuf);## 12 ##src/udpcksum/pcap.c## + }## 13 ##src/udpcksum/pcap.c## + printf("device = %s\n", device);## 14 ##src/udpcksum/pcap.c## + + /* 4hardcode: promisc=0, to_ms=500 */## 15 ##src/udpcksum/pcap.c## + if ((pd = pcap_open_live(device, snaplen, 0, 500, errbuf)) == NULL)## 16 ##src/udpcksum/pcap.c## + err_quit("pcap_open_live: %s", errbuf);## 17 ##src/udpcksum/pcap.c## + + if (pcap_lookupnet(device, &localnet, &netmask, errbuf) < 0)## 18 ##src/udpcksum/pcap.c## + err_quit("pcap_lookupnet: %s", errbuf);## 19 ##src/udpcksum/pcap.c## + if (verbose)## 20 ##src/udpcksum/pcap.c## + printf("localnet = %s, netmask = %s\n",## 21 ##src/udpcksum/pcap.c## + Inet_ntop(AF_INET, &localnet, str1, sizeof(str1)),## 22 ##src/udpcksum/pcap.c## + Inet_ntop(AF_INET, &netmask, str2, sizeof(str2)));## 23 ##src/udpcksum/pcap.c## + + snprintf(cmd, sizeof(cmd), CMD,## 24 ##src/udpcksum/pcap.c## + Sock_ntop_host(dest, destlen),## 25 ##src/udpcksum/pcap.c## + ntohs(sock_get_port(dest, destlen)));## 26 ##src/udpcksum/pcap.c## + if (verbose)## 27 ##src/udpcksum/pcap.c## + printf("cmd = %s\n", cmd);## 28 ##src/udpcksum/pcap.c## + if (pcap_compile(pd, &fcode, cmd, 0, netmask) < 0)## 29 ##src/udpcksum/pcap.c## + err_quit("pcap_compile: %s", pcap_geterr(pd));## 30 ##src/udpcksum/pcap.c## + + if (pcap_setfilter(pd, &fcode) < 0)## 31 ##src/udpcksum/pcap.c## + err_quit("pcap_setfilter: %s", pcap_geterr(pd));## 32 ##src/udpcksum/pcap.c## + + if ((datalink = pcap_datalink(pd)) < 0)## 33 ##src/udpcksum/pcap.c## + err_quit("pcap_datalink: %s", pcap_geterr(pd));## 34 ##src/udpcksum/pcap.c## + if (verbose)## 35 ##src/udpcksum/pcap.c## + printf("datalink = %d\n", datalink);## 36 ##src/udpcksum/pcap.c## +}## 37 ##src/udpcksum/pcap.c## +/* end open_pcap */ + +/* include next_pcap */ +char *## 38 ##src/udpcksum/pcap.c## +next_pcap(int *len)## 39 ##src/udpcksum/pcap.c## +{## 40 ##src/udpcksum/pcap.c## + char *ptr;## 41 ##src/udpcksum/pcap.c## + struct pcap_pkthdr hdr;## 42 ##src/udpcksum/pcap.c## + + /* 4keep looping until packet ready */## 43 ##src/udpcksum/pcap.c## + while ((ptr = (char *) pcap_next(pd, &hdr)) == NULL) ;## 44 ##src/udpcksum/pcap.c## + + *len = hdr.caplen; /* captured length */## 45 ##src/udpcksum/pcap.c## + return (ptr);## 46 ##src/udpcksum/pcap.c## +}## 47 ##src/udpcksum/pcap.c## +/* end next_pcap */ diff --git a/udpcksum/senddnsquery-libnet.c b/udpcksum/senddnsquery-libnet.c new file mode 100644 index 0000000..614e2ae --- /dev/null +++ b/udpcksum/senddnsquery-libnet.c @@ -0,0 +1,78 @@ +#include "udpcksum.h" +#include + +/* + * Build a DNS A query for "a.root-servers.net" and write it to + * the raw socket. + */ + +/* include open_output_libnet */ +static libnet_t *l; /* libnet descriptor */ + +void +open_output(void) +{ + char errbuf[LIBNET_ERRBUF_SIZE]; + + /* Initialize libnet with an IPv4 raw socket */ + l = libnet_init(LIBNET_RAW4, NULL, errbuf); + if (l == NULL) { + err_quit("Can't initialize libnet: %s", errbuf); + } +} +/* end open_output_libnet */ + +/* include send_dns_query_libnet */ +void +send_dns_query(void) +{ + char qbuf[24], *ptr; + u_int16_t one; + int packet_size = LIBNET_UDP_H + LIBNET_DNSV4_H + 24; + static libnet_ptag_t ip_tag, udp_tag, dns_tag; + + /* build query portion of DNS packet */ + ptr = qbuf; + memcpy(ptr, "\001a\014root-servers\003net\000", 20); + ptr += 20; + one = htons(1); + memcpy(ptr, &one, 2); /* query type = A */ + ptr += 2; + memcpy(ptr, &one, 2); /* query class = 1 (IP addr) */ + + /* build DNS packet */ + dns_tag = libnet_build_dnsv4( + 1234 /* identification */, + 0x0100 /* flags: recursion desired */, + 1 /* # questions */, 0 /* # answer RRs */, + 0 /* # authority RRs */, 0 /* # additional RRs */, + qbuf /* query */, 24 /* length of query */, l, dns_tag); + /* build UDP header */ + udp_tag = libnet_build_udp( + ((struct sockaddr_in *) local)->sin_port /* source port */, + ((struct sockaddr_in *) dest)->sin_port /* dest port */, + packet_size /* length */, 0 /* checksum */, + NULL /* payload */, 0 /* payload length */, l, udp_tag); + /* Since we specified the checksum as 0, libnet will automatically */ + /* calculate the UDP checksum. Turn it off if the user doesn't want it. */ + if (zerosum) + if (libnet_toggle_checksum(l, udp_tag, LIBNET_OFF) < 0) + err_quit("turning off checksums: %s\n", libnet_geterror(l)); + /* build IP header */ +/* *INDENT-OFF* */ + ip_tag = libnet_build_ipv4(packet_size + LIBNET_IPV4_H /* len */, + 0 /* tos */, 0 /* IP ID */, 0 /* fragment */, + TTL_OUT /* ttl */, IPPROTO_UDP /* protocol */, + 0 /* checksum */, + ((struct sockaddr_in *) local)->sin_addr.s_addr /* source */, + ((struct sockaddr_in *) dest)->sin_addr.s_addr /* dest */, + NULL /* payload */, 0 /* payload length */, l, ip_tag); +/* *INDENT-ON* */ + + if (libnet_write(l) < 0) { + err_quit("libnet_write: %s\n", libnet_geterror(l)); + } + if (verbose) + printf("sent: %d bytes of data\n", packet_size); +} +/* end send_dns_query_libnet */ diff --git a/udpcksum/senddnsquery-libnet.lc b/udpcksum/senddnsquery-libnet.lc new file mode 100644 index 0000000..3708a65 --- /dev/null +++ b/udpcksum/senddnsquery-libnet.lc @@ -0,0 +1,79 @@ +#include "udpcksum.h"## 1 ##src/udpcksum/senddnsquery-libnet.c## +#include ## 2 ##src/udpcksum/senddnsquery-libnet.c## + +/*## 3 ##src/udpcksum/senddnsquery-libnet.c## + * Build a DNS A query for "a.root-servers.net" and write it to## 4 ##src/udpcksum/senddnsquery-libnet.c## + * the raw socket.## 5 ##src/udpcksum/senddnsquery-libnet.c## + */## 6 ##src/udpcksum/senddnsquery-libnet.c## + +/* include open_output_libnet */ +static libnet_t *l; /* libnet descriptor */## 7 ##src/udpcksum/senddnsquery-libnet.c## + +void## 8 ##src/udpcksum/senddnsquery-libnet.c## +open_output(void)## 9 ##src/udpcksum/senddnsquery-libnet.c## +{## 10 ##src/udpcksum/senddnsquery-libnet.c## + char errbuf[LIBNET_ERRBUF_SIZE];## 11 ##src/udpcksum/senddnsquery-libnet.c## + + /* Initialize libnet, with an IPv4 raw socket. */## 12 ##src/udpcksum/senddnsquery-libnet.c## + l = libnet_init(LIBNET_RAW4, NULL, errbuf);## 13 ##src/udpcksum/senddnsquery-libnet.c## + if (l == NULL) {## 14 ##src/udpcksum/senddnsquery-libnet.c## + err_quit("Can't initialize libnet: %s", errbuf);## 15 ##src/udpcksum/senddnsquery-libnet.c## + }## 16 ##src/udpcksum/senddnsquery-libnet.c## +}## 17 ##src/udpcksum/senddnsquery-libnet.c## +/* end open_output_libnet */ + +/* include send_dns_query_libnet */ +void## 18 ##src/udpcksum/senddnsquery-libnet.c## +send_dns_query(void)## 19 ##src/udpcksum/senddnsquery-libnet.c## +{## 20 ##src/udpcksum/senddnsquery-libnet.c## + char qbuf[24], *ptr;## 21 ##src/udpcksum/senddnsquery-libnet.c## + u_int16_t one;## 22 ##src/udpcksum/senddnsquery-libnet.c## + int packet_size = LIBNET_UDP_H + LIBNET_DNSV4_H + 24;## 23 ##src/udpcksum/senddnsquery-libnet.c## + static libnet_ptag_t ip_tag, udp_tag, dns_tag;## 24 ##src/udpcksum/senddnsquery-libnet.c## + + /* Build the query portion of the DNS packet. */## 25 ##src/udpcksum/senddnsquery-libnet.c## + ptr = qbuf;## 26 ##src/udpcksum/senddnsquery-libnet.c## + memcpy(ptr, "\001a\014root-servers\003net\000", 20);## 27 ##src/udpcksum/senddnsquery-libnet.c## + ptr += 20;## 28 ##src/udpcksum/senddnsquery-libnet.c## + one = htons(1);## 29 ##src/udpcksum/senddnsquery-libnet.c## + memcpy(ptr, &one, 2); /* query type = A */## 30 ##src/udpcksum/senddnsquery-libnet.c## + ptr += 2;## 31 ##src/udpcksum/senddnsquery-libnet.c## + memcpy(ptr, &one, 2); /* query class = 1 (IP addr) */## 32 ##src/udpcksum/senddnsquery-libnet.c## + + /* Build the DNS packet. */## 33 ##src/udpcksum/senddnsquery-libnet.c## + dns_tag = libnet_build_dnsv4(1234 /* identification */ ,## 34 ##src/udpcksum/senddnsquery-libnet.c## + 0x0100 /* flags: recursion desired */ ,## 35 ##src/udpcksum/senddnsquery-libnet.c## + 1 /* #questions */ , 0 /* #answer RRs */ ,## 36 ##src/udpcksum/senddnsquery-libnet.c## + 0 /* #authority RRs */ ,## 37 ##src/udpcksum/senddnsquery-libnet.c## + 0 /* #additional RRs */ ,## 38 ##src/udpcksum/senddnsquery-libnet.c## + qbuf /* query */ ,## 39 ##src/udpcksum/senddnsquery-libnet.c## + 24 /* length of query */ , l, dns_tag);## 40 ##src/udpcksum/senddnsquery-libnet.c## + /* Build the UDP header. */## 41 ##src/udpcksum/senddnsquery-libnet.c## + udp_tag = libnet_build_udp(((struct sockaddr_in *) local)->## 42 ##src/udpcksum/senddnsquery-libnet.c## + sin_port /* source port */ ,## 43 ##src/udpcksum/senddnsquery-libnet.c## + ((struct sockaddr_in *) dest)->## 44 ##src/udpcksum/senddnsquery-libnet.c## + sin_port /* dest port */ ,## 45 ##src/udpcksum/senddnsquery-libnet.c## + packet_size /* length */ , 0 /* checksum */ ,## 46 ##src/udpcksum/senddnsquery-libnet.c## + NULL /* payload */ , 0 /* payload length */ ,## 47 ##src/udpcksum/senddnsquery-libnet.c## + l, udp_tag);## 48 ##src/udpcksum/senddnsquery-libnet.c## + /* Since we specified the checksum as 0, libnet will automatically */## 49 ##src/udpcksum/senddnsquery-libnet.c## + /* calculate the udp checksum. Turn it off if the user doesn't want it */## 50 ##src/udpcksum/senddnsquery-libnet.c## + if (zerosum)## 51 ##src/udpcksum/senddnsquery-libnet.c## + if (libnet_toggle_checksum(l, udp_tag, LIBNET_OFF) < 0)## 52 ##src/udpcksum/senddnsquery-libnet.c## + err_quit("turning off checksums: %s\n", libnet_geterror(l));## 53 ##src/udpcksum/senddnsquery-libnet.c## + /* Build the IP header. */## 54 ##src/udpcksum/senddnsquery-libnet.c## + ip_tag = libnet_build_ipv4(packet_size + LIBNET_IPV4_H /* len */,## 55 ##src/udpcksum/senddnsquery-libnet.c## + 0 /* tos */, 0 /* IP ID */, 0 /* fragment */,## 56 ##src/udpcksum/senddnsquery-libnet.c## + TTL_OUT /* ttl */, IPPROTO_UDP /* protocol */,## 57 ##src/udpcksum/senddnsquery-libnet.c## + 0 /* checksum */,## 58 ##src/udpcksum/senddnsquery-libnet.c## + ((struct sockaddr_in *) local)->sin_addr.s_addr /* source */,## 59 ##src/udpcksum/senddnsquery-libnet.c## + ((struct sockaddr_in *) dest)->sin_addr.s_addr /* dest */,## 60 ##src/udpcksum/senddnsquery-libnet.c## + NULL /* payload */, 0 /* payload length */, l, ip_tag);## 61 ##src/udpcksum/senddnsquery-libnet.c## + + if (libnet_write(l) < 0) {## 62 ##src/udpcksum/senddnsquery-libnet.c## + err_quit("libnet_write: %s\n", libnet_geterror(l));## 63 ##src/udpcksum/senddnsquery-libnet.c## + }## 64 ##src/udpcksum/senddnsquery-libnet.c## + if (verbose)## 65 ##src/udpcksum/senddnsquery-libnet.c## + printf("sent: %d bytes of data\n", packet_size);## 66 ##src/udpcksum/senddnsquery-libnet.c## +}## 67 ##src/udpcksum/senddnsquery-libnet.c## +/* end send_dns_query_libnet */ diff --git a/udpcksum/senddnsquery-raw.c b/udpcksum/senddnsquery-raw.c new file mode 100644 index 0000000..1f16875 --- /dev/null +++ b/udpcksum/senddnsquery-raw.c @@ -0,0 +1,43 @@ +#include "udpcksum.h" + +/* + * Build a DNS A query for "a.root-servers.net" and write it to + * the raw socket. + */ + +/* include send_dns_query */ +void +send_dns_query(void) +{ + size_t nbytes; + char *buf, *ptr; + + buf = Malloc(sizeof(struct udpiphdr) + 100); + ptr = buf + sizeof(struct udpiphdr);/* leave room for IP/UDP headers */ + + *((uint16_t *) ptr) = htons(1234); /* identification */ + ptr += 2; + *((uint16_t *) ptr) = htons(0x0100); /* flags: recursion desired */ + ptr += 2; + *((uint16_t *) ptr) = htons(1); /* # questions */ + ptr += 2; + *((uint16_t *) ptr) = 0; /* # answer RRs */ + ptr += 2; + *((uint16_t *) ptr) = 0; /* # authority RRs */ + ptr += 2; + *((uint16_t *) ptr) = 0; /* # additional RRs */ + ptr += 2; + + memcpy(ptr, "\001a\014root-servers\003net\000", 20); + ptr += 20; + *((uint16_t *) ptr) = htons(1); /* query type = A */ + ptr += 2; + *((uint16_t *) ptr) = htons(1); /* query class = 1 (IP addr) */ + ptr += 2; + + nbytes = (ptr - buf) - sizeof(struct udpiphdr); + udp_write(buf, nbytes); + if (verbose) + printf("sent: %d bytes of data\n", nbytes); +} +/* end send_dns_query */ diff --git a/udpcksum/senddnsquery-raw.lc b/udpcksum/senddnsquery-raw.lc new file mode 100644 index 0000000..1ad6f8d --- /dev/null +++ b/udpcksum/senddnsquery-raw.lc @@ -0,0 +1,44 @@ +#include "udpcksum.h"## 1 ##src/udpcksum/senddnsquery-raw.c## + +/*## 2 ##src/udpcksum/senddnsquery-raw.c## + * Build a DNS A query for "a.root-servers.net" and write it to## 3 ##src/udpcksum/senddnsquery-raw.c## + * the raw socket.## 4 ##src/udpcksum/senddnsquery-raw.c## + */## 5 ##src/udpcksum/senddnsquery-raw.c## + +/* include send_dns_query */ +void## 6 ##src/udpcksum/senddnsquery-raw.c## +send_dns_query(void)## 7 ##src/udpcksum/senddnsquery-raw.c## +{## 8 ##src/udpcksum/senddnsquery-raw.c## + size_t nbytes;## 9 ##src/udpcksum/senddnsquery-raw.c## + char buf[sizeof(struct udpiphdr) + 100], *ptr;## 10 ##src/udpcksum/senddnsquery-raw.c## + uint16_t one;## 11 ##src/udpcksum/senddnsquery-raw.c## + + ptr = buf + sizeof(struct udpiphdr); /* leave room for IP/UDP headers */## 12 ##src/udpcksum/senddnsquery-raw.c## + + *((uint16_t *) ptr) = htons(1234); /* identification */## 13 ##src/udpcksum/senddnsquery-raw.c## + ptr += 2;## 14 ##src/udpcksum/senddnsquery-raw.c## + *((uint16_t *) ptr) = htons(0x0100); /* flags: recursion desired */## 15 ##src/udpcksum/senddnsquery-raw.c## + ptr += 2;## 16 ##src/udpcksum/senddnsquery-raw.c## + *((uint16_t *) ptr) = htons(1); /* #questions */## 17 ##src/udpcksum/senddnsquery-raw.c## + ptr += 2;## 18 ##src/udpcksum/senddnsquery-raw.c## + *((uint16_t *) ptr) = 0; /* #answer RRs */## 19 ##src/udpcksum/senddnsquery-raw.c## + ptr += 2;## 20 ##src/udpcksum/senddnsquery-raw.c## + *((uint16_t *) ptr) = 0; /* #authority RRs */## 21 ##src/udpcksum/senddnsquery-raw.c## + ptr += 2;## 22 ##src/udpcksum/senddnsquery-raw.c## + *((uint16_t *) ptr) = 0; /* #additional RRs */## 23 ##src/udpcksum/senddnsquery-raw.c## + ptr += 2;## 24 ##src/udpcksum/senddnsquery-raw.c## + + memcpy(ptr, "\001a\014root-servers\003net\000", 20);## 25 ##src/udpcksum/senddnsquery-raw.c## + ptr += 20;## 26 ##src/udpcksum/senddnsquery-raw.c## + one = htons(1);## 27 ##src/udpcksum/senddnsquery-raw.c## + memcpy(ptr, &one, 2); /* query type = A */## 28 ##src/udpcksum/senddnsquery-raw.c## + ptr += 2;## 29 ##src/udpcksum/senddnsquery-raw.c## + memcpy(ptr, &one, 2); /* query class = 1 (IP addr) */## 30 ##src/udpcksum/senddnsquery-raw.c## + ptr += 2;## 31 ##src/udpcksum/senddnsquery-raw.c## + + nbytes = 36;## 32 ##src/udpcksum/senddnsquery-raw.c## + udp_write(buf, nbytes);## 33 ##src/udpcksum/senddnsquery-raw.c## + if (verbose)## 34 ##src/udpcksum/senddnsquery-raw.c## + printf("sent: %d bytes of data\n", nbytes);## 35 ##src/udpcksum/senddnsquery-raw.c## +}## 36 ##src/udpcksum/senddnsquery-raw.c## +/* end send_dns_query */ diff --git a/udpcksum/udpcksum.c b/udpcksum/udpcksum.c new file mode 100644 index 0000000..d6e7929 --- /dev/null +++ b/udpcksum/udpcksum.c @@ -0,0 +1,49 @@ +/* include sig_alrm */ +#include "udpcksum.h" +#include + +static sigjmp_buf jmpbuf; +static int canjump; + +void +sig_alrm(int signo) +{ + if (canjump == 0) + return; + siglongjmp(jmpbuf, 1); +} +/* end sig_alrm */ + +/* include test_udp */ +void +test_udp(void) +{ + volatile int nsent = 0, timeout = 3; + struct udpiphdr *ui; + + Signal(SIGALRM, sig_alrm); + + if (sigsetjmp(jmpbuf, 1)) { + if (nsent >= 3) + err_quit("no response"); + printf("timeout\n"); + timeout *= 2; /* exponential backoff: 3, 6, 12 */ + } + canjump = 1; /* siglongjmp is now OK */ + + send_dns_query(); + nsent++; + + alarm(timeout); + ui = udp_read(); + canjump = 0; + alarm(0); + + if (ui->ui_sum == 0) + printf("UDP checksums off\n"); + else + printf("UDP checksums on\n"); + if (verbose) + printf("received UDP checksum = %x\n", ntohs(ui->ui_sum)); +} +/* end test_udp */ diff --git a/udpcksum/udpcksum.h b/udpcksum/udpcksum.h new file mode 100644 index 0000000..f48842b --- /dev/null +++ b/udpcksum/udpcksum.h @@ -0,0 +1,34 @@ +#include "unp.h" +#include + +#include /* required for ip.h */ +#include +#include +#include +#include +#include +#include +#include + +#define TTL_OUT 64 /* outgoing TTL */ + + /* declare global variables */ +extern struct sockaddr *dest, *local; +extern socklen_t destlen, locallen; +extern int datalink; +extern char *device; +extern pcap_t *pd; +extern int rawfd; +extern int snaplen; +extern int verbose; +extern int zerosum; + + /* function prototypes */ +void cleanup(int); +char *next_pcap(int *); +void open_output(void); +void open_pcap(void); +void send_dns_query(void); +void test_udp(void); +void udp_write(char *, int); +struct udpiphdr *udp_read(void); diff --git a/udpcksum/udpcksum.lc b/udpcksum/udpcksum.lc new file mode 100644 index 0000000..fc765db --- /dev/null +++ b/udpcksum/udpcksum.lc @@ -0,0 +1,49 @@ +/* include sig_alrm */ +#include "udpcksum.h"## 1 ##src/udpcksum/udpcksum.c## +#include ## 2 ##src/udpcksum/udpcksum.c## + +static sigjmp_buf jmpbuf;## 3 ##src/udpcksum/udpcksum.c## +static int canjump;## 4 ##src/udpcksum/udpcksum.c## + +void## 5 ##src/udpcksum/udpcksum.c## +sig_alrm(int signo)## 6 ##src/udpcksum/udpcksum.c## +{## 7 ##src/udpcksum/udpcksum.c## + if (canjump == 0)## 8 ##src/udpcksum/udpcksum.c## + return;## 9 ##src/udpcksum/udpcksum.c## + siglongjmp(jmpbuf, 1);## 10 ##src/udpcksum/udpcksum.c## +}## 11 ##src/udpcksum/udpcksum.c## +/* end sig_alrm */ + +/* include test_udp */ +void## 12 ##src/udpcksum/udpcksum.c## +test_udp(void)## 13 ##src/udpcksum/udpcksum.c## +{## 14 ##src/udpcksum/udpcksum.c## + volatile int nsent = 0, timeout = 3;## 15 ##src/udpcksum/udpcksum.c## + struct udpiphdr *ui;## 16 ##src/udpcksum/udpcksum.c## + + Signal(SIGALRM, sig_alrm);## 17 ##src/udpcksum/udpcksum.c## + + if (sigsetjmp(jmpbuf, 1)) {## 18 ##src/udpcksum/udpcksum.c## + if (nsent >= 3)## 19 ##src/udpcksum/udpcksum.c## + err_quit("no response");## 20 ##src/udpcksum/udpcksum.c## + printf("timeout\n");## 21 ##src/udpcksum/udpcksum.c## + timeout *= 2; /* exponential backoff: 3, 6, 12 */## 22 ##src/udpcksum/udpcksum.c## + }## 23 ##src/udpcksum/udpcksum.c## + canjump = 1; /* siglongjmp is now OK */## 24 ##src/udpcksum/udpcksum.c## + + send_dns_query();## 25 ##src/udpcksum/udpcksum.c## + nsent++;## 26 ##src/udpcksum/udpcksum.c## + + alarm(timeout);## 27 ##src/udpcksum/udpcksum.c## + ui = udp_read();## 28 ##src/udpcksum/udpcksum.c## + canjump = 0;## 29 ##src/udpcksum/udpcksum.c## + alarm(0);## 30 ##src/udpcksum/udpcksum.c## + + if (ui->ui_sum == 0)## 31 ##src/udpcksum/udpcksum.c## + printf("UDP checksums off\n");## 32 ##src/udpcksum/udpcksum.c## + else## 33 ##src/udpcksum/udpcksum.c## + printf("UDP checksums on\n");## 34 ##src/udpcksum/udpcksum.c## + if (verbose)## 35 ##src/udpcksum/udpcksum.c## + printf("received UDP checksum = %x\n", ntohs(ui->ui_sum));## 36 ##src/udpcksum/udpcksum.c## +}## 37 ##src/udpcksum/udpcksum.c## +/* end test_udp */ diff --git a/udpcksum/udpread.c b/udpcksum/udpread.c new file mode 100644 index 0000000..5499963 --- /dev/null +++ b/udpcksum/udpread.c @@ -0,0 +1,85 @@ +#include "udpcksum.h" + +struct udpiphdr *udp_check(char *, int); + +/* + * Read from the network until a UDP datagram is read that matches + * the arguments. + */ + +/* include udp_read */ +struct udpiphdr * +udp_read(void) +{ + int len; + char *ptr; + struct ether_header *eptr; + + for ( ; ; ) { + ptr = next_pcap(&len); + + switch (datalink) { + case DLT_NULL: /* loopback header = 4 bytes */ + return(udp_check(ptr+4, len-4)); + + case DLT_EN10MB: + eptr = (struct ether_header *) ptr; + if (ntohs(eptr->ether_type) != ETHERTYPE_IP) + err_quit("Ethernet type %x not IP", ntohs(eptr->ether_type)); + return(udp_check(ptr+14, len-14)); + + case DLT_SLIP: /* SLIP header = 24 bytes */ + return(udp_check(ptr+24, len-24)); + + case DLT_PPP: /* PPP header = 24 bytes */ + return(udp_check(ptr+24, len-24)); + + default: + err_quit("unsupported datalink (%d)", datalink); + } + } +} +/* end udp_read */ + +/* + * Check the received packet. + * If UDP and OK, return pointer to packet. + * If ICMP error, return NULL. + * We assume the filter picks out desired UDP datagrams. + */ + +/* include udp_check */ +struct udpiphdr * +udp_check(char *ptr, int len) +{ + int hlen; + struct ip *ip; + struct udpiphdr *ui; +/* *INDENT-OFF* */ + + if (len < sizeof(struct ip) + sizeof(struct udphdr)) + err_quit("len = %d", len); +/* *INDENT-ON* */ + + /* 4minimal verification of IP header */ + ip = (struct ip *) ptr; + if (ip->ip_v != IPVERSION) + err_quit("ip_v = %d", ip->ip_v); + hlen = ip->ip_hl << 2; +/* *INDENT-OFF* */ + if (hlen < sizeof(struct ip)) + err_quit("ip_hl = %d", ip->ip_hl); + if (len < hlen + sizeof(struct udphdr)) + err_quit("len = %d, hlen = %d", len, hlen); +/* *INDENT-ON* */ + + if ( (ip->ip_sum = in_cksum((uint16_t *) ip, hlen)) != 0) + err_quit("ip checksum error"); + + if (ip->ip_p == IPPROTO_UDP) { + ui = (struct udpiphdr *) ip; + return(ui); + } else + err_quit("not a UDP packet"); +} +/* end udp_check */ diff --git a/udpcksum/udpread.c.bad b/udpcksum/udpread.c.bad new file mode 100644 index 0000000..36dff4b --- /dev/null +++ b/udpcksum/udpread.c.bad @@ -0,0 +1,85 @@ +#include "udpcksum.h" + +struct udpiphdr *udp_check (char *, int); + +/* + * Read from the network until a UDP datagram is read that matches + * the arguments. + */ + +/* include udp_read */ +struct udpiphdr * +udp_read (void) +{ + int len; + char *ptr; + struct ether_header *eptr; + + for (;;) + { + ptr = next_pcap (&len); + + switch (datalink) + { + case DLT_NULL: /* loopback header = 4 bytes */ + return (udp_check (ptr + 4, len - 4)); + + case DLT_EN10MB: + eptr = (struct ether_header *) ptr; + if (ntohs (eptr->ether_type) != ETHERTYPE_IP) + err_quit ("Ethernet type %x not IP", ntohs (eptr->ether_type)); + return (udp_check (ptr + 14, len - 14)); + + case DLT_SLIP: /* SLIP header = 24 bytes */ + return (udp_check (ptr + 24, len - 24)); + + case DLT_PPP: /* PPP header = 24 bytes */ + return (udp_check (ptr + 24, len - 24)); + + default: + err_quit ("unsupported data link (%d)", datalink); + } + } +} +/* end udp_read */ + +/* + * Check the received packet. + * If UDP and OK, return pointer to packet. + * If ICMP error, return NULL. + * We assume the filter picks out desired UDP datagrams. + */ + +/* include udp_check */ +struct udpiphdr * +udp_check (char *ptr, int len) +{ + int hlen; + struct ip *ip; + struct udpiphdr *ui; + + if (len < sizeof (struct ip) + sizeof (struct udphdr)) + err_quit ("len = %d", len); + + /* minimal verification of IP header */ + ip = (struct ip *) ptr; + if (ip->ip_v != IPVERSION) + err_quit ("ip_v = %d", ip->ip_v); + hlen = ip->ip_hl << 2; + if (hlen < sizeof (struct ip)) + err_quit ("ip_hl = %d", ip->ip_hl); + if (len < hlen + sizeof (struct udphdr)) + err_quit ("len = %d, hlen = %d", len, hlen); + + if ((ip->ip_sum = in_cksum ((u_short *) ip, hlen)) != 0) + err_quit ("ip checksum error"); + + if (ip->ip_p == IPPROTO_UDP) + { + ui = (struct udpiphdr *) ip; + return (ui); + } + else + err_quit ("not a UDP packet"); +} +/* end udp_check */ diff --git a/udpcksum/udpread.lc b/udpcksum/udpread.lc new file mode 100644 index 0000000..c5eb376 --- /dev/null +++ b/udpcksum/udpread.lc @@ -0,0 +1,81 @@ +#include "udpcksum.h"## 1 ##src/udpcksum/udpread.c## + +struct udpiphdr *udp_check(char *, int);## 2 ##src/udpcksum/udpread.c## + +/*## 3 ##src/udpcksum/udpread.c## + * Read from the network until a UDP datagram is read that matches## 4 ##src/udpcksum/udpread.c## + * the arguments.## 5 ##src/udpcksum/udpread.c## + */## 6 ##src/udpcksum/udpread.c## + +/* include udp_read */ +struct udpiphdr *## 7 ##src/udpcksum/udpread.c## +udp_read(void)## 8 ##src/udpcksum/udpread.c## +{## 9 ##src/udpcksum/udpread.c## + int len;## 10 ##src/udpcksum/udpread.c## + char *ptr;## 11 ##src/udpcksum/udpread.c## + struct ether_header *eptr;## 12 ##src/udpcksum/udpread.c## + + for (;;) {## 13 ##src/udpcksum/udpread.c## + ptr = next_pcap(&len);## 14 ##src/udpcksum/udpread.c## + + switch (datalink) {## 15 ##src/udpcksum/udpread.c## + case DLT_NULL: /* loopback header = 4 bytes */## 16 ##src/udpcksum/udpread.c## + return (udp_check(ptr + 4, len - 4));## 17 ##src/udpcksum/udpread.c## + + case DLT_EN10MB:## 18 ##src/udpcksum/udpread.c## + eptr = (struct ether_header *) ptr;## 19 ##src/udpcksum/udpread.c## + if (ntohs(eptr->ether_type) != ETHERTYPE_IP)## 20 ##src/udpcksum/udpread.c## + err_quit("Ethernet type %x not IP", ntohs(eptr->ether_type));## 21 ##src/udpcksum/udpread.c## + return (udp_check(ptr + 14, len - 14));## 22 ##src/udpcksum/udpread.c## + + case DLT_SLIP: /* SLIP header = 24 bytes */## 23 ##src/udpcksum/udpread.c## + return (udp_check(ptr + 24, len - 24));## 24 ##src/udpcksum/udpread.c## + + case DLT_PPP: /* PPP header = 24 bytes */## 25 ##src/udpcksum/udpread.c## + return (udp_check(ptr + 24, len - 24));## 26 ##src/udpcksum/udpread.c## + + default:## 27 ##src/udpcksum/udpread.c## + err_quit("unsupported datalink (%d)", datalink);## 28 ##src/udpcksum/udpread.c## + }## 29 ##src/udpcksum/udpread.c## + }## 30 ##src/udpcksum/udpread.c## +}## 31 ##src/udpcksum/udpread.c## +/* end udp_read */ + +/*## 32 ##src/udpcksum/udpread.c## + * Check the received packet.## 33 ##src/udpcksum/udpread.c## + * If UDP and OK, return pointer to packet.## 34 ##src/udpcksum/udpread.c## + * If ICMP error, return NULL.## 35 ##src/udpcksum/udpread.c## + * We assume the filter picks out desired UDP datagrams.## 36 ##src/udpcksum/udpread.c## + */## 37 ##src/udpcksum/udpread.c## + +/* include udp_check */ +struct udpiphdr *## 38 ##src/udpcksum/udpread.c## +udp_check(char *ptr, int len)## 39 ##src/udpcksum/udpread.c## +{## 40 ##src/udpcksum/udpread.c## + int hlen;## 41 ##src/udpcksum/udpread.c## + struct ip *ip;## 42 ##src/udpcksum/udpread.c## + struct udpiphdr *ui;## 43 ##src/udpcksum/udpread.c## + + if (len < sizeof(struct ip) + sizeof(struct udphdr))## 44 ##src/udpcksum/udpread.c## + err_quit("len = %d", len);## 45 ##src/udpcksum/udpread.c## + + /* 4minimal verification of IP header */## 46 ##src/udpcksum/udpread.c## + ip = (struct ip *) ptr;## 47 ##src/udpcksum/udpread.c## + if (ip->ip_v != IPVERSION)## 48 ##src/udpcksum/udpread.c## + err_quit("ip_v = %d", ip->ip_v);## 49 ##src/udpcksum/udpread.c## + hlen = ip->ip_hl << 2;## 50 ##src/udpcksum/udpread.c## + if (hlen < sizeof(struct ip))## 51 ##src/udpcksum/udpread.c## + err_quit("ip_hl = %d", ip->ip_hl);## 52 ##src/udpcksum/udpread.c## + if (len < hlen + sizeof(struct udphdr))## 53 ##src/udpcksum/udpread.c## + err_quit("len = %d, hlen = %d", len, hlen);## 54 ##src/udpcksum/udpread.c## + + if ((ip->ip_sum = in_cksum((uint16_t *) ip, hlen)) != 0)## 55 ##src/udpcksum/udpread.c## + err_quit("ip checksum error");## 56 ##src/udpcksum/udpread.c## + + if (ip->ip_p == IPPROTO_UDP) {## 57 ##src/udpcksum/udpread.c## + ui = (struct udpiphdr *) ip;## 58 ##src/udpcksum/udpread.c## + return (ui);## 59 ##src/udpcksum/udpread.c## + } else## 60 ##src/udpcksum/udpread.c## + err_quit("not a UDP packet");## 61 ##src/udpcksum/udpread.c## +}## 62 ##src/udpcksum/udpread.c## +/* end udp_check */ diff --git a/udpcksum/udpwrite.c b/udpcksum/udpwrite.c new file mode 100644 index 0000000..0329aec --- /dev/null +++ b/udpcksum/udpwrite.c @@ -0,0 +1,74 @@ +#include "udpcksum.h" + +/* include open_output_raw */ +int rawfd; /* raw socket to write on */ + +void +open_output(void) +{ + int on=1; + /* + * Need a raw socket to write our own IP datagrams to. + * Process must have superuser privileges to create this socket. + * Also must set IP_HDRINCL so we can write our own IP headers. + */ + + rawfd = Socket(dest->sa_family, SOCK_RAW, 0); + + Setsockopt(rawfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)); +} +/* end open_output_raw */ + +/* + * "buf" points to an empty IP/UDP header, + * followed by "ulen" bytes of user data. + */ + +/* include udp_write */ +void +udp_write(char *buf, int userlen) +{ + struct udpiphdr *ui; + struct ip *ip; + + /* 4fill in and checksum UDP header */ + ip = (struct ip *) buf; + ui = (struct udpiphdr *) buf; + bzero(ui, sizeof(*ui)); + /* 8add 8 to userlen for pseudoheader length */ + ui->ui_len = htons((uint16_t) (sizeof(struct udphdr) + userlen)); + /* 8then add 28 for IP datagram length */ + userlen += sizeof(struct udpiphdr); + + ui->ui_pr = IPPROTO_UDP; + ui->ui_src.s_addr = ((struct sockaddr_in *) local)->sin_addr.s_addr; + ui->ui_dst.s_addr = ((struct sockaddr_in *) dest)->sin_addr.s_addr; + ui->ui_sport = ((struct sockaddr_in *) local)->sin_port; + ui->ui_dport = ((struct sockaddr_in *) dest)->sin_port; + ui->ui_ulen = ui->ui_len; + if (zerosum == 0) { +#if 1 /* change to if 0 for Solaris 2.x, x < 6 */ + if ( (ui->ui_sum = in_cksum((u_int16_t *) ui, userlen)) == 0) + ui->ui_sum = 0xffff; +#else + ui->ui_sum = ui->ui_len; +#endif + } + + /* 4fill in rest of IP header; */ + /* 4ip_output() calcuates & stores IP header checksum */ + ip->ip_v = IPVERSION; + ip->ip_hl = sizeof(struct ip) >> 2; + ip->ip_tos = 0; +#if defined(linux) || defined(__OpenBSD__) + ip->ip_len = htons(userlen); /* network byte order */ +#else + ip->ip_len = userlen; /* host byte order */ +#endif + ip->ip_id = 0; /* let IP set this */ + ip->ip_off = 0; /* frag offset, MF and DF flags */ + ip->ip_ttl = TTL_OUT; + + Sendto(rawfd, buf, userlen, 0, dest, destlen); +} +/* end udp_write */ diff --git a/udpcksum/udpwrite.lc b/udpcksum/udpwrite.lc new file mode 100644 index 0000000..7da7a30 --- /dev/null +++ b/udpcksum/udpwrite.lc @@ -0,0 +1,74 @@ +#include "udpcksum.h"## 1 ##src/udpcksum/udpwrite.c## + +/* include open_output_raw */ +int rawfd; /* raw socket to write on */## 2 ##src/udpcksum/udpwrite.c## + +void## 3 ##src/udpcksum/udpwrite.c## +open_output(void)## 4 ##src/udpcksum/udpwrite.c## +{## 5 ##src/udpcksum/udpwrite.c## + int on = 1;## 6 ##src/udpcksum/udpwrite.c## + /* ## 7 ##src/udpcksum/udpwrite.c## + * Need a raw socket to write our own IP datagrams to.## 8 ##src/udpcksum/udpwrite.c## + * Process must have superuser privileges to create this socket.## 9 ##src/udpcksum/udpwrite.c## + * Also must set IP_HDRINCL so we can write our own IP headers.## 10 ##src/udpcksum/udpwrite.c## + */## 11 ##src/udpcksum/udpwrite.c## + + rawfd = Socket(dest->sa_family, SOCK_RAW, 0);## 12 ##src/udpcksum/udpwrite.c## + + Setsockopt(rawfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on));## 13 ##src/udpcksum/udpwrite.c## +}## 14 ##src/udpcksum/udpwrite.c## +/* end open_output_raw */ + +/*## 15 ##src/udpcksum/udpwrite.c## + * "buf" points to an empty IP/UDP header,## 16 ##src/udpcksum/udpwrite.c## + * followed by "ulen" bytes of user data.## 17 ##src/udpcksum/udpwrite.c## + */## 18 ##src/udpcksum/udpwrite.c## + +/* include udp_write */ +void## 19 ##src/udpcksum/udpwrite.c## +udp_write(char *buf, int userlen)## 20 ##src/udpcksum/udpwrite.c## +{## 21 ##src/udpcksum/udpwrite.c## + struct udpiphdr *ui;## 22 ##src/udpcksum/udpwrite.c## + struct ip *ip;## 23 ##src/udpcksum/udpwrite.c## + + /* 4Fill in and checksum UDP header */## 24 ##src/udpcksum/udpwrite.c## + ip = (struct ip *) buf;## 25 ##src/udpcksum/udpwrite.c## + ui = (struct udpiphdr *) buf;## 26 ##src/udpcksum/udpwrite.c## + bzero(ui, sizeof(*ui));## 27 ##src/udpcksum/udpwrite.c## + /* 8add 8 to userlen for pseudo-header length */## 28 ##src/udpcksum/udpwrite.c## + ui->ui_len = htons((uint16_t) (sizeof(struct udphdr) + userlen));## 29 ##src/udpcksum/udpwrite.c## + /* 8then add 28 for IP datagram length */## 30 ##src/udpcksum/udpwrite.c## + userlen += sizeof(struct udpiphdr);## 31 ##src/udpcksum/udpwrite.c## + + ui->ui_pr = IPPROTO_UDP;## 32 ##src/udpcksum/udpwrite.c## + ui->ui_src.s_addr = ((struct sockaddr_in *) local)->sin_addr.s_addr;## 33 ##src/udpcksum/udpwrite.c## + ui->ui_dst.s_addr = ((struct sockaddr_in *) dest)->sin_addr.s_addr;## 34 ##src/udpcksum/udpwrite.c## + ui->ui_sport = ((struct sockaddr_in *) local)->sin_port;## 35 ##src/udpcksum/udpwrite.c## + ui->ui_dport = ((struct sockaddr_in *) dest)->sin_port;## 36 ##src/udpcksum/udpwrite.c## + ui->ui_ulen = ui->ui_len;## 37 ##src/udpcksum/udpwrite.c## + if (zerosum == 0) {## 38 ##src/udpcksum/udpwrite.c## +#if 1 /* change to if 0 for Solaris 2.x, x < 6 */## 39 ##src/udpcksum/udpwrite.c## + if ((ui->ui_sum = in_cksum((u_int16_t *) ui, userlen)) == 0)## 40 ##src/udpcksum/udpwrite.c## + ui->ui_sum = 0xffff;## 41 ##src/udpcksum/udpwrite.c## +#else## 42 ##src/udpcksum/udpwrite.c## + ui->ui_sum = ui->ui_len;## 43 ##src/udpcksum/udpwrite.c## +#endif## 44 ##src/udpcksum/udpwrite.c## + }## 45 ##src/udpcksum/udpwrite.c## + + /* 4Fill in rest of IP header; */## 46 ##src/udpcksum/udpwrite.c## + /* 4ip_output() calcuates & stores IP header checksum */## 47 ##src/udpcksum/udpwrite.c## + ip->ip_v = IPVERSION;## 48 ##src/udpcksum/udpwrite.c## + ip->ip_hl = sizeof(struct ip) >> 2;## 49 ##src/udpcksum/udpwrite.c## + ip->ip_tos = 0;## 50 ##src/udpcksum/udpwrite.c## +#if defined(linux) || defined(__OpenBSD__)## 51 ##src/udpcksum/udpwrite.c## + ip->ip_len = htons(userlen); /* network byte order */## 52 ##src/udpcksum/udpwrite.c## +#else## 53 ##src/udpcksum/udpwrite.c## + ip->ip_len = userlen; /* host byte order */## 54 ##src/udpcksum/udpwrite.c## +#endif## 55 ##src/udpcksum/udpwrite.c## + ip->ip_id = 0; /* let IP set this */## 56 ##src/udpcksum/udpwrite.c## + ip->ip_off = 0; /* frag offset, MF and DF flags */## 57 ##src/udpcksum/udpwrite.c## + ip->ip_ttl = TTL_OUT;## 58 ##src/udpcksum/udpwrite.c## + + Sendto(rawfd, buf, userlen, 0, dest, destlen);## 59 ##src/udpcksum/udpwrite.c## +}## 60 ##src/udpcksum/udpwrite.c## +/* end udp_write */ diff --git a/udpcliserv/Makefile b/udpcliserv/Makefile new file mode 100644 index 0000000..bdded3b --- /dev/null +++ b/udpcliserv/Makefile @@ -0,0 +1,49 @@ +include ../Make.defines + +PROGS = udpcli01 udpserv01 udpcli02 udpcli03 udpcli04 \ + udpcli06 udpserv06 udpserv07 udpcli08 udpcli09 udpcli10 \ + udpservselect01 + +all: ${PROGS} + +udpcli01: udpcli01.o + ${CC} ${CFLAGS} -o $@ udpcli01.o ${LIBS} + +udpserv01: udpserv01.o + ${CC} ${CFLAGS} -o $@ udpserv01.o ${LIBS} + +udpcli02: udpcli02.o dgcliaddr.o + ${CC} ${CFLAGS} -o $@ udpcli02.o dgcliaddr.o ${LIBS} + +udpcli03: udpcli03.o dgcliinetaddr.o + ${CC} ${CFLAGS} -o $@ udpcli03.o dgcliinetaddr.o ${LIBS} + +udpcli04: udpcli04.o dgcliconnect.o + ${CC} ${CFLAGS} -o $@ udpcli04.o dgcliconnect.o ${LIBS} + +udpcli06: udpcli06.o dgcliloop1.o + ${CC} ${CFLAGS} -o $@ udpcli06.o dgcliloop1.o ${LIBS} + +udpserv06: udpserv06.o dgecholoop1.o + ${CC} ${CFLAGS} -o $@ udpserv06.o dgecholoop1.o ${LIBS} + +udpcli07: udpcli07.o dgcliloop2.o + ${CC} ${CFLAGS} -o $@ udpcli07.o dgcliloop2.o ${LIBS} + +udpserv07: udpserv07.o dgecholoop2.o + ${CC} ${CFLAGS} -o $@ udpserv07.o dgecholoop2.o ${LIBS} + +udpcli08: udpcli08.o dgcliloop3.o + ${CC} ${CFLAGS} -o $@ udpcli08.o dgcliloop3.o ${LIBS} + +udpcli09: udpcli09.o + ${CC} ${CFLAGS} -o $@ udpcli09.o ${LIBS} + +udpcli10: udpcli10.o dgclibig.o + ${CC} ${CFLAGS} -o $@ udpcli10.o dgclibig.o ${LIBS} + +udpservselect01: udpservselect01.o sigchldwaitpid.o + ${CC} ${CFLAGS} -o $@ udpservselect01.o sigchldwaitpid.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/udpcliserv/dgcliaddr.c b/udpcliserv/dgcliaddr.c new file mode 100644 index 0000000..b037ac9 --- /dev/null +++ b/udpcliserv/dgcliaddr.c @@ -0,0 +1,28 @@ +#include "unp.h" + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + socklen_t len; + struct sockaddr *preply_addr; + + preply_addr = Malloc(servlen); + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + len = servlen; + n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len); + if (len != servlen || memcmp(pservaddr, preply_addr, len) != 0) { + printf("reply from %s (ignored)\n", + Sock_ntop(preply_addr, len)); + continue; + } + + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } +} diff --git a/udpcliserv/dgclibig.c b/udpcliserv/dgclibig.c new file mode 100644 index 0000000..a425151 --- /dev/null +++ b/udpcliserv/dgclibig.c @@ -0,0 +1,22 @@ +#include "unp.h" + +#undef MAXLINE +#define MAXLINE 65507 + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int size; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + ssize_t n; + + size = 70000; + Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); + Setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); + + Sendto(sockfd, sendline, MAXLINE, 0, pservaddr, servlen); + + n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL); + + printf("received %d bytes\n", n); +} diff --git a/udpcliserv/dgclibig.lc b/udpcliserv/dgclibig.lc new file mode 100644 index 0000000..931401f --- /dev/null +++ b/udpcliserv/dgclibig.lc @@ -0,0 +1,22 @@ +#include "unp.h"## 1 ##src/udpcliserv/dgclibig.c## + +#undef MAXLINE## 2 ##src/udpcliserv/dgclibig.c## +#define MAXLINE 65507## 3 ##src/udpcliserv/dgclibig.c## + +void## 4 ##src/udpcliserv/dgclibig.c## +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)## 5 ##src/udpcliserv/dgclibig.c## +{## 6 ##src/udpcliserv/dgclibig.c## + int size;## 7 ##src/udpcliserv/dgclibig.c## + char sendline[MAXLINE], recvline[MAXLINE + 1];## 8 ##src/udpcliserv/dgclibig.c## + ssize_t n;## 9 ##src/udpcliserv/dgclibig.c## + + size = 70000;## 10 ##src/udpcliserv/dgclibig.c## + Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));## 11 ##src/udpcliserv/dgclibig.c## + Setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));## 12 ##src/udpcliserv/dgclibig.c## + + Sendto(sockfd, sendline, MAXLINE, 0, pservaddr, servlen);## 13 ##src/udpcliserv/dgclibig.c## + + n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);## 14 ##src/udpcliserv/dgclibig.c## + + printf("received %d bytes\n", n);## 15 ##src/udpcliserv/dgclibig.c## +}## 16 ##src/udpcliserv/dgclibig.c## diff --git a/udpcliserv/dgcliconnect.c b/udpcliserv/dgcliconnect.c new file mode 100644 index 0000000..a65b24a --- /dev/null +++ b/udpcliserv/dgcliconnect.c @@ -0,0 +1,20 @@ +#include "unp.h" + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + + Connect(sockfd, (SA *) pservaddr, servlen); + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Write(sockfd, sendline, strlen(sendline)); + + n = Read(sockfd, recvline, MAXLINE); + + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } +} diff --git a/udpcliserv/dgcliconnect.lc b/udpcliserv/dgcliconnect.lc new file mode 100644 index 0000000..6dc4026 --- /dev/null +++ b/udpcliserv/dgcliconnect.lc @@ -0,0 +1,20 @@ +#include "unp.h"## 1 ##src/udpcliserv/dgcliconnect.c## + +void## 2 ##src/udpcliserv/dgcliconnect.c## +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)## 3 ##src/udpcliserv/dgcliconnect.c## +{## 4 ##src/udpcliserv/dgcliconnect.c## + int n;## 5 ##src/udpcliserv/dgcliconnect.c## + char sendline[MAXLINE], recvline[MAXLINE + 1];## 6 ##src/udpcliserv/dgcliconnect.c## + + Connect(sockfd, (SA *) pservaddr, servlen);## 7 ##src/udpcliserv/dgcliconnect.c## + + while (Fgets(sendline, MAXLINE, fp) != NULL) {## 8 ##src/udpcliserv/dgcliconnect.c## + + Write(sockfd, sendline, strlen(sendline));## 9 ##src/udpcliserv/dgcliconnect.c## + + n = Read(sockfd, recvline, MAXLINE);## 10 ##src/udpcliserv/dgcliconnect.c## + + recvline[n] = 0; /* null terminate */## 11 ##src/udpcliserv/dgcliconnect.c## + Fputs(recvline, stdout);## 12 ##src/udpcliserv/dgcliconnect.c## + }## 13 ##src/udpcliserv/dgcliconnect.c## +}## 14 ##src/udpcliserv/dgcliconnect.c## diff --git a/udpcliserv/dgcliinetaddr.c b/udpcliserv/dgcliinetaddr.c new file mode 100644 index 0000000..b79b3a9 --- /dev/null +++ b/udpcliserv/dgcliinetaddr.c @@ -0,0 +1,25 @@ +#include "unp.h" + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int n; + char sendline[MAXLINE], recvline[MAXLINE + 1]; + socklen_t len; + struct sockaddr_in *replyaddr; + + replyaddr = Malloc(servlen); + + while (Fgets(sendline, MAXLINE, fp) != NULL) { + + Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); + + len = servlen; + n = Recvfrom(sockfd, recvline, MAXLINE, 0, (SA *) replyaddr, &len); + printf("received reply from %s, port %d\n", + inet_ntoa(replyaddr->sin_addr), htons(replyaddr->sin_port)); + + recvline[n] = 0; /* null terminate */ + Fputs(recvline, stdout); + } +} diff --git a/udpcliserv/dgcliloop1.c b/udpcliserv/dgcliloop1.c new file mode 100644 index 0000000..cb5ce4b --- /dev/null +++ b/udpcliserv/dgcliloop1.c @@ -0,0 +1,15 @@ +#include "unp.h" + +#define NDG 2000 /* datagrams to send */ +#define DGLEN 1400 /* length of each datagram */ + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int i; + char sendline[DGLEN]; + + for (i = 0; i < NDG; i++) { + Sendto(sockfd, sendline, DGLEN, 0, pservaddr, servlen); + } +} diff --git a/udpcliserv/dgcliloop3.c b/udpcliserv/dgcliloop3.c new file mode 100644 index 0000000..85567f1 --- /dev/null +++ b/udpcliserv/dgcliloop3.c @@ -0,0 +1,21 @@ +#include "unp.h" + +/* Try and get ENOBUFS from sendto() by sending huge datagrams. + But I still cannot get the error. */ + +#define NDG 2000 /* datagrams to send */ +#define DGLEN 65507 /* length of each datagram */ + +void +dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) +{ + int i, n; + char sendline[DGLEN]; + + n = 100 * 1024; + Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n)); + + for (i = 0; i < NDG; i++) { + Sendto(sockfd, sendline, DGLEN, 0, pservaddr, servlen); + } +} diff --git a/udpcliserv/dgecholoop1.c b/udpcliserv/dgecholoop1.c new file mode 100644 index 0000000..c9b900b --- /dev/null +++ b/udpcliserv/dgecholoop1.c @@ -0,0 +1,27 @@ +#include "unp.h" + +static void recvfrom_int(int); +static int count; + +void +dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen) +{ + socklen_t len; + char mesg[MAXLINE]; + + Signal(SIGINT, recvfrom_int); + + for ( ; ; ) { + len = clilen; + Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len); + + count++; + } +} + +static void +recvfrom_int(int signo) +{ + printf("\nreceived %d datagrams\n", count); + exit(0); +} diff --git a/udpcliserv/dgecholoop2.c b/udpcliserv/dgecholoop2.c new file mode 100644 index 0000000..c94b49e --- /dev/null +++ b/udpcliserv/dgecholoop2.c @@ -0,0 +1,31 @@ +#include "unp.h" + +static void recvfrom_int(int); +static int count; + +void +dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen) +{ + int n; + socklen_t len; + char mesg[MAXLINE]; + + Signal(SIGINT, recvfrom_int); + + n = 220 * 1024; + Setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)); + + for ( ; ; ) { + len = clilen; + Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len); + + count++; + } +} + +static void +recvfrom_int(int signo) +{ + printf("\nreceived %d datagrams\n", count); + exit(0); +} diff --git a/udpcliserv/dgecholoop2.lc b/udpcliserv/dgecholoop2.lc new file mode 100644 index 0000000..f0b39de --- /dev/null +++ b/udpcliserv/dgecholoop2.lc @@ -0,0 +1,31 @@ +#include "unp.h"## 1 ##src/udpcliserv/dgecholoop2.c## + +static void recvfrom_int(int);## 2 ##src/udpcliserv/dgecholoop2.c## +static int count;## 3 ##src/udpcliserv/dgecholoop2.c## + +void## 4 ##src/udpcliserv/dgecholoop2.c## +dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)## 5 ##src/udpcliserv/dgecholoop2.c## +{## 6 ##src/udpcliserv/dgecholoop2.c## + int n;## 7 ##src/udpcliserv/dgecholoop2.c## + socklen_t len;## 8 ##src/udpcliserv/dgecholoop2.c## + char mesg[MAXLINE];## 9 ##src/udpcliserv/dgecholoop2.c## + + Signal(SIGINT, recvfrom_int);## 10 ##src/udpcliserv/dgecholoop2.c## + + n = 240 * 1024;## 11 ##src/udpcliserv/dgecholoop2.c## + Setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n));## 12 ##src/udpcliserv/dgecholoop2.c## + + for (;;) {## 13 ##src/udpcliserv/dgecholoop2.c## + len = clilen;## 14 ##src/udpcliserv/dgecholoop2.c## + Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);## 15 ##src/udpcliserv/dgecholoop2.c## + + count++;## 16 ##src/udpcliserv/dgecholoop2.c## + }## 17 ##src/udpcliserv/dgecholoop2.c## +}## 18 ##src/udpcliserv/dgecholoop2.c## + +static void## 19 ##src/udpcliserv/dgecholoop2.c## +recvfrom_int(int signo)## 20 ##src/udpcliserv/dgecholoop2.c## +{## 21 ##src/udpcliserv/dgecholoop2.c## + printf("\nreceived %d datagrams\n", count);## 22 ##src/udpcliserv/dgecholoop2.c## + exit(0);## 23 ##src/udpcliserv/dgecholoop2.c## +}## 24 ##src/udpcliserv/dgecholoop2.c## diff --git a/udpcliserv/sigchldwaitpid.c b/udpcliserv/sigchldwaitpid.c new file mode 100644 index 0000000..12b5ff3 --- /dev/null +++ b/udpcliserv/sigchldwaitpid.c @@ -0,0 +1,12 @@ +#include "unp.h" + +void +sig_chld(int signo) +{ + pid_t pid; + int stat; + + while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) + printf("child %d terminated\n", pid); + return; +} diff --git a/udpcliserv/udpcli01.c b/udpcliserv/udpcli01.c new file mode 100644 index 0000000..1d5a5d9 --- /dev/null +++ b/udpcliserv/udpcli01.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/udpcliserv/udpcli02.c b/udpcliserv/udpcli02.c new file mode 100644 index 0000000..71b4175 --- /dev/null +++ b/udpcliserv/udpcli02.c @@ -0,0 +1,25 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli "); + + bzero(&servaddr, sizeof(servaddr)); +#ifdef HAVE_SOCKADDR_SA_LEN + servaddr.sin_len = sizeof(servaddr); +#endif + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(7); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/udpcliserv/udpcli03.c b/udpcliserv/udpcli03.c new file mode 100644 index 0000000..01beb88 --- /dev/null +++ b/udpcliserv/udpcli03.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(7); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/udpcliserv/udpcli04.c b/udpcliserv/udpcli04.c new file mode 100644 index 0000000..1d5a5d9 --- /dev/null +++ b/udpcliserv/udpcli04.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/udpcliserv/udpcli05.c b/udpcliserv/udpcli05.c new file mode 100644 index 0000000..44c1113 --- /dev/null +++ b/udpcliserv/udpcli05.c @@ -0,0 +1,28 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + bzero(&cliaddr, sizeof(cliaddr)); + cliaddr.sin_family = AF_INET; + cliaddr.sin_addr.s_addr = htonl(INADDR_ANY); + cliaddr.sin_port = htons(0); /* force assignment of ephemeral port */ + Bind(sockfd, (SA *) &cliaddr, sizeof(cliaddr)); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/udpcliserv/udpcli06.c b/udpcliserv/udpcli06.c new file mode 100644 index 0000000..1d5a5d9 --- /dev/null +++ b/udpcliserv/udpcli06.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/udpcliserv/udpcli08.c b/udpcliserv/udpcli08.c new file mode 100644 index 0000000..a37ff30 --- /dev/null +++ b/udpcliserv/udpcli08.c @@ -0,0 +1,22 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + + if (argc != 2) + err_quit("usage: udpcli "); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(9); /* discard server */ + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/udpcliserv/udpcli09.c b/udpcliserv/udpcli09.c new file mode 100644 index 0000000..b5d3deb --- /dev/null +++ b/udpcliserv/udpcli09.c @@ -0,0 +1,27 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + socklen_t len; + struct sockaddr_in cliaddr, servaddr; + + if (argc != 2) + err_quit("usage: udpcli "); + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + len = sizeof(cliaddr); + Getsockname(sockfd, (SA *) &cliaddr, &len); + printf("local address %s\n", Sock_ntop((SA *) &cliaddr, len)); + + exit(0); +} diff --git a/udpcliserv/udpcli10.c b/udpcliserv/udpcli10.c new file mode 100644 index 0000000..634b894 --- /dev/null +++ b/udpcliserv/udpcli10.c @@ -0,0 +1,18 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + socklen_t salen; + struct sockaddr *sa; + + if (argc != 3) + err_quit("usage: udpcli02 "); + + sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen); + + dg_cli(stdin, sockfd, sa, salen); + + exit(0); +} diff --git a/udpcliserv/udpserv01.c b/udpcliserv/udpserv01.c new file mode 100644 index 0000000..a21a857 --- /dev/null +++ b/udpcliserv/udpserv01.c @@ -0,0 +1,19 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr, cliaddr; + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr)); +} diff --git a/udpcliserv/udpserv06.c b/udpcliserv/udpserv06.c new file mode 100644 index 0000000..a21a857 --- /dev/null +++ b/udpcliserv/udpserv06.c @@ -0,0 +1,19 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr, cliaddr; + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr)); +} diff --git a/udpcliserv/udpserv07.c b/udpcliserv/udpserv07.c new file mode 100644 index 0000000..a21a857 --- /dev/null +++ b/udpcliserv/udpserv07.c @@ -0,0 +1,19 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr, cliaddr; + + sockfd = Socket(AF_INET, SOCK_DGRAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr)); +} diff --git a/udpcliserv/udpservselect01.c b/udpcliserv/udpservselect01.c new file mode 100644 index 0000000..4aedf8a --- /dev/null +++ b/udpcliserv/udpservselect01.c @@ -0,0 +1,76 @@ +/* include udpservselect01 */ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd, udpfd, nready, maxfdp1; + char mesg[MAXLINE]; + pid_t childpid; + fd_set rset; + ssize_t n; + socklen_t len; + const int on = 1; + struct sockaddr_in cliaddr, servaddr; + void sig_chld(int); + + /* 4create listening TCP socket */ + listenfd = Socket(AF_INET, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + /* 4create UDP socket */ + udpfd = Socket(AF_INET, SOCK_DGRAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(SERV_PORT); + + Bind(udpfd, (SA *) &servaddr, sizeof(servaddr)); +/* end udpservselect01 */ + +/* include udpservselect02 */ + Signal(SIGCHLD, sig_chld); /* must call waitpid() */ + + FD_ZERO(&rset); + maxfdp1 = max(listenfd, udpfd) + 1; + for ( ; ; ) { + FD_SET(listenfd, &rset); + FD_SET(udpfd, &rset); + if ( (nready = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) { + if (errno == EINTR) + continue; /* back to for() */ + else + err_sys("select error"); + } + + if (FD_ISSET(listenfd, &rset)) { + len = sizeof(cliaddr); + connfd = Accept(listenfd, (SA *) &cliaddr, &len); + + if ( (childpid = Fork()) == 0) { /* child process */ + Close(listenfd); /* close listening socket */ + str_echo(connfd); /* process the request */ + exit(0); + } + Close(connfd); /* parent closes connected socket */ + } + + if (FD_ISSET(udpfd, &rset)) { + len = sizeof(cliaddr); + n = Recvfrom(udpfd, mesg, MAXLINE, 0, (SA *) &cliaddr, &len); + + Sendto(udpfd, mesg, n, 0, (SA *) &cliaddr, len); + } + } +} +/* end udpservselect02 */ diff --git a/udpcliserv/udpservselect01.lc b/udpcliserv/udpservselect01.lc new file mode 100644 index 0000000..3d58628 --- /dev/null +++ b/udpcliserv/udpservselect01.lc @@ -0,0 +1,76 @@ +/* include udpservselect01 */ +#include "unp.h"## 1 ##src/udpcliserv/udpservselect01.c## + +int## 2 ##src/udpcliserv/udpservselect01.c## +main(int argc, char **argv)## 3 ##src/udpcliserv/udpservselect01.c## +{## 4 ##src/udpcliserv/udpservselect01.c## + int listenfd, connfd, udpfd, nready, maxfdp1;## 5 ##src/udpcliserv/udpservselect01.c## + char mesg[MAXLINE];## 6 ##src/udpcliserv/udpservselect01.c## + pid_t childpid;## 7 ##src/udpcliserv/udpservselect01.c## + fd_set rset;## 8 ##src/udpcliserv/udpservselect01.c## + ssize_t n;## 9 ##src/udpcliserv/udpservselect01.c## + socklen_t len;## 10 ##src/udpcliserv/udpservselect01.c## + const int on = 1;## 11 ##src/udpcliserv/udpservselect01.c## + struct sockaddr_in cliaddr, servaddr;## 12 ##src/udpcliserv/udpservselect01.c## + void sig_chld(int);## 13 ##src/udpcliserv/udpservselect01.c## + + /* 4create listening TCP socket */## 14 ##src/udpcliserv/udpservselect01.c## + listenfd = Socket(AF_INET, SOCK_STREAM, 0);## 15 ##src/udpcliserv/udpservselect01.c## + + bzero(&servaddr, sizeof(servaddr));## 16 ##src/udpcliserv/udpservselect01.c## + servaddr.sin_family = AF_INET;## 17 ##src/udpcliserv/udpservselect01.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 18 ##src/udpcliserv/udpservselect01.c## + servaddr.sin_port = htons(SERV_PORT);## 19 ##src/udpcliserv/udpservselect01.c## + + Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 20 ##src/udpcliserv/udpservselect01.c## + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));## 21 ##src/udpcliserv/udpservselect01.c## + + Listen(listenfd, LISTENQ);## 22 ##src/udpcliserv/udpservselect01.c## + + /* 4create UDP socket */## 23 ##src/udpcliserv/udpservselect01.c## + udpfd = Socket(AF_INET, SOCK_DGRAM, 0);## 24 ##src/udpcliserv/udpservselect01.c## + + bzero(&servaddr, sizeof(servaddr));## 25 ##src/udpcliserv/udpservselect01.c## + servaddr.sin_family = AF_INET;## 26 ##src/udpcliserv/udpservselect01.c## + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 27 ##src/udpcliserv/udpservselect01.c## + servaddr.sin_port = htons(SERV_PORT);## 28 ##src/udpcliserv/udpservselect01.c## + + Bind(udpfd, (SA *) &servaddr, sizeof(servaddr));## 29 ##src/udpcliserv/udpservselect01.c## +/* end udpservselect01 */ + +/* include udpservselect02 */ + Signal(SIGCHLD, sig_chld); /* must call waitpid() */## 30 ##src/udpcliserv/udpservselect01.c## + + FD_ZERO(&rset);## 31 ##src/udpcliserv/udpservselect01.c## + maxfdp1 = max(listenfd, udpfd) + 1;## 32 ##src/udpcliserv/udpservselect01.c## + for (;;) {## 33 ##src/udpcliserv/udpservselect01.c## + FD_SET(listenfd, &rset);## 34 ##src/udpcliserv/udpservselect01.c## + FD_SET(udpfd, &rset);## 35 ##src/udpcliserv/udpservselect01.c## + if ((nready = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) {## 36 ##src/udpcliserv/udpservselect01.c## + if (errno == EINTR)## 37 ##src/udpcliserv/udpservselect01.c## + continue; /* back to for() */## 38 ##src/udpcliserv/udpservselect01.c## + else## 39 ##src/udpcliserv/udpservselect01.c## + err_sys("select error");## 40 ##src/udpcliserv/udpservselect01.c## + }## 41 ##src/udpcliserv/udpservselect01.c## + + if (FD_ISSET(listenfd, &rset)) {## 42 ##src/udpcliserv/udpservselect01.c## + len = sizeof(cliaddr);## 43 ##src/udpcliserv/udpservselect01.c## + connfd = Accept(listenfd, (SA *) &cliaddr, &len);## 44 ##src/udpcliserv/udpservselect01.c## + + if ((childpid = Fork()) == 0) { /* child process */## 45 ##src/udpcliserv/udpservselect01.c## + Close(listenfd); /* close listening socket */## 46 ##src/udpcliserv/udpservselect01.c## + str_echo(connfd); /* process the request */## 47 ##src/udpcliserv/udpservselect01.c## + exit(0);## 48 ##src/udpcliserv/udpservselect01.c## + }## 49 ##src/udpcliserv/udpservselect01.c## + Close(connfd); /* parent closes connected socket */## 50 ##src/udpcliserv/udpservselect01.c## + }## 51 ##src/udpcliserv/udpservselect01.c## + + if (FD_ISSET(udpfd, &rset)) {## 52 ##src/udpcliserv/udpservselect01.c## + len = sizeof(cliaddr);## 53 ##src/udpcliserv/udpservselect01.c## + n = Recvfrom(udpfd, mesg, MAXLINE, 0, (SA *) &cliaddr, &len);## 54 ##src/udpcliserv/udpservselect01.c## + + Sendto(udpfd, mesg, n, 0, (SA *) &cliaddr, len);## 55 ##src/udpcliserv/udpservselect01.c## + }## 56 ##src/udpcliserv/udpservselect01.c## + }## 57 ##src/udpcliserv/udpservselect01.c## +}## 58 ##src/udpcliserv/udpservselect01.c## +/* end udpservselect02 */ diff --git a/unixdomain/Makefile b/unixdomain/Makefile new file mode 100644 index 0000000..0202967 --- /dev/null +++ b/unixdomain/Makefile @@ -0,0 +1,43 @@ +include ../Make.defines + +PROGS = daytimetcpcli daytimetcpsrv2 mycat openfile \ + tfcred01 unixbind unixstrcli01 unixstrserv01 unixstrserv02 + +all: ${PROGS} + +daytimetcpcli: daytimetcpcli.o + ${CC} ${CFLAGS} -o $@ daytimetcpcli.o ${LIBS} + +daytimetcpsrv2: daytimetcpsrv2.o + ${CC} ${CFLAGS} -o $@ daytimetcpsrv2.o ${LIBS} + +mycat: mycat.o myopen.o + ${CC} ${CFLAGS} -o $@ mycat.o myopen.o ${LIBS} + +openfile: openfile.o + ${CC} ${CFLAGS} -o $@ openfile.o ${LIBS} + +tfcred01: tfcred01.o + ${CC} ${CFLAGS} -o $@ tfcred01.o ${LIBS} + +unixbind: unixbind.o + ${CC} ${CFLAGS} -o $@ unixbind.o ${LIBS} + +unixdgcli01: unixdgcli01.o + ${CC} ${CFLAGS} -o $@ unixdgcli01.o ${LIBS} + +unixdgserv01: unixdgserv01.o + ${CC} ${CFLAGS} -o $@ unixdgserv01.o ${LIBS} + +unixstrcli01: unixstrcli01.o + ${CC} ${CFLAGS} -o $@ unixstrcli01.o ${LIBS} + +unixstrserv01: unixstrserv01.o sigchldwaitpid.o + ${CC} ${CFLAGS} -o $@ unixstrserv01.o sigchldwaitpid.o ${LIBS} + +unixstrserv02: unixstrserv02.o strecho.o sigchldwaitpid.o readcred.o + ${CC} ${CFLAGS} -o $@ unixstrserv02.o strecho.o sigchldwaitpid.o \ + readcred.o ${LIBS} + +clean: + rm -f ${PROGS} ${CLEANFILES} diff --git a/unixdomain/daytimetcpcli.c b/unixdomain/daytimetcpcli.c new file mode 100644 index 0000000..975a9e7 --- /dev/null +++ b/unixdomain/daytimetcpcli.c @@ -0,0 +1,27 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd, n; + char recvline[MAXLINE + 1]; + socklen_t len; + struct sockaddr *sa; + + if (argc != 3) + err_quit("usage: daytimetcpcli "); + + sockfd = Tcp_connect(argv[1], argv[2]); + + sa = Malloc(sizeof(struct sockaddr_storage)); + len = sizeof(struct sockaddr_storage); + Getpeername(sockfd, sa, &len); + printf("connected to %s\n", Sock_ntop_host(sa, len)); + sleep(5); + + while ( (n = Read(sockfd, recvline, MAXLINE)) > 0) { + recvline[n] = 0; /* null terminate */ + printf("%d bytes: %s", n, recvline); + } + exit(0); +} diff --git a/unixdomain/daytimetcpsrv2.c b/unixdomain/daytimetcpsrv2.c new file mode 100644 index 0000000..10c8b82 --- /dev/null +++ b/unixdomain/daytimetcpsrv2.c @@ -0,0 +1,34 @@ +#include "unp.h" +#include + +int +main(int argc, char **argv) +{ + int i, listenfd, connfd; + socklen_t addrlen, len; + struct sockaddr *cliaddr; + char buff[MAXLINE]; + time_t ticks; + + if (argc == 2) + listenfd = Tcp_listen(NULL, argv[1], &addrlen); + else if (argc == 3) + listenfd = Tcp_listen(argv[1], argv[2], &addrlen); + else + err_quit("usage: daytimetcpsrv2 [ ] "); + + cliaddr = Malloc(addrlen); + + for ( ; ; ) { + len = addrlen; + connfd = Accept(listenfd, cliaddr, &len); + printf("connection from %s\n", Sock_ntop(cliaddr, len)); + + ticks = time(NULL); + snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); + for (i = 0; i < strlen(buff); i++) + Send(connfd, &buff[i], 1, MSG_EOR); + + Close(connfd); + } +} diff --git a/unixdomain/mycat.c b/unixdomain/mycat.c new file mode 100644 index 0000000..b9a5720 --- /dev/null +++ b/unixdomain/mycat.c @@ -0,0 +1,21 @@ +#include "unp.h" + +int my_open(const char *, int); + +int +main(int argc, char **argv) +{ + int fd, n; + char buff[BUFFSIZE]; + + if (argc != 2) + err_quit("usage: mycat "); + + if ( (fd = my_open(argv[1], O_RDONLY)) < 0) + err_sys("cannot open %s", argv[1]); + + while ( (n = Read(fd, buff, BUFFSIZE)) > 0) + Write(STDOUT_FILENO, buff, n); + + exit(0); +} diff --git a/unixdomain/mycat.lc b/unixdomain/mycat.lc new file mode 100644 index 0000000..4836627 --- /dev/null +++ b/unixdomain/mycat.lc @@ -0,0 +1,21 @@ +#include "unp.h"## 1 ##src/unixdomain/mycat.c## + +int my_open(const char *, int);## 2 ##src/unixdomain/mycat.c## + +int## 3 ##src/unixdomain/mycat.c## +main(int argc, char **argv)## 4 ##src/unixdomain/mycat.c## +{## 5 ##src/unixdomain/mycat.c## + int fd, n;## 6 ##src/unixdomain/mycat.c## + char buff[BUFFSIZE];## 7 ##src/unixdomain/mycat.c## + + if (argc != 2)## 8 ##src/unixdomain/mycat.c## + err_quit("usage: mycat ");## 9 ##src/unixdomain/mycat.c## + + if ((fd = my_open(argv[1], O_RDONLY)) < 0)## 10 ##src/unixdomain/mycat.c## + err_sys("cannot open %s", argv[1]);## 11 ##src/unixdomain/mycat.c## + + while ((n = Read(fd, buff, BUFFSIZE)) > 0)## 12 ##src/unixdomain/mycat.c## + Write(STDOUT_FILENO, buff, n);## 13 ##src/unixdomain/mycat.c## + + exit(0);## 14 ##src/unixdomain/mycat.c## +}## 15 ##src/unixdomain/mycat.c## diff --git a/unixdomain/myopen.c b/unixdomain/myopen.c new file mode 100644 index 0000000..86c5c44 --- /dev/null +++ b/unixdomain/myopen.c @@ -0,0 +1,36 @@ +#include "unp.h" + +int +my_open(const char *pathname, int mode) +{ + int fd, sockfd[2], status; + pid_t childpid; + char c, argsockfd[10], argmode[10]; + + Socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd); + + if ( (childpid = Fork()) == 0) { /* child process */ + Close(sockfd[0]); + snprintf(argsockfd, sizeof(argsockfd), "%d", sockfd[1]); + snprintf(argmode, sizeof(argmode), "%d", mode); + execl("./openfile", "openfile", argsockfd, pathname, argmode, + (char *) NULL); + err_sys("execl error"); + } + + /* parent process - wait for the child to terminate */ + Close(sockfd[1]); /* close the end we don't use */ + + Waitpid(childpid, &status, 0); + if (WIFEXITED(status) == 0) + err_quit("child did not terminate"); + if ( (status = WEXITSTATUS(status)) == 0) + Read_fd(sockfd[0], &c, 1, &fd); + else { + errno = status; /* set errno value from child's status */ + fd = -1; + } + + Close(sockfd[0]); + return(fd); +} diff --git a/unixdomain/openfile.c b/unixdomain/openfile.c new file mode 100644 index 0000000..c98a1f7 --- /dev/null +++ b/unixdomain/openfile.c @@ -0,0 +1,18 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int fd; + + if (argc != 4) + err_quit("openfile "); + + if ( (fd = open(argv[2], atoi(argv[3]))) < 0) + exit( (errno > 0) ? errno : 255 ); + + if (write_fd(atoi(argv[1]), "", 1, fd) < 0) + exit( (errno > 0) ? errno : 255 ); + + exit(0); +} diff --git a/unixdomain/readcred.c b/unixdomain/readcred.c new file mode 100644 index 0000000..1200ed9 --- /dev/null +++ b/unixdomain/readcred.c @@ -0,0 +1,40 @@ +#include "unp.h" + +#define CONTROL_LEN (sizeof(struct cmsghdr) + sizeof(struct cmsgcred)) + +ssize_t +read_cred(int fd, void *ptr, size_t nbytes, struct cmsgcred *cmsgcredptr) +{ + struct msghdr msg; + struct iovec iov[1]; + char control[CONTROL_LEN]; + int n; + + msg.msg_name = NULL; + msg.msg_namelen = 0; + iov[0].iov_base = ptr; + iov[0].iov_len = nbytes; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + msg.msg_control = control; + msg.msg_controllen = sizeof(control); + msg.msg_flags = 0; + + if ( (n = recvmsg(fd, &msg, 0)) < 0) + return(n); + + cmsgcredptr->cmcred_ngroups = 0; /* indicates no credentials returned */ + if (cmsgcredptr && msg.msg_controllen > 0) { + struct cmsghdr *cmptr = (struct cmsghdr *) control; + + if (cmptr->cmsg_len < CONTROL_LEN) + err_quit("control length = %d", cmptr->cmsg_len); + if (cmptr->cmsg_level != SOL_SOCKET) + err_quit("control level != SOL_SOCKET"); + if (cmptr->cmsg_type != SCM_CREDS) + err_quit("control type != SCM_CREDS"); + memcpy(cmsgcredptr, CMSG_DATA(cmptr), sizeof(struct cmsgcred)); + } + + return(n); +} diff --git a/unixdomain/sigchldwaitpid.c b/unixdomain/sigchldwaitpid.c new file mode 100644 index 0000000..5fa9cbf --- /dev/null +++ b/unixdomain/sigchldwaitpid.c @@ -0,0 +1,13 @@ +#include "unp.h" + +void +sig_chld(int signo) +{ + pid_t pid; + int stat; + + while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) { + printf("child %d terminated\n", pid); + } + return; +} diff --git a/unixdomain/strecho.c b/unixdomain/strecho.c new file mode 100644 index 0000000..0fff58d --- /dev/null +++ b/unixdomain/strecho.c @@ -0,0 +1,34 @@ +#include "unp.h" + +ssize_t read_cred(int, void *, size_t, struct cmsgcred *); + +void +str_echo(int sockfd) +{ + ssize_t n; + int i; + char buf[MAXLINE]; + struct cmsgcred cred; + +again: + while ( (n = read_cred(sockfd, buf, MAXLINE, &cred)) > 0) { + if (cred.cmcred_ngroups == 0) { + printf("(no credentials returned)\n"); + } else { + printf("PID of sender = %d\n", cred.cmcred_pid); + printf("real user ID = %d\n", cred.cmcred_uid); + printf("real group ID = %d\n", cred.cmcred_gid); + printf("effective user ID = %d\n", cred.cmcred_euid); + printf("%d groups:", cred.cmcred_ngroups - 1); + for (i = 1; i < cred.cmcred_ngroups; i++) + printf(" %d", cred.cmcred_groups[i]); + printf("\n"); + } + Writen(sockfd, buf, n); + } + + if (n < 0 && errno == EINTR) + goto again; + else if (n < 0) + err_sys("str_echo: read error"); +} diff --git a/unixdomain/testfcred.c b/unixdomain/testfcred.c new file mode 100644 index 0000000..48568e9 --- /dev/null +++ b/unixdomain/testfcred.c @@ -0,0 +1,10 @@ +#include "unp.h" +#include +#include + +main() +{ + printf("sizeof(struct fcred) = %d\n", sizeof(struct fcred)); + printf("sizeof(struct cmsghdr) = %d\n", sizeof(struct cmsghdr)); + exit(0); +} diff --git a/unixdomain/tfcred01.c b/unixdomain/tfcred01.c new file mode 100644 index 0000000..9204e4e --- /dev/null +++ b/unixdomain/tfcred01.c @@ -0,0 +1,84 @@ +#include "unp.h" +#include +#include + +ssize_t recv_cred(int, void *, size_t, struct fcred *); + +main() +{ + int fd[2], on, n; + char buf[100]; + struct fcred cred; + + if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fd) < 0) + err_sys("socketpair error"); + + /* must set the socket option on the *receiving* socket */ + on = 1; + Setsockopt(fd[1], 0, LOCAL_CREDS, &on, sizeof(on)); + + Write(fd[0], "hello, world\n", 13); + + if ( (n = recv_cred(fd[1], buf, sizeof(buf), &cred)) < 0) + err_sys("recv_cred error"); + else if (n == 0) + err_quit("recv_cred, unexpected EOF"); + + buf[n] = 0; /* null terminate */ + printf("data: %s", buf); + + if (cred.fc_ngroups == 0) + printf("(no credentials returned)\n"); + else { + printf("real user ID = %d\n", cred.fc_ruid); + printf("real group ID = %d\n", cred.fc_rgid); + printf("login name = %-*s\n", MAXLOGNAME, cred.fc_login); + printf("effective user ID = %d\n", cred.fc_uid); + printf("effective group ID = %d\n", cred.fc_gid); + printf("%d supplementary groups:", cred.fc_ngroups - 1); + for (n = 1; n < cred.fc_ngroups; n++) /* [0] is the egid */ + printf(" %d", cred.fc_groups[n]); + printf("\n"); + } + + exit(0); +} + +#define CONTROL_LEN (sizeof(struct cmsghdr) + sizeof(struct fcred)) + +ssize_t +recv_cred(int fd, void *ptr, size_t nbytes, struct fcred *fcredptr) +{ + struct msghdr msg; + struct iovec iov[1]; + char control[CONTROL_LEN + 20]; + int n; + + msg.msg_name = NULL; + msg.msg_namelen = 0; + iov[0].iov_base = ptr; + iov[0].iov_len = nbytes; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + msg.msg_control = control; + msg.msg_controllen = sizeof(control); + msg.msg_flags = 0; + + if ( (n = recvmsg(fd, &msg, 0)) < 0) + return(n); + + fcredptr->fc_ngroups = 0; /* indicates no credentials returned */ + if (fcredptr && msg.msg_controllen > 0) { + struct cmsghdr *cmptr = (struct cmsghdr *) control; + + if (cmptr->cmsg_len != sizeof(struct cmsghdr) + sizeof(struct fcred)) + err_quit("control length = %d", cmptr->cmsg_len); + if (cmptr->cmsg_level != SOL_SOCKET) + err_quit("control level != SOL_SOCKET"); + if (cmptr->cmsg_type != SCM_CREDS) + err_quit("control type != SCM_CREDS"); + memcpy(fcredptr, CMSG_DATA(cmptr), sizeof(struct fcred)); + } + + return(n); +} diff --git a/unixdomain/unixbind.c b/unixdomain/unixbind.c new file mode 100644 index 0000000..8bc8242 --- /dev/null +++ b/unixdomain/unixbind.c @@ -0,0 +1,27 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + socklen_t len; + struct sockaddr_un addr1, addr2; + + if (argc != 2) + err_quit("usage: unixbind "); + + sockfd = Socket(AF_LOCAL, SOCK_STREAM, 0); + + unlink(argv[1]); /* OK if this fails */ + + bzero(&addr1, sizeof(addr1)); + addr1.sun_family = AF_LOCAL; + strncpy(addr1.sun_path, argv[1], sizeof(addr1.sun_path)-1); + Bind(sockfd, (SA *) &addr1, SUN_LEN(&addr1)); + + len = sizeof(addr2); + Getsockname(sockfd, (SA *) &addr2, &len); + printf("bound name = %s, returned len = %d\n", addr2.sun_path, len); + + exit(0); +} diff --git a/unixdomain/unixbind.lc b/unixdomain/unixbind.lc new file mode 100644 index 0000000..56165f9 --- /dev/null +++ b/unixdomain/unixbind.lc @@ -0,0 +1,27 @@ +#include "unp.h"## 1 ##src/unixdomain/unixbind.c## + +int## 2 ##src/unixdomain/unixbind.c## +main(int argc, char **argv)## 3 ##src/unixdomain/unixbind.c## +{## 4 ##src/unixdomain/unixbind.c## + int sockfd;## 5 ##src/unixdomain/unixbind.c## + socklen_t len;## 6 ##src/unixdomain/unixbind.c## + struct sockaddr_un addr1, addr2;## 7 ##src/unixdomain/unixbind.c## + + if (argc != 2)## 8 ##src/unixdomain/unixbind.c## + err_quit("usage: unixbind ");## 9 ##src/unixdomain/unixbind.c## + + sockfd = Socket(AF_LOCAL, SOCK_STREAM, 0);## 10 ##src/unixdomain/unixbind.c## + + unlink(argv[1]); /* OK if this fails */## 11 ##src/unixdomain/unixbind.c## + + bzero(&addr1, sizeof(addr1));## 12 ##src/unixdomain/unixbind.c## + addr1.sun_family = AF_LOCAL;## 13 ##src/unixdomain/unixbind.c## + strncpy(addr1.sun_path, argv[1], sizeof(addr1.sun_path) - 1);## 14 ##src/unixdomain/unixbind.c## + Bind(sockfd, (SA *) &addr1, SUN_LEN(&addr1));## 15 ##src/unixdomain/unixbind.c## + + len = sizeof(addr2);## 16 ##src/unixdomain/unixbind.c## + Getsockname(sockfd, (SA *) &addr2, &len);## 17 ##src/unixdomain/unixbind.c## + printf("bound name = %s, returned len = %d\n", addr2.sun_path, len);## 18 ##src/unixdomain/unixbind.c## + + exit(0);## 19 ##src/unixdomain/unixbind.c## +}## 20 ##src/unixdomain/unixbind.c## diff --git a/unixdomain/unixdgcli01.c b/unixdomain/unixdgcli01.c new file mode 100644 index 0000000..008b8cc --- /dev/null +++ b/unixdomain/unixdgcli01.c @@ -0,0 +1,24 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_un cliaddr, servaddr; + + sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0); + + bzero(&cliaddr, sizeof(cliaddr)); /* bind an address for us */ + cliaddr.sun_family = AF_LOCAL; + strcpy(cliaddr.sun_path, tmpnam(NULL)); + + Bind(sockfd, (SA *) &cliaddr, sizeof(cliaddr)); + + bzero(&servaddr, sizeof(servaddr)); /* fill in server's address */ + servaddr.sun_family = AF_LOCAL; + strcpy(servaddr.sun_path, UNIXDG_PATH); + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); + + exit(0); +} diff --git a/unixdomain/unixdgcli01.lc b/unixdomain/unixdgcli01.lc new file mode 100644 index 0000000..1f173d6 --- /dev/null +++ b/unixdomain/unixdgcli01.lc @@ -0,0 +1,24 @@ +#include "unp.h"## 1 ##src/unixdomain/unixdgcli01.c## + +int## 2 ##src/unixdomain/unixdgcli01.c## +main(int argc, char **argv)## 3 ##src/unixdomain/unixdgcli01.c## +{## 4 ##src/unixdomain/unixdgcli01.c## + int sockfd;## 5 ##src/unixdomain/unixdgcli01.c## + struct sockaddr_un cliaddr, servaddr;## 6 ##src/unixdomain/unixdgcli01.c## + + sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0);## 7 ##src/unixdomain/unixdgcli01.c## + + bzero(&cliaddr, sizeof(cliaddr)); /* bind an address for us */## 8 ##src/unixdomain/unixdgcli01.c## + cliaddr.sun_family = AF_LOCAL;## 9 ##src/unixdomain/unixdgcli01.c## + strcpy(cliaddr.sun_path, tmpnam(NULL));## 10 ##src/unixdomain/unixdgcli01.c## + + Bind(sockfd, (SA *) &cliaddr, sizeof(cliaddr));## 11 ##src/unixdomain/unixdgcli01.c## + + bzero(&servaddr, sizeof(servaddr)); /* fill in server's address */## 12 ##src/unixdomain/unixdgcli01.c## + servaddr.sun_family = AF_LOCAL;## 13 ##src/unixdomain/unixdgcli01.c## + strcpy(servaddr.sun_path, UNIXDG_PATH);## 14 ##src/unixdomain/unixdgcli01.c## + + dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));## 15 ##src/unixdomain/unixdgcli01.c## + + exit(0);## 16 ##src/unixdomain/unixdgcli01.c## +}## 17 ##src/unixdomain/unixdgcli01.c## diff --git a/unixdomain/unixdgserv01.c b/unixdomain/unixdgserv01.c new file mode 100644 index 0000000..fd9abe8 --- /dev/null +++ b/unixdomain/unixdgserv01.c @@ -0,0 +1,19 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_un servaddr, cliaddr; + + sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0); + + unlink(UNIXDG_PATH); + bzero(&servaddr, sizeof(servaddr)); + servaddr.sun_family = AF_LOCAL; + strcpy(servaddr.sun_path, UNIXDG_PATH); + + Bind(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr)); +} diff --git a/unixdomain/unixstrcli01.c b/unixdomain/unixstrcli01.c new file mode 100644 index 0000000..c346a62 --- /dev/null +++ b/unixdomain/unixstrcli01.c @@ -0,0 +1,20 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_un servaddr; + + sockfd = Socket(AF_LOCAL, SOCK_STREAM, 0); + + bzero(&servaddr, sizeof(servaddr)); + servaddr.sun_family = AF_LOCAL; + strcpy(servaddr.sun_path, UNIXSTR_PATH); + + Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); + + str_cli(stdin, sockfd); /* do it all */ + + exit(0); +} diff --git a/unixdomain/unixstrserv01.c b/unixdomain/unixstrserv01.c new file mode 100644 index 0000000..053dbde --- /dev/null +++ b/unixdomain/unixstrserv01.c @@ -0,0 +1,41 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + pid_t childpid; + socklen_t clilen; + struct sockaddr_un cliaddr, servaddr; + void sig_chld(int); + + listenfd = Socket(AF_LOCAL, SOCK_STREAM, 0); + + unlink(UNIXSTR_PATH); + bzero(&servaddr, sizeof(servaddr)); + servaddr.sun_family = AF_LOCAL; + strcpy(servaddr.sun_path, UNIXSTR_PATH); + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + Signal(SIGCHLD, sig_chld); + + for ( ; ; ) { + clilen = sizeof(cliaddr); + if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) { + if (errno == EINTR) + continue; /* back to for() */ + else + err_sys("accept error"); + } + + if ( (childpid = Fork()) == 0) { /* child process */ + Close(listenfd); /* close listening socket */ + str_echo(connfd); /* process request */ + exit(0); + } + Close(connfd); /* parent closes connected socket */ + } +} diff --git a/unixdomain/unixstrserv01.lc b/unixdomain/unixstrserv01.lc new file mode 100644 index 0000000..f26dd54 --- /dev/null +++ b/unixdomain/unixstrserv01.lc @@ -0,0 +1,41 @@ +#include "unp.h"## 1 ##src/unixdomain/unixstrserv01.c## + +int## 2 ##src/unixdomain/unixstrserv01.c## +main(int argc, char **argv)## 3 ##src/unixdomain/unixstrserv01.c## +{## 4 ##src/unixdomain/unixstrserv01.c## + int listenfd, connfd;## 5 ##src/unixdomain/unixstrserv01.c## + pid_t childpid;## 6 ##src/unixdomain/unixstrserv01.c## + socklen_t clilen;## 7 ##src/unixdomain/unixstrserv01.c## + struct sockaddr_un cliaddr, servaddr;## 8 ##src/unixdomain/unixstrserv01.c## + void sig_chld(int);## 9 ##src/unixdomain/unixstrserv01.c## + + listenfd = Socket(AF_LOCAL, SOCK_STREAM, 0);## 10 ##src/unixdomain/unixstrserv01.c## + + unlink(UNIXSTR_PATH);## 11 ##src/unixdomain/unixstrserv01.c## + bzero(&servaddr, sizeof(servaddr));## 12 ##src/unixdomain/unixstrserv01.c## + servaddr.sun_family = AF_LOCAL;## 13 ##src/unixdomain/unixstrserv01.c## + strcpy(servaddr.sun_path, UNIXSTR_PATH);## 14 ##src/unixdomain/unixstrserv01.c## + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));## 15 ##src/unixdomain/unixstrserv01.c## + + Listen(listenfd, LISTENQ);## 16 ##src/unixdomain/unixstrserv01.c## + + Signal(SIGCHLD, sig_chld);## 17 ##src/unixdomain/unixstrserv01.c## + + for (;;) {## 18 ##src/unixdomain/unixstrserv01.c## + clilen = sizeof(cliaddr);## 19 ##src/unixdomain/unixstrserv01.c## + if ((connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {## 20 ##src/unixdomain/unixstrserv01.c## + if (errno == EINTR)## 21 ##src/unixdomain/unixstrserv01.c## + continue; /* back to for() */## 22 ##src/unixdomain/unixstrserv01.c## + else## 23 ##src/unixdomain/unixstrserv01.c## + err_sys("accept error");## 24 ##src/unixdomain/unixstrserv01.c## + }## 25 ##src/unixdomain/unixstrserv01.c## + + if ((childpid = Fork()) == 0) { /* child process */## 26 ##src/unixdomain/unixstrserv01.c## + Close(listenfd); /* close listening socket */## 27 ##src/unixdomain/unixstrserv01.c## + str_echo(connfd); /* process the request */## 28 ##src/unixdomain/unixstrserv01.c## + exit(0);## 29 ##src/unixdomain/unixstrserv01.c## + }## 30 ##src/unixdomain/unixstrserv01.c## + Close(connfd); /* parent closes connected socket */## 31 ##src/unixdomain/unixstrserv01.c## + }## 32 ##src/unixdomain/unixstrserv01.c## +}## 33 ##src/unixdomain/unixstrserv01.c## diff --git a/unixdomain/unixstrserv02.c b/unixdomain/unixstrserv02.c new file mode 100644 index 0000000..78a7dec --- /dev/null +++ b/unixdomain/unixstrserv02.c @@ -0,0 +1,41 @@ +#include "unp.h" + +int +main(int argc, char **argv) +{ + int listenfd, connfd; + pid_t childpid; + socklen_t clilen; + struct sockaddr_un cliaddr, servaddr; + void sig_chld(int); + + listenfd = Socket(AF_LOCAL, SOCK_STREAM, 0); + + unlink(UNIXSTR_PATH); + bzero(&servaddr, sizeof(servaddr)); + servaddr.sun_family = AF_LOCAL; + strcpy(servaddr.sun_path, UNIXSTR_PATH); + + Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); + + Listen(listenfd, LISTENQ); + + Signal(SIGCHLD, sig_chld); + + for ( ; ; ) { + clilen = sizeof(cliaddr); + if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) { + if (errno == EINTR) + continue; /* back to for() */ + else + err_sys("accept error"); + } + + if ( (childpid = Fork()) == 0) { /* child process */ + Close(listenfd); /* close listening socket */ + str_echo(connfd); /* process the request */ + exit(0); + } + Close(connfd); /* parent closes connected socket */ + } +}