Jan 'RedBully' Seiffert schrieb:
> Simon Kelley schrieb:
>> Adding IPv6 support would be fairly simple: the DNS part of dnsmasq does
>> do IPv6, so all the bits are already in place, there just need to be an
>> IPv6 socket listening as well as an IPv4 one, and a couple of address
>> fields in structures need to be extended to hold IPv6 addresses.
>>
> 
> step one:
> widen the addresses used in tftp.c for use with IPv4 & IPv6
> 
> 

step two:
tell the udpfromto copy how to deal with ipv6

> only compile tested, i do not have any netboot stuff.

same, but i tested code like that in another project of mine, so should work,
minus bugs...

Greetings
        Jan

-- 
Every program in development at MIT expands until it can read mail.
=== modified file 'src/tftp.c'
--- upstream/src/tftp.c 2010-06-18 16:34:34 +0000
+++ ipv6_tftp/src/tftp.c        2010-06-18 17:09:35 +0000
@@ -90,15 +90,9 @@
   if ((len = recvmsg(listen->tftpfd, &msg, 0)) < 2)
     return;
 
-  memset(&addr, 0, sizeof(addr));
-// TODO: get proper address family
-  addr.sa.sa_family = AF_INET;
-#ifdef HAVE_SOCKADDR_SA_LEN
-  addr.sa.sa_len = sizeof(addr);
-#endif
   if (daemon->options & OPT_NOWILD)
     {
-      addr.in = listen->iface->addr.in;
+      addr = listen->iface->addr;
       mtu = listen->iface->mtu;
       name = listen->iface->name;
     }
@@ -108,8 +102,13 @@
       int check;
       struct interface_list *ir;
 
+      memset(&addr, 0, sizeof(addr));
+#ifdef HAVE_SOCKADDR_SA_LEN
+      addr.sa.sa_len = sizeof(addr);
+#endif
+      addr.sa.sa_family = AF_INET;
+
 // TODO: this looks like recvfromto
-      /* and needs to be pimped for IPv6 */
 #if defined(HAVE_LINUX_NETWORK)
       for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, 
cmptr))
        if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO)
@@ -122,6 +121,19 @@
            addr.in.sin_addr = p.p->ipi_spec_dst;
            if_index = p.p->ipi_ifindex;
          }
+#ifdef HAVE_IPV6
+       else if (cmptr->cmsg_level == SOL_IPV6 && cmptr->cmsg_type == 
daemon->v6pktinfo)
+         {
+           union {
+             unsigned char *c;
+             struct in6_pktinfo *p;
+           } p;
+           p.c = CMSG_DATA(cmptr);
+           addr.in6.sin6_family = AF_INET6;
+           memcpy(&addr.in6.sin6_addr, &p.p->ipi6_addr, 
sizeof(addr.in6.sin6_addr));
+           if_index = p.p->ipi6_ifindex;
+         }
+#endif
 
 #elif defined(HAVE_SOLARIS_NETWORK)
       for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, 
cmptr))
@@ -136,6 +148,14 @@
            addr.in.sin_addr = *(p.a);
          else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == 
IP_RECVIF)
            if_index = *(p.i);
+#ifdef HAVE_IPV6
+         /* Solaris does not have IPV6_RECVDSTADDR AFAIK, */
+         else if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == 
IP_RECVIF)
+           {
+             addr.in6.sin6_family = AF_INET6;
+             if_index = p.s->sdl_index;
+           }
+#endif
        }
 
 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
@@ -144,6 +164,9 @@
          union {
            unsigned char *c;
            struct in_addr *a;
+#ifdef HAVE_IPV6
+           struct in6_addr *b;
+#endif
            struct sockaddr_dl *s;
          } p;
          p.c = CMSG_DATA(cmptr);
@@ -151,6 +174,18 @@
            addr.in.sin_addr = *(p.a);
          else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == 
IP_RECVIF)
            if_index = p.s->sdl_index;
+#ifdef HAVE_IPV6
+         else if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == 
IPV6_RECVDSTADDR)
+           {
+             addr.in6.sin6_family = AF_INET6;
+             memcpy(&addr.in6.sin6_addr, p.b, sizeof(addr.in6.sin6_addr));
+           }
+         else if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == 
IP_RECVIF)
+           {
+             addr.in6.sin6_family = AF_INET6;
+             if_index = p.s->sdl_index;
+           }
+#endif
        }
 
 #endif
@@ -172,13 +207,13 @@
       for (ir = daemon->tftp_interfaces; ir; ir = ir->next)
        if (strcmp(ir->interface, name) == 0)
          break;
-       
+
       if (!ir)
        {
          if (!daemon->tftp_unlimited || !check)
            return;
-         
-#ifdef HAVE_DHCP      
+
+#ifdef HAVE_DHCP
          /* allowed interfaces are the same as for DHCP */
          for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
            if (tmp->name && (strcmp(tmp->name, name) == 0))

Reply via email to