Annotation of 43BSDReno/sys/nfs/TEST/unix-tests/tools/pmapbrd.c, revision 1.1.1.1

1.1       root        1: /*     @(#)pmapbrd.c   1.2 90/01/03 NFS Rev 2 Testsuite
                      2:  *     1.4 Lachman ONC Test Suite source
                      3:  *
                      4:  * Test portmap broadcast rpc facility
                      5:  */
                      6: 
                      7: #include <rpc/rpc.h>
                      8: #include <rpc/pmap_prot.h>
                      9: #include <rpc/pmap_clnt.h>
                     10: #include <sys/socket.h>
                     11: #ifdef SVR3
                     12: #include <sys/fs/nfs/time.h>
                     13: #else
                     14: #include <sys/time.h>
                     15: #endif
                     16: #include <stdio.h>
                     17: #include <errno.h>
                     18: #include <net/if.h>
                     19: #include <sys/ioctl.h>
                     20: #include <arpa/inet.h>
                     21: 
                     22: #define MAX_BROADCAST_SIZE 1400
                     23: 
                     24: XDR xdr_stream;
                     25: extern int errno;
                     26: static struct timeval timeout = { 3, 0 };
                     27: struct sockaddr_in baddr; /* broadcast addresses */
                     28: typedef bool_t (*resultproc_t)();
                     29: char outbuf[MAX_BROADCAST_SIZE], inbuf[MAX_BROADCAST_SIZE];
                     30: 
                     31: 
                     32: /*
                     33:  * Structures and XDR routines for parameters to and replys from
                     34:  * the pmapper remote-call-service.
                     35:  */
                     36: 
                     37: struct rmtcallargs {
                     38: #ifdef SVR3
                     39:        ulong prog, vers, proc, arglen;
                     40: #else
                     41:        u_long prog, vers, proc, arglen;
                     42: #endif
                     43:        caddr_t args_ptr;
                     44:        xdrproc_t xdr_args;
                     45: };
                     46: static bool_t xdr_rmtcall_args();
                     47: 
                     48: struct rmtcallres {
                     49: #ifdef SVR3
                     50:        ulong *port_ptr;
                     51:        ulong resultslen;
                     52: #else
                     53:        u_long *port_ptr;
                     54:        u_long resultslen;
                     55: #endif
                     56:        caddr_t results_ptr;
                     57:        xdrproc_t xdr_results;
                     58: };
                     59: static bool_t xdr_rmtcallres();
                     60: 
                     61: #ifdef SVR3
                     62: #define RPROG (ulong)40000010
                     63: #define RVERS (ulong)1
                     64: #define RPROC_NUM (ulong)1
                     65: #else
                     66: #define RPROG (u_long)40000010
                     67: #define RVERS (u_long)1
                     68: #define RPROC_NUM (u_long)1
                     69: #endif
                     70: 
                     71: 
                     72: int i;
                     73: main(argc, argv)
                     74: int argc;
                     75: char **argv;
                     76: {
                     77:        SVCXPRT *transp;
                     78:        struct sockaddr_in sin;
                     79:        int pktspersec, count;
                     80:        int sock, readfds;
                     81:        enum clnt_stat clnt_stat;
                     82: #ifdef SVR3
                     83:        ulong result;
                     84: #else
                     85:        u_long result;
                     86: #endif
                     87:        bool_t eachresult();
                     88:        struct timeval t;
                     89:        int a, b;
                     90: 
                     91:        if (argc != 3) {
                     92:                fprintf(stderr, "usage: %s pktspersec count\n", argv[0]);
                     93:                exit(1);
                     94:        }
                     95: 
                     96:        pktspersec = atoi(argv[1]);
                     97:        if (pktspersec < 1) {
                     98:                fprintf(stderr,
                     99:                        "%s: packet rate must greater than or equal to 1\n",
                    100:                        argv[0]);
                    101:                exit(1);
                    102:        }
                    103:        count = atoi(argv[2]);
                    104: 
                    105:        sock = socket(AF_INET,SOCK_DGRAM,0);
                    106:         sin.sin_family = AF_INET;
                    107:         sin.sin_addr.s_addr = INADDR_ANY;
                    108:         sin.sin_port = htons(3300);
                    109: 
                    110:         if(bind(sock, (char *)&sin, sizeof (sin)) == -1) {
                    111:                 perror("brd:  bind");
                    112:                 exit(1);
                    113:         }
                    114: #ifdef SO_BROADCAST
                    115:        i = 1;
                    116:        if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &i, sizeof(i)) == -1) {
                    117:                perror("brd: setsockopt");
                    118:                exit(1);
                    119:        }
                    120: #endif
                    121:        getbroadcastnets(sock, inbuf);
                    122:        baddr.sin_family = AF_INET;
                    123:        baddr.sin_port = htons(PMAPPORT);
                    124:        printf("broadcast addr %x\n", ntohl(baddr.sin_addr.s_addr));
                    125: 
                    126:        if (pktspersec == 1) {
                    127:                t.tv_sec = 1;
                    128:                t.tv_usec = 0;
                    129:        } else {
                    130:                t.tv_sec = 0;
                    131:                t.tv_usec = 1000000 / pktspersec;
                    132:        }
                    133:        printf("%d/sec for %d\n", pktspersec, count);
                    134: 
                    135:        for (i=0; i<count; i++) {
                    136:                /*
                    137:                 * modified verison of clnt_broadcast is called
                    138:                 */
                    139:                clnt_stat =
                    140:                    clnt_broadcast(sock, RPROG, RVERS, RPROC_NUM, xdr_void, &a,
                    141:                    xdr_void, &b, eachresult, &t);
                    142:                if(clnt_stat != RPC_TIMEDOUT) {
                    143:                        printf("error: clnt_stat = %d\n", clnt_stat);
                    144:                        clnt_perrno(clnt_stat);
                    145:                        exit(-1);
                    146:                }
                    147:        }
                    148: }
                    149: 
                    150: bool_t
                    151: eachresult()
                    152: {
                    153:        return(1);
                    154: }
                    155: 
                    156: /*
                    157:  * XDR remote call arguments
                    158:  * written for XDR_ENCODE direction only
                    159:  */
                    160: static bool_t
                    161: xdr_rmtcall_args(xdrs, cap)
                    162:        register XDR *xdrs;
                    163:        register struct rmtcallargs *cap;
                    164: {
                    165: #ifdef SVR3
                    166:        uint lenposition, argposition, position;
                    167: #else
                    168:        u_int lenposition, argposition, position;
                    169: #endif
                    170: 
                    171:        if (xdr_u_long(xdrs, &(cap->prog)) &&
                    172:            xdr_u_long(xdrs, &(cap->vers)) &&
                    173:            xdr_u_long(xdrs, &(cap->proc))) {
                    174:                lenposition = XDR_GETPOS(xdrs);
                    175:                if (! xdr_u_long(xdrs, &(cap->arglen)))
                    176:                    return (FALSE);
                    177:                argposition = XDR_GETPOS(xdrs);
                    178:                if (! (*(cap->xdr_args))(xdrs, cap->args_ptr))
                    179:                    return (FALSE);
                    180:                position = XDR_GETPOS(xdrs);
                    181: #ifdef SVR3
                    182:                cap->arglen = (ulong)position - (ulong)argposition;
                    183: #else
                    184:                cap->arglen = (u_long)position - (u_long)argposition;
                    185: #endif
                    186:                XDR_SETPOS(xdrs, lenposition);
                    187:                if (! xdr_u_long(xdrs, &(cap->arglen)))
                    188:                    return (FALSE);
                    189:                XDR_SETPOS(xdrs, position);
                    190:                return (TRUE);
                    191:        }
                    192:        return (FALSE);
                    193: }
                    194: 
                    195: /*
                    196:  * XDR remote call results
                    197:  * written for XDR_DECODE direction only
                    198:  */
                    199: static bool_t
                    200: xdr_rmtcallres(xdrs, crp)
                    201:        register XDR *xdrs;
                    202:        register struct rmtcallres *crp;
                    203: {
                    204: 
                    205: #ifdef SVR3
                    206:        if (xdr_reference(xdrs, &crp->port_ptr, sizeof (ulong), xdr_u_long) &&
                    207: #else
                    208:        if (xdr_reference(xdrs, &crp->port_ptr, sizeof (u_long), xdr_u_long) &&
                    209: #endif
                    210:                xdr_u_long(xdrs, &crp->resultslen))
                    211:                return ((*(crp->xdr_results))(xdrs, crp->results_ptr));
                    212:        return (FALSE);
                    213: }
                    214: 
                    215: /*
                    216:  * The following is kludged-up support for simple rpc broadcasts.
                    217:  * Someday a large, complicated system will replace these trivial 
                    218:  * routines which only support udp/ip .
                    219:  */
                    220: 
                    221: static int
                    222: getbroadcastnets(sock, buf)
                    223:        int sock;  /* any valid socket will do */
                    224:        char *buf;  /* why allocxate more when we can use existing... */
                    225: {
                    226:        struct ifconf ifc;
                    227:         struct ifreq ifreq, *ifr;
                    228:        struct sockaddr_in *sin;
                    229:         int n, i;
                    230: 
                    231:        ifc.ifc_len = MAX_BROADCAST_SIZE;
                    232:         ifc.ifc_buf = buf;
                    233:         if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
                    234:                 perror("broadcast: ioctl (get interface configuration)");
                    235:                 return (0);
                    236:         }
                    237:         ifr = ifc.ifc_req;
                    238:         for (i = 0, n = ifc.ifc_len/sizeof (struct ifreq); n > 0; n--, ifr++) {
                    239:                 ifreq = *ifr;
                    240:                 if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
                    241:                         perror("broadcast: ioctl (get interface flags)");
                    242:                         continue;
                    243:                 }
                    244:                 if ((ifreq.ifr_flags & IFF_BROADCAST) &&
                    245:                    (ifreq.ifr_flags & IFF_UP) &&
                    246:                    ifr->ifr_addr.sa_family == AF_INET) {
                    247:                         sin = (struct sockaddr_in *)&ifr->ifr_addr;
                    248: #ifdef SIOCGIFBRDADDR
                    249:                        if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
                    250:                                baddr.sin_addr = inet_makeaddr(inet_netof(sin->sin_addr),
                    251:                                                               INADDR_ANY);
                    252:                        } else {
                    253:                                baddr.sin_addr = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
                    254:                        }
                    255:                
                    256: #else
                    257:                        baddr.sin_addr = inet_makeaddr(inet_netof
                    258:                            (sin->sin_addr.s_addr), INADDR_ANY);
                    259: #endif
                    260:                        break;
                    261:                 }
                    262:         }
                    263: }
                    264: 
                    265: enum clnt_stat 
                    266: clnt_broadcast(sock, prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult, t)
                    267:        int             sock;
                    268: #ifdef SVR3
                    269:        ulong           prog;           /* program number */
                    270:        ulong           vers;           /* version number */
                    271:        ulong           proc;           /* procedure number */
                    272: #else
                    273:        u_long          prog;           /* program number */
                    274:        u_long          vers;           /* version number */
                    275:        u_long          proc;           /* procedure number */
                    276: #endif
                    277:        xdrproc_t       xargs;          /* xdr routine for args */
                    278:        caddr_t         argsp;          /* pointer to args */
                    279:        xdrproc_t       xresults;       /* xdr routine for results */
                    280:        caddr_t         resultsp;       /* pointer to results */
                    281:        resultproc_t    eachresult;     /* call with each result obtained */
                    282:        struct timeval *t;
                    283: {
                    284:        XDR *xdrs = &xdr_stream;
                    285:        enum clnt_stat stat;
                    286:        AUTH *unix_auth = authunix_create_default();
                    287:        int outlen, inlen, fromlen, readfds;
                    288:        register int mask, i;
                    289:        bool_t done = FALSE;
                    290: #ifdef SVR3
                    291:        register ulong xid;
                    292:        ulong port;
                    293: #else
                    294:        register u_long xid;
                    295:        u_long port;
                    296: #endif
                    297:        struct sockaddr_in raddr; /* broadcast and response addresses */
                    298:        struct rmtcallargs a;
                    299:        struct rmtcallres r;
                    300:        struct rpc_msg msg;
                    301: 
                    302:        mask = (1 << sock);
                    303:        msg.rm_xid = xid;
                    304:        msg.rm_direction = CALL;
                    305:        msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
                    306:        msg.rm_call.cb_prog = PMAPPROG;
                    307:        msg.rm_call.cb_vers = PMAPVERS;
                    308:        msg.rm_call.cb_proc = PMAPPROC_CALLIT;
                    309:        msg.rm_call.cb_cred = unix_auth->ah_cred;
                    310:        msg.rm_call.cb_verf = unix_auth->ah_verf;
                    311:        a.prog = prog;
                    312:        a.vers = vers;
                    313:        a.proc = proc;
                    314:        a.xdr_args = xargs;
                    315:        a.args_ptr = argsp;
                    316:        r.port_ptr = &port;
                    317:        r.xdr_results = xresults;
                    318:        r.results_ptr = resultsp;
                    319:        xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE);
                    320:        if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) {
                    321:                stat = RPC_CANTENCODEARGS;
                    322:                goto done_broad;
                    323:        }
                    324:        outlen = (int)xdr_getpos(xdrs);
                    325:        xdr_destroy(xdrs);
                    326:        /*
                    327:         * Basic loop: broadcast a packet and wait a while for response(s).
                    328:         * The response timeout grows larger per iteration.
                    329:         */
                    330: 
                    331:        if (sendto(sock, outbuf, outlen, 0,
                    332:            (struct socketaddr *)&baddr,
                    333:            sizeof (struct sockaddr)) != outlen) {
                    334:                perror("Cannot send broadcast packet");
                    335:                stat = RPC_CANTSEND;
                    336:                goto done_broad;
                    337:        }
                    338: recv_again:
                    339:        msg.acpted_rply.ar_verf = _null_auth;
                    340:        msg.acpted_rply.ar_results.where = (caddr_t)&r;
                    341:        msg.acpted_rply.ar_results.proc = xdr_rmtcallres;
                    342:        readfds = mask;
                    343:        switch (select(32, &readfds, (int *)NULL, (int *)NULL, t)) {
                    344: 
                    345:        case 0:  /* timed out */
                    346:                stat = RPC_TIMEDOUT;
                    347:                goto done_broad;
                    348: 
                    349:        case -1:  /* some kind of error */
                    350:                if (errno == EINTR)
                    351:                        goto recv_again;
                    352:                perror("Broadcast select problem");
                    353:                stat = RPC_CANTRECV;
                    354:                goto done_broad;
                    355: 
                    356:        }  /* end of select results switch */
                    357:        if ((readfds & mask) == 0)
                    358:                goto recv_again;
                    359: try_again:
                    360:        fromlen = sizeof(struct sockaddr);
                    361:        inlen = recvfrom(sock, inbuf, MAX_BROADCAST_SIZE, 0,
                    362:                (struct sockaddr *)&raddr, &fromlen);
                    363:        if (inlen < 0) {
                    364:                if (errno == EINTR)
                    365:                        goto try_again;
                    366:                perror("Cannot receive reply to broadcast");
                    367:                stat = RPC_CANTRECV;
                    368:                goto done_broad;
                    369:        }
                    370: #ifdef SVR3
                    371:        if (inlen < sizeof(ulong))
                    372: #else
                    373:        if (inlen < sizeof(u_long))
                    374: #endif
                    375:                goto recv_again;
                    376:        /*
                    377:         * see if reply transaction id matches sent id.
                    378:         * If so, decode the results.
                    379:         */
                    380:        xdrmem_create(xdrs, inbuf, inlen, XDR_DECODE);
                    381:        if (xdr_replymsg(xdrs, &msg)) {
                    382:                if ((msg.rm_xid == xid) &&
                    383:                        (msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
                    384:                        (msg.acpted_rply.ar_stat == SUCCESS)) {
                    385: #ifdef SVR3
                    386:                        raddr.sin_port = htons((ushort)port);
                    387: #else
                    388:                        raddr.sin_port = htons((u_short)port);
                    389: #endif
                    390:                        done = (*eachresult)(resultsp, &raddr);
                    391:                }
                    392:                /* otherwise, we just ignore the errors ... */
                    393:        } else {
                    394:                /* some kind of deserialization problem ... */
                    395:                if (msg.rm_xid == xid)
                    396:                        fprintf(stderr, "Broadcast deserialization problem");
                    397:                /* otherwise, just random garbage */
                    398:        }
                    399:        xdrs->x_op = XDR_FREE;
                    400:        msg.acpted_rply.ar_results.proc = xdr_void;
                    401:        (void)xdr_replymsg(xdrs, &msg);
                    402:        (void)(*xresults)(xdrs, resultsp);
                    403:        xdr_destroy(xdrs);
                    404:        if (done) {
                    405:                stat = RPC_SUCCESS;
                    406:        } else {
                    407:                goto recv_again;
                    408:        }
                    409: 
                    410: done_broad:
                    411:        AUTH_DESTROY(unix_auth);
                    412:        return (stat);
                    413: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.