Annotation of 43BSD/contrib/sunrpc/portmap.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)portmap.c 1.2 85/03/13 Copyr 1984 Sun Micro";
                      3: #endif
                      4: 
                      5: /*
                      6:  * Copyright (c) 1984 by Sun Microsystems, Inc.
                      7:  */
                      8: 
                      9: /*
                     10:  * portmap.c, Implements the program,version to port number mapping for
                     11:  * rpc.
                     12:  */
                     13: 
                     14: /*
                     15:  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
                     16:  * unrestricted use provided that this legend is included on all tape
                     17:  * media and as a part of the software program in whole or part.  Users
                     18:  * may copy or modify Sun RPC without charge, but are not authorized
                     19:  * to license or distribute it to anyone else except as part of a product or
                     20:  * program developed by the user.
                     21:  * 
                     22:  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
                     23:  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
                     24:  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
                     25:  * 
                     26:  * Sun RPC is provided with no support and without any obligation on the
                     27:  * part of Sun Microsystems, Inc. to assist in its use, correction,
                     28:  * modification or enhancement.
                     29:  * 
                     30:  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
                     31:  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
                     32:  * OR ANY PART THEREOF.
                     33:  * 
                     34:  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
                     35:  * or profits or other special, indirect and consequential damages, even if
                     36:  * Sun has been advised of the possibility of such damages.
                     37:  * 
                     38:  * Sun Microsystems, Inc.
                     39:  * 2550 Garcia Avenue
                     40:  * Mountain View, California  94043
                     41:  */
                     42: 
                     43: #include <rpc/rpc.h>
                     44: #include <rpc/pmap_prot.h>
                     45: #include <stdio.h>
                     46: #include <netdb.h>
                     47: #include <sys/socket.h>
                     48: #include <sys/time.h>
                     49: #include <sys/ioctl.h>
                     50: 
                     51: char *malloc();
                     52: int reg_service();
                     53: static int debugging = 0;
                     54: 
                     55: main()
                     56: {
                     57:        SVCXPRT *xprt;
                     58:        int sock, pid, t;
                     59:        struct sockaddr_in addr;
                     60:        int len = sizeof(struct sockaddr_in);
                     61: 
                     62: #ifndef DEBUG
                     63:        pid = fork();
                     64:        if (pid < 0) {
                     65:                perror("portmap: fork");
                     66:                exit(1);
                     67:        }
                     68:        if (pid != 0)
                     69:                exit(0);
                     70:        for (t = 0; t < 20; t++)
                     71:                close(t);
                     72:        open("/", 0);
                     73:        dup2(0, 1);
                     74:        dup2(0, 2);
                     75:        t = open("/dev/tty", 2);
                     76:        if (t >= 0) {
                     77:                ioctl(t, TIOCNOTTY, (char *)0);
                     78:                close(t);
                     79:        }
                     80: #endif
                     81:        if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
                     82:                perror("portmap cannot create socket");
                     83:                exit(1);
                     84:        }
                     85: 
                     86:        addr.sin_addr.s_addr = 0;
                     87:        addr.sin_family = AF_INET;
                     88:        addr.sin_port = htons(PMAPPORT);
                     89:        if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
                     90:                perror("portmap cannot bind");
                     91:                exit(1);
                     92:        }
                     93: 
                     94:        if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) {
                     95:                fprintf(stderr, "couldn't do udp_create\n");
                     96:                exit(1);
                     97:        }
                     98: 
                     99:        if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
                    100:                perror("portmap cannot create socket");
                    101:                exit(1);
                    102:        }
                    103:        if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
                    104:                perror("portmap cannot bind");
                    105:                exit(1);
                    106:        }
                    107:        if ((xprt = svctcp_create(sock, 0, 0)) == (SVCXPRT *)NULL) {
                    108:                fprintf(stderr, "couldn't do tcp_create\n");
                    109:                exit(1);
                    110:        }
                    111: 
                    112:         (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE);
                    113:        svc_run();
                    114:        fprintf(stderr, "run_svc returned unexpectedly\n");
                    115:        abort();
                    116: }
                    117: 
                    118: struct pmaplist *pmaplist;
                    119: 
                    120: static struct pmaplist *
                    121: find_service(prog, vers, prot)
                    122:        u_long prog;
                    123:        u_long vers;
                    124: {
                    125:        register struct pmaplist *hit = NULL;
                    126:        register struct pmaplist *pml;
                    127: 
                    128:        for (pml = pmaplist; pml != NULL; pml = pml->pml_next) {
                    129:                if ((pml->pml_map.pm_prog != prog) ||
                    130:                        (pml->pml_map.pm_prot != prot))
                    131:                        continue;
                    132:                hit = pml;
                    133:                if (pml->pml_map.pm_vers == vers)
                    134:                    break;
                    135:        }
                    136:        return (hit);
                    137: }
                    138: 
                    139: /* 
                    140:  * 1 OK, 0 not
                    141:  */
                    142: reg_service(rqstp, xprt)
                    143:        struct svc_req *rqstp;
                    144:        SVCXPRT *xprt;
                    145: {
                    146:        struct pmap reg;
                    147:        struct pmaplist *pml, *prevpml, *fnd;
                    148:        int ans, port;
                    149:        caddr_t t;
                    150:        
                    151: #ifdef DEBUG
                    152:        fprintf(stderr, "server: about do a switch\n");
                    153: #endif
                    154:        switch (rqstp->rq_proc) {
                    155: 
                    156:        case PMAPPROC_NULL:
                    157:                /*
                    158:                 * Null proc call
                    159:                 */
                    160:                if ((!svc_sendreply(xprt, xdr_void, NULL)) && debugging) {
                    161:                        abort();
                    162:                }
                    163:                break;
                    164: 
                    165:        case PMAPPROC_SET:
                    166:                /*
                    167:                 * Set a program,version to port mapping
                    168:                 */
                    169:                if (!svc_getargs(xprt, xdr_pmap, &reg))
                    170:                        svcerr_decode(xprt);
                    171:                else {
                    172:                        /*
                    173:                         * check to see if already used
                    174:                         * find_service returns a hit even if
                    175:                         * the versions don't match, so check for it
                    176:                         */
                    177:                        fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
                    178:                        if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) {
                    179:                                if (fnd->pml_map.pm_port == reg.pm_port) {
                    180:                                        ans = 1;
                    181:                                        goto done;
                    182:                                }
                    183:                                else {
                    184:                                        ans = 0;
                    185:                                        goto done;
                    186:                                }
                    187:                        } else {
                    188:                                /* 
                    189:                                 * add to list
                    190:                                 */
                    191:                                pml = (struct pmaplist *)
                    192:                                    malloc((u_int)sizeof(struct pmaplist));
                    193:                                pml->pml_map = reg;
                    194:                                pml->pml_next = pmaplist;
                    195:                                pmaplist = pml;
                    196:                                ans = 1;
                    197:                        }
                    198:                done:
                    199:                        if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) &&
                    200:                            debugging) {
                    201:                                fprintf(stderr, "svc_sendreply\n");
                    202:                                abort();
                    203:                        }
                    204:                }
                    205:                break;
                    206: 
                    207:        case PMAPPROC_UNSET:
                    208:                /*
                    209:                 * Remove a program,version to port mapping.
                    210:                 */
                    211:                if (!svc_getargs(xprt, xdr_pmap, &reg))
                    212:                        svcerr_decode(xprt);
                    213:                else {
                    214:                        ans = 0;
                    215:                        for (prevpml = NULL, pml = pmaplist; pml != NULL; ) {
                    216:                                if ((pml->pml_map.pm_prog != reg.pm_prog) ||
                    217:                                        (pml->pml_map.pm_vers != reg.pm_vers)) {
                    218:                                        /* both pml & prevpml move forwards */
                    219:                                        prevpml = pml;
                    220:                                        pml = pml->pml_next;
                    221:                                        continue;
                    222:                                }
                    223:                                /* found it; pml moves forward, prevpml stays */
                    224:                                ans = 1;
                    225:                                t = (caddr_t)pml;
                    226:                                pml = pml->pml_next;
                    227:                                if (prevpml == NULL)
                    228:                                        pmaplist = pml;
                    229:                                else
                    230:                                        prevpml->pml_next = pml;
                    231:                                free(t);
                    232:                        }
                    233:                        if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) &&
                    234:                            debugging) {
                    235:                                fprintf(stderr, "svc_sendreply\n");
                    236:                                abort();
                    237:                        }
                    238:                }
                    239:                break;
                    240: 
                    241:        case PMAPPROC_GETPORT:
                    242:                /*
                    243:                 * Lookup the mapping for a program,version and return its port
                    244:                 */
                    245:                if (!svc_getargs(xprt, xdr_pmap, &reg))
                    246:                        svcerr_decode(xprt);
                    247:                else {
                    248:                        fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
                    249:                        if (fnd)
                    250:                                port = fnd->pml_map.pm_port;
                    251:                        else
                    252:                                port = 0;
                    253:                        if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&port)) &&
                    254:                            debugging) {
                    255:                                fprintf(stderr, "svc_sendreply\n");
                    256:                                abort();
                    257:                        }
                    258:                }
                    259:                break;
                    260: 
                    261:        case PMAPPROC_DUMP:
                    262:                /*
                    263:                 * Return the current set of mapped program,version
                    264:                 */
                    265:                if (!svc_getargs(xprt, xdr_void, NULL))
                    266:                        svcerr_decode(xprt);
                    267:                else {
                    268:                        if ((!svc_sendreply(xprt, xdr_pmaplist,
                    269:                            (caddr_t)&pmaplist)) && debugging) {
                    270:                                fprintf(stderr, "svc_sendreply\n");
                    271:                                abort();
                    272:                        }
                    273:                }
                    274:                break;
                    275: 
                    276:        case PMAPPROC_CALLIT:
                    277:                /*
                    278:                 * Calls a procedure on the local machine.  If the requested
                    279:                 * procedure is not registered this procedure does not return
                    280:                 * error information!!
                    281:                 * This procedure is only supported on rpc/udp and calls via 
                    282:                 * rpc/udp.  It passes null authentication parameters.
                    283:                 */
                    284:                callit(rqstp, xprt);
                    285:                break;
                    286: 
                    287:        default:
                    288:                svcerr_noproc(xprt);
                    289:                break;
                    290:        }
                    291: }
                    292: 
                    293: 
                    294: /*
                    295:  * Stuff for the rmtcall service
                    296:  */
                    297: #define ARGSIZE 9000
                    298: 
                    299: typedef struct encap_parms {
                    300:        u_long arglen;
                    301:        char *args;
                    302: };
                    303: 
                    304: static bool_t
                    305: xdr_encap_parms(xdrs, epp)
                    306:        XDR *xdrs;
                    307:        struct encap_parms *epp;
                    308: {
                    309: 
                    310:        return (xdr_bytes(xdrs, &(epp->args), &(epp->arglen), ARGSIZE));
                    311: }
                    312: 
                    313: typedef struct rmtcallargs {
                    314:        u_long  rmt_prog;
                    315:        u_long  rmt_vers;
                    316:        u_long  rmt_port;
                    317:        u_long  rmt_proc;
                    318:        struct encap_parms rmt_args;
                    319: };
                    320: 
                    321: static bool_t
                    322: xdr_rmtcall_args(xdrs, cap)
                    323:        register XDR *xdrs;
                    324:        register struct rmtcallargs *cap;
                    325: {
                    326: 
                    327:        /* does not get a port number */
                    328:        if (xdr_u_long(xdrs, &(cap->rmt_prog)) &&
                    329:            xdr_u_long(xdrs, &(cap->rmt_vers)) &&
                    330:            xdr_u_long(xdrs, &(cap->rmt_proc))) {
                    331:                return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
                    332:        }
                    333:        return (FALSE);
                    334: }
                    335: 
                    336: static bool_t
                    337: xdr_rmtcall_result(xdrs, cap)
                    338:        register XDR *xdrs;
                    339:        register struct rmtcallargs *cap;
                    340: {
                    341:        if (xdr_u_long(xdrs, &(cap->rmt_port)))
                    342:                return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
                    343:        return (FALSE);
                    344: }
                    345: 
                    346: /*
                    347:  * only worries about the struct encap_parms part of struct rmtcallargs.
                    348:  * The arglen must already be set!!
                    349:  */
                    350: static bool_t
                    351: xdr_opaque_parms(xdrs, cap)
                    352:        XDR *xdrs;
                    353:        struct rmtcallargs *cap;
                    354: {
                    355: 
                    356:        return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen));
                    357: }
                    358: 
                    359: /*
                    360:  * This routine finds and sets the length of incoming opaque paraters
                    361:  * and then calls xdr_opaque_parms.
                    362:  */
                    363: static bool_t
                    364: xdr_len_opaque_parms(xdrs, cap)
                    365:        register XDR *xdrs;
                    366:        struct rmtcallargs *cap;
                    367: {
                    368:        register u_int beginpos, lowpos, highpos, currpos, pos;
                    369: 
                    370:        beginpos = lowpos = pos = xdr_getpos(xdrs);
                    371:        highpos = lowpos + ARGSIZE;
                    372:        while ((int)(highpos - lowpos) >= 0) {
                    373:                currpos = (lowpos + highpos) / 2;
                    374:                if (xdr_setpos(xdrs, currpos)) {
                    375:                        pos = currpos;
                    376:                        lowpos = currpos + 1;
                    377:                } else {
                    378:                        highpos = currpos - 1;
                    379:                }
                    380:        }
                    381:        xdr_setpos(xdrs, beginpos);
                    382:        cap->rmt_args.arglen = pos - beginpos;
                    383:        return (xdr_opaque_parms(xdrs, cap));
                    384: }
                    385: 
                    386: /*
                    387:  * Call a remote procedure service
                    388:  * This procedure is very quiet when things go wrong.
                    389:  * The proc is written to support broadcast rpc.  In the broadcast case,
                    390:  * a machine should shut-up instead of complain, less the requestor be
                    391:  * overrun with complaints at the expense of not hearing a valid reply ...
                    392:  */
                    393: static
                    394: callit(rqstp, xprt)
                    395:        struct svc_req *rqstp;
                    396:        SVCXPRT *xprt;
                    397: {
                    398:        char buf[2000];
                    399:        struct rmtcallargs a;
                    400:        struct pmaplist *pml;
                    401:        u_short port;
                    402:        struct sockaddr_in me;
                    403:        int socket = -1;
                    404:        CLIENT *client;
                    405:        struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred;
                    406:        struct timeval timeout;
                    407: 
                    408:        timeout.tv_sec = 5;
                    409:        timeout.tv_usec = 0;
                    410:        a.rmt_args.args = buf;
                    411:        if (!svc_getargs(xprt, xdr_rmtcall_args, &a))
                    412:            return;
                    413:        if ((pml = find_service(a.rmt_prog, a.rmt_vers, IPPROTO_UDP)) == NULL)
                    414:            return;
                    415:        port = pml->pml_map.pm_port;
                    416:        get_myaddress(&me);
                    417:        me.sin_port = htons(port);
                    418:        client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &socket);
                    419:        if (client != (CLIENT *)NULL) {
                    420:                if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) {
                    421:                        client->cl_auth = authunix_create(au->aup_machname,
                    422:                           au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids);
                    423:                }
                    424:                a.rmt_port = (u_long)port;
                    425:                if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a,
                    426:                    xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) {
                    427:                        svc_sendreply(xprt, xdr_rmtcall_result, &a);
                    428:                }
                    429:                AUTH_DESTROY(client->cl_auth);
                    430:                clnt_destroy(client);
                    431:        }
                    432:        (void)close(socket);
                    433: }

unix.superglobalmegacorp.com

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