|
|
1.1 ! root 1: /* ! 2: * Sun RPC is a product of Sun Microsystems, Inc. and is provided for ! 3: * unrestricted use provided that this legend is included on all tape ! 4: * media and as a part of the software program in whole or part. Users ! 5: * may copy or modify Sun RPC without charge, but are not authorized ! 6: * to license or distribute it to anyone else except as part of a product or ! 7: * program developed by the user. ! 8: * ! 9: * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE ! 10: * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR ! 11: * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. ! 12: * ! 13: * Sun RPC is provided with no support and without any obligation on the ! 14: * part of Sun Microsystems, Inc. to assist in its use, correction, ! 15: * modification or enhancement. ! 16: * ! 17: * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE ! 18: * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC ! 19: * OR ANY PART THEREOF. ! 20: * ! 21: * In no event will Sun Microsystems, Inc. be liable for any lost revenue ! 22: * or profits or other special, indirect and consequential damages, even if ! 23: * Sun has been advised of the possibility of such damages. ! 24: * ! 25: * Sun Microsystems, Inc. ! 26: * 2550 Garcia Avenue ! 27: * Mountain View, California 94043 ! 28: */ ! 29: #ifndef lint ! 30: static char sccsid[] = "@(#)svc_udp.c 1.4 85/03/14 Copyr 1984 Sun Micro"; ! 31: #endif ! 32: ! 33: /* ! 34: * svc_udp.c, ! 35: * Server side for UDP/IP based RPC. (Does some caching in the hopes of ! 36: * achieving execute-at-most-once semantics.) ! 37: * ! 38: * Copyright (C) 1984, Sun Microsystems, Inc. ! 39: */ ! 40: ! 41: #include <stdio.h> ! 42: #include "types.h" ! 43: #include <netinet/in.h> ! 44: #include <sys/socket.h> ! 45: #include <errno.h> ! 46: #include "xdr.h" ! 47: #include "auth.h" ! 48: #include "clnt.h" ! 49: #include "rpc_msg.h" ! 50: #include "svc.h" ! 51: ! 52: char *mem_alloc(); ! 53: ! 54: #define rpc_buffer(xprt) ((xprt)->xp_p1) ! 55: ! 56: static bool_t svcudp_recv(); ! 57: static bool_t svcudp_reply(); ! 58: static enum xprt_stat svcudp_stat(); ! 59: static bool_t svcudp_getargs(); ! 60: static bool_t svcudp_freeargs(); ! 61: static void svcudp_destroy(); ! 62: ! 63: static struct xp_ops svcudp_op = { ! 64: svcudp_recv, ! 65: svcudp_stat, ! 66: svcudp_getargs, ! 67: svcudp_reply, ! 68: svcudp_freeargs, ! 69: svcudp_destroy ! 70: }; ! 71: ! 72: extern int errno; ! 73: ! 74: /* ! 75: * kept in xprt->xp_p2 ! 76: */ ! 77: struct svcudp_data { ! 78: u_long su_xid; /* transaction id */ ! 79: XDR su_xdrs; /* XDR handle */ ! 80: char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */ ! 81: }; ! 82: #define su_data(xprt) ((struct svcudp_data *)(xprt->xp_p2)) ! 83: ! 84: /* ! 85: * Usage: ! 86: * xprt = svcudp_create(sock); ! 87: * ! 88: * If sock<0 then a socket is created, else sock is used. ! 89: * If the socket, sock is not bound to a port then svcudp_create ! 90: * binds it to an arbitrary port. In any (successful) case, ! 91: * xprt->xp_sock is the registered socket number and xprt->xp_port is the ! 92: * associated port number. ! 93: * Once *xprt is initialized, it is registered as a transporter; ! 94: * see (svc.h, xprt_register). ! 95: * The routines returns NULL if a problem occurred. ! 96: */ ! 97: SVCXPRT * ! 98: svcudp_create(sock) ! 99: register int sock; ! 100: { ! 101: bool_t madesock = FALSE; ! 102: register SVCXPRT *xprt; ! 103: register struct svcudp_data *su; ! 104: struct sockaddr_in addr; ! 105: int len = sizeof(struct sockaddr_in); ! 106: ! 107: if (sock == RPC_ANYSOCK) { ! 108: if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { ! 109: perror("svcudp_create: socket creation problem"); ! 110: return ((SVCXPRT *)NULL); ! 111: } ! 112: madesock = TRUE; ! 113: } ! 114: addr.sin_addr.s_addr = 0; ! 115: addr.sin_family = AF_INET; ! 116: addr.sin_port = 0; ! 117: (void)bind(sock, (struct sockaddr *)&addr, len); ! 118: if (getsockname(sock, (caddr_t)&addr, &len) != 0) { ! 119: perror("svcudp_create - cannot getsockname"); ! 120: if (madesock) ! 121: (void)close(sock); ! 122: return ((SVCXPRT *)NULL); ! 123: } ! 124: xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); ! 125: if (xprt == NULL) { ! 126: fprintf(stderr, "svcudp_create: out of memory\n"); ! 127: return (NULL); ! 128: } ! 129: if ((rpc_buffer(xprt) = mem_alloc(UDPMSGSIZE)) == NULL) { ! 130: fprintf(stderr, "svcudp_create: out of memory\n"); ! 131: return (NULL); ! 132: } ! 133: su = (struct svcudp_data *)mem_alloc(sizeof(*su)); ! 134: if (su == NULL) { ! 135: fprintf(stderr, "svcudp_create: out of memory\n"); ! 136: return (NULL); ! 137: } ! 138: xdrmem_create( ! 139: &(su->su_xdrs), rpc_buffer(xprt), UDPMSGSIZE, XDR_DECODE); ! 140: xprt->xp_p2 = (caddr_t)su; ! 141: xprt->xp_verf.oa_base = su->su_verfbody; ! 142: xprt->xp_ops = &svcudp_op; ! 143: xprt->xp_port = ntohs(addr.sin_port); ! 144: xprt->xp_sock = sock; ! 145: xprt_register(xprt); ! 146: return (xprt); ! 147: } ! 148: ! 149: static enum xprt_stat ! 150: svcudp_stat(xprt) ! 151: SVCXPRT *xprt; ! 152: { ! 153: ! 154: return (XPRT_IDLE); ! 155: } ! 156: ! 157: static bool_t ! 158: svcudp_recv(xprt, msg) ! 159: register SVCXPRT *xprt; ! 160: struct rpc_msg *msg; ! 161: { ! 162: register struct svcudp_data *su = su_data(xprt); ! 163: register XDR *xdrs = &(su->su_xdrs); ! 164: register int rlen; ! 165: ! 166: again: ! 167: xprt->xp_addrlen = sizeof(struct sockaddr_in); ! 168: rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), UDPMSGSIZE, ! 169: 0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen)); ! 170: if (rlen == -1 && errno == EINTR) ! 171: goto again; ! 172: if (rlen < 4*sizeof(u_long)) ! 173: return (FALSE); ! 174: xdrs->x_op = XDR_DECODE; ! 175: XDR_SETPOS(xdrs, 0); ! 176: if (! xdr_callmsg(xdrs, msg)) ! 177: return (FALSE); ! 178: su->su_xid = msg->rm_xid; ! 179: return (TRUE); ! 180: } ! 181: ! 182: static bool_t ! 183: svcudp_reply(xprt, msg) ! 184: register SVCXPRT *xprt; ! 185: struct rpc_msg *msg; ! 186: { ! 187: register struct svcudp_data *su = su_data(xprt); ! 188: register XDR *xdrs = &(su->su_xdrs); ! 189: register int slen; ! 190: register bool_t stat = FALSE; ! 191: ! 192: xdrs->x_op = XDR_ENCODE; ! 193: XDR_SETPOS(xdrs, 0); ! 194: msg->rm_xid = su->su_xid; ! 195: if (xdr_replymsg(xdrs, msg)) { ! 196: slen = (int)XDR_GETPOS(xdrs); ! 197: if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0, ! 198: (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen) ! 199: == slen) ! 200: stat = TRUE; ! 201: } ! 202: return (stat); ! 203: } ! 204: ! 205: static bool_t ! 206: svcudp_getargs(xprt, xdr_args, args_ptr) ! 207: SVCXPRT *xprt; ! 208: xdrproc_t xdr_args; ! 209: caddr_t args_ptr; ! 210: { ! 211: ! 212: return ((*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr)); ! 213: } ! 214: ! 215: static bool_t ! 216: svcudp_freeargs(xprt, xdr_args, args_ptr) ! 217: SVCXPRT *xprt; ! 218: xdrproc_t xdr_args; ! 219: caddr_t args_ptr; ! 220: { ! 221: register XDR *xdrs = &(su_data(xprt)->su_xdrs); ! 222: ! 223: xdrs->x_op = XDR_FREE; ! 224: return ((*xdr_args)(xdrs, args_ptr)); ! 225: } ! 226: ! 227: static void ! 228: svcudp_destroy(xprt) ! 229: register SVCXPRT *xprt; ! 230: { ! 231: register struct svcudp_data *su = su_data(xprt); ! 232: ! 233: xprt_unregister(xprt); ! 234: (void)close(xprt->xp_sock); ! 235: XDR_DESTROY(&(su->su_xdrs)); ! 236: mem_free((caddr_t)su, sizeof(struct svcudp_data)); ! 237: mem_free(rpc_buffer(xprt), UDPMSGSIZE); ! 238: mem_free((caddr_t)xprt, sizeof(SVCXPRT)); ! 239: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.