[Xastir-Dev] IPv6?

Alan Crosswell alan at columbia.edu
Tue Aug 5 13:10:27 EDT 2003


You have to do some small code changes which are then backward compatible with 
IPv4, but the normal struct sockaddr union doesn't have enough space in it.  See 
my aprsdigi code for some examples.  It's not that terrible to make the change 
if your code is written using sizeof(foo), and getaddrinfo() etc.

Some sample snippets:

#ifdef IPV6
   struct sockaddr_storage rsa,tsa,rsafrom;      /* and their sockaddrs */
#else
   struct sockaddr rsa,tsa,rsafrom;      /* and their sockaddrs */
#endif /*IPV6*/

...

static void
do_port_udp(struct interface *i)
{
   struct hostent *hp;
   struct servent *sp;
   char *name, *service, *ttl;
   const int one=1;
   int ttlval;
   struct addrinfo *ai, hints = {0, PF_UNSPEC, SOCK_DGRAM, 0};

   i->dev = i->port;             /* might as well just use the same thing */
   /* hostname/service(port)/ttl */
   name = i->port;
   service = strchr(name,'/');
   if (!service || *service != '/')
     usage_udp();
   *service++ = '\0';
   ttl = strchr(service,'/');
   if (!ttl || *ttl != '/')
     usage_udp();
   *ttl++ = '\0';
   if ((ttlval = atoi(ttl)) <= 0)
       usage_udp();

   if (Verbose)
     fprintf(stderr,"opening UDP socket on %s/%s/%d\n", name, service, ttlval);
   if (getaddrinfo(name,service,&hints,&ai) < 0)
     die(name);
   if (Verbose)
     fprintf(stderr,"UDP address info: family %d type %d proto %d next 0x%0x\n",
             ai->ai_family,ai->ai_socktype,ai->ai_protocol,ai->ai_next);
   if (ai->ai_socktype != SOCK_DGRAM) {
     die("getaddrinfo returned non SOCK_DGRAM!\n");
   }
   if (!(i->i_flags & I_TX)) {
     i->tsock = -1;
   } else {
     if ((i->tsock = socket(ai->ai_family, SOCK_DGRAM, 0)) == -1)
       die(name);
     if (setsockopt(i->tsock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0)
       die(i->port);
     if (ai->ai_family == AF_INET) { /* IPv4 */
       i->tsa_size = sizeof(struct sockaddr);
       if (IN_MULTICAST(ntohl(((struct 
sockaddr_in*)ai->ai_addr)->sin_addr.s_addr))) {
         if (setsockopt(i->tsock, SOL_IP, IP_MULTICAST_TTL, &ttlval, 
sizeof(ttlval)) < 0
)
           die(i->port);
       } else {
         if (setsockopt(i->tsock, SOL_IP, IP_TTL, &ttlval, sizeof(ttlval)) < 0)
           die(i->port);
       }
#ifdef IPV6
     } else if (ai->ai_family == AF_INET6) { /* IPv6 */
       i->tsa_size = sizeof(struct sockaddr_storage);
       /* XXX ??? */
#endif /* IPV6 */
     } else {
       fprintf(stderr,"%s: unsupported protocol family\n",i->port);
       exit(1);
     }
     bzero(&i->tsa,sizeof(i->tsa));
     bcopy((struct sockaddr*)ai->ai_addr,&i->tsa,sizeof(i->tsa)); /* fill 
sockaddr w/soc
kaddr_in */
     if (connect(i->tsock, (struct sockaddr *)&i->tsa, i->tsa_size) < 0) {
       die(i->dev);
     }
   }

   /* now the receive socket */
   if (!(i->i_flags & I_RX)) {
     i->rsock = -1;
   } else {
     if ((i->rsock = socket(ai->ai_family, SOCK_DGRAM, 0)) == -1) {
       die(i->port);
     }
     if (setsockopt(i->rsock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0)
       die(i->port);

     if (ai->ai_family == AF_INET && !IN_MULTICAST(ntohl(((struct 
sockaddr_in*)ai->ai_ad
dr)->sin_addr.s_addr))) {
       ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr = INADDR_ANY; /* not 
mcast s
o wildcard listen */
       i->rsa_size = sizeof(struct sockaddr);
#ifdef IPV6
     } else if (ai->ai_family == AF_INET6) { /* IPv6 */
       /* XXX ??? */
#endif /* IPV6 */
     }
     i->rsa_size = sizeof(struct sockaddr_storage);
     bzero(&i->rsa,sizeof(i->rsa));
     bcopy((struct sockaddr*)ai->ai_addr,&i->rsa,sizeof(i->rsa));
     if (bind(i->rsock, (struct sockaddr *)&i->rsa, i->rsa_size) < 0) {
       die(i->dev);
     }
     /* if the UDP socket is a multicast group, then do IGMP join for rsock */

     if (ai->ai_family == AF_INET && IN_MULTICAST(ntohl(((struct 
sockaddr_in*)ai->ai_add
r)->sin_addr.s_addr))) {
       struct ip_mreq mreq;
       mreq.imr_multiaddr = ((struct sockaddr_in*)ai->ai_addr)->sin_addr;
       mreq.imr_interface.s_addr = INADDR_ANY;
       if (setsockopt(i->rsock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, 
sizeof(mreq)) < 0)
         die(i->port);
#ifdef IPV6
     } else if (ai->ai_family == AF_INET6) { /* IPv6 */
       /* XXX ??? */
#endif /* IPV6 */
     }
   }
}




More information about the Xastir-dev mailing list