ReactOS 0.4.15-dev-7788-g1ad9096
rpc_generic.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009, Sun Microsystems, Inc.
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 are met:
7 * - Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * - Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * - Neither the name of Sun Microsystems, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28/*
29 * Copyright (c) 1986-1991 by Sun Microsystems Inc.
30 */
31
32//#include <sys/cdefs.h>
33
34/*
35 * rpc_generic.c, Miscl routines for RPC.
36 *
37 */
38#include <wintirpc.h>
39//#include <pthread.h>
40#include <reentrant.h>
41#include <sys/types.h>
42//#include <sys/param.h>
43//#include <sys/socket.h>
44//#include <sys/time.h>
45//#include <sys/un.h>
46//#include <sys/resource.h>
47//#include <netinet/in.h>
48//#include <arpa/inet.h>
49#include <rpc/rpc.h>
50//#include <ctype.h>
51//#include <stddef.h>
52#include <stdio.h>
53//#include <netdb.h>
54#include <netconfig.h>
55#include <stdlib.h>
56#include <string.h>
57//#include <syslog.h>
58#include <rpc/nettype.h>
59#include "rpc_com.h"
60
61struct handle {
63 int nflag; /* Whether NETPATH or NETCONFIG */
65};
66
67static const struct _rpcnettype {
68 const char *name;
69 const int type;
70} _rpctypelist[] = {
71 { "netpath", _RPC_NETPATH },
72 { "visible", _RPC_VISIBLE },
73 { "circuit_v", _RPC_CIRCUIT_V },
74 { "datagram_v", _RPC_DATAGRAM_V },
75 { "circuit_n", _RPC_CIRCUIT_N },
76 { "datagram_n", _RPC_DATAGRAM_N },
77 { "tcp", _RPC_TCP },
78 { "udp", _RPC_UDP },
79 { 0, _RPC_NONE }
80};
81
82struct netid_af {
83 const char *netid;
86};
87
88static const struct netid_af na_cvt[] = {
89 { "udp", AF_INET, IPPROTO_UDP },
90 { "tcp", AF_INET, IPPROTO_TCP },
91#ifdef INET6
92 { "udp6", AF_INET6, IPPROTO_UDP },
93 { "tcp6", AF_INET6, IPPROTO_TCP },
94#endif
95#ifdef AF_LOCAL
96 { "local", AF_LOCAL, 0 }
97#endif
98};
99
100#if 0
101static char *strlocase(char *);
102#endif
103static int getnettype(const char *);
104
105/*
106 * Cache the result of getrlimit(), so we don't have to do an
107 * expensive call every time.
108 */
109int
111{
112#ifdef _WIN32
114#else
115
116 static int tbsize;
117 struct rlimit rl;
118
119 if (tbsize) {
120 return (tbsize);
121 }
122 if (getrlimit(RLIMIT_NOFILE, &rl) == 0) {
123 return (tbsize = (int)rl.rlim_max);
124 }
125 /*
126 * Something wrong. I'll try to save face by returning a
127 * pessimistic number.
128 */
129 return (32);
130#endif
131}
132
133
134/*
135 * Find the appropriate buffer size
136 */
137u_int
138/*ARGSUSED*/
140 int af, proto;
141 int size; /* Size requested */
142{
143 int maxsize, defsize;
144
145 maxsize = 256 * 1024; /* XXX */
146 switch (proto) {
147 case IPPROTO_TCP:
148 defsize = 1024 * 1024; /* XXX */
149 break;
150 case IPPROTO_UDP:
151 defsize = UDPMSGSIZE;
152 break;
153 default:
154 defsize = RPC_MAXDATASIZE;
155 break;
156 }
157 if (size == 0)
158 return defsize;
159#if 1
160 /* cbodley- give us the size we ask for, or we'll get fragmented! */
161 return (u_int)size;
162#else
163 /* Check whether the value is within the upper max limit */
164 return (size > maxsize ? (u_int)maxsize : (u_int)size);
165#endif
166}
167
168/*
169 * Find the appropriate address buffer size
170 */
171u_int
173 int af;
174{
175 switch (af) {
176 case AF_INET:
177 return sizeof (struct sockaddr_in);
178#ifdef INET6
179 case AF_INET6:
180 return sizeof (struct sockaddr_in6);
181#endif
182#ifdef AF_LOCAL
183 case AF_LOCAL:
184 return sizeof (struct sockaddr_un);
185#endif
186 default:
187 break;
188 }
189 return ((u_int)RPC_MAXADDRSIZE);
190}
191
192#if 0
193static char *
194strlocase(p)
195 char *p;
196{
197 char *t = p;
198
199 for (; *p; p++)
200 if (isupper(*p))
201 *p = tolower(*p);
202 return (t);
203}
204#endif
205
206/*
207 * Returns the type of the network as defined in <rpc/nettype.h>
208 * If nettype is NULL, it defaults to NETPATH.
209 */
210static int
212 const char *nettype;
213{
214 int i;
215
216 if ((nettype == NULL) || (nettype[0] == 0)) {
217 return (_RPC_NETPATH); /* Default */
218 }
219
220#if 0
221 nettype = strlocase(nettype);
222#endif
223 for (i = 0; _rpctypelist[i].name; i++)
224 if (strcasecmp(nettype, _rpctypelist[i].name) == 0) {
225 return (_rpctypelist[i].type);
226 }
227 return (_rpctypelist[i].type);
228}
229
230/*
231 * For the given nettype (tcp or udp only), return the first structure found.
232 * This should be freed by calling freenetconfigent()
233 */
234struct netconfig *
236 const char *nettype;
237{
238 char *netid;
239 char *netid_tcp = (char *) NULL;
240 char *netid_udp = (char *) NULL;
241 struct netconfig *dummy;
243 extern mutex_t tsd_lock;
244
245 if (tcp_key == -1) {
247 if (tcp_key == -1)
248 tcp_key = TlsAlloc(); //thr_keycreate(&tcp_key, free);
250 }
251 netid_tcp = (char *)thr_getspecific(tcp_key);
252 if (udp_key == -1) {
254 if (udp_key == -1)
255 udp_key = TlsAlloc(); //thr_keycreate(&udp_key, free);
257 }
258 netid_udp = (char *)thr_getspecific(udp_key);
259 if (!netid_udp && !netid_tcp) {
260 struct netconfig *nconf;
261 void *confighandle;
262
263 if (!(confighandle = setnetconfig())) {
264 //syslog (LOG_ERR, "rpc: failed to open " NETCONFIG);
265 return (NULL);
266 }
267 while ((nconf = getnetconfig(confighandle)) != NULL) {
268 if (strcmp(nconf->nc_protofmly, NC_INET) == 0 ||
269 strcmp(nconf->nc_protofmly, NC_INET6) == 0) {
270 if (strcmp(nconf->nc_proto, NC_TCP) == 0 &&
271 netid_tcp == NULL) {
272 netid_tcp = strdup(nconf->nc_netid);
274 (void *) netid_tcp);
275 } else
276 if (strcmp(nconf->nc_proto, NC_UDP) == 0 &&
277 netid_udp == NULL) {
278 netid_udp = strdup(nconf->nc_netid);
280 (void *) netid_udp);
281 }
282 }
283 }
284 endnetconfig(confighandle);
285 }
286 if (strcmp(nettype, "udp") == 0)
287 netid = netid_udp;
288 else if (strcmp(nettype, "tcp") == 0)
289 netid = netid_tcp;
290 else {
291 return (NULL);
292 }
293 if ((netid == NULL) || (netid[0] == 0)) {
294 return (NULL);
295 }
296 dummy = getnetconfigent(netid);
297 return (dummy);
298}
299
300/*
301 * Returns the type of the nettype, which should then be used with
302 * __rpc_getconf().
303 */
304void *
306 const char *nettype;
307{
308 struct handle *handle;
309
310 handle = (struct handle *) malloc(sizeof (struct handle));
311 if (handle == NULL) {
312 return (NULL);
313 }
314 switch (handle->nettype = getnettype(nettype)) {
315 case _RPC_NETPATH:
316 case _RPC_CIRCUIT_N:
317 case _RPC_DATAGRAM_N:
318 if (!(handle->nhandle = setnetpath())) {
319 free(handle);
320 return (NULL);
321 }
322 handle->nflag = TRUE;
323 break;
324 case _RPC_VISIBLE:
325 case _RPC_CIRCUIT_V:
326 case _RPC_DATAGRAM_V:
327 case _RPC_TCP:
328 case _RPC_UDP:
329 if (!(handle->nhandle = setnetconfig())) {
330 //syslog (LOG_ERR, "rpc: failed to open " NETCONFIG);
331 free(handle);
332 return (NULL);
333 }
334 handle->nflag = FALSE;
335 break;
336 default:
337 return (NULL);
338 }
339
340 return (handle);
341}
342
343/*
344 * Returns the next netconfig struct for the given "net" type.
345 * __rpc_setconf() should have been called previously.
346 */
347struct netconfig *
349 void *vhandle;
350{
351 struct handle *handle;
352 struct netconfig *nconf;
353
354 handle = (struct handle *)vhandle;
355 if (handle == NULL) {
356 return (NULL);
357 }
358 for (;;) {
359 if (handle->nflag)
360 nconf = getnetpath(handle->nhandle);
361 else
362 nconf = getnetconfig(handle->nhandle);
363 if (nconf == NULL)
364 break;
365 if ((nconf->nc_semantics != NC_TPI_CLTS) &&
366 (nconf->nc_semantics != NC_TPI_COTS) &&
367 (nconf->nc_semantics != NC_TPI_COTS_ORD))
368 continue;
369 switch (handle->nettype) {
370 case _RPC_VISIBLE:
371 if (!(nconf->nc_flag & NC_VISIBLE))
372 continue;
373 /* FALLTHROUGH */
374 case _RPC_NETPATH: /* Be happy */
375 break;
376 case _RPC_CIRCUIT_V:
377 if (!(nconf->nc_flag & NC_VISIBLE))
378 continue;
379 /* FALLTHROUGH */
380 case _RPC_CIRCUIT_N:
381 if ((nconf->nc_semantics != NC_TPI_COTS) &&
382 (nconf->nc_semantics != NC_TPI_COTS_ORD))
383 continue;
384 break;
385 case _RPC_DATAGRAM_V:
386 if (!(nconf->nc_flag & NC_VISIBLE))
387 continue;
388 /* FALLTHROUGH */
389 case _RPC_DATAGRAM_N:
390 if (nconf->nc_semantics != NC_TPI_CLTS)
391 continue;
392 break;
393 case _RPC_TCP:
394 if (((nconf->nc_semantics != NC_TPI_COTS) &&
395 (nconf->nc_semantics != NC_TPI_COTS_ORD)) ||
396 (strcmp(nconf->nc_protofmly, NC_INET)
397#ifdef INET6
398 && strcmp(nconf->nc_protofmly, NC_INET6))
399#else
400 )
401#endif
402 ||
403 strcmp(nconf->nc_proto, NC_TCP))
404 continue;
405 break;
406 case _RPC_UDP:
407 if ((nconf->nc_semantics != NC_TPI_CLTS) ||
408 (strcmp(nconf->nc_protofmly, NC_INET)
409#ifdef INET6
410 && strcmp(nconf->nc_protofmly, NC_INET6))
411#else
412 )
413#endif
414 ||
415 strcmp(nconf->nc_proto, NC_UDP))
416 continue;
417 break;
418 }
419 break;
420 }
421 return (nconf);
422}
423
424void
426 void * vhandle;
427{
428 struct handle *handle;
429
430 handle = (struct handle *) vhandle;
431 if (handle == NULL) {
432 return;
433 }
434 if (handle->nflag) {
436 } else {
438 }
439 free(handle);
440}
441
442/*
443 * Used to ping the NULL procedure for clnt handle.
444 * Returns NULL if fails, else a non-NULL pointer.
445 */
446void *
448 CLIENT *clnt;
449{
450 struct timeval TIMEOUT = {25, 0};
451
454 return (NULL);
455 }
456 return ((void *) clnt);
457}
458
459/*
460 * Try all possible transports until
461 * one succeeds in finding the netconf for the given fd.
462 */
463struct netconfig *
465 SOCKET fd;
466{
467 const char *netid;
468 struct __rpc_sockinfo si;
469
470 if (!__rpc_fd2sockinfo(fd, &si))
471 return NULL;
472
473 if (!__rpc_sockinfo2netid(&si, &netid))
474 return NULL;
475
476 /*LINTED const castaway*/
477 return getnetconfigent((char *)netid);
478}
479
480int
482{
484 int type, proto;
485 struct sockaddr_storage ss;
486
487#ifdef _WIN32
488 WSAPROTOCOL_INFO proto_info;
489 int proto_info_size = sizeof(proto_info);
490 if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL_INFO, (char *)&proto_info, &proto_info_size) == SOCKET_ERROR) {
491#ifndef __REACTOS__
492 int err = WSAGetLastError();
493#endif
494 return 0;
495 }
496 len = proto_info.iMaxSockAddr;
497 ss.ss_family = (ADDRESS_FAMILY)proto_info.iAddressFamily;
498#else
499 len = sizeof ss;
500 if (getsockname(fd, (struct sockaddr *)&ss, &len) == SOCKET_ERROR) {
501 return 0;
502 }
503#endif
504 sip->si_alen = len;
505
506 len = sizeof type;
507 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&type, &len) == SOCKET_ERROR) {
508#ifndef __REACTOS__
509 int err = WSAGetLastError();
510#endif
511 return 0;
512 }
513
514 /* XXX */
515#ifdef AF_LOCAL
516 if (ss.ss_family != AF_LOCAL) {
517#endif
518 if (type == SOCK_STREAM)
520 else if (type == SOCK_DGRAM)
522 else
523 return 0;
524#ifdef AF_LOCAL
525 } else
526 proto = 0;
527#endif
528
529 sip->si_af = ss.ss_family;
530 sip->si_proto = proto;
531 sip->si_socktype = type;
532
533 return 1;
534}
535
536/*
537 * Linear search, but the number of entries is small.
538 */
539int
540__rpc_nconf2sockinfo(const struct netconfig *nconf, struct __rpc_sockinfo *sip)
541{
542 int i;
543
544 for (i = 0; i < (sizeof na_cvt) / (sizeof (struct netid_af)); i++)
545 if (strcmp(na_cvt[i].netid, nconf->nc_netid) == 0 || (
546 strcmp(nconf->nc_netid, "unix") == 0 &&
547 strcmp(na_cvt[i].netid, "local") == 0)) {
548 sip->si_af = na_cvt[i].af;
549 sip->si_proto = na_cvt[i].protocol;
550 sip->si_socktype =
552 if (sip->si_socktype == -1)
553 return 0;
554 sip->si_alen = __rpc_get_a_size(sip->si_af);
555 return 1;
556 }
557
558 return 0;
559}
560
561SOCKET
562__rpc_nconf2fd(const struct netconfig *nconf)
563{
564 struct __rpc_sockinfo si;
565 SOCKET fd;
566
567 if (!__rpc_nconf2sockinfo(nconf, &si))
568 return 0;
569
570 if ((fd = socket(si.si_af, si.si_socktype, si.si_proto)) != INVALID_SOCKET &&
571 si.si_af == AF_INET6) {
572 int val = 1;
573
574 setsockopt(fd, SOL_IPV6, IPV6_V6ONLY, (const char *)&val, sizeof(val));
575 }
576 return fd;
577}
578
579int
580__rpc_sockinfo2netid(struct __rpc_sockinfo *sip, const char **netid)
581{
582 int i;
583 struct netconfig *nconf;
584
585 nconf = getnetconfigent("local");
586
587 for (i = 0; i < (sizeof na_cvt) / (sizeof (struct netid_af)); i++) {
588 if (na_cvt[i].af == sip->si_af &&
589 na_cvt[i].protocol == sip->si_proto) {
590 if (strcmp(na_cvt[i].netid, "local") == 0 && nconf == NULL) {
591 if (netid)
592 *netid = "unix";
593 } else {
594 if (netid)
595 *netid = na_cvt[i].netid;
596 }
597 if (nconf != NULL)
598 freenetconfigent(nconf);
599 return 1;
600 }
601 }
602 if (nconf != NULL)
603 freenetconfigent(nconf);
604
605 return 0;
606}
607
608char *
609taddr2uaddr(const struct netconfig *nconf, const struct netbuf *nbuf)
610{
611 struct __rpc_sockinfo si;
612
613 if (!__rpc_nconf2sockinfo(nconf, &si))
614 return NULL;
615 return __rpc_taddr2uaddr_af(si.si_af, nbuf);
616}
617
618struct netbuf *
619uaddr2taddr(const struct netconfig *nconf, const char *uaddr)
620{
621 struct __rpc_sockinfo si;
622
623 if (!__rpc_nconf2sockinfo(nconf, &si))
624 return NULL;
625 return __rpc_uaddr2taddr_af(si.si_af, uaddr);
626}
627
628void freeuaddr(char *uaddr)
629{
630 free(uaddr);
631}
632
633void freenetbuf(struct netbuf *nbuf)
634{
635 if (nbuf) {
636 free(nbuf->buf);
637 free(nbuf);
638 }
639}
640
641#ifdef __REACTOS__
642PCSTR
643WSAAPI
644inet_ntop(INT af, PVOID src, PSTR dst, size_t cnt)
645{
646 struct in_addr in;
647 char *text_addr;
648
649 if (af == AF_INET) {
650 memcpy(&in.s_addr, src, sizeof(in.s_addr));
651 text_addr = inet_ntoa(in);
652 if (text_addr && dst) {
653 strncpy(dst, text_addr, cnt);
654 return dst;
655 }
656 }
657
658 return 0;
659}
660#endif
661
662char *
663__rpc_taddr2uaddr_af(int af, const struct netbuf *nbuf)
664{
665 char *ret;
666 struct sockaddr_in *sin;
667#ifdef AF_LOCAL
668 struct sockaddr_un *sun;
669#endif
670 char namebuf[INET_ADDRSTRLEN];
671#ifdef INET6
672 struct sockaddr_in6 *sin6;
673 char namebuf6[INET6_ADDRSTRLEN];
674#endif
676
677 if (nbuf->len <= 0)
678 return NULL;
679
680 switch (af) {
681 case AF_INET:
682#ifdef __REACTOS__ // CVE-2017-8779
683 if (nbuf->len < sizeof(*sin)) {
684 return NULL;
685 }
686#endif
687 sin = nbuf->buf;
688 if (inet_ntop(af, &sin->sin_addr, namebuf, sizeof namebuf)
689 == NULL)
690 return NULL;
691 port = ntohs(sin->sin_port);
692 if (asprintf(&ret, "%s.%u.%u", namebuf, ((u_int32_t)port) >> 8,
693 port & 0xff) < 0)
694 return NULL;
695 break;
696#ifdef INET6
697 case AF_INET6:
698#ifdef __REACTOS__ // CVE-2017-8779
699 if (nbuf->len < sizeof(*sin6)) {
700 return NULL;
701 }
702#endif
703 sin6 = nbuf->buf;
704 if (inet_ntop(af, &sin6->sin6_addr, namebuf6, sizeof namebuf6)
705 == NULL)
706 return NULL;
707 port = ntohs(sin6->sin6_port);
708 if (asprintf(&ret, "%s.%u.%u", namebuf6, ((u_int32_t)port) >> 8,
709 port & 0xff) < 0)
710 return NULL;
711 break;
712#endif
713#ifdef AF_LOCAL
714 case AF_LOCAL:
715 sun = nbuf->buf;
716 /* if (asprintf(&ret, "%.*s", (int)(sun->sun_len -
717 offsetof(struct sockaddr_un, sun_path)),
718 sun->sun_path) < 0)*/
719 if (asprintf(&ret, "%.*s", (int)(sizeof(*sun) -
720 offsetof(struct sockaddr_un, sun_path)),
721 sun->sun_path) < 0)
722
723 return (NULL);
724 break;
725#endif
726 default:
727 return NULL;
728 }
729
730 return ret;
731}
732
733struct netbuf *
734__rpc_uaddr2taddr_af(int af, const char *uaddr)
735{
736 struct netbuf *ret = NULL;
737 char *addrstr, *p;
738 unsigned short port, portlo, porthi;
739 struct sockaddr_in *sin;
740#ifdef INET6
741 struct sockaddr_in6 *sin6;
742#endif
743#ifdef AF_LOCAL
744 struct sockaddr_un *sun;
745#endif
746
747 port = 0;
748 sin = NULL;
749#ifdef __REACTOS__ // CVE-2017-8779
750 if (uaddr == NULL)
751 return NULL;
752#endif
753 addrstr = strdup(uaddr);
754 if (addrstr == NULL)
755 return NULL;
756
757 /*
758 * AF_LOCAL addresses are expected to be absolute
759 * pathnames, anything else will be AF_INET or AF_INET6.
760 */
761 if (*addrstr != '/') {
762 p = strrchr(addrstr, '.');
763 if (p == NULL)
764 goto out;
765 portlo = (unsigned)atoi(p + 1);
766 *p = '\0';
767
768 p = strrchr(addrstr, '.');
769 if (p == NULL)
770 goto out;
771 porthi = (unsigned)atoi(p + 1);
772 *p = '\0';
773 port = (porthi << 8) | portlo;
774 }
775
776 ret = (struct netbuf *)malloc(sizeof *ret);
777 if (ret == NULL)
778 goto out;
779
780 switch (af) {
781 case AF_INET:
782 sin = (struct sockaddr_in *)malloc(sizeof *sin);
783 if (sin == NULL)
784 goto out;
785 memset(sin, 0, sizeof *sin);
786 sin->sin_family = AF_INET;
787 sin->sin_port = htons(port);
788#ifndef __REACTOS__
789 if (inet_pton(AF_INET, addrstr, &sin->sin_addr) <= 0) {
790#else
791 sin->sin_addr.S_un.S_addr = inet_addr(addrstr);
792 if (sin->sin_addr.S_un.S_addr == INADDR_NONE) {
793#endif
794 free(sin);
795 free(ret);
796 ret = NULL;
797 goto out;
798 }
799 ret->maxlen = ret->len = sizeof *sin;
800 ret->buf = sin;
801 break;
802#ifdef INET6
803 case AF_INET6:
804 sin6 = (struct sockaddr_in6 *)malloc(sizeof *sin6);
805 if (sin6 == NULL)
806 goto out;
807 memset(sin6, 0, sizeof *sin6);
808 sin6->sin6_family = AF_INET6;
809 sin6->sin6_port = htons(port);
810 if (inet_pton(AF_INET6, addrstr, &sin6->sin6_addr) <= 0) {
811 free(sin6);
812 free(ret);
813 ret = NULL;
814 goto out;
815 }
816 ret->maxlen = ret->len = sizeof *sin6;
817 ret->buf = sin6;
818 break;
819#endif
820#ifdef AF_LOCAL
821 case AF_LOCAL:
822 sun = (struct sockaddr_un *)malloc(sizeof *sun);
823 if (sun == NULL)
824 goto out;
825 memset(sun, 0, sizeof *sun);
826 sun->sun_family = AF_LOCAL;
827 strncpy(sun->sun_path, addrstr, sizeof(sun->sun_path) - 1);
828 ret->len = SUN_LEN(sun);
829 ret->maxlen = sizeof(struct sockaddr_un);
830 ret->buf = sun;
831 break;
832#endif
833 default:
834 break;
835 }
836out:
837 free(addrstr);
838 return ret;
839}
840
841int
843{
844 switch (semantics) {
845 case NC_TPI_CLTS:
846 return SOCK_DGRAM;
847 case NC_TPI_COTS_ORD:
848 return SOCK_STREAM;
849 case NC_TPI_RAW:
850 return SOCK_RAW;
851 default:
852 break;
853 }
854
855 return -1;
856}
857
858int
860{
861 switch (socktype) {
862 case SOCK_DGRAM:
863 return NC_TPI_CLTS;
864 case SOCK_STREAM:
865 return NC_TPI_COTS_ORD;
866 case SOCK_RAW:
867 return NC_TPI_RAW;
868 default:
869 break;
870 }
871
872 return -1;
873}
874
875/*
876 * XXXX - IPv6 scope IDs can't be handled in universal addresses.
877 * Here, we compare the original server address to that of the RPC
878 * service we just received back from a call to rpcbind on the remote
879 * machine. If they are both "link local" or "site local", copy
880 * the scope id of the server address over to the service address.
881 */
882int
883__rpc_fixup_addr(struct netbuf *new, const struct netbuf *svc)
884{
885#ifdef INET6
886 struct sockaddr *sa_new, *sa_svc;
887 struct sockaddr_in6 *sin6_new, *sin6_svc;
888
889 sa_svc = (struct sockaddr *)svc->buf;
890 sa_new = (struct sockaddr *)new->buf;
891
892 if (sa_new->sa_family == sa_svc->sa_family &&
893 sa_new->sa_family == AF_INET6) {
894 sin6_new = (struct sockaddr_in6 *)new->buf;
895 sin6_svc = (struct sockaddr_in6 *)svc->buf;
896
897 if ((IN6_IS_ADDR_LINKLOCAL(&sin6_new->sin6_addr) &&
898 IN6_IS_ADDR_LINKLOCAL(&sin6_svc->sin6_addr)) ||
899 (IN6_IS_ADDR_SITELOCAL(&sin6_new->sin6_addr) &&
900 IN6_IS_ADDR_SITELOCAL(&sin6_svc->sin6_addr))) {
901 sin6_new->sin6_scope_id = sin6_svc->sin6_scope_id;
902 }
903 }
904#endif
905 return 1;
906}
907
908int
910{
911 struct sockaddr_storage ss;
912 union {
913 struct sockaddr_in sin;
914 struct sockaddr_in6 sin6;
915#ifdef AF_LOCAL
916 struct sockaddr_un usin;
917#endif
918 } u_addr;
919 socklen_t slen;
920
921 slen = sizeof (struct sockaddr_storage);
922 if (getsockname(fd, (struct sockaddr *)(void *)&ss, &slen) == SOCKET_ERROR)
923 return 0;
924
925 switch (ss.ss_family) {
926 case AF_INET:
927 memcpy(&u_addr.sin, &ss, sizeof(u_addr.sin));
928 return (u_addr.sin.sin_port != 0);
929#ifdef INET6
930 case AF_INET6:
931 memcpy(&u_addr.sin6, &ss, sizeof(u_addr.sin6));
932 return (u_addr.sin6.sin6_port != 0);
933#endif
934#ifdef AF_LOCAL
935 case AF_LOCAL:
936 /* XXX check this */
937 memcpy(&u_addr.usin, &ss, sizeof(u_addr.usin));
938 return (u_addr.usin.sun_path[0] != 0);
939#endif
940 default:
941 break;
942 }
943
944 return 0;
945}
946
947/*
948 * Helper function to set up a netbuf
949 */
950struct netbuf *
951__rpc_set_netbuf(struct netbuf *nb, const void *ptr, size_t len)
952{
953 if (nb->len != len) {
954 if (nb->len)
955 mem_free(nb->buf, nb->len);
956 nb->buf = mem_alloc(len);
957 if (nb->buf == NULL)
958 return NULL;
959
960 nb->maxlen = nb->len = len;
961 }
962 memcpy(nb->buf, ptr, len);
963 return nb;
964}
bool_t xdr_void(void)
Definition: xdr.c:92
_STLP_DECLSPEC complex< float > _STLP_CALL sin(const complex< float > &)
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define isupper(c)
Definition: acclib.h:71
int tolower(int c)
Definition: utclib.c:902
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
int asprintf(char **str, const char *fmt,...)
Definition: asprintf.c:95
#define INADDR_NONE
Definition: tcp.c:42
#define NULLPROC
Definition: clnt.h:294
#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs)
Definition: clnt.h:202
@ RPC_SUCCESS
Definition: clnt_stat.h:22
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
UINT32 u_int
Definition: types.h:82
#define mem_free(ptr, bsize)
Definition: types.h:124
#define NULL
Definition: types.h:112
#define mem_alloc(bsize)
Definition: types.h:123
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
DWORD WINAPI TlsAlloc(VOID)
Definition: thread.c:1100
USHORT port
Definition: uri.c:228
#define IPPROTO_TCP
Definition: ip.h:196
#define IPPROTO_UDP
Definition: ip.h:197
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
#define strcasecmp
Definition: fake.h:9
void freenetconfigent(struct netconfig *netconfigp)
Definition: getnetconfig.c:530
int endnetconfig(void *handlep)
Definition: getnetconfig.c:373
struct netconfig * getnetconfigent(char *netid) const
Definition: getnetconfig.c:432
struct netconfig * getnetconfig(void *handlep)
Definition: getnetconfig.c:253
void * setnetconfig()
Definition: getnetconfig.c:217
void * setnetpath()
Definition: getnetpath.c:78
struct netconfig * getnetpath(void *handlep)
Definition: getnetpath.c:134
int endnetpath(void *handlep)
Definition: getnetpath.c:191
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble GLdouble t
Definition: gl.h:2047
GLsizeiptr size
Definition: glext.h:5919
GLenum src
Definition: glext.h:6340
GLuint in
Definition: glext.h:9616
GLenum GLenum dst
Definition: glext.h:6340
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ss
Definition: i386-dis.c:441
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
#define inet_addr(cp)
Definition: inet.h:98
#define inet_ntoa(addr)
Definition: inet.h:100
if(dx< 0)
Definition: linetemp.h:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define htons(x)
Definition: module.h:215
#define ntohs(x)
Definition: module.h:210
int socklen_t
Definition: tcp.c:35
static PVOID ptr
Definition: dispmode.c:27
static unsigned(__cdecl *hash_bstr)(bstr_t s)
thread_key_t tcp_key
Definition: mt_misc.c:91
thread_key_t udp_key
Definition: mt_misc.c:92
mutex_t tsd_lock
Definition: mt_misc.c:86
#define NC_TPI_COTS
Definition: netconfig.h:36
#define NC_VISIBLE
Definition: netconfig.h:44
#define NC_TPI_CLTS
Definition: netconfig.h:35
#define NC_TPI_COTS_ORD
Definition: netconfig.h:37
#define NC_TPI_RAW
Definition: netconfig.h:38
#define NC_INET6
Definition: netconfig.h:53
#define NC_TCP
Definition: netconfig.h:79
#define NC_INET
Definition: netconfig.h:52
#define NC_UDP
Definition: netconfig.h:80
#define _RPC_UDP
Definition: nettype.h:54
#define _RPC_CIRCUIT_V
Definition: nettype.h:49
#define _RPC_CIRCUIT_N
Definition: nettype.h:51
#define _RPC_VISIBLE
Definition: nettype.h:48
#define _RPC_NONE
Definition: nettype.h:46
#define _RPC_NETPATH
Definition: nettype.h:47
#define _RPC_DATAGRAM_V
Definition: nettype.h:50
#define _RPC_TCP
Definition: nettype.h:53
#define _RPC_DATAGRAM_N
Definition: nettype.h:52
#define TIMEOUT
Definition: ntpclient.c:12
#define err(...)
#define thr_setspecific(k, p)
Definition: reentrant.h:146
#define mutex_lock(m)
Definition: reentrant.h:128
#define thr_getspecific(k)
Definition: reentrant.h:147
#define mutex_unlock(m)
Definition: reentrant.h:129
#define thread_key_t
Definition: reentrant.h:124
static FILE * out
Definition: regtests2xml.c:44
unsigned int u_int32_t
Definition: rosdhcp.h:35
unsigned short u_int16_t
Definition: rosdhcp.h:34
int __rpc_fixup_addr(struct netbuf *new, const struct netbuf *svc)
Definition: rpc_generic.c:883
struct netconfig * __rpcgettp(SOCKET fd)
Definition: rpc_generic.c:464
void * __rpc_setconf(char *nettype) const
Definition: rpc_generic.c:305
static const struct netid_af na_cvt[]
Definition: rpc_generic.c:88
u_int __rpc_get_t_size(int af, int proto, int size)
Definition: rpc_generic.c:139
char * taddr2uaddr(const struct netconfig *nconf, const struct netbuf *nbuf)
Definition: rpc_generic.c:609
int __rpc_sockinfo2netid(struct __rpc_sockinfo *sip, const char **netid)
Definition: rpc_generic.c:580
int __rpc_dtbsize()
Definition: rpc_generic.c:110
void freenetbuf(struct netbuf *nbuf)
Definition: rpc_generic.c:633
static int getnettype(const char *)
struct netbuf * __rpc_set_netbuf(struct netbuf *nb, const void *ptr, size_t len)
Definition: rpc_generic.c:951
struct netconfig * __rpc_getconf(void *vhandle)
Definition: rpc_generic.c:348
struct netbuf * __rpc_uaddr2taddr_af(int af, const char *uaddr)
Definition: rpc_generic.c:734
int __rpc_fd2sockinfo(SOCKET fd, struct __rpc_sockinfo *sip)
Definition: rpc_generic.c:481
int __rpc_seman2socktype(int semantics)
Definition: rpc_generic.c:842
char * __rpc_taddr2uaddr_af(int af, const struct netbuf *nbuf)
Definition: rpc_generic.c:663
static const struct _rpcnettype _rpctypelist[]
void freeuaddr(char *uaddr)
Definition: rpc_generic.c:628
int __rpc_socktype2seman(int socktype)
Definition: rpc_generic.c:859
void __rpc_endconf(void *vhandle)
Definition: rpc_generic.c:425
u_int __rpc_get_a_size(int af)
Definition: rpc_generic.c:172
void * rpc_nullproc(CLIENT *clnt)
Definition: rpc_generic.c:447
struct netconfig * __rpc_getconfip(char *nettype) const
Definition: rpc_generic.c:235
int __rpc_nconf2sockinfo(const struct netconfig *nconf, struct __rpc_sockinfo *sip)
Definition: rpc_generic.c:540
int __rpc_sockisbound(SOCKET fd)
Definition: rpc_generic.c:909
SOCKET __rpc_nconf2fd(const struct netconfig *nconf)
Definition: rpc_generic.c:562
struct netbuf * uaddr2taddr(const struct netconfig *nconf, const char *uaddr)
Definition: rpc_generic.c:619
#define offsetof(TYPE, MEMBER)
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
static int fd
Definition: io.c:51
#define memset(x, y, z)
Definition: compat.h:39
INT WSAAPI getsockname(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR *namelen)
Definition: sockctrl.c:213
INT WSAAPI setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
INT WSAAPI getsockopt(IN SOCKET s, IN INT level, IN INT optname, OUT CHAR FAR *optval, IN OUT INT FAR *optlen)
Definition: sockctrl.c:271
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
#define RPC_MAXDATASIZE
Definition: rpc_com.h:51
#define RPC_MAXADDRSIZE
Definition: rpc_com.h:52
int si_socktype
Definition: types.h:167
int si_alen
Definition: types.h:168
ADDRESS_FAMILY si_af
Definition: types.h:165
int si_proto
Definition: types.h:166
const int type
Definition: rpc_generic.c:69
const char * name
Definition: rpc_generic.c:68
NCONF_HANDLE * nhandle
Definition: rpc_generic.c:62
int nettype
Definition: rpc_generic.c:64
int nflag
Definition: rpc_generic.c:63
Definition: tcpip.h:126
Definition: module.h:456
Definition: name.c:39
Definition: types.h:144
void * buf
Definition: types.h:147
unsigned int len
Definition: types.h:146
unsigned int maxlen
Definition: types.h:145
unsigned long nc_semantics
Definition: netconfig.h:17
unsigned long nc_flag
Definition: netconfig.h:18
char * nc_netid
Definition: netconfig.h:16
char * nc_protofmly
Definition: netconfig.h:19
char * nc_proto
Definition: netconfig.h:20
ADDRESS_FAMILY af
Definition: rpc_generic.c:84
const char * netid
Definition: rpc_generic.c:83
int protocol
Definition: rpc_generic.c:85
ULONG sin6_scope_id
Definition: ws2ipdef.h:184
ADDRESS_FAMILY sin6_family
Definition: ws2ipdef.h:179
IN6_ADDR sin6_addr
Definition: ws2ipdef.h:182
USHORT sin6_port
Definition: ws2ipdef.h:180
int sun_family
Definition: wintirpc.h:89
char sun_path[MAX_PATH]
Definition: wintirpc.h:90
u_short sa_family
Definition: winsock.h:217
#define UDPMSGSIZE
Definition: svc_raw.c:49
#define new(TYPE, numElems)
Definition: treelist.c:54
char * PSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
const char * PCSTR
Definition: typedefs.h:52
const char *WSAAPI inet_ntop(int af, const void *src, char *dst, size_t cnt)
Definition: unix_func.c:8
int ret
#define SO_PROTOCOL_INFO
Definition: winsock2.h:253
#define WSAAPI
Definition: winsock2.h:605
int PASCAL FAR WSAGetLastError(void)
Definition: dllmain.c:112
#define INVALID_SOCKET
Definition: winsock.h:332
#define SOCK_RAW
Definition: winsock.h:337
#define SOCK_DGRAM
Definition: winsock.h:336
UINT_PTR SOCKET
Definition: winsock.h:47
#define SOCKET_ERROR
Definition: winsock.h:333
#define SO_TYPE
Definition: winsock.h:195
#define SOL_SOCKET
Definition: winsock.h:398
#define AF_INET6
Definition: winsock.h:369
#define WINSOCK_HANDLE_HASH_SIZE
Definition: wintirpc.h:69
#define SOL_IPV6
Definition: wintirpc.h:84
#define SUN_LEN(ptr)
Definition: wintirpc.h:94
USHORT ADDRESS_FAMILY
Definition: ws2def.h:25
#define IPV6_V6ONLY
Definition: ws2ipdef.h:108
#define INET_ADDRSTRLEN
Definition: ws2ipdef.h:131
WS2TCPIP_INLINE BOOLEAN IN6_IS_ADDR_SITELOCAL(CONST IN6_ADDR *a)
Definition: ws2ipdef.h:371
WS2TCPIP_INLINE BOOLEAN IN6_IS_ADDR_LINKLOCAL(CONST IN6_ADDR *a)
Definition: ws2ipdef.h:364
#define INET6_ADDRSTRLEN
Definition: ws2ipdef.h:132
WINSOCK_API_LINKAGE INT WSAAPI inet_pton(_In_ INT Family, _In_ PCSTR pszAddrString, _Out_writes_bytes_(sizeof(IN6_ADDR)) PVOID pAddrBuf)
bool_t(* xdrproc_t)(XDR *,...)
Definition: xdr.h:144