1 /* 2 * Copyright (c) 1988, 1990 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted provided 6 * that: (1) source distributions retain this entire copyright notice and 7 * comment, and (2) distributions including binaries display the following 8 * acknowledgement: ``This product includes software developed by the 9 * University of California, Berkeley and its contributors'' in the 10 * documentation or other materials provided with the distribution and in 11 * all advertising materials mentioning features or use of this software. 12 * Neither the name of the University nor the names of its contributors may 13 * be used to endorse or promote products derived from this software without 14 * specific prior written permission. 15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 16 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 18 */ 19 #ifndef lint 20 static char sccsid[] = "@(#)xi_sink.c 7.2 (Berkeley) 11/13/90"; 21 #endif /* not lint */ 22 23 /* 24 * This is a test program to be a sink for TP4 connections. 25 */ 26 #include <sys/param.h> 27 #include <sys/uio.h> 28 #include <sys/socket.h> 29 #include <sys/ioctl.h> 30 #include <net/route.h> 31 #include <net/if.h> 32 #include <netccitt/x25.h> 33 34 #include <stdio.h> 35 #include <errno.h> 36 #include <ctype.h> 37 #include <netdb.h> 38 39 40 #define dbprintf if(verbose)printf 41 #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,"a",x);\ 42 if(x<0) {perror("a"); myexit(0);}} 43 44 45 struct ifreq ifr; 46 short port = 3000; 47 struct sockaddr_x25 faddr, laddr = { sizeof(laddr), AF_CCITT }; 48 struct sockaddr_x25 *sx25 = &laddr; 49 char **xenvp; 50 51 long size, count = 10, forkp, confp, echop, mynamep, verbose = 1, playtag = 0; 52 long records, intercept = 0, isode_mode; 53 54 char buf[2048]; 55 char your_it[] = "You're it!"; 56 57 char *Servername; 58 59 main(argc, argv, envp) 60 int argc; 61 char *argv[]; 62 char *envp[]; 63 { 64 register char **av = argv; 65 register char *cp; 66 67 xenvp = envp; 68 while(--argc > 0) { 69 av++; 70 if (strcmp(*av,"host")==0) { 71 av++; 72 ccitt_addr(*av, sx25); 73 argc--; 74 } else if (strcmp(*av,"count")==0) { 75 av++; 76 sscanf(*av,"%ld",&count); 77 argc--; 78 } else if (strcmp(*av,"size")==0) { 79 av++; 80 sscanf(*av,"%ld",&size); 81 argc--; 82 } else if (strcmp(*av, "intercept")==0) { 83 intercept++; 84 } 85 } 86 tisink(); 87 } 88 #define BIG 2048 89 #define MIDLIN 512 90 char readbuf[BIG]; 91 char x25info[1]; 92 struct iovec iov[2] = { 93 x25info, 94 sizeof x25info, 95 readbuf, 96 sizeof readbuf, 97 }; 98 char name[MIDLIN]; 99 union { 100 struct { 101 struct cmsghdr cmhdr; 102 char cmdata[128 - sizeof(struct cmsghdr)]; 103 } cm; 104 char data[128]; 105 } cbuf; 106 #define control cbuf.data 107 struct msghdr msghdr = { 108 name, sizeof(name), 109 iov, sizeof(iov)/sizeof(iov[1]), 110 control, sizeof control, 111 0 /* flags */ 112 }; 113 114 tisink() 115 { 116 int x, s, pid, on = 1, loop = 0, n; 117 extern int errno; 118 119 try(socket, (AF_CCITT, SOCK_STREAM, 0),""); 120 121 s = x; 122 123 sx25->x25_opts.op_flags |= X25_MQBIT; 124 try(bind, (s, (struct sockaddr *) sx25, sx25->x25_len), ""); 125 126 /*try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)), ""); */ 127 128 try(listen, (s, 5), ""); 129 for(;;) { 130 int child, ns; 131 int addrlen = sizeof(faddr); 132 char childname[50]; 133 134 try (accept, (s, &faddr, &addrlen), ""); 135 ns = x; 136 dumpit("connection from:", &faddr, sizeof faddr); 137 if (mynamep || intercept) { 138 addrlen = sizeof(faddr); 139 try (getsockname, (ns, &faddr, &addrlen), ""); 140 dumpit("connected as:", &faddr, addrlen); 141 } 142 loop++; 143 if (loop > 3) myexit(0); 144 if (forkp) { 145 try(fork, (), ""); 146 } else 147 x = 0; 148 if (x == 0) { 149 long n, count = 0, cn, flags; 150 records = 0; 151 #ifdef ISODE_MODE 152 if (isode_mode) { 153 static char fdbuf[10]; 154 static char *nargv[4] = 155 {"/usr/sbin/isod.tsap", fdbuf, "", 0}; 156 sprintf(fdbuf, "Z%d", ns); 157 old_isod_main(3, nargv, xenvp); 158 } else 159 #endif 160 for (;;) { 161 msghdr.msg_iovlen = 1; 162 msghdr.msg_controllen = sizeof(control); 163 iov[0].iov_len = sizeof(x25info); 164 iov[1].iov_len = sizeof(readbuf); 165 /* n = recvmsg(ns, &msghdr, 0); */ 166 n = readv(ns, iov, 2); 167 flags = msghdr.msg_flags; 168 count++; 169 dbprintf("recvmsg from child %d got %d ctl %d x25info %x\n", 170 getpid(), n, (cn = msghdr.msg_controllen), 171 x25info[0]); 172 fflush(stdout); 173 /* if (cn && verbose) 174 dumpit("control data:\n", control, cn); */ 175 if (n < 0) { 176 fprintf(stderr, "errno is %d\n", errno); 177 perror("recvmsg"); 178 /*sleep (10);*/ 179 break; 180 } else { 181 if (verbose) 182 dumpit("data:\n", readbuf, n - 1); 183 } 184 if (echop) { 185 n = answerback(flags, n, ns); 186 } 187 if (flags & MSG_EOR) 188 records++; 189 if (playtag && n == sizeof(your_it) && (flags & MSG_EOR) 190 && bcmp(readbuf, your_it, n) == 0) { 191 printf("Answering back!!!!\n"); 192 answerback(flags, n, ns); 193 answerback(flags, n, ns); 194 } 195 errno = 0; 196 } 197 } 198 myexit(0); 199 } 200 } 201 answerback(flags, n, ns) 202 { 203 msghdr.msg_controllen = 0; 204 msghdr.msg_iovlen = 1; 205 iov->iov_len = n; 206 n = sendmsg(ns, &msghdr, flags); 207 dbprintf("echoed %d\n", n); 208 return n; 209 } 210 211 dumpit(what, where, n) 212 char *what; unsigned short *where; int n; 213 { 214 unsigned short *s = where; 215 unsigned short *z = where + (n+1)/2; 216 int count = 0; 217 printf(what); 218 while(s < z) { 219 count++; 220 printf("%x ",*s++); 221 if ((count & 15) == 0) 222 putchar('\n'); 223 } 224 if (count & 15) 225 putchar('\n'); 226 fflush(stdout); 227 } 228 myexit(n) 229 { 230 fflush(stderr); 231 printf("got %d records\n", records); 232 fflush(stdout); 233 exit(n); 234 } 235