ReactOS  0.4.14-dev-554-g2f8d847
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 
61 struct handle {
63  int nflag; /* Whether NETPATH or NETCONFIG */
64  int nettype;
65 };
66 
67 static 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 
82 struct netid_af {
83  const char *netid;
85  int protocol;
86 };
87 
88 static 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
101 static char *strlocase(char *);
102 #endif
103 static 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  */
109 int
111 {
112 #ifdef _WIN32
113  return (WINSOCK_HANDLE_HASH_SIZE);
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  */
137 u_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  */
171 u_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
193 static char *
194 strlocase(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  */
210 static int
211 getnettype(nettype)
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  */
234 struct 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;
242  extern thread_key_t tcp_key, udp_key;
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  */
304 void *
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  */
347 struct 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 
424 void
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  */
446 void *
448  CLIENT *clnt;
449 {
450  struct timeval TIMEOUT = {25, 0};
451 
452  if (clnt_call(clnt, NULLPROC, (xdrproc_t) xdr_void, NULL,
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  */
463 struct 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 
480 int
482 {
483  socklen_t len;
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)
519  proto = IPPROTO_TCP;
520  else if (type == SOCK_DGRAM)
521  proto = IPPROTO_UDP;
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  */
539 int
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 =
551  __rpc_seman2socktype((int)nconf->nc_semantics);
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 
561 SOCKET
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 
579 int
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 
608 char *
609 taddr2uaddr(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 
618 struct netbuf *
619 uaddr2taddr(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 
628 void freeuaddr(char *uaddr)
629 {
630  free(uaddr);
631 }
632 
633 void freenetbuf(struct netbuf *nbuf)
634 {
635  if (nbuf) {
636  free(nbuf->buf);
637  free(nbuf);
638  }
639 }
640 
641 #ifdef __REACTOS__
642 PCSTR
643 WSAAPI
644 inet_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 
662 char *
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
675  u_int16_t port;
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 
733 struct 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  }
836 out:
837  free(addrstr);
838  return ret;
839 }
840 
841 int
842 __rpc_seman2socktype(int semantics)
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 
858 int
859 __rpc_socktype2seman(int socktype)
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  */
882 int
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 
908 int
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  */
950 struct 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 }
u_int __rpc_get_t_size(int af, int proto, int size)
Definition: rpc_generic.c:139
#define SOCKET_ERROR
Definition: winsock.h:333
NCONF_HANDLE * nhandle
Definition: rpc_generic.c:62
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define TRUE
Definition: types.h:120
#define _RPC_TCP
Definition: nettype.h:53
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
#define inet_addr(cp)
Definition: inet.h:98
ADDRESS_FAMILY sin6_family
Definition: ws2ipdef.h:179
ADDRESS_FAMILY si_af
Definition: types.h:165
#define new(TYPE, numElems)
Definition: treelist.c:54
thread_key_t tcp_key
Definition: mt_misc.c:91
#define strcasecmp
Definition: fake.h:9
int si_proto
Definition: types.h:166
USHORT sin6_port
Definition: ws2ipdef.h:180
int nflag
Definition: rpc_generic.c:63
void * setnetpath()
Definition: getnetpath.c:78
#define NC_TPI_CLTS
Definition: netconfig.h:30
#define _RPC_UDP
Definition: nettype.h:54
struct netbuf * __rpc_set_netbuf(struct netbuf *nb, const void *ptr, size_t len)
Definition: rpc_generic.c:951
#define thr_setspecific(k, p)
Definition: reentrant.h:146
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
#define free
Definition: debug_ros.c:5
#define INADDR_NONE
Definition: tcp.c:42
char sun_path[MAX_PATH]
Definition: wintirpc.h:90
GLdouble GLdouble t
Definition: gl.h:2047
#define NC_TCP
Definition: netconfig.h:74
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
void * buf
Definition: types.h:147
static int fd
Definition: io.c:51
int __rpc_seman2socktype(int semantics)
Definition: rpc_generic.c:842
#define INET6_ADDRSTRLEN
Definition: request.c:1491
int __rpc_sockisbound(SOCKET fd)
Definition: rpc_generic.c:909
struct netconfig * __rpc_getconf(void *vhandle)
Definition: rpc_generic.c:348
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
void freenetbuf(struct netbuf *nbuf)
Definition: rpc_generic.c:633
#define SOL_SOCKET
Definition: winsock.h:398
unsigned long nc_flag
Definition: netconfig.h:13
ULONG sin6_scope_id
Definition: ws2ipdef.h:184
int32_t INT
Definition: typedefs.h:56
#define ntohs(x)
Definition: module.h:208
#define mutex_lock(m)
Definition: reentrant.h:128
#define SOCK_RAW
Definition: winsock.h:337
static const struct _rpcnettype _rpctypelist[]
struct netconfig * __rpc_getconfip(char *nettype) const
Definition: rpc_generic.c:235
int asprintf(char **str, const char *fmt,...)
Definition: asprintf.c:95
#define _RPC_VISIBLE
Definition: nettype.h:48
#define _RPC_CIRCUIT_N
Definition: nettype.h:51
struct netconfig * getnetconfig(void *handlep)
Definition: getnetconfig.c:253
#define mutex_unlock(m)
Definition: reentrant.h:129
void freeuaddr(char *uaddr)
Definition: rpc_generic.c:628
bool_t(* xdrproc_t)(XDR *,...)
Definition: xdr.h:144
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
static int getnettype(const char *)
#define mem_alloc(bsize)
Definition: types.h:123
#define thread_key_t
Definition: reentrant.h:124
int __rpc_fd2sockinfo(SOCKET fd, struct __rpc_sockinfo *sip)
Definition: rpc_generic.c:481
int si_socktype
Definition: types.h:167
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
#define NC_TPI_COTS_ORD
Definition: netconfig.h:32
char * nc_protofmly
Definition: netconfig.h:14
INT WSAAPI setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
static PVOID ptr
Definition: dispmode.c:27
void freenetconfigent(struct netconfig *netconfigp)
Definition: getnetconfig.c:530
#define NC_TPI_RAW
Definition: netconfig.h:33
smooth NULL
Definition: ftsmooth.c:416
struct netconfig * getnetconfigent(char *netid) const
Definition: getnetconfig.c:432
#define offsetof(TYPE, MEMBER)
#define _RPC_DATAGRAM_N
Definition: nettype.h:52
struct netbuf * uaddr2taddr(const struct netconfig *nconf, const char *uaddr)
Definition: rpc_generic.c:619
#define AF_INET6
Definition: winsock.h:369
int nettype
Definition: rpc_generic.c:64
char * nc_proto
Definition: netconfig.h:15
#define NC_VISIBLE
Definition: netconfig.h:39
#define SUN_LEN(ptr)
Definition: wintirpc.h:94
#define inet_ntoa(addr)
Definition: inet.h:100
GLuint GLfloat * val
Definition: glext.h:7180
#define TIMEOUT
Definition: ntpclient.c:12
#define WINSOCK_HANDLE_HASH_SIZE
Definition: wintirpc.h:69
mutex_t tsd_lock
Definition: mt_misc.c:86
int __rpc_fixup_addr(struct netbuf *new, const struct netbuf *svc)
Definition: rpc_generic.c:883
#define NULLPROC
Definition: clnt.h:294
#define _RPC_DATAGRAM_V
Definition: nettype.h:50
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
IN6_ADDR sin6_addr
Definition: ws2ipdef.h:182
GLsizeiptr size
Definition: glext.h:5919
#define INVALID_SOCKET
Definition: winsock.h:332
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define isupper(c)
Definition: acclib.h:71
int si_alen
Definition: types.h:168
char * __rpc_taddr2uaddr_af(int af, const struct netbuf *nbuf)
Definition: rpc_generic.c:663
Definition: tcpip.h:125
ADDRESS_FAMILY af
Definition: rpc_generic.c:84
int endnetpath(void *handlep)
Definition: getnetpath.c:191
static FILE * out
Definition: regtests2xml.c:44
int socklen_t
Definition: tcp.c:35
unsigned int maxlen
Definition: types.h:145
char * nc_netid
Definition: netconfig.h:11
#define SO_PROTOCOL_INFO
Definition: winsock2.h:253
const char * netid
Definition: rpc_generic.c:83
unsigned int len
Definition: types.h:146
USHORT ADDRESS_FAMILY
Definition: ws2def.h:25
unsigned short u_int16_t
Definition: rosdhcp.h:34
WS2TCPIP_INLINE BOOLEAN IN6_IS_ADDR_SITELOCAL(CONST IN6_ADDR *a)
Definition: ws2ipdef.h:371
#define thr_getspecific(k)
Definition: reentrant.h:147
#define NC_UDP
Definition: netconfig.h:75
#define NC_INET
Definition: netconfig.h:47
int ret
#define NC_TPI_COTS
Definition: netconfig.h:31
#define INET_ADDRSTRLEN
Definition: ws2ipdef.h:131
struct netbuf * __rpc_uaddr2taddr_af(int af, const char *uaddr)
Definition: rpc_generic.c:734
#define SO_TYPE
Definition: winsock.h:195
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned int u_int32_t
Definition: rosdhcp.h:35
DWORD WINAPI TlsAlloc(VOID)
Definition: thread.c:1088
GLenum src
Definition: glext.h:6340
#define err(...)
int __rpc_sockinfo2netid(struct __rpc_sockinfo *sip, const char **netid)
Definition: rpc_generic.c:580
#define RPC_MAXADDRSIZE
Definition: rpc_com.h:52
bool_t xdr_void(void)
Definition: xdr.c:92
SOCKET __rpc_nconf2fd(const struct netconfig *nconf)
Definition: rpc_generic.c:562
#define _RPC_NETPATH
Definition: nettype.h:47
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
u_short sa_family
Definition: winsock.h:217
int endnetconfig(void *handlep)
Definition: getnetconfig.c:373
#define _RPC_CIRCUIT_V
Definition: nettype.h:49
#define NC_INET6
Definition: netconfig.h:48
struct netconfig * __rpcgettp(SOCKET fd)
Definition: rpc_generic.c:464
GLuint in
Definition: glext.h:9616
void * __rpc_setconf(char *nettype) const
Definition: rpc_generic.c:305
UINT32 u_int
Definition: types.h:82
unsigned char dummy
Definition: maze.c:118
static const struct netid_af na_cvt[]
Definition: rpc_generic.c:88
#define WSAAPI
Definition: winsock2.h:584
GLenum GLenum dst
Definition: glext.h:6340
signed char * PSTR
Definition: retypes.h:7
#define IPV6_V6ONLY
Definition: ws2ipdef.h:108
#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs)
Definition: clnt.h:202
#define SOL_IPV6
Definition: wintirpc.h:84
Definition: types.h:144
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
int protocol
Definition: rpc_generic.c:85
Definition: name.c:38
WINSOCK_API_LINKAGE INT WSAAPI inet_pton(_In_ INT Family, _In_ PCSTR pszAddrString, _Out_writes_bytes_(sizeof(IN6_ADDR)) PVOID pAddrBuf)
const char * name
Definition: rpc_generic.c:68
thread_key_t udp_key
Definition: mt_misc.c:92
#define RPC_MAXDATASIZE
Definition: rpc_com.h:51
#define AF_INET
Definition: tcpip.h:117
#define mem_free(ptr, bsize)
Definition: types.h:124
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
struct netconfig * getnetpath(void *handlep)
Definition: getnetpath.c:134
const char *WSAAPI inet_ntop(int af, const void *src, char *dst, size_t cnt)
Definition: unix_func.c:8
#define _RPC_NONE
Definition: nettype.h:46
#define malloc
Definition: debug_ros.c:4
int __rpc_dtbsize()
Definition: rpc_generic.c:110
void __rpc_endconf(void *vhandle)
Definition: rpc_generic.c:425
int __rpc_nconf2sockinfo(const struct netconfig *nconf, struct __rpc_sockinfo *sip)
Definition: rpc_generic.c:540
UINT_PTR SOCKET
Definition: winsock.h:47
unsigned long nc_semantics
Definition: netconfig.h:12
const char * PCSTR
Definition: typedefs.h:51
_STLP_DECLSPEC complex< float > _STLP_CALL sin(const complex< float > &)
int sun_family
Definition: wintirpc.h:89
char * taddr2uaddr(const struct netconfig *nconf, const struct netbuf *nbuf)
Definition: rpc_generic.c:609
#define SOCK_STREAM
Definition: tcpip.h:118
#define UDPMSGSIZE
Definition: svc_raw.c:49
GLfloat GLfloat p
Definition: glext.h:8902
#define htons(x)
Definition: module.h:213
#define ss
Definition: i386-dis.c:432
Definition: module.h:446
void * setnetconfig()
Definition: getnetconfig.c:217
#define SOCK_DGRAM
Definition: winsock.h:336
USHORT port
Definition: uri.c:228
#define memset(x, y, z)
Definition: compat.h:39
u_int __rpc_get_a_size(int af)
Definition: rpc_generic.c:172
int tolower(int c)
Definition: utclib.c:902
int __rpc_socktype2seman(int socktype)
Definition: rpc_generic.c:859
INT WSAAPI getsockname(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR *namelen)
Definition: sockctrl.c:213
const int type
Definition: rpc_generic.c:69
static unsigned(__cdecl *hash_bstr)(bstr_t s)
WS2TCPIP_INLINE BOOLEAN IN6_IS_ADDR_LINKLOCAL(CONST IN6_ADDR *a)
Definition: ws2ipdef.h:364
void * rpc_nullproc(CLIENT *clnt)
Definition: rpc_generic.c:447