home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / tests / netiso / tisrc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-07  |  9.7 KB  |  389 lines

  1. /*-
  2.  * Copyright (c) 1988, 1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. char copyright[] =
  36. "@(#) Copyright (c) 1988, 1990 The Regents of the University of California.\n\
  37.  All rights reserved.\n";
  38. #endif /* not lint */
  39.  
  40. #ifndef lint
  41. static char sccsid[] = "@(#)tisrc.c    7.5 (Berkeley) 5/7/91";
  42. #endif /* not lint */
  43.  
  44. /*
  45.  * This is a test program to be a source for ISO transport.
  46.  */
  47. #include <sys/types.h>
  48. #include <sys/socket.h>
  49. #include <sys/uio.h>
  50. #include <sys/ioctl.h>
  51. #include <net/route.h>
  52. #include <net/if.h>
  53. #define  TCPT_NTIMERS 4
  54. #include <netiso/iso.h>
  55. #include <netiso/tp_user.h>
  56.  
  57. #include <stdio.h>
  58. #include <errno.h>
  59. #include <ctype.h>
  60. #include <netdb.h>
  61.  
  62.  
  63. #define dbprintf if(verbose)printf
  64. #define try(a,b,c) {x = (a b);dbprintf("%s%s returns %d\n",c,"a",x);\
  65.             if (x < 0) {perror("a"); exit(1);}}
  66.  
  67. struct    iso_addr eon = {20, 0x47, 0, 6, 3, 0, 0, 0, 25 /*EGP for Berkeley*/};
  68. struct    iso_addr *iso_addr();
  69. struct  sockaddr_iso to_s = { sizeof(to_s), AF_ISO }, *to = &to_s;
  70. struct  sockaddr_iso old_s = { sizeof(to_s), AF_ISO }, *old = &old_s;
  71. struct    tp_conn_param tp_params;
  72. fd_set    readfds, writefds, exceptfds;
  73. long size, count = 10;
  74. int verbose = 1, selectp, type = SOCK_SEQPACKET, nobuffs, errno, playtag = 0;
  75. int verify = 0, dgramp = 0, debug = 0, tp0mode = 1;
  76. short portnumber = 3000;
  77. char your_it[] = "You're it!";
  78. char *Servername, *conndata, data_msg[2048];
  79. char Serverbuf[128];
  80. char name[128];
  81. struct iovec iov[1] = {data_msg};
  82. union {
  83.     struct {
  84.         struct cmsghdr    cmhdr;
  85.         char        cmdata[128 - sizeof(struct cmsghdr)];
  86.     } cm;
  87.     char data[128];
  88. } cm;
  89. struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0};
  90.  
  91. main(argc, argv)
  92. int argc;
  93. char *argv[];
  94. {
  95.     register char **av = argv;
  96.     register char *cp;
  97.     u_long len;
  98.     int handy;
  99.  
  100.     while(--argc > 0) {
  101.         av++;
  102.         if(strcmp(*av,"Servername")==0) {
  103.             av++;
  104.             Servername = *av;
  105.             argc--;
  106.         } else if(strcmp(*av,"conndata")==0) {
  107.             av++;
  108.             conndata = *av;
  109.             argc--;
  110.         } else if(strcmp(*av,"host")==0) {
  111.             av++;
  112.             to_s.siso_addr = *iso_addr(*av);
  113.             argc--;
  114.         } else if(strcmp(*av,"port")==0) {
  115.             av++;
  116.             sscanf(*av,"%hd",&portnumber);
  117.             argc--;
  118.         } else if(strcmp(*av,"count")==0) {
  119.             av++;
  120.             sscanf(*av,"%ld",&count);
  121.             argc--;
  122.         } else if(strcmp(*av,"size")==0) {
  123.             av++;
  124.             sscanf(*av,"%ld",&size);
  125.             iov->iov_len = size;
  126.         } else if(strcmp(*av,"stream")==0) {
  127.             type = SOCK_STREAM;
  128.         } else if (strcmp(*av,"eon") == 0) {
  129.             unsigned long l, inet_addr();
  130.  
  131.             l = inet_addr(*++av); argc--;
  132.             to_s.siso_addr = eon;
  133.             bcopy((char *)&l, &to_s.siso_data[15], 4);
  134.         }
  135.     }
  136.     maketoaddr();
  137.     tisrc();
  138. }
  139.  
  140. maketoaddr()
  141. {
  142.     if (Servername) {
  143.         int tlen = strlen(Servername);
  144.         int len =  tlen + TSEL(to) - (caddr_t) to;
  145.         if (len < sizeof(*to)) len = sizeof(*to);
  146.         if (len > to->siso_len) {
  147.             old = to;
  148.             to = (struct sockaddr_iso *)malloc(len);
  149.             *to = *old; /* We dont care if all old tsel is copied*/
  150.             if (old != &to_s) free(old);
  151.         }
  152.         bcopy(Servername, TSEL(to), tlen);
  153.         to->siso_tlen = tlen;
  154.     } else {
  155.         to->siso_tlen = sizeof(portnumber);
  156.         portnumber = htons(portnumber);
  157.         bcopy((char *)&portnumber, TSEL(to), sizeof(portnumber));
  158.     }
  159. }
  160.  
  161. tisrc() {
  162.     int x, s, pid, on = 1, flags = 8, n, proto = tp0mode ? ISOPROTO_TP0: 0;
  163.  
  164.     if (dgramp) type = SOCK_DGRAM;
  165.     try(socket, (AF_ISO, type, proto),"");
  166.     s = x;
  167.  
  168.     if (debug)
  169.         try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof on), "");
  170.     if (dgramp == 0) {
  171.         if (conndata)
  172.             doconndata(s);
  173.         try(connect, (s, (struct sockaddr *) to, to->siso_len), "");
  174.     }
  175.     if (selectp) {
  176.         FD_ZERO(&writefds); FD_SET(s, &writefds);
  177.         select(1, &writefds, 0, 0, 0);
  178.     }
  179.     while (count-- > 0) {
  180.         if (size <= 0 && get_record(&flags) == EOF)
  181.             exit(0);
  182.         n = put_record(s, flags);
  183.         if (n < iov->iov_len) {
  184.             if (n==-1 && errno == 55) {
  185.                 nobuffs++;
  186.                 count++;
  187.                 continue;
  188.             }
  189.             fprintf(stderr, "wrote %d < %d, count %d,",
  190.                         n, iov->iov_len, count);
  191.             perror("due to");
  192.         }
  193.     }
  194.     if (playtag) {
  195.         printf("Tag time!\n");
  196.         iov->iov_base = your_it;
  197.         iov->iov_len = sizeof your_it;
  198.         sendmsg(s, &msg, MSG_EOR);
  199.         sendmsg(s, &msg, MSG_EOR);
  200.         iov->iov_base = data_msg;
  201.         iov->iov_len = sizeof data_msg;
  202.         try(recvmsg, (s, &msg, flags), " playtag ");
  203.     }
  204.     if(nobuffs) {
  205.         printf("looped %d times waiting for bufs\n", nobuffs);
  206.     }
  207. }
  208. int localsize;
  209. char dupbuf[4096];
  210.  
  211. put_record(s, flags)
  212. int s, flags;
  213. {
  214.     int fd, buflen;
  215.     char *buf;
  216.     int x, saved_x;
  217.  
  218.     msg.msg_flags = flags;
  219.     if (verbose) {
  220.         if (msg.msg_controllen) {
  221.             printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type);
  222.             dumpit("CMsg data:\n", &msg.msg_control, msg.msg_controllen);
  223.         }
  224.         if (iov->iov_len) {
  225.             printf("sending: %s %s",
  226.             (flags & MSG_OOB ? "(OOB Data)" : ""),
  227.                 (flags & MSG_EOR ? "(Record Mark)" : ""));
  228.             dumpit("data: ", data_msg, localsize);
  229.         }
  230.     }
  231.     if (verify) {
  232.         buflen = iov->iov_len;
  233.         bcopy(iov->iov_base, dupbuf, buflen);
  234.     }
  235.     if (dgramp) {
  236.         msg.msg_name = (caddr_t)to;
  237.         msg.msg_namelen = to->siso_len;
  238.     }
  239.     try(sendmsg, (s, &msg, flags), " put_record ");
  240.     saved_x = x;
  241.     while (verify && buflen > 0) {
  242.         iov->iov_len = buflen;
  243.         iov->iov_base = dupbuf;
  244.         try(recvmsg, (s, &msg, flags), " put_record ");
  245.         if (dgramp) {
  246.             if (msg.msg_namelen)
  247.                 dumpit("from: ", to, msg.msg_namelen);
  248.             msg.msg_namelen = old->siso_len;
  249.         }
  250.         printf("verify got %d\n", x);
  251.         buflen -= x;
  252.     }
  253.     bcopy(old, to, old->siso_len);
  254.     msg.msg_control = 0;
  255.     return (saved_x);
  256. }
  257. dumpit(what, where, n)
  258. char *what; unsigned short *where; int n;
  259. {
  260.     unsigned short *s = where;
  261.     unsigned short *z = where + (n+1)/2;
  262.     int count = 0;
  263.     if (verbose == 0)
  264.         return;
  265.     printf(what);
  266.     while(s < z) {
  267.         count++;
  268.         printf("%x ",*s++);
  269.         if ((count & 15) == 0)
  270.             putchar('\n');
  271.     }
  272.     if (count & 15)
  273.         putchar('\n');
  274.     fflush(stdout);
  275. }
  276. int *datasize = &iov->iov_len;
  277. char *cp, *cplim;
  278.  
  279. get_control_data(type)
  280. {
  281.  
  282.     datasize = (int *)&msg.msg_controllen;
  283.     cp = cm.cm.cmdata;
  284.     cplim = cp + sizeof(cm.cm.cmdata);
  285.     cm.cm.cmhdr.cmsg_level = SOL_TRANSPORT;
  286.     cm.cm.cmhdr.cmsg_type = type;
  287.     msg.msg_control = cm.data;
  288. }
  289.  
  290. doconndata(s)
  291. {
  292.     get_control_data(TPOPT_CONN_DATA);
  293.     *datasize = strlen(conndata) + sizeof(cm.cm.cmhdr);
  294.     cm.cm.cmhdr.cmsg_len = *datasize;
  295.     bcopy(conndata, cp, *datasize);
  296.     put_record(s, 0);
  297. }
  298.  
  299. get_altbuf(addrbuf)
  300. char *addrbuf;
  301. {
  302.     if (dgramp == 0) {
  303.         printf("illegal option for stream\n");
  304.         return 1;
  305.     }
  306.     return (scanf("%s", addrbuf) == EOF ? 1 : 0);
  307. }
  308.  
  309. get_record(flags)
  310. int *flags;
  311. {
  312.     int factor = 1, x = 0, newaddr = 0;
  313.     static repeatcount, repeatsize;
  314.     char workbuf[10240];
  315.     char addrbuf[128];
  316.  
  317.     if (repeatcount > 0) {
  318.         repeatcount--;
  319.         return;
  320.     }
  321.  
  322.     *flags = 0;
  323.     *datasize = 0;
  324.     datasize = &iov->iov_len;
  325.     cp = data_msg;
  326.     cplim  = cp + sizeof(data_msg);
  327.  
  328.     for(;;) {
  329.         x = scanf("%s", workbuf);
  330.         if (x == EOF)
  331.             break;
  332.         if (strcmp(workbuf, "host") == 0) {
  333.             if (get_altbuf(addrbuf))
  334.                 break;
  335.             to->siso_addr = *iso_addr(addrbuf);
  336.             newaddr = 1;
  337.         } else if (strcmp(workbuf, "Servername") == 0) {
  338.             if (get_altbuf(Serverbuf))
  339.                 break;
  340.             Servername = Serverbuf;
  341.             newaddr = 1;
  342.         } else if (strcmp(workbuf, "port") == 0) {
  343.             x = scanf("%hd", &portnumber);
  344.             if (x == EOF)
  345.                 break;
  346.             Servername = 0;
  347.             newaddr = 1;
  348.         } else if (strcmp(workbuf, "repeat") == 0) {
  349.             x = scanf("%d", &repeatcount);
  350.             if (repeatcount <= 0) repeatcount = 1;
  351.             repeatcount--;
  352.             if (x == EOF)
  353.                 break;
  354.         } else if (strcmp(workbuf, "disc") == 0)
  355.             x = get_control_data(TPOPT_DISC_DATA);
  356.         else if (strcmp(workbuf, "cfrm") == 0)
  357.             x = get_control_data(TPOPT_CFRM_DATA);
  358.         else if (strcmp(workbuf, "oob") == 0)
  359.             *flags |= MSG_OOB;
  360.         else if (strcmp(workbuf, "eom") == 0)
  361.             *flags |= MSG_EOR;
  362.         else if (strcmp(workbuf, "factor") == 0) {
  363.             x = scanf("%d", &factor);
  364.             if (factor <= 0) factor = 1;
  365.             if (x == EOF)
  366.                 break;
  367.         } else {
  368.             int len = strlen(workbuf);
  369.             localsize = 0;
  370.             while ((factor-- > 0) &&
  371.                    ((cp + len) < cplim)) {
  372.                     strcpy(cp, workbuf);
  373.                     cp += len;
  374.                     localsize += len;
  375.             }
  376.             *datasize = localsize;
  377.             if (datasize != &iov->iov_len) {
  378.                 *datasize += sizeof(cm.cm.cmhdr);
  379.                 repeatsize = cm.cm.cmhdr.cmsg_len = *datasize;
  380.             }
  381.             break;
  382.         }
  383.     }
  384.     errno = 0;
  385.     if (newaddr)
  386.         maketoaddr();
  387.     return (x);
  388. }
  389.