ReactOS  0.4.14-dev-50-g13bb5e2
clnt_bcast.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 //#include <sys/cdefs.h>
32 
33 /*
34  * clnt_bcast.c
35  * Client interface to broadcast service.
36  *
37  * Copyright (C) 1988, Sun Microsystems, Inc.
38  *
39  * The following is kludged-up support for simple rpc broadcasts.
40  * Someday a large, complicated system will replace these routines.
41  */
42 
43 #include <wintirpc.h>
44 //#include <sys/socket.h>
45 #include <sys/types.h>
46 //#include <sys/queue.h>
47 
48 /* new queue functions */
49 //#include <misc/queue.h>
50 
51 //#include <net/if.h>
52 //#include <netinet/in.h>
53 //#include <ifaddrs.h>
54 //#include <sys/poll.h>
55 #include <rpc/rpc.h>
56 #ifdef PORTMAP
57 #include <rpc/pmap_prot.h>
58 #include <rpc/pmap_clnt.h>
59 #include <rpc/pmap_rmt.h>
60 #endif /* PORTMAP */
61 #include <rpc/nettype.h>
62 //#include <arpa/inet.h>
63 #ifdef RPC_DEBUG
64 #include <stdio.h>
65 #endif
66 #include <errno.h>
67 #include <stdlib.h>
68 //#include <unistd.h>
69 //#include <netdb.h>
70 //#include <err.h>
71 #include <string.h>
72 
73 #include "rpc_com.h"
74 
75 #define MAXBCAST 20 /* Max no of broadcasting transports */
76 #define INITTIME 4000 /* Time to wait initially */
77 #define WAITTIME 8000 /* Maximum time to wait */
78 
79 #ifndef POLLRDNORM
80 # define POLLRDNORM 0x040 /* Normal data may be read. */
81 #endif
82 #ifndef POLLRDBAND
83 # define POLLRDBAND 0x080 /* Priority data may be read. */
84 #endif
85 
86 /*
87  * For now, ASSUME that we do not need this for the Windows port!!!!
88  */
89 #include <wintirpc.h>
90 #ifdef _WIN32
91 int __rpc_lowvers = 0;
92 
93 enum clnt_stat
94 rpc_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp,
95  eachresult, nettype)
96  rpcprog_t prog; /* program number */
97  rpcvers_t vers; /* version number */
98  rpcproc_t proc; /* procedure number */
99  xdrproc_t xargs; /* xdr routine for args */
100  caddr_t argsp; /* pointer to args */
101  xdrproc_t xresults; /* xdr routine for results */
102  caddr_t resultsp; /* pointer to results */
103  resultproc_t eachresult; /* call with each result obtained */
104  const char *nettype; /* transport type */
105 {
106  return 0;
107 }
108 #else
109 
110 
111 /*
112  * If nettype is NULL, it broadcasts on all the available
113  * datagram_n transports. May potentially lead to broadacst storms
114  * and hence should be used with caution, care and courage.
115  *
116  * The current parameter xdr packet size is limited by the max tsdu
117  * size of the transport. If the max tsdu size of any transport is
118  * smaller than the parameter xdr packet, then broadcast is not
119  * sent on that transport.
120  *
121  * Also, the packet size should be less the packet size of
122  * the data link layer (for ethernet it is 1400 bytes). There is
123  * no easy way to find out the max size of the data link layer and
124  * we are assuming that the args would be smaller than that.
125  *
126  * The result size has to be smaller than the transport tsdu size.
127  *
128  * If PORTMAP has been defined, we send two packets for UDP, one for
129  * rpcbind and one for portmap. For those machines which support
130  * both rpcbind and portmap, it will cause them to reply twice, and
131  * also here it will get two responses ... inefficient and clumsy.
132  */
133 
134 #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
135 
136 #define TAILQ_FIRST(head) ((head)->tqh_first)
137 
138 
139 struct broadif {
140  int index;
143 };
144 
145 typedef TAILQ_HEAD(, broadif) broadlist_t;
146 
147 int __rpc_getbroadifs(int, int, int, broadlist_t *);
148 void __rpc_freebroadifs(broadlist_t *);
149 int __rpc_broadenable(int, int, struct broadif *);
150 
151 int __rpc_lowvers = 0;
152 
153 int
154 __rpc_getbroadifs(int af, int proto, int socktype, broadlist_t *list)
155 {
156  int count = 0;
157  struct broadif *bip;
158  struct ifaddrs *ifap, *ifp;
159 #ifdef INET6
160  struct sockaddr_in6 *sin6;
161 #endif
162  struct sockaddr_in *sin;
163  struct addrinfo hints, *res;
164 
165 #if 0 /* WINDOWS */
166  if (getifaddrs(&ifp) < 0)
167  return 0;
168 #else
169  /* Use GetAdaptersAddresses() ? */
170 #endif
171 
172  memset(&hints, 0, sizeof hints);
173 
174  hints.ai_family = af;
175  hints.ai_protocol = proto;
176  hints.ai_socktype = socktype;
177 
178  if (getaddrinfo(NULL, "sunrpc", &hints, &res) != 0)
179  return 0;
180 
181  for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
182  if (ifap->ifa_addr->sa_family != af ||
183  !(ifap->ifa_flags & IFF_UP))
184  continue;
185  bip = (struct broadif *)malloc(sizeof *bip);
186  if (bip == NULL)
187  break;
188  bip->index = if_nametoindex(ifap->ifa_name);
189  if (
190 #ifdef INET6
191  af != AF_INET6 &&
192 #endif
193  (ifap->ifa_flags & IFF_BROADCAST) &&
194  ifap->ifa_broadaddr) {
195  /* memcpy(&bip->broadaddr, ifap->ifa_broadaddr,
196  (size_t)ifap->ifa_broadaddr->sa_len);*/
197  memcpy(&bip->broadaddr, ifap->ifa_broadaddr,
198  sizeof(bip->broadaddr));
199  sin = (struct sockaddr_in *)(void *)&bip->broadaddr;
200  sin->sin_port =
201  ((struct sockaddr_in *)
202  (void *)res->ai_addr)->sin_port;
203  } else
204 #ifdef INET6
205  if (af == AF_INET6 && (ifap->ifa_flags & IFF_MULTICAST)) {
206  sin6 = (struct sockaddr_in6 *)(void *)&bip->broadaddr;
208  sin6->sin6_family = af;
209  sin6->sin6_port =
210  ((struct sockaddr_in6 *)
211  (void *)res->ai_addr)->sin6_port;
212  sin6->sin6_scope_id = bip->index;
213  } else
214 #endif
215  {
216  free(bip);
217  continue;
218  }
219  TAILQ_INSERT_TAIL(list, bip, link);
220  count++;
221  }
222  freeifaddrs(ifp);
223  freeaddrinfo(res);
224 
225  return count;
226 }
227 
228 void
230 {
231  struct broadif *bip, *next;
232 
233  bip = TAILQ_FIRST(list);
234 
235  while (bip != NULL) {
236  next = TAILQ_NEXT(bip, link);
237  free(bip);
238  bip = next;
239  }
240 }
241 
242 int
243 /*ARGSUSED*/
244 __rpc_broadenable(int af, int s, struct broadif *bip)
245 {
246  int o = 1;
247 
248 #if 0
249  if (af == AF_INET6) {
250  fprintf(stderr, "set v6 multicast if to %d\n", bip->index);
251  if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &bip->index,
252  sizeof bip->index) < 0)
253  return -1;
254  } else
255 #endif
256  if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &o, sizeof o) == SOCKET_ERROR)
257  return -1;
258 
259  return 0;
260 }
261 
262 
263 enum clnt_stat
264 rpc_broadcast_exp(prog, vers, proc, xargs, argsp, xresults, resultsp,
265  eachresult, inittime, waittime, nettype)
266  rpcprog_t prog; /* program number */
267  rpcvers_t vers; /* version number */
268  rpcproc_t proc; /* procedure number */
269  xdrproc_t xargs; /* xdr routine for args */
270  caddr_t argsp; /* pointer to args */
271  xdrproc_t xresults; /* xdr routine for results */
272  caddr_t resultsp; /* pointer to results */
273  resultproc_t eachresult; /* call with each result obtained */
274  int inittime; /* how long to wait initially */
275  int waittime; /* maximum time to wait */
276  const char *nettype; /* transport type */
277 {
278  enum clnt_stat stat = RPC_SUCCESS; /* Return status */
279  XDR xdr_stream; /* XDR stream */
280  XDR *xdrs = &xdr_stream;
281  struct rpc_msg msg; /* RPC message */
282  struct timeval t;
283  char *outbuf = NULL; /* Broadcast msg buffer */
284  char *inbuf = NULL; /* Reply buf */
285  int inlen;
286  u_int maxbufsize = 0;
287  AUTH *sys_auth = authunix_create_default();
288  int i;
289  void *handle;
290  char uaddress[1024]; /* A self imposed limit */
291  char *uaddrp = uaddress;
292  int pmap_reply_flag; /* reply recvd from PORTMAP */
293  /* An array of all the suitable broadcast transports */
294  struct {
295  int fd; /* File descriptor */
296  int af;
297  int proto;
298  struct netconfig *nconf; /* Netconfig structure */
299  u_int asize; /* Size of the addr buf */
300  u_int dsize; /* Size of the data buf */
301  struct sockaddr_storage raddr; /* Remote address */
302  broadlist_t nal;
303  } fdlist[MAXBCAST];
304  struct pollfd pfd[MAXBCAST];
305  size_t fdlistno = 0;
306  struct r_rpcb_rmtcallargs barg; /* Remote arguments */
307  struct r_rpcb_rmtcallres bres; /* Remote results */
308  size_t outlen;
309  struct netconfig *nconf;
310  int msec;
311  int pollretval;
312  int fds_found;
313 
314 #ifdef PORTMAP
315  size_t outlen_pmap = 0;
316  u_long port; /* Remote port number */
317  int pmap_flag = 0; /* UDP exists ? */
318  char *outbuf_pmap = NULL;
319  struct rmtcallargs barg_pmap; /* Remote arguments */
320  struct rmtcallres bres_pmap; /* Remote results */
321  u_int udpbufsz = 0;
322 #endif /* PORTMAP */
323 
324  if (sys_auth == NULL) {
325  return (RPC_SYSTEMERROR);
326  }
327  /*
328  * initialization: create a fd, a broadcast address, and send the
329  * request on the broadcast transport.
330  * Listen on all of them and on replies, call the user supplied
331  * function.
332  */
333 
334  if (nettype == NULL)
335  nettype = "datagram_n";
336  if ((handle = __rpc_setconf(nettype)) == NULL) {
337  return (RPC_UNKNOWNPROTO);
338  }
339  while ((nconf = __rpc_getconf(handle)) != NULL) {
340  int fd;
341  struct __rpc_sockinfo si;
342 
343  if (nconf->nc_semantics != NC_TPI_CLTS)
344  continue;
345  if (fdlistno >= MAXBCAST)
346  break; /* No more slots available */
347  if (!__rpc_nconf2sockinfo(nconf, &si))
348  continue;
349 
350  TAILQ_INIT(&fdlist[fdlistno].nal);
351  if (__rpc_getbroadifs(si.si_af, si.si_proto, si.si_socktype,
352  &fdlist[fdlistno].nal) == 0)
353  continue;
354 
355  fd = socket(si.si_af, si.si_socktype, si.si_proto);
356  if (fd == INVALID_SOCKET) {
357  stat = RPC_CANTSEND;
358  continue;
359  }
360  fdlist[fdlistno].af = si.si_af;
361  fdlist[fdlistno].proto = si.si_proto;
362  fdlist[fdlistno].fd = fd;
363  fdlist[fdlistno].nconf = nconf;
364  fdlist[fdlistno].asize = __rpc_get_a_size(si.si_af);
365  pfd[fdlistno].events = POLLIN | POLLPRI |
367  pfd[fdlistno].fd = fdlist[fdlistno].fd = fd;
368  fdlist[fdlistno].dsize = __rpc_get_t_size(si.si_af, si.si_proto,
369  0);
370 
371  if (maxbufsize <= fdlist[fdlistno].dsize)
372  maxbufsize = fdlist[fdlistno].dsize;
373 
374 #ifdef PORTMAP
375  if (si.si_af == AF_INET && si.si_proto == IPPROTO_UDP) {
376  udpbufsz = fdlist[fdlistno].dsize;
377  if ((outbuf_pmap = malloc(udpbufsz)) == NULL) {
378  closesocket(fd);
380  goto done_broad;
381  }
382  pmap_flag = 1;
383  }
384 #endif /* PORTMAP */
385  fdlistno++;
386  }
387 
388  if (fdlistno == 0) {
389  if (stat == RPC_SUCCESS)
391  goto done_broad;
392  }
393  if (maxbufsize == 0) {
394  if (stat == RPC_SUCCESS)
395  stat = RPC_CANTSEND;
396  goto done_broad;
397  }
398  inbuf = malloc(maxbufsize);
399  outbuf = malloc(maxbufsize);
400  if ((inbuf == NULL) || (outbuf == NULL)) {
402  goto done_broad;
403  }
404 
405  /* Serialize all the arguments which have to be sent */
406  (void) gettimeofday(&t, NULL);
407  msg.rm_xid = __RPC_GETXID(&t);
408  msg.rm_direction = CALL;
409  msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
410  msg.rm_call.cb_prog = RPCBPROG;
411  msg.rm_call.cb_vers = RPCBVERS;
412  msg.rm_call.cb_proc = RPCBPROC_CALLIT;
413  barg.prog = prog;
414  barg.vers = vers;
415  barg.proc = proc;
416  barg.args.args_val = argsp;
417  barg.xdr_args = xargs;
418  bres.addr = uaddrp;
419  bres.results.results_val = resultsp;
420  bres.xdr_res = xresults;
421  msg.rm_call.cb_cred = sys_auth->ah_cred;
422  msg.rm_call.cb_verf = sys_auth->ah_verf;
423  xdrmem_create(xdrs, outbuf, maxbufsize, XDR_ENCODE);
424  if ((!xdr_callmsg(xdrs, &msg)) ||
425  (!xdr_rpcb_rmtcallargs(xdrs,
426  (struct rpcb_rmtcallargs *)(void *)&barg))) {
428  goto done_broad;
429  }
430  outlen = xdr_getpos(xdrs);
431  xdr_destroy(xdrs);
432 
433 #ifdef PORTMAP
434  /* Prepare the packet for version 2 PORTMAP */
435  if (pmap_flag) {
436  msg.rm_xid++; /* One way to distinguish */
437  msg.rm_call.cb_prog = PMAPPROG;
438  msg.rm_call.cb_vers = PMAPVERS;
439  msg.rm_call.cb_proc = PMAPPROC_CALLIT;
440  barg_pmap.prog = prog;
441  barg_pmap.vers = vers;
442  barg_pmap.proc = proc;
443  barg_pmap.args_ptr = argsp;
444  barg_pmap.xdr_args = xargs;
445  bres_pmap.port_ptr = &port;
446  bres_pmap.xdr_results = xresults;
447  bres_pmap.results_ptr = resultsp;
448  xdrmem_create(xdrs, outbuf_pmap, udpbufsz, XDR_ENCODE);
449  if ((! xdr_callmsg(xdrs, &msg)) ||
450  (! xdr_rmtcall_args(xdrs, &barg_pmap))) {
452  goto done_broad;
453  }
454  outlen_pmap = xdr_getpos(xdrs);
455  xdr_destroy(xdrs);
456  }
457 #endif /* PORTMAP */
458 
459  /*
460  * Basic loop: broadcast the packets to transports which
461  * support data packets of size such that one can encode
462  * all the arguments.
463  * Wait a while for response(s).
464  * The response timeout grows larger per iteration.
465  */
466  for (msec = inittime; msec <= waittime; msec += msec) {
467  struct broadif *bip;
468 
469  /* Broadcast all the packets now */
470  for (i = 0; i < fdlistno; i++) {
471  if (fdlist[i].dsize < outlen) {
472  stat = RPC_CANTSEND;
473  continue;
474  }
475  for (bip = TAILQ_FIRST(&fdlist[i].nal); bip != NULL;
476  bip = TAILQ_NEXT(bip, link)) {
477  void *addr;
478 
479  addr = &bip->broadaddr;
480 
481  __rpc_broadenable(fdlist[i].af, fdlist[i].fd,
482  bip);
483 
484  /*
485  * Only use version 3 if lowvers is not set
486  */
487 
488  if (!__rpc_lowvers)
489  if (sendto(fdlist[i].fd, outbuf,
490  outlen, 0, (struct sockaddr*)addr,
491  (size_t)fdlist[i].asize) !=
492  outlen) {
493 #ifdef RPC_DEBUG
494  perror("sendto");
495 #endif
496  warnx("clnt_bcast: cannot send"
497  "broadcast packet");
498  stat = RPC_CANTSEND;
499  continue;
500  };
501 #ifdef RPC_DEBUG
502  if (!__rpc_lowvers)
503  fprintf(stderr, "Broadcast packet sent "
504  "for %s\n",
505  fdlist[i].nconf->nc_netid);
506 #endif
507 #ifdef PORTMAP
508  /*
509  * Send the version 2 packet also
510  * for UDP/IP
511  */
512  if (pmap_flag &&
513  fdlist[i].proto == IPPROTO_UDP) {
514  if (sendto(fdlist[i].fd, outbuf_pmap,
515  outlen_pmap, 0, addr,
516  (size_t)fdlist[i].asize) !=
517  outlen_pmap) {
518  warnx("clnt_bcast: "
519  "Cannot send broadcast packet");
520  stat = RPC_CANTSEND;
521  continue;
522  }
523  }
524 #ifdef RPC_DEBUG
525  fprintf(stderr, "PMAP Broadcast packet "
526  "sent for %s\n",
527  fdlist[i].nconf->nc_netid);
528 #endif
529 #endif /* PORTMAP */
530  }
531  /* End for sending all packets on this transport */
532  } /* End for sending on all transports */
533 
534  if (eachresult == NULL) {
535  stat = RPC_SUCCESS;
536  goto done_broad;
537  }
538 
539  /*
540  * Get all the replies from these broadcast requests
541  */
542  recv_again:
543 
544  switch (pollretval = poll(pfd, fdlistno, msec)) {
545  case 0: /* timed out */
546  stat = RPC_TIMEDOUT;
547  continue;
548  case -1: /* some kind of error - we ignore it */
549  goto recv_again;
550  } /* end of poll results switch */
551 
552  for (i = fds_found = 0;
553  i < fdlistno && fds_found < pollretval; i++) {
554  bool_t done = FALSE;
555 
556  if (pfd[i].revents == 0)
557  continue;
558  else if (pfd[i].revents & POLLNVAL) {
559  /*
560  * Something bad has happened to this descri-
561  * ptor. We can cause _poll() to ignore
562  * it simply by using a negative fd. We do that
563  * rather than compacting the pfd[] and fdlist[]
564  * arrays.
565  */
566  pfd[i].fd = -1;
567  fds_found++;
568  continue;
569  } else
570  fds_found++;
571 #ifdef RPC_DEBUG
572  fprintf(stderr, "response for %s\n",
573  fdlist[i].nconf->nc_netid);
574 #endif
575  try_again:
576  inlen = recvfrom(fdlist[i].fd, inbuf, fdlist[i].dsize,
577  0, (struct sockaddr *)(void *)&fdlist[i].raddr,
578  &fdlist[i].asize);
579  if (inlen < 0) {
580  if (errno == EINTR)
581  goto try_again;
582  warnx("clnt_bcast: Cannot receive reply to "
583  "broadcast");
584  stat = RPC_CANTRECV;
585  continue;
586  }
587  if (inlen < sizeof (u_int32_t))
588  continue; /* Drop that and go ahead */
589  /*
590  * see if reply transaction id matches sent id.
591  * If so, decode the results. If return id is xid + 1
592  * it was a PORTMAP reply
593  */
594  if (*((u_int32_t *)(void *)(inbuf)) ==
595  *((u_int32_t *)(void *)(outbuf))) {
596  pmap_reply_flag = 0;
597  msg.acpted_rply.ar_verf = _null_auth;
598  msg.acpted_rply.ar_results.where =
599  (caddr_t)(void *)&bres;
600  msg.acpted_rply.ar_results.proc =
602 #ifdef PORTMAP
603  } else if (pmap_flag &&
604  *((u_int32_t *)(void *)(inbuf)) ==
605  *((u_int32_t *)(void *)(outbuf_pmap))) {
606  pmap_reply_flag = 1;
607  msg.acpted_rply.ar_verf = _null_auth;
608  msg.acpted_rply.ar_results.where =
609  (caddr_t)(void *)&bres_pmap;
610  msg.acpted_rply.ar_results.proc =
612 #endif /* PORTMAP */
613  } else
614  continue;
615  xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE);
616  if (xdr_replymsg(xdrs, &msg)) {
617  if ((msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
618  (msg.acpted_rply.ar_stat == SUCCESS)) {
619  struct netbuf *np;
620 #ifdef PORTMAP
621  struct netbuf taddr;
622  struct sockaddr_in sin;
623 
624  if (pmap_flag && pmap_reply_flag) {
625  memcpy(&sin, &fdlist[i].raddr, sizeof(sin));
626  sin.sin_port = htons((u_short)port);
627  memcpy(&fdlist[i].raddr, &sin, sizeof(sin));
628  taddr.len = taddr.maxlen =
629  sizeof(fdlist[i].raddr);
630  taddr.buf = &fdlist[i].raddr;
631  done = (*eachresult)(resultsp,
632  &taddr, fdlist[i].nconf);
633  } else {
634 #endif /* PORTMAP */
635 #ifdef RPC_DEBUG
636  fprintf(stderr, "uaddr %s\n",
637  uaddrp);
638 #endif
639  np = uaddr2taddr(
640  fdlist[i].nconf, uaddrp);
641  done = (*eachresult)(resultsp,
642  np, fdlist[i].nconf);
643  free(np);
644 #ifdef PORTMAP
645  }
646 #endif /* PORTMAP */
647  }
648  /* otherwise, we just ignore the errors ... */
649  }
650  /* else some kind of deserialization problem ... */
651 
652  xdrs->x_op = XDR_FREE;
653  msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
654  (void) xdr_replymsg(xdrs, &msg);
655  (void) (*xresults)(xdrs, resultsp);
656  XDR_DESTROY(xdrs);
657  if (done) {
658  stat = RPC_SUCCESS;
659  goto done_broad;
660  } else {
661  goto recv_again;
662  }
663  } /* The recv for loop */
664  } /* The giant for loop */
665 
666 done_broad:
667  if (inbuf)
668  (void) free(inbuf);
669  if (outbuf)
670  (void) free(outbuf);
671 #ifdef PORTMAP
672  if (outbuf_pmap)
673  (void) free(outbuf_pmap);
674 #endif /* PORTMAP */
675  for (i = 0; i < fdlistno; i++) {
676  (void)closesocket(fdlist[i].fd);
677  __rpc_freebroadifs(&fdlist[i].nal);
678  }
679  AUTH_DESTROY(sys_auth);
681 
682  return (stat);
683 }
684 
685 
686 enum clnt_stat
687 rpc_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp,
688  eachresult, nettype)
689  rpcprog_t prog; /* program number */
690  rpcvers_t vers; /* version number */
691  rpcproc_t proc; /* procedure number */
692  xdrproc_t xargs; /* xdr routine for args */
693  caddr_t argsp; /* pointer to args */
694  xdrproc_t xresults; /* xdr routine for results */
695  caddr_t resultsp; /* pointer to results */
696  resultproc_t eachresult; /* call with each result obtained */
697  const char *nettype; /* transport type */
698 {
699  enum clnt_stat dummy;
700 
701  dummy = rpc_broadcast_exp(prog, vers, proc, xargs, argsp,
702  xresults, resultsp, eachresult,
703  INITTIME, WAITTIME, nettype);
704  return (dummy);
705 }
706 
707 #endif
#define xdr_getpos(xdrs)
Definition: xdr.h:201
rpcprog_t prog
Definition: rpcb_prot.h:253
u_int __rpc_get_t_size(int af, int proto, int size)
Definition: rpc_generic.c:139
#define TAILQ_INIT(head)
Definition: queue.h:348
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:363
namespace GUID const ADDRINFOEXW * hints
Definition: sock.c:80
#define SOCKET_ERROR
Definition: winsock.h:333
INT WSAAPI recvfrom(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags, OUT LPSOCKADDR from, IN OUT INT FAR *fromlen)
Definition: recv.c:87
struct sockaddr_storage broadaddr
Definition: clnt_bcast.c:141
u_int32_t rpcproc_t
Definition: types.h:106
#define PMAPPROG
Definition: pmap_prot.h:77
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
typedef TAILQ_HEAD(broadif)
Definition: clnt_bcast.c:145
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
u_short sin_port
Definition: winsock.h:511
#define freeaddrinfo
Definition: wspiapi.h:46
unsigned long u_long
Definition: linux.h:269
u_int32_t rpcvers_t
Definition: types.h:105
Definition: rpc_msg.h:78
ADDRESS_FAMILY sin6_family
Definition: ws2ipdef.h:179
int __rpc_broadenable(int af, int s, struct broadif *bip)
Definition: clnt_bcast.c:244
ADDRESS_FAMILY si_af
Definition: types.h:165
u_long proc
Definition: pmap_rmt.h:47
int si_proto
Definition: types.h:166
USHORT sin6_port
Definition: ws2ipdef.h:180
int32_t bool_t
Definition: types.h:101
#define NC_TPI_CLTS
Definition: netconfig.h:30
#define IFF_UP
Definition: ws2ipdef.h:21
char * prog
Definition: isohybrid.c:47
GLuint GLuint GLsizei count
Definition: gl.h:1545
rpcvers_t vers
Definition: rpcb_prot.h:254
#define free
Definition: debug_ros.c:5
#define EINTR
Definition: acclib.h:80
#define INITTIME
Definition: clnt_bcast.c:76
u_long vers
Definition: pmap_rmt.h:47
struct r_rpcb_rmtcallargs::@193 args
#define POLLRDBAND
Definition: clnt_bcast.c:83
GLdouble GLdouble t
Definition: gl.h:2047
#define PMAPPROC_CALLIT
Definition: pmap_prot.h:86
Definition: auth.h:205
#define warnx(...)
void * buf
Definition: types.h:147
static int fd
Definition: io.c:51
xdrproc_t xdr_res
Definition: rpcb_prot.h:295
u_long prog
Definition: pmap_rmt.h:47
static HANDLE proc()
Definition: pdb.c:32
struct netconfig * __rpc_getconf(void *vhandle)
Definition: rpc_generic.c:348
#define TAILQ_FIRST(head)
Definition: clnt_bcast.c:136
int errno
#define SOL_SOCKET
Definition: winsock.h:398
#define xdr_destroy(xdrs)
Definition: xdr.h:217
char * caddr_t
Definition: rosdhcp.h:36
caddr_t results_ptr
Definition: pmap_rmt.h:55
ULONG sin6_scope_id
Definition: ws2ipdef.h:184
Definition: xdr.h:103
bool_t xdr_rmtcallres(XDR *xdrs, struct rmtcallres *crp)
Definition: pmap_rmt.c:153
AUTH * authunix_create_default()
Definition: auth_unix.c:198
#define gettimeofday(tv, tz)
Definition: adns_win32.h:159
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
int index
Definition: clnt_bcast.c:140
struct opaque_auth _null_auth
void __rpc_freebroadifs(broadlist_t *list)
Definition: clnt_bcast.c:229
#define IFF_BROADCAST
Definition: ws2ipdef.h:22
#define closesocket
Definition: main.c:39
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
int si_socktype
Definition: types.h:167
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define SO_BROADCAST
Definition: winsock.h:183
#define RPCBPROG
Definition: rpcb_prot.h:626
INT WSAAPI setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
smooth NULL
Definition: ftsmooth.c:416
caddr_t args_ptr
Definition: pmap_rmt.h:48
struct netbuf * uaddr2taddr(const struct netconfig *nconf, const char *uaddr)
Definition: rpc_generic.c:619
#define AF_INET6
Definition: winsock.h:369
#define PMAPVERS
Definition: pmap_prot.h:78
bool_t xdr_rmtcall_args(XDR *xdrs, struct rmtcallargs *cap)
Definition: pmap_rmt.c:119
bool_t xdr_callmsg(XDR *xdrs, struct rpc_msg *cmsg)
Definition: rpc_callmsg.c:50
rpcproc_t proc
Definition: rpcb_prot.h:255
IN6_ADDR sin6_addr
Definition: ws2ipdef.h:182
bool_t xdr_rpcb_rmtcallres(XDR *xdrs, struct rpcb_rmtcallres *p)
Definition: rpcb_prot.c:322
#define POLLRDNORM
Definition: clnt_bcast.c:80
#define INVALID_SOCKET
Definition: winsock.h:332
struct opaque_auth ah_verf
Definition: auth.h:207
int poll(struct pollfd *ufds, int nfds, int timeout)
Definition: adnstest.c:68
xdrproc_t xdr_args
Definition: rpcb_prot.h:260
struct r_rpcb_rmtcallres::@195 results
enum xdr_op x_op
Definition: xdr.h:104
u_int32_t rpcprog_t
Definition: types.h:104
#define POLLIN
Definition: linux.h:1853
unsigned int maxlen
Definition: types.h:145
char * nc_netid
Definition: netconfig.h:11
Definition: linux.h:1867
enum clnt_stat rpc_broadcast(rpcprog_t prog, rpcvers_t vers, rpcproc_t proc, xdrproc_t xargs, caddr_t argsp, xdrproc_t xresults, caddr_t resultsp, resultproc_t eachresult, const char *nettype)
Definition: clnt_bcast.c:687
bool_t xdr_rpcb_rmtcallargs(XDR *xdrs, struct rpcb_rmtcallargs *p)
Definition: rpcb_prot.c:270
#define POLLPRI
Definition: linux.h:1854
unsigned int len
Definition: types.h:146
unsigned short u_short
Definition: types.h:81
enum clnt_stat rpc_broadcast_exp(rpcprog_t prog, rpcvers_t vers, rpcproc_t proc, xdrproc_t xargs, caddr_t argsp, xdrproc_t xresults, caddr_t resultsp, resultproc_t eachresult, int inittime, int waittime, const char *nettype)
Definition: clnt_bcast.c:264
uchar inbuf[M_BLOCK]
Definition: unzcrash.c:40
int __rpc_lowvers
static PIXELFORMATDESCRIPTOR pfd
Definition: ssstars.c:67
GLenum const GLvoid * addr
Definition: glext.h:9621
#define RPCBVERS
Definition: rpcb_prot.h:627
Definition: xdr.h:85
Definition: stat.h:55
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned int u_int32_t
Definition: rosdhcp.h:35
GLdouble s
Definition: gl.h:2039
Definition: _list.h:228
#define TAILQ_NEXT(elm, field)
Definition: clnt_bcast.c:134
#define POLLNVAL
Definition: linux.h:1858
bool_t xdr_void(void)
Definition: xdr.c:92
u_long * port_ptr
Definition: pmap_rmt.h:53
static unsigned __int64 next
Definition: rand_nt.c:6
#define RPC_MSG_VERSION
Definition: rpc_msg.h:66
void * __rpc_setconf(char *nettype) const
Definition: rpc_generic.c:305
#define caddr_t
Definition: ftp.c:24
UINT32 u_int
Definition: types.h:82
unsigned char dummy
Definition: maze.c:118
#define RPCB_MULTICAST_ADDR
Definition: clnt.h:77
xdrproc_t xdr_results
Definition: pmap_rmt.h:56
#define __RPC_GETXID(now)
Definition: rpc_com.h:58
void xdrmem_create(XDR *xdrs, char *addr, u_int size, enum xdr_op op)
Definition: xdr_mem.c:94
INT WSAAPI sendto(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags, IN CONST struct sockaddr *to, IN INT tolen)
Definition: send.c:82
Definition: types.h:144
#define msg(x)
Definition: auth_time.c:54
Definition: xdr.h:87
WINSOCK_API_LINKAGE INT WSAAPI inet_pton(_In_ INT Family, _In_ PCSTR pszAddrString, _Out_writes_bytes_(sizeof(IN6_ADDR)) PVOID pAddrBuf)
GLuint res
Definition: glext.h:9613
#define IFF_MULTICAST
Definition: ws2ipdef.h:25
struct opaque_auth ah_cred
Definition: auth.h:206
Definition: xdr.h:86
FILE * stderr
#define AF_INET
Definition: tcpip.h:117
#define IPV6_MULTICAST_IF
Definition: ws2ipdef.h:94
#define malloc
Definition: debug_ros.c:4
void __rpc_endconf(void *vhandle)
Definition: rpc_generic.c:425
#define MAXBCAST
Definition: clnt_bcast.c:75
int __rpc_nconf2sockinfo(const struct netconfig *nconf, struct __rpc_sockinfo *sip)
Definition: rpc_generic.c:540
const WCHAR * link
Definition: db.cpp:988
unsigned long nc_semantics
Definition: netconfig.h:12
#define AUTH_DESTROY(auth)
Definition: auth.h:257
_STLP_DECLSPEC complex< float > _STLP_CALL sin(const complex< float > &)
#define WAITTIME
Definition: clnt_bcast.c:77
#define htons(x)
Definition: module.h:213
USHORT port
Definition: uri.c:227
#define memset(x, y, z)
Definition: compat.h:39
bool_t xdr_replymsg(XDR *xdrs, struct rpc_msg *rmsg)
Definition: rpc_prot.c:188
__BEGIN_DECLS u_int __rpc_get_a_size(int)
Definition: rpc_generic.c:172
#define TAILQ_ENTRY(type)
Definition: queue.h:315
#define XDR_DESTROY(xdrs)
Definition: xdr.h:214
clnt_stat
Definition: clnt_stat.h:21
__END_DECLS typedef bool_t(* resultproc_t)(caddr_t,...)
Definition: clnt.h:570
uchar outbuf[M_BLOCK_OUT]
Definition: unzcrash.c:41
#define getaddrinfo
Definition: wspiapi.h:44
#define RPCBPROC_CALLIT
Definition: rpcb_prot.h:694
xdrproc_t xdr_args
Definition: pmap_rmt.h:49