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))