DTS Application Library  0.2.3
Application library containing referenced objects and interfaces to common libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
Multicast sockets

Support for multicast sockets either IPv4 or IPv6. More...

Functions

void mcast6_ip (struct in6_addr *addr)
 Randomally assign a SSM Multicast address.param addr Ip address structure to fill out. More...
 
void mcast4_ip (struct in_addr *addr)
 Randomally assign a SSM Multicast address. More...
 
struct fwsocketmcast_socket (const char *iface, int family, const char *mcastip, const char *port, int flags)
 Create a multicast socket. More...
 

Detailed Description

Support for multicast sockets either IPv4 or IPv6.

Function Documentation

void mcast4_ip ( struct in_addr *  addr)

Randomally assign a SSM Multicast address.

Parameters
addrIp address structure to fill out.

Definition at line 504 of file iputil.c.

References genrand().

Referenced by mcast_socket().

504  {
505  uint32_t mip, rand;
506 
507  do {
508  rand = genrand(&mip, 3);
509  mip >>= 8;
510  } while (!rand || !(mip >> 8));
511  mip |= 232 << 24;
512 
513  addr->s_addr = htonl(mip);
514 }
int genrand(void *buf, int len)
Generate random sequence.
Definition: util.c:82
void mcast6_ip ( struct in6_addr *  addr)

Randomally assign a SSM Multicast address.param addr Ip address structure to fill out.

Definition at line 480 of file iputil.c.

References genrand().

Referenced by mcast_socket().

480  {
481  int mip, rand;
482  uint32_t *i;
483 
484 #ifndef __WIN32
485  i = (uint32_t*)&addr->s6_addr32;
486 #else
487  i = (uint32_t*)&addr->u.Word;
488 #endif
489  i[0] = htonl(0xFF350000);
490  i[1] = 0;
491  i[2] = 0;
492  i[3] = 1 << 31;
493 
494  do {
495  rand = genrand(&mip, 4);
496  } while (!rand);
497 
498  i[3] = htonl(i[3] | mip);
499 }
int genrand(void *buf, int len)
Generate random sequence.
Definition: util.c:82
struct fwsocket* mcast_socket ( const char *  iface,
int  family,
const char *  mcastip,
const char *  port,
int  flags 
)

Create a multicast socket.

A multicast socket is both a client and server due to the nature of multicasting writing to a multicast socket should only be done with socketwrite not socketwrite_d the socket is created on a interface and the initial address can be set.

Todo:
Win32 support for inet_ntop/inet_pton
Parameters
ifaceInterface to send and recieve multicast traffic.
familyIP address family PF_INET or PF_INET6.
mcastipMulticast ip to use must be in "family".
portPort to use.
flagsMulticast flags currently disables LOOP.
Returns
Reference to multicast ocket structure.

Definition at line 536 of file socket.c.

References fwsocket::addr, fwsocket::flags, get_iface_index(), get_ifinfo(), get_ifipaddr(), ifinfo::idx, inet_lookup(), ifinfo::ipv4addr, ifinfo::ipv6addr, make_socket(), mcast4_ip(), mcast6_ip(), objref(), objunref(), sockstruct::sa, seedrand(), fwsocket::sock, and SOCK_FLAG_MCAST.

536  {
537  struct fwsocket *fws;
538  struct addrinfo hint, *result, *rp;
539  struct in_addr *srcif;
540  const char *srcip;
541  int ifidx;
542  int on = 1;
543  int off = 0;
544  int ttl = 50;
545  socklen_t slen = sizeof(union sockstruct);
546 #ifdef __WIN32
547  struct ifinfo *ifinf;
548 #endif
549 
550  memset(&hint, 0, sizeof(hint));
551  hint.ai_family = PF_UNSPEC;
552  hint.ai_socktype = SOCK_DGRAM;
553  hint.ai_protocol = IPPROTO_UDP;
554 
555 #ifndef __WIN32
556  if (!(srcip = get_ifipaddr(iface, family))) {
557  return NULL;
558  }
559 
560  if (getaddrinfo(srcip, port, &hint, &result) || !result) {
561  free((void*)srcip);
562  return NULL;
563  }
564  free((void*)srcip);
565 #else
566  if (!(ifinf = get_ifinfo(iface))) {
567  return NULL;
568  }
569  ifidx = ifinf->idx;
570 
571  srcip = (family == AF_INET) ? ifinf->ipv4addr : ifinf->ipv6addr;
572  if (!srcip || (getaddrinfo(srcip, port, &hint, &result) || !result)) {
573  objunref(ifinf);
574  return NULL;
575  }
576  objunref(ifinf);
577 #endif
578 
579  for(rp = result; rp; rp = result->ai_next) {
580  if (!(fws = make_socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol, NULL))) {
581  continue;
582  }
583  break;
584  }
585 
586  if (!rp || !fws) {
587  freeaddrinfo(result);
588  return NULL;
589  }
590 
591  if(setsockopt(fws->sock, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on))) {
592  objunref(fws);
593  freeaddrinfo(result);
594  return NULL;
595  }
596 
597  if (rp->ai_family == PF_INET) {
598  struct in_addr mcastip4;
599  struct ip_mreq mg;
600  struct sockaddr_in *src_ip;
601 
602  src_ip = (struct sockaddr_in*)rp->ai_addr;
603 
604  if (setsockopt(fws->sock, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(ttl))) {
605  objunref(fws);
606  freeaddrinfo(result);
607  return NULL;
608  }
609 
610  if (flags && setsockopt(fws->sock, IPPROTO_IP, IP_MULTICAST_LOOP, (char*)&off, sizeof(off))) {
611  freeaddrinfo(result);
612  objunref(fws);
613  return NULL;
614  }
615 
616  if (mcastip) {
617  inet_lookup(PF_INET, mcastip, &mcastip4, sizeof(mcastip4));
618  } else {
619  seedrand();
620  mcast4_ip(&mcastip4);
621  }
622 
623  mg.imr_multiaddr = mcastip4;
624  mg.imr_interface.s_addr = src_ip->sin_addr.s_addr;
625  if (setsockopt(fws->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mg, sizeof(mg))) {
626  objunref(fws);
627  freeaddrinfo(rp);
628  return NULL;
629  }
630 
631  memset(&srcif, 0, sizeof(srcif));
632  srcif = &src_ip->sin_addr;
633  if(setsockopt(fws->sock, IPPROTO_IP, IP_MULTICAST_IF, (char*)srcif, sizeof(*srcif))) {
634  freeaddrinfo(rp);
635  objunref(fws);
636  return NULL;
637  }
638  src_ip->sin_addr.s_addr = mcastip4.s_addr;
639  } else if (rp->ai_family == PF_INET6) {
640  struct in6_addr mcastip6;
641  struct ipv6_mreq mg;
642  struct sockaddr_in6 *src_ip;
643 
644 #ifndef __WIN32
645  ifidx = get_iface_index(iface);
646 #endif
647  src_ip = (struct sockaddr_in6*)rp->ai_addr;
648 
649  if (setsockopt(fws->sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char*)&ttl, sizeof(ttl))) {
650  objunref(fws);
651  freeaddrinfo(result);
652  return NULL;
653  }
654 
655  if (flags && setsockopt(fws->sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char*)&off, sizeof(off))) {
656  freeaddrinfo(result);
657  objunref(fws);
658  return NULL;
659  }
660 
661  if (mcastip) {
662  inet_lookup(PF_INET6, mcastip, &mcastip6, sizeof(mcastip6));
663  } else {
664  seedrand();
665  mcast6_ip(&mcastip6);
666  }
667 
668  mg.ipv6mr_multiaddr = mcastip6;
669  mg.ipv6mr_interface = ifidx;
670  if (setsockopt(fws->sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char*)&mg, sizeof(mg))) {
671  objunref(fws);
672  freeaddrinfo(rp);
673  return NULL;
674  }
675 
676  if (setsockopt(fws->sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char*)&ifidx, sizeof(ifidx))) {
677  objref(fws);
678  freeaddrinfo(rp);
679  return NULL;
680  }
681 
682  src_ip->sin6_addr = mcastip6;
683  }
684 
685  if (bind(fws->sock, (struct sockaddr*)rp->ai_addr, sizeof(struct sockaddr_storage))) {
686  freeaddrinfo(result);
687  objunref(fws);
688  return NULL;
689  }
690 
691  getsockname(fws->sock, &fws->addr.sa, &slen);
692  freeaddrinfo(result);
693  fws->flags |= SOCK_FLAG_MCAST;
694 
695  return fws;
696 }
union sockstruct addr
system socket data structure.
Definition: dtsapp.h:143
int objref(void *data)
Reference a object.
Definition: refobj.c:153
void mcast6_ip(struct in6_addr *addr)
Randomally assign a SSM Multicast address.param addr Ip address structure to fill out...
Definition: iputil.c:480
int inet_lookup(int family, const char *host, void *addr, socklen_t len)
Perform DNS lookup on a host/ip retun the IP address.
Definition: iputil.c:523
Socket data structure.
Definition: dtsapp.h:131
Multicast Socket.
Definition: dtsapp.h:112
Data structure containing interface information.
Definition: dtsapp.h:176
int idx
Interface index required for at least IPv6 multicast support.
Definition: dtsapp.h:178
struct ifinfo * get_ifinfo(const char *iface)
Return interface info for a specified interface.
Definition: winiface.cpp:83
int sock
Socket FD.
Definition: dtsapp.h:133
const char * get_ifipaddr(const char *iface, int family)
Find best IP adress for a interface.
Definition: interface.c:783
int get_iface_index(const char *ifname)
Get the netlink interface for a named interface.
Definition: interface.c:139
const char * ipv6addr
IPv6 address priorised by Local/6in4.
Definition: dtsapp.h:184
const char * ipv4addr
IPv4 address priorotised by Routed/Reserved/Zeroconf.
Definition: dtsapp.h:182
struct fwsocket * make_socket(int family, int type, int proto, void *ssl)
Allocate a socket structure and return reference.
Definition: socket.c:120
void seedrand(void)
Seed openssl random number generator.
Definition: util.c:68
struct sockaddr sa
Base socket addr structure.
Definition: dtsapp.h:82
void mcast4_ip(struct in_addr *addr)
Randomally assign a SSM Multicast address.
Definition: iputil.c:504
Socket union describing all address types.
Definition: dtsapp.h:80
enum sock_flags flags
Socket control flags.
Definition: dtsapp.h:140
int objunref(void *data)
Drop reference held.
Definition: refobj.c:184