1 /* $OpenBSD: clnt_udp_bufcreate.c,v 1.1 2024/01/22 16:18:06 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 2010, Oracle America, Inc. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following 14 * disclaimer in the documentation and/or other materials 15 * provided with the distribution. 16 * * Neither the name of the "Oracle America, Inc." nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * clnt_udp.c, Implements a UDP/IP based, client side RPC. 36 */ 37 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <unistd.h> 42 #include <fcntl.h> 43 #include <rpc/rpc.h> 44 #include <sys/socket.h> 45 #include <netdb.h> 46 #include <errno.h> 47 #include <rpc/pmap_clnt.h> 48 #include "clnt_udp.h" 49 50 /* 51 * Create a UDP based client handle. 52 * If *sockp<0, *sockp is set to a newly created UPD socket. 53 * If raddr->sin_port is 0 a binder on the remote machine 54 * is consulted for the correct port number. 55 * NB: It is the client's responsibility to close *sockp, unless 56 * clntudp_bufcreate() was called with *sockp = -1 (so it created 57 * the socket), and CLNT_DESTROY() is used. 58 * NB: The rpch->cl_auth is initialized to null authentication. 59 * Caller may wish to set this something more useful. 60 * 61 * wait is the amount of time used between retransmitting a call if 62 * no response has been heard; retransmission occurs until the actual 63 * rpc call times out. 64 * 65 * sendsz and recvsz are the maximum allowable packet sizes that can be 66 * sent and received. 67 */ 68 69 CLIENT * 70 clntudp_bufcreate(struct sockaddr_in *raddr, u_long program, u_long version, 71 struct timeval wait, int *sockp, u_int sendsz, u_int recvsz) 72 { 73 struct clntudp_bufcreate_args args; 74 75 args.raddr = raddr; 76 args.program = program; 77 args.version = version; 78 args.wait = wait; 79 args.sockp = sockp; 80 args.sendsz = sendsz; 81 args.recvsz = recvsz; 82 83 if (clntudp_bufcreate1(&args) == -1) 84 goto fooy; 85 86 if (raddr->sin_port == 0) { 87 u_short port; 88 if ((port = 89 pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) { 90 goto fooy; 91 } 92 raddr->sin_port = htons(port); 93 } 94 args.cu->cu_raddr = *raddr; 95 if (*sockp < 0) { 96 *sockp = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 97 IPPROTO_UDP); 98 if (*sockp == -1) { 99 rpc_createerr.cf_stat = RPC_SYSTEMERROR; 100 rpc_createerr.cf_error.re_errno = errno; 101 goto fooy; 102 } 103 /* attempt to bind to priv port */ 104 (void)bindresvport(*sockp, NULL); 105 args.cu->cu_closeit = TRUE; 106 } 107 args.cu->cu_sock = *args.sockp; 108 109 if (clntudp_bufcreate2(&args) == -1) 110 goto fooy; 111 return (args.cl); 112 fooy: 113 if (args.cu) 114 mem_free((caddr_t)args.cu, 115 sizeof(*args.cu) + args.sendsz + args.recvsz); 116 if (args.cl) 117 mem_free((caddr_t)args.cl, sizeof(CLIENT)); 118 return (NULL); 119 } 120 DEF_WEAK(clntudp_bufcreate); 121 122 CLIENT * 123 clntudp_create(struct sockaddr_in *raddr, u_long program, u_long version, 124 struct timeval wait, int *sockp) 125 { 126 127 return(clntudp_bufcreate(raddr, program, version, wait, sockp, 128 UDPMSGSIZE, UDPMSGSIZE)); 129 } 130 DEF_WEAK(clntudp_create); 131