Date: Fri, 7 Jan 2005 17:57:04 +0100 From: Andrea Campi <andrea+freebsd_net@webcom.it> To: freebsd-net@freebsd.org Subject: howl patch for better BSD support Message-ID: <20050107165703.GC16579@webcom.it>
next in thread | raw e-mail | index | archive | help
--dTy3Mrz/UPE2dbVg Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, as promised, I've been working on improving howl. I've been in touch with the authors, so in fact this is also resulting in cross-platform fixes. You can find the results of my work so far either attached to this email (provided they get through mailing list filters) or at this URL: http://www.webcom.it/ports/howl/files/patch-BSD ; you can just drop in the ports/net/howl/files directory. The current status is that autoipd and nifd are working (for people not familiar with howl, these deal with address negotiation and interface status monitoring respectively). I haven't done anything with mDNSResponder apart from checking it still compiles. There's a lot of stuff to cleanup. Style sucks beyond telling, but that's because at this stage I'm striving to keep the sources diffable to their Linux counterpart. This will change at a later stage. Could some kind folk familiar look at the diff and maybe try it? Apart from feedback of the "it works/doesn't" kind, I'm also looking for guidance on the preferred way to do things. On this note: I'm still using SIOCAIFADDR, as mentioned before, to add a new IP address. I'm still not sure on how to do it best. The way things currently work is: - when autoipd starts, it figures out a random IP, using the MAC address as a seed. It starts probing for someone else already using it, and if nobody is, it start announcing it; - autoipd then starts monitoring for conflicts, and when it detects one it either tries to defend or picks a different one; - nifd is charged with monitoring link state changes; if it detects one, or it notices that an interface changed IP address, it signals autoipd to go through all the process again. Now all this all nice, except it doesn't work! If I manually change the interface address, to simulate what for instance dhclient would do, nifd notices and signals autoipd, who then goes, picks a new IP address and sets it! This happens because nothing is checking whether the IP is valid before letting autoipd loose. The problem is that this is too hard to do in the general case; however, I think we can reasonably deal with the common DHCP+zeroconf case by using dhclient-script(8). Basically, I'd start autoipd on EXPIRE or FAIL and kill it on BOUND. I will go this way, at least for a beginning, unless someone with more experience is willing to guide me. I do plan on creating a sample script that could be provided in the port to give a complete solution. Thought? Bye, Andrea -- Intel: where Quality is job number 0.9998782345! --dTy3Mrz/UPE2dbVg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=patch-BSD Content-Transfer-Encoding: quoted-printable Index: configure =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/CVS/howl/work/howl-0.9.7/configure,v retrieving revision 1.1.1.1 retrieving revision 1.3 diff -u -r1.1.1.1 -r1.3 --- configure 12 Dec 2004 08:24:26 -0000 1.1.1.1 +++ configure 12 Dec 2004 09:16:29 -0000 1.3 @@ -8516,6 +8516,17 @@ PLATFORM_LIBS=3D"-framework CoreFoundation" HOWL_MAN_PAGES=3D ;; + *-*-freebsd*) + SRC_SUBDIRS=3D"lib mDNSResponder autoipd nifd" + LIB_SUBDIRS=3D"howl mDNSResponder" + HOWL_LIB_SUBDIRS=3D"Posix NotOSX" + HOWL_LIB_OBJECTS=3D'posix_salt.lo posix_socket.lo posix_time.lo posix_si= gnal.lo posix_interface.lo notosx_mdns_stub.lo' + MDNSRESPONDER_LIB_SUBDIRS=3D"Posix" + MDNSRESPONDER_LIB_OBJECTS=3D'posix_mdns.lo' + AUTOIPD_EXTRA_OBJECTS=3D'freebsd_autoip.lo posix_main.lo' + PLATFORM_LIBS=3D-lpthread + HOWL_MAN_PAGES=3D'mDNSResponder.8 autoipd.8 nifd.8' + ;; *-*-linux*) SRC_SUBDIRS=3D"lib mDNSResponder autoipd nifd" LIB_SUBDIRS=3D"howl mDNSResponder" @@ -8562,7 +8573,7 @@ =20 =20 =20 - = = = = ac_config_file= s=3D"$ac_config_files Makefile include/Makefile include/salt/Makefile inclu= de/corby/Makefile include/discovery/Makefile include/rendezvous/Makefile sr= c/Makefile src/lib/Makefile src/lib/howl/Makefile src/lib/howl/MacOSX/Makef= ile src/lib/howl/Posix/Makefile src/lib/howl/Win32/Makefile src/lib/howl/No= tOSX/Makefile src/lib/mDNSResponder/Makefile src/lib/mDNSResponder/Posix/Ma= kefile src/lib/mDNSResponder/Win32/Makefile src/mDNSResponder/Makefile src/= mDNSResponder/Posix/Makefile src/mDNSResponder/Win32/Makefile src/autoipd/M= akefile src/autoipd/Posix/Makefile src/autoipd/Linux/Makefile src/nifd/Make= file test/Makefile test/step/Makefile samples/Makefile samples/console/Make= file samples/console/publish/Makefile samples/console/browse/Makefile sampl= es/console/resolve/Makefile samples/console/query/Makefile samples/Win32/Ma= kefile samples/Win32/IEBar/Makefile docs/Makefile etc/Makefile howl.pc" + = = = = ac_config_file= s=3D"$ac_config_files Makefile include/Makefile include/salt/Makefile inclu= de/corby/Makefile include/discovery/Makefile include/rendezvous/Makefile sr= c/Makefile src/lib/Makefile src/lib/howl/Makefile src/lib/howl/MacOSX/Makef= ile src/lib/howl/Posix/Makefile src/lib/howl/Win32/Makefile src/lib/howl/No= tOSX/Makefile src/lib/mDNSResponder/Makefile src/lib/mDNSResponder/Posix/Ma= kefile src/lib/mDNSResponder/Win32/Makefile src/mDNSResponder/Makefile src/= mDNSResponder/Posix/Makefile src/mDNSResponder/Win32/Makefile src/autoipd/M= akefile src/autoipd/Posix/Makefile src/autoipd/BSD/Makefile src/autoipd/Lin= ux/Makefile src/nifd/Makefile test/Makefile test/step/Makefile samples/Make= file samples/console/Makefile samples/console/publish/Makefile samples/cons= ole/browse/Makefile samples/console/resolve/Makefile samples/console/query/= Makefile samples/Win32/Makefile samples/Win32/IEBar/Makefile docs/Makefile = etc/Makefile howl.pc" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -9125,6 +9136,7 @@ "src/mDNSResponder/Win32/Makefile" ) CONFIG_FILES=3D"$CONFIG_FILES src/m= DNSResponder/Win32/Makefile" ;; "src/autoipd/Makefile" ) CONFIG_FILES=3D"$CONFIG_FILES src/autoipd/Makef= ile" ;; "src/autoipd/Posix/Makefile" ) CONFIG_FILES=3D"$CONFIG_FILES src/autoipd= /Posix/Makefile" ;; + "src/autoipd/BSD/Makefile" ) CONFIG_FILES=3D"$CONFIG_FILES src/autoipd/B= SD/Makefile" ;; "src/autoipd/Linux/Makefile" ) CONFIG_FILES=3D"$CONFIG_FILES src/autoipd= /Linux/Makefile" ;; "src/nifd/Makefile" ) CONFIG_FILES=3D"$CONFIG_FILES src/nifd/Makefile" ;; "test/Makefile" ) CONFIG_FILES=3D"$CONFIG_FILES test/Makefile" ;; Index: src/autoipd/Makefile.in =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/CVS/howl/work/howl-0.9.7/src/autoipd/Makefile.in,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/autoipd/Makefile.in 12 Dec 2004 08:24:39 -0000 1.1.1.1 +++ src/autoipd/Makefile.in 12 Dec 2004 09:16:29 -0000 1.2 @@ -96,13 +96,13 @@ am__include =3D @am__include@ am__quote =3D @am__quote@ install_sh =3D @install_sh@ -SUBDIRS =3D Posix Linux +SUBDIRS =3D Posix BSD Linux INCLUDES =3D -I$(top_srcdir)/include/ LDADD =3D $(AUTOIPD_EXTRA_OBJECTS) $(top_srcdir)/src/lib/howl/libhowl.la $= (PLATFORM_LIBS) AM_LDFLAGS =3D -static bin_PROGRAMS =3D autoipd autoipd_SOURCES =3D autoip.c autoip.h -EXTRA_autoipd_SOURCES =3D Linux/linux_autoip.c Posix/posix_main.c +EXTRA_autoipd_SOURCES =3D BSD/freebsd_autoip.c Linux/linux_autoip.c Posix/= posix_main.c autoipd_DEPENDENCIES =3D $(AUTOIPD_EXTRA_OBJECTS) subdir =3D src/autoipd mkinstalldirs =3D $(SHELL) $(top_srcdir)/mkinstalldirs @@ -124,6 +124,7 @@ depcomp =3D $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe =3D depfiles @AMDEP_TRUE@DEP_FILES =3D ./$(DEPDIR)/autoip.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/freebsd_autoip.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/linux_autoip.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/posix_main.Po COMPILE =3D $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -182,6 +183,7 @@ echo " rm -f $$p $$f"; \ rm -f $$p $$f ; \ done +freebsd_autoip.$(OBJEXT): BSD/freebsd_autoip.c linux_autoip.$(OBJEXT): Linux/linux_autoip.c posix_main.$(OBJEXT): Posix/posix_main.c autoipd$(EXEEXT): $(autoipd_OBJECTS) $(autoipd_DEPENDENCIES)=20 @@ -195,6 +197,7 @@ -rm -f *.tab.c =20 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/autoip.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/freebsd_autoip.Po@am__quo= te@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux_autoip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/posix_main.Po@am__quote@ =20 @@ -219,6 +222,24 @@ @AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< =20 +freebsd_autoip.o: BSD/freebsd_autoip.c +@AMDEP_TRUE@ source=3D'BSD/freebsd_autoip.c' object=3D'freebsd_autoip.o' l= ibtool=3Dno @AMDEPBACKSLASH@ +@AMDEP_TRUE@ depfile=3D'$(DEPDIR)/freebsd_autoip.Po' tmpdepfile=3D'$(DEPDI= R)/freebsd_autoip.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) = $(AM_CFLAGS) $(CFLAGS) -c -o freebsd_autoip.o `test -f 'BSD/freebsd_autoip.= c' || echo '$(srcdir)/'`BSD/freebsd_autoip.c + +freebsd_autoip.obj: BSD/freebsd_autoip.c +@AMDEP_TRUE@ source=3D'BSD/freebsd_autoip.c' object=3D'freebsd_autoip.obj'= libtool=3Dno @AMDEPBACKSLASH@ +@AMDEP_TRUE@ depfile=3D'$(DEPDIR)/freebsd_autoip.Po' tmpdepfile=3D'$(DEPDI= R)/freebsd_autoip.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) = $(AM_CFLAGS) $(CFLAGS) -c -o freebsd_autoip.obj `cygpath -w BSD/freebsd_aut= oip.c` + +freebsd_autoip.lo: BSD/freebsd_autoip.c +@AMDEP_TRUE@ source=3D'BSD/freebsd_autoip.c' object=3D'freebsd_autoip.lo' = libtool=3Dyes @AMDEPBACKSLASH@ +@AMDEP_TRUE@ depfile=3D'$(DEPDIR)/freebsd_autoip.Plo' tmpdepfile=3D'$(DEPD= IR)/freebsd_autoip.TPlo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(LIBTOOL) --mode=3Dcompile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)= $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o freebsd_autoip.lo = `test -f 'BSD/freebsd_autoip.c' || echo '$(srcdir)/'`BSD/freebsd_autoip.c + linux_autoip.o: Linux/linux_autoip.c @AMDEP_TRUE@ source=3D'Linux/linux_autoip.c' object=3D'linux_autoip.o' lib= tool=3Dno @AMDEPBACKSLASH@ @AMDEP_TRUE@ depfile=3D'$(DEPDIR)/linux_autoip.Po' tmpdepfile=3D'$(DEPDIR)= /linux_autoip.TPo' @AMDEPBACKSLASH@ Index: src/autoipd/autoip.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/CVS/howl/work/howl-0.9.7/src/autoipd/autoip.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/autoipd/autoip.c 12 Dec 2004 08:24:39 -0000 1.1.1.1 +++ src/autoipd/autoip.c 12 Dec 2004 09:09:50 -0000 1.2 @@ -212,6 +212,12 @@ sw_debug(SW_LOG_VERBOSE, "IDLE\n"); =20 /* + * initialize the MAC address + */ + err =3D sw_network_interface_mac_address(self->m_nif, &self->m_mac_addr); + sw_check_okay(err, exit); + + /* * initialize the ip address */ err =3D sw_autoip_network_interface_make_initial_ip_address(self); Index: src/lib/howl/Posix/posix_interface.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/CVS/howl/work/howl-0.9.7/src/lib/howl/Posix/posix_interface= =2Ec,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 posix_interface.c --- src/lib/howl/Posix/posix_interface.c 12 Dec 2004 08:24:31 -0000 1.1.1.1 +++ src/lib/howl/Posix/posix_interface.c 7 Jan 2005 15:39:58 -0000 @@ -45,6 +45,14 @@ # include <linux/ethtool.h>=20 #endif =20 +#if defined(__FreeBSD__) +#include <sys/sysctl.h> +#include <net/ethernet.h> +#include <net/if_types.h> +#include <net/if_media.h> +#include <net/route.h> +#endif + #ifndef SIOCGIFCONF # include <sys/sockio.h> #endif @@ -231,13 +240,16 @@ sw_network_interface self,=20 sw_bool * islinked) { -#if defined(__linux__) int fd; - struct ifreq ifr; int r; - struct ethtool_value edata; + struct ifreq ifr; int res; sw_result err =3D SW_OKAY; +#if defined(__linux__) + struct ethtool_value edata; +#elif defined(__FreeBSD__) + struct ifmediareq ifmr; +#endif =20 sw_assert(self !=3D NULL); /* must be initialized */ sw_assert(islinked !=3D NULL); /* must be allocated */ @@ -251,6 +263,19 @@ memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, self->m_name, sizeof(ifr.ifr_name) - 1); =20 + /* get the interface flags */ + res =3D ioctl(fd, SIOCGIFFLAGS, &ifr); + err =3D sw_translate_error(res =3D=3D 0, errno); + sw_check_okay_log(err, exit); + + /* if it's down, we can't have a link */ + if ((ifr.ifr_flags & IFF_UP) !=3D IFF_UP) + { + *islinked =3D SW_FALSE; + goto exit; + } + +#if defined(__linux__) edata.cmd =3D ETHTOOL_GLINK; ifr.ifr_data =3D (caddr_t) &edata; =20 @@ -259,15 +284,25 @@ sw_check_okay_log(err, exit); =20 *islinked =3D edata.data ? SW_TRUE : SW_FALSE; +#elif defined(__FreeBSD__) + memset(&ifmr, 0, sizeof(ifmr)); + strncpy(ifmr.ifm_name, self->m_name, sizeof(ifmr.ifm_name) - 1); + + res =3D ioctl(fd, SIOCGIFMEDIA, (caddr_t)&ifmr); + err =3D sw_translate_error(res =3D=3D 0, errno); + sw_check_okay_log(err, exit); + + if (!ifmr.ifm_status & IFM_AVALID) + goto exit; + + *islinked =3D (ifmr.ifm_status & IFM_ACTIVE)? SW_TRUE : SW_FALSE; +#endif =20 exit: =20 close(fd); =20 return err; -#else - return SW_OKAY; -#endif } =20 =20 @@ -280,6 +315,77 @@ } =20 =20 +#if defined(__FreeBSD__) +static int +get_interface_lladdr_by_index(unsigned int ifindex, sw_mac_address *m_mac_= addr) { + + int mib[6]; + struct if_msghdr *ifm; + struct sockaddr_dl *sdl; + + int needed, count =3D 0; + int res; + sw_result err =3D SW_OKAY; + +retry: + mib[0] =3D CTL_NET; + mib[1] =3D PF_ROUTE; + mib[2] =3D 0; + mib[3] =3D 0; /* address family */ + mib[4] =3D NET_RT_IFLIST; + mib[5] =3D ifindex; /* interface index */ + + /* determine how much memory is needed */ + res =3D sysctl(mib, 6, NULL, &needed, NULL, 0); + err =3D sw_translate_error(res =3D=3D 0, errno); + sw_check_okay_log(err, exit); + + ifm =3D (struct if_msghdr *)malloc(needed); + err =3D sw_translate_error(ifm !=3D NULL, SW_E_MEM); + sw_check_okay_log(err, exit); + + /* retrieve information */ + res =3D sysctl(mib, 6, ifm, &needed, NULL, 0); + if (res < 0) { + if (errno =3D=3D ENOMEM && count++ < 10) { + sw_debug(SW_LOG_WARNING, + "Routing table grew, retrying"); + free(ifm); + sleep(1); + goto retry; + } + + err =3D sw_translate_error(res =3D=3D 0, errno); + sw_check_okay_log(err, exit); + } + + sw_debug(SW_LOG_ERROR, "ifm->ifm_type %d=3D%d\n", + ifm->ifm_type, RTM_IFINFO); + if (ifm->ifm_type !=3D RTM_IFINFO) + return 0; + + if (ifm->ifm_data.ifi_datalen =3D=3D 0) + ifm->ifm_data.ifi_datalen =3D sizeof(struct if_data); + + sdl =3D (struct sockaddr_dl *)((char *)ifm + sizeof(struct if_msghdr) - + sizeof(struct if_data) + ifm->ifm_data.ifi_datalen); + + sw_debug(SW_LOG_ERROR, "sdl->sdl_alen %d\n", sdl->sdl_alen); + if (sdl->sdl_alen > 1) { + if (sdl->sdl_type =3D=3D IFT_ETHER && + sdl->sdl_alen =3D=3D ETHER_ADDR_LEN) { + sw_memcpy(m_mac_addr->m_id, + (struct ether_addr *)LLADDR(sdl), + sizeof(struct ether_addr)); + return 1; + } + } + +exit: + return 0; +} +#endif + static sw_result sw_posix_network_interface_init_from_name( sw_posix_network_interface nif, @@ -332,6 +438,7 @@ sw_debug(SW_LOG_VERBOSE, "got ip address: %s\n", tmpname); =20 /* mac address */ +#if !defined(__FreeBSD__) #if defined(SIOCGIFHWADDR) res =3D ioctl(sock, SIOCGIFHWADDR, &ifr); err =3D sw_translate_error(res =3D=3D 0, errno); @@ -343,10 +450,17 @@ sw_check_okay_log(err, exit); sw_memcpy(nif->m_super.m_mac_address.m_id, (sw_uint8*)(ifr.ifr_ifru.ifru_= enaddr), sizeof(sw_mac_address));=20 #endif +#endif =20 /* index */ nif->m_super.m_index =3D if_nametoindex(ifr.ifr_name); =20 +#if defined(__FreeBSD__) + res =3D get_interface_lladdr_by_index(nif->m_super.m_index, &nif->m_super= =2Em_mac_address); + err =3D sw_translate_error(res =3D=3D 1, SW_E_UNKNOWN); + sw_check_okay_log(err, exit); +#endif + /* initialize link status field */ sw_network_interface_link_status(&nif->m_super, &(nif->m_super.m_linked)); =20 @@ -387,6 +501,12 @@ /* ip address */ sw_ipv4_address_init_from_saddr(&(nif->m_super.m_ipv4_address), ((struct = sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr); =20 +#if defined(__FreeBSD__) + res =3D get_interface_lladdr_by_index(nif->m_super.m_index, &nif->m_super= =2Em_mac_address); + sw_debug(SW_LOG_ERROR, "%d %s res %d\n", nif->m_super.m_index, ifr->ifr_n= ame, res); + err =3D sw_translate_error(res =3D=3D 1, SW_E_UNKNOWN); + sw_check_okay_log(err, exit); +#else /* get a socket for ioctling */ err =3D sw_posix_inet_socket(&sock); sw_check_okay(err, exit); @@ -403,6 +523,7 @@ sw_check_okay_log(err, exit); sw_memcpy(nif->m_super.m_mac_address.m_id, (sw_uint8*)(ifr->ifr_ifru.ifru= _enaddr), sizeof(sw_mac_address));=20 #endif +#endif =20 /* initialize link status field */ sw_network_interface_link_status(&nif->m_super, &(nif->m_super.m_linked)); @@ -515,6 +636,7 @@ sw_uint32 * nifc, sw_network_interface ** nifv) { +#if defined(__linux__) FILE * fh; char buf[512]; int procnetdev_vsn; @@ -585,6 +707,132 @@ } =20 return err; +#elif defined(__FreeBSD__) + int mib[6]; + struct if_msghdr *ifm, *nextifm; + struct ifa_msghdr *ifam; + int addrcount; + struct sockaddr_dl *sdl; + char name[IFNAMSIZ]; + sw_posix_network_interface nif; + sw_ipv4_address ipaddr; + + int needed, count =3D 0; + char *buf, *lim, *next; + int res; + sw_result err =3D SW_OKAY; + + /* TODO hard code 10 for now */ + /* allocate nifv */ + *nifv =3D (sw_network_interface*) sw_malloc(10 * sizeof(sw_network_interf= ace)); + err =3D sw_translate_error(*nifv, SW_E_MEM); + sw_check_okay_log(err, exit); +=09 + *nifc =3D 0; + +retry: + mib[0] =3D CTL_NET; + mib[1] =3D PF_ROUTE; + mib[2] =3D 0; + mib[3] =3D 0; + mib[4] =3D NET_RT_IFLIST; + mib[5] =3D 0; + + /* determine how much memory is needed */ + res =3D sysctl(mib, 6, NULL, &needed, NULL, 0); + err =3D sw_translate_error(res =3D=3D 0, errno); + sw_check_okay_log(err, exit); + + buf =3D malloc(needed); + err =3D sw_translate_error(buf !=3D NULL, SW_E_MEM); + sw_check_okay_log(err, exit); + + /* retrieve information */ + res =3D sysctl(mib, 6, buf, &needed, NULL, 0); + if (res < 0) { + if (errno =3D=3D ENOMEM && count++ < 10) { + warnx("Routing table grew, retrying"); + free(ifm); + sleep(1); + goto retry; + } + + err =3D sw_translate_error(res =3D=3D 0, errno); + sw_check_okay_log(err, exit); + } + + lim =3D buf + needed; + next =3D buf; + while (next < lim) { + ifm =3D (struct if_msghdr *)next; + + if (ifm->ifm_type =3D=3D RTM_IFINFO) { + if (ifm->ifm_data.ifi_datalen =3D=3D 0) + ifm->ifm_data.ifi_datalen =3D sizeof(struct if_data); + + sdl =3D (struct sockaddr_dl *)((char *)ifm + + sizeof(struct if_msghdr) - + sizeof(struct if_data) + + ifm->ifm_data.ifi_datalen); + } else { + sw_debug(SW_LOG_ERROR, + "out of sync parsing NET_RT_IFLIST\n"); + err =3D SW_E_INIT; + goto exit; + } + + next +=3D ifm->ifm_msglen; + ifam =3D NULL; + addrcount =3D 0; + while (next < lim) { + nextifm =3D (struct if_msghdr *)next; + if (nextifm->ifm_type !=3D RTM_NEWADDR) + break; + + if (ifam =3D=3D NULL) + ifam =3D (struct ifa_msghdr *)nextifm; + + next +=3D nextifm->ifm_msglen; + } + + memcpy(name, sdl->sdl_data, + sizeof(name) < sdl->sdl_nlen ? + sizeof(name)-1 : sdl->sdl_nlen); + name[sizeof(name) < sdl->sdl_nlen ? + sizeof(name)-1 : sdl->sdl_nlen] =3D '\0'; + + sw_debug(SW_LOG_ERROR, "name=3D%s", name); + + if ((ifm->ifm_flags & IFF_BROADCAST) =3D=3D 0) + { + continue; + } + + /* create a new netif */ + err =3D sw_network_interface_init((sw_network_interface*)&nif);=20 + sw_check_okay(err, exit); + + /* initialize fields */ + err =3D sw_posix_network_interface_init_from_name(nif, name); + sw_check_okay(err, exit); + + err =3D sw_network_interface_ipv4_address((sw_network_interface)nif, &ip= addr); + sw_check_okay(err, exit); + + (*nifv)[(*nifc)++] =3D (sw_network_interface)nif; + } +=09 + err =3D SW_OKAY; + +exit: + + if (err && *nifv) + { + sw_network_interfaces_fina(*nifc, *nifv); + } + + return err; +#endif } =20 sw_result diff -urN empty/Makefile src/autoipd/BSD/Makefile --- src/autoipd/BSD/Makefile Thu Jan 1 01:00:00 1970 +++ src/autoipd/BSD/Makefile Sun Dec 12 10:36:27 2004 @@ -0,0 +1,232 @@ +# Makefile.in generated by automake 1.6.3 from Makefile.am. +# src/autoipd/BSD/Makefile. Generated from Makefile.in by configure. + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL =3D /bin/sh + +srcdir =3D . +top_srcdir =3D ../../.. + +prefix =3D /usr/local +exec_prefix =3D ${prefix} + +bindir =3D ${exec_prefix}/bin +sbindir =3D ${exec_prefix}/sbin +libexecdir =3D ${exec_prefix}/libexec +datadir =3D ${prefix}/share +sysconfdir =3D ${prefix}/etc +sharedstatedir =3D ${prefix}/com +localstatedir =3D ${prefix}/var +libdir =3D ${exec_prefix}/lib +infodir =3D ${prefix}/info +mandir =3D ${prefix}/man +includedir =3D ${prefix}/include +oldincludedir =3D /usr/include +pkgdatadir =3D $(datadir)/howl +pkglibdir =3D $(libdir)/howl +pkgincludedir =3D $(includedir)/howl +top_builddir =3D ../../.. + +ACLOCAL =3D ${SHELL} /usr/ports/net/howl/work/howl-0.9.7/missing --run acl= ocal-1.6 +AUTOCONF =3D ${SHELL} /usr/ports/net/howl/work/howl-0.9.7/missing --run au= toconf +AUTOMAKE =3D ${SHELL} /usr/ports/net/howl/work/howl-0.9.7/missing --run au= tomake-1.6 +AUTOHEADER =3D ${SHELL} /usr/ports/net/howl/work/howl-0.9.7/missing --run = autoheader + +am__cd =3D CDPATH=3D"$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL =3D /usr/bin/install -c=20 +INSTALL_PROGRAM =3D install -s -m 555 +INSTALL_DATA =3D install -m 444 +install_sh_DATA =3D $(install_sh) -c -m 644 +install_sh_PROGRAM =3D $(install_sh) -c +install_sh_SCRIPT =3D $(install_sh) -c +INSTALL_SCRIPT =3D install -m 555 +INSTALL_HEADER =3D $(INSTALL_DATA) +transform =3D s,x,x, +NORMAL_INSTALL =3D : +PRE_INSTALL =3D : +POST_INSTALL =3D : +NORMAL_UNINSTALL =3D : +PRE_UNINSTALL =3D : +POST_UNINSTALL =3D : +host_alias =3D=20 +host_triplet =3D i386-portbld-freebsd5.3 + +EXEEXT =3D=20 +OBJEXT =3D o +PATH_SEPARATOR =3D : +AMTAR =3D ${SHELL} /usr/ports/net/howl/work/howl-0.9.7/missing --run tar +AS =3D @AS@ +AUTOIPD_EXTRA_OBJECTS =3D freebsd_autoip.lo posix_main.lo +AWK =3D nawk +CC =3D cc +CXX =3D c++ +DEPDIR =3D .deps +DLLTOOL =3D @DLLTOOL@ +ECHO =3D echo +HOWL_LIBRARY_VERSION =3D 1:0:0 +HOWL_LIB_OBJECTS =3D posix_salt.lo posix_socket.lo posix_time.lo posix_sig= nal.lo posix_interface.lo notosx_mdns_stub.lo +HOWL_LIB_SUBDIRS =3D Posix NotOSX +HOWL_MAN_PAGES =3D mDNSResponder.8 autoipd.8 nifd.8 +HOWL_RELEASE =3D=20 +INSTALL_STRIP_PROGRAM =3D ${SHELL} $(install_sh) -c -s +LIBTOOL =3D $(SHELL) /usr/local/bin/libtool15 +LIB_SUBDIRS =3D howl mDNSResponder +LN_S =3D ln -s +MDNSRESPONDER_LIBRARY_VERSION =3D 0:0:0 +MDNSRESPONDER_LIB_OBJECTS =3D posix_mdns.lo +MDNSRESPONDER_LIB_SUBDIRS =3D Posix +OBJDUMP =3D @OBJDUMP@ +PACKAGE =3D howl +PLATFORM_LIBS =3D -lpthread +RANLIB =3D ranlib +SRC_SUBDIRS =3D lib mDNSResponder autoipd nifd +STRIP =3D strip +VERSION =3D 0.9.7 +am__include =3D include +am__quote =3D=20 +install_sh =3D /usr/ports/net/howl/work/howl-0.9.7/install-sh +sources_h =3D freebsd_autoip.h +sources_c =3D freebsd_autoip.c +DIST_SOURCES =3D $(sources_h) $(sources_c) Makefile.am +INCLUDES =3D -I$(top_srcdir)/include/ +subdir =3D src/autoipd/BSD +mkinstalldirs =3D $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER =3D $(top_builddir)/include/howl_config.h +CONFIG_CLEAN_FILES =3D +DIST_COMMON =3D Makefile.am Makefile.in +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_= M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/autoipd/BSD/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfile= s_maybe) + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +DISTFILES =3D $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir =3D ../../.. +distdir =3D $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @list=3D'$(DISTFILES)'; for file in $$list; do \ + if test -f $$file || test -d $$file; then d=3D.; else d=3D$(srcdir); fi= ; \ + dir=3D`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" !=3D "$$file" && test "$$dir" !=3D "."; then \ + dir=3D"/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=3D''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d !=3D $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile + +installdirs: + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM=3D"$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=3D-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=3DSTRIPPROG=3D'$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff -urN empty/Makefile.in src/autoipd/BSD/Makefile.in --- src/autoipd/BSD/Makefile.in Thu Jan 1 01:00:00 1970 +++ src/autoipd/BSD/Makefile.in Sun Dec 12 10:35:09 2004 @@ -0,0 +1,232 @@ +# Makefile.in generated by automake 1.6.3 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SHELL =3D @SHELL@ + +srcdir =3D @srcdir@ +top_srcdir =3D @top_srcdir@ +VPATH =3D @srcdir@ +prefix =3D @prefix@ +exec_prefix =3D @exec_prefix@ + +bindir =3D @bindir@ +sbindir =3D @sbindir@ +libexecdir =3D @libexecdir@ +datadir =3D @datadir@ +sysconfdir =3D @sysconfdir@ +sharedstatedir =3D @sharedstatedir@ +localstatedir =3D @localstatedir@ +libdir =3D @libdir@ +infodir =3D @infodir@ +mandir =3D @mandir@ +includedir =3D @includedir@ +oldincludedir =3D /usr/include +pkgdatadir =3D $(datadir)/@PACKAGE@ +pkglibdir =3D $(libdir)/@PACKAGE@ +pkgincludedir =3D $(includedir)/@PACKAGE@ +top_builddir =3D ../../.. + +ACLOCAL =3D @ACLOCAL@ +AUTOCONF =3D @AUTOCONF@ +AUTOMAKE =3D @AUTOMAKE@ +AUTOHEADER =3D @AUTOHEADER@ + +am__cd =3D CDPATH=3D"$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL =3D @INSTALL@ +INSTALL_PROGRAM =3D @INSTALL_PROGRAM@ +INSTALL_DATA =3D @INSTALL_DATA@ +install_sh_DATA =3D $(install_sh) -c -m 644 +install_sh_PROGRAM =3D $(install_sh) -c +install_sh_SCRIPT =3D $(install_sh) -c +INSTALL_SCRIPT =3D @INSTALL_SCRIPT@ +INSTALL_HEADER =3D $(INSTALL_DATA) +transform =3D @program_transform_name@ +NORMAL_INSTALL =3D : +PRE_INSTALL =3D : +POST_INSTALL =3D : +NORMAL_UNINSTALL =3D : +PRE_UNINSTALL =3D : +POST_UNINSTALL =3D : +host_alias =3D @host_alias@ +host_triplet =3D @host@ + +EXEEXT =3D @EXEEXT@ +OBJEXT =3D @OBJEXT@ +PATH_SEPARATOR =3D @PATH_SEPARATOR@ +AMTAR =3D @AMTAR@ +AS =3D @AS@ +AUTOIPD_EXTRA_OBJECTS =3D @AUTOIPD_EXTRA_OBJECTS@ +AWK =3D @AWK@ +CC =3D @CC@ +CXX =3D @CXX@ +DEPDIR =3D @DEPDIR@ +DLLTOOL =3D @DLLTOOL@ +ECHO =3D @ECHO@ +HOWL_LIBRARY_VERSION =3D @HOWL_LIBRARY_VERSION@ +HOWL_LIB_OBJECTS =3D @HOWL_LIB_OBJECTS@ +HOWL_LIB_SUBDIRS =3D @HOWL_LIB_SUBDIRS@ +HOWL_MAN_PAGES =3D @HOWL_MAN_PAGES@ +HOWL_RELEASE =3D @HOWL_RELEASE@ +INSTALL_STRIP_PROGRAM =3D @INSTALL_STRIP_PROGRAM@ +LIBTOOL =3D @LIBTOOL@ +LIB_SUBDIRS =3D @LIB_SUBDIRS@ +LN_S =3D @LN_S@ +MDNSRESPONDER_LIBRARY_VERSION =3D @MDNSRESPONDER_LIBRARY_VERSION@ +MDNSRESPONDER_LIB_OBJECTS =3D @MDNSRESPONDER_LIB_OBJECTS@ +MDNSRESPONDER_LIB_SUBDIRS =3D @MDNSRESPONDER_LIB_SUBDIRS@ +OBJDUMP =3D @OBJDUMP@ +PACKAGE =3D @PACKAGE@ +PLATFORM_LIBS =3D @PLATFORM_LIBS@ +RANLIB =3D @RANLIB@ +SRC_SUBDIRS =3D @SRC_SUBDIRS@ +STRIP =3D @STRIP@ +VERSION =3D @VERSION@ +am__include =3D @am__include@ +am__quote =3D @am__quote@ +install_sh =3D @install_sh@ +sources_h =3D freebsd_autoip.h +sources_c =3D freebsd_autoip.c +DIST_SOURCES =3D $(sources_h) $(sources_c) Makefile.am +INCLUDES =3D -I$(top_srcdir)/include/ +subdir =3D src/autoipd/BSD +mkinstalldirs =3D $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER =3D $(top_builddir)/include/howl_config.h +CONFIG_CLEAN_FILES =3D +DIST_COMMON =3D Makefile.am Makefile.in +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_= M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/autoipd/BSD/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfile= s_maybe) + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +DISTFILES =3D $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir =3D ../../.. +distdir =3D $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @list=3D'$(DISTFILES)'; for file in $$list; do \ + if test -f $$file || test -d $$file; then d=3D.; else d=3D$(srcdir); fi= ; \ + dir=3D`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" !=3D "$$file" && test "$$dir" !=3D "."; then \ + dir=3D"/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=3D''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d !=3D $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile + +installdirs: + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM=3D"$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=3D-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=3DSTRIPPROG=3D'$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff -urN empty/freebsd_autoip.c src/autoipd/BSD/freebsd_autoip.c --- src/autoipd/BSD/freebsd_autoip.c Thu Jan 1 01:00:00 1970 +++ src/autoipd/BSD/freebsd_autoip.c Fri Jan 7 16:07:11 2005 @@ -0,0 +1,511 @@ +/* + * Copyright 2003, 2004 Porchdog Software. All rights reserved. + * Copyright 2004, 2005 Andrea Campi <andrea PLUS freebsd AT webcom DOT it> + * + * Redistribution and use in source and binary forms, with or without modi= fication, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright noti= ce, + * this list of conditions and the following disclaimer. =20 + * 2. Redistributions in binary form must reproduce the above copyright n= otice, + * this list of conditions and the following disclaimer in the documen= tation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY PORCHDOG SOFTWARE ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLI= ED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE = DISCLAIMED. + * IN NO EVENT SHALL THE HOWL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DI= RECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INC= LUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS O= F USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY T= HEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING= NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN = IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation a= re those + * of the authors and should not be interpreted as representing official p= olicies, + * either expressed or implied, of Porchdog Software. + */ + +#include "freebsd_autoip.h" +#include <sys/sysctl.h> +#include <netinet/in.h> +#include <net/bpf.h> +#include <net/ethernet.h> +#include <net/if_dl.h> +#include <net/route.h> +#include <salt/socket.h> +#include <salt/address.h> +#include <salt/debug.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> + + +static sw_result +sw_freebsd_autoip_network_interface_socket_event_handler( + sw_socket_handler handler, + sw_salt salt, + sw_socket socket, + sw_socket_event events, + sw_opaque extra); + + +static struct bpf_insn arp_bpf_filter [] =3D { + /* Make sure this is an IP packet... */ + BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12), + BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_ARP, 0, 1), + + /* If we passed all the tests, ask for the whole packet. */ + BPF_STMT(BPF_RET+BPF_K, 96), + + /* Otherwise, drop it. */ + BPF_STMT(BPF_RET+BPF_K, 0), +}; + +int arp_bpf_filter_len =3D (sizeof arp_bpf_filter / sizeof (struct bpf_ins= n)); + + +sw_string +sw_platform_autoip_network_interface_default_interface_name() +{ + sw_string ret =3D NULL; + int mib[6]; + struct if_msghdr *ifm, *nextifm; + struct ifa_msghdr *ifam; + struct sockaddr_dl *sdl; + char name[IFNAMSIZ]; + + int needed, count =3D 0; + char *buf, *lim, *next; + int res; + sw_result err =3D SW_OKAY; + +retry: + mib[0] =3D CTL_NET; + mib[1] =3D PF_ROUTE; + mib[2] =3D 0; + mib[3] =3D 0; + mib[4] =3D NET_RT_IFLIST; + mib[5] =3D 0; + + /* determine how much memory is needed */ + res =3D sysctl(mib, 6, NULL, &needed, NULL, 0); + err =3D sw_translate_error(res =3D=3D 0, errno); + sw_check_okay_log(err, exit); + + buf =3D malloc(needed); + err =3D sw_translate_error(buf !=3D NULL, SW_E_MEM); + sw_check_okay_log(err, exit); + + /* retrieve information */ + res =3D sysctl(mib, 6, buf, &needed, NULL, 0); + if (res < 0) { + if (errno =3D=3D ENOMEM && count++ < 10) { + warnx("Routing table grew, retrying"); + free(ifm); + sleep(1); + goto retry; + } + + err =3D sw_translate_error(res =3D=3D 0, errno); + sw_check_okay_log(err, exit); + } + + lim =3D buf + needed; + next =3D buf; + while (next < lim) { + ifm =3D (struct if_msghdr *)next; + + if (ifm->ifm_type =3D=3D RTM_IFINFO) { + if (ifm->ifm_data.ifi_datalen =3D=3D 0) + ifm->ifm_data.ifi_datalen =3D sizeof(struct if_data); + + sdl =3D (struct sockaddr_dl *)((char *)ifm + + sizeof(struct if_msghdr) - + sizeof(struct if_data) + + ifm->ifm_data.ifi_datalen); + } else { + sw_debug(SW_LOG_ERROR, + "out of sync parsing NET_RT_IFLIST\n"); + err =3D SW_E_INIT; + goto exit; + } + + next +=3D ifm->ifm_msglen; + ifam =3D NULL; + while (next < lim) { + nextifm =3D (struct if_msghdr *)next; + if (nextifm->ifm_type !=3D RTM_NEWADDR) + break; + + if (ifam =3D=3D NULL) + ifam =3D (struct ifa_msghdr *)nextifm; + + next +=3D nextifm->ifm_msglen; + } + + if ((ifm->ifm_flags & IFF_BROADCAST) =3D=3D 0) + { + continue; + } + + memcpy(name, sdl->sdl_data, + sizeof(name) < sdl->sdl_nlen ? + sizeof(name)-1 : sdl->sdl_nlen); + name[sizeof(name) < sdl->sdl_nlen ? + sizeof(name)-1 : sdl->sdl_nlen] =3D '\0'; + + ret =3D strdup(name); + break; + } +=09 + err =3D SW_OKAY; + +exit: + + return ret; +} + + +sw_result +sw_platform_autoip_network_interface_new( + sw_autoip_network_interface * anif, + sw_salt salt, + sw_network_interface nif) +{ + sw_freebsd_autoip_network_interface self; + int res; + int macsock; + struct ifreq ifr; + char tname[IFNAMSIZ]; + sw_result err =3D SW_OKAY; + int fd; + char name[IFNAMSIZ]; + struct bpf_version v; + struct bpf_program p; + int flag, n; + + self =3D (sw_freebsd_autoip_network_interface) sw_malloc(sizeof(struct _s= w_freebsd_autoip_network_interface)); + sw_check(self, exit, err =3D SW_E_MEM); + + err =3D sw_autoip_network_interface_init(&self->m_super, salt, nif); + sw_check_okay(err, exit); +=09 + /* + * create out socket + */ + n =3D 0; + do { + sprintf(tname, "/dev/bpf%d", n++); + fd =3D open(tname, O_RDWR); + } while (fd < 0 && errno =3D=3D EBUSY && n < 1000); + err =3D sw_translate_error(fd !=3D -1, errno); + sw_check_okay_log(err, exit); + + self->m_osock =3D fd; + self->m_isock =3D fd; + + /* Make sure the BPF version is in range... */ + res =3D ioctl(fd, BIOCVERSION, &v); + err =3D sw_translate_error(res !=3D -1, errno); + sw_check_okay_log(err, exit); + + if (v.bv_major !=3D BPF_MAJOR_VERSION || v.bv_minor < BPF_MINOR_VERSION) { + fprintf(stderr, "BPF version mismatch\n"); + err =3D sw_translate_error(0, SW_E_UNKNOWN); + sw_check_okay_log(err, exit); + } + + /* + * initialize the device name + */ + sw_memset(&ifr, 0, sizeof(ifr)); + sw_network_interface_name(self->m_super.m_nif, name, IFNAMSIZ); + strncpy(ifr.ifr_name, name, IFNAMSIZ - 1); + + /* + * bind to the interface + */ + res =3D ioctl(fd, BIOCSETIF, &ifr); + err =3D sw_translate_error(res !=3D -1, errno); + sw_check_okay_log(err, exit); + + /* Set immediate mode so that reads return as soon as a packet + * comes in, rather than waiting for the input buffer to fill with + * packets. */ + flag =3D 1; + res =3D ioctl(fd, BIOCIMMEDIATE, &flag); + err =3D sw_translate_error(res !=3D -1, errno); + sw_check_okay_log(err, exit); + + /* */ + flag =3D 0; + res =3D ioctl(fd, BIOCSSEESENT, &flag); + err =3D sw_translate_error(res !=3D -1, errno); + sw_check_okay_log(err, exit); + + /* */ + flag =3D 1; + res =3D ioctl(fd, BIOCSHDRCMPLT, &flag); + err =3D sw_translate_error(res !=3D -1, errno); + sw_check_okay_log(err, exit); + + /* Get the required BPF buffer length from the kernel. */ + res =3D ioctl(fd, BIOCGBLEN, &self->m_blen); + err =3D sw_translate_error(res !=3D -1, errno); + sw_check_okay_log(err, exit); + + self->m_buf =3D malloc(self->m_blen); + err =3D sw_translate_error(self->m_buf !=3D NULL, errno); + sw_check_okay_log(err, exit); + + /* + * set BPF filter + */ + p.bf_len =3D arp_bpf_filter_len; + p.bf_insns =3D arp_bpf_filter; + res =3D ioctl(fd, BIOCSETF, &p); + err =3D sw_translate_error(res !=3D -1, errno); + sw_check_okay_log(err, exit); + + /* + * set non-blocking socket + */ + res =3D fcntl(self->m_isock, F_GETFL); + err =3D sw_translate_error(res !=3D -1, errno); + sw_check_okay_log(err, exit); + + res =3D fcntl(self->m_isock, F_SETFL, res | O_NONBLOCK); + err =3D sw_translate_error(res !=3D -1, errno); + sw_check_okay_log(err, exit); + + err =3D sw_tcp_socket_init_with_desc(&self->m_socket, self->m_isock); + sw_check_okay(err, exit); + + err =3D sw_autoip_network_interface_handle_wakeup(&self->m_super); + sw_check_okay(err, exit); + + *anif =3D &self->m_super; + +exit: + + if (err && self) + { + sw_platform_autoip_network_interface_delete(&self->m_super); + *anif =3D NULL; + } + + return err; +} + + +sw_result +sw_platform_autoip_network_interface_delete( + sw_autoip_network_interface anif) +{ + sw_freebsd_autoip_network_interface self =3D (sw_freebsd_autoip_network_i= nterface) anif; + + sw_autoip_network_interface_fina(&self->m_super); + + sw_platform_autoip_network_interface_stop_monitoring(anif); + + /* + * free + */ + close(self->m_isock); + close(self->m_osock); + + /*=20 + * and we're good + */ + sw_free(self); + + return SW_OKAY; +} + + +sw_result +sw_platform_autoip_network_interface_set_mac_address( + const char * s) +{ + return SW_E_INIT; +} + + +sw_result +sw_platform_autoip_network_interface_start_monitoring( + sw_autoip_network_interface anif) +{ + sw_freebsd_autoip_network_interface self =3D (sw_freebsd_autoip_network_i= nterface) anif; + sw_result err; + + err =3D sw_salt_register_socket(self->m_super.m_salt, self->m_socket, SW_= SOCKET_READ, (sw_socket_handler) self, sw_freebsd_autoip_network_interface_= socket_event_handler, (sw_opaque) NULL); + sw_check_okay(err, exit); + +exit: + + return err; +} + + +sw_result +sw_platform_autoip_network_interface_stop_monitoring( + sw_autoip_network_interface anif) +{ + sw_freebsd_autoip_network_interface self =3D (sw_freebsd_autoip_network_i= nterface) anif; + sw_result err; + + err =3D sw_salt_unregister_socket(self->m_super.m_salt, self->m_socket); + sw_check_okay(err, exit); + +exit: + + return err; +} + + =09 + +sw_result +sw_platform_autoip_network_interface_send_arp_packet( + sw_autoip_network_interface anif,=20 + sw_arp_packet * packet) +{ + sw_freebsd_autoip_network_interface self =3D (sw_freebsd_autoip_network_i= nterface) anif; + struct sockaddr sndarp; + char name[IFNAMSIZ]; + sw_mac_address mymac; + int res; + sw_result err =3D SW_OKAY; + + /* + * get interface name + */ + sw_network_interface_name(self->m_super.m_nif, name, IFNAMSIZ); + strcpy(sndarp.sa_data, name); + + /* + * send packet + */ + res =3D write(self->m_osock, packet, sizeof(struct _sw_arp_packet)); + err =3D sw_translate_error(res >=3D 0, errno); + sw_check_okay_log(err, exit); + +exit: + + return err; +} + + +sw_result +sw_platform_autoip_network_interface_set_ip_address( + sw_autoip_network_interface anif) +{ + sw_freebsd_autoip_network_interface self =3D (sw_freebsd_autoip_network_i= nterface) anif; + int r; + int sock_fd; + struct ifreq ifr; + struct in_addr saddr; + char name[IFNAMSIZ]; + int res; + sw_result err =3D SW_OKAY; + struct ifaliasreq ifra; + struct sockaddr_in addr; + + /* + * socket for ioctl + */ + sock_fd =3D socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + err =3D sw_translate_error(sock_fd !=3D -1, errno); + sw_check_okay_log(err, exit); + + /* + * initialize the device name + */ + sw_memset(&ifra, 0, sizeof(ifra)); + sw_network_interface_name(self->m_super.m_nif, name, IFNAMSIZ); + strncpy(ifra.ifra_name, name, IFNAMSIZ - 1); + =20 + /* + * initialize the ip address + */ + addr.sin_addr.s_addr =3D sw_ipv4_address_saddr(self->m_super.m_ip_addr); + addr.sin_family =3D AF_INET; + addr.sin_len =3D sizeof(struct sockaddr_in); + memcpy(&ifra.ifra_addr, &addr, sizeof(struct sockaddr_in)); + + addr.sin_addr.s_addr |=3D ntohl(0x0000ffff); + memcpy(&ifra.ifra_broadaddr, &addr, sizeof(struct sockaddr_in)); + + addr.sin_addr.s_addr =3D ntohl(0xffff0000); + memcpy(&ifra.ifra_mask, &addr, sizeof(struct sockaddr_in)); + + res =3D ioctl(sock_fd, SIOCAIFADDR, &ifra); + err =3D sw_translate_error(res =3D=3D 0, errno); + sw_check_okay_log(err, exit); + + err =3D sw_network_interface_set_ipv4_address(self->m_super.m_nif, self->= m_super.m_ip_addr); + sw_check_okay(err, exit); + +exit: + + if (sock_fd !=3D -1) + { + close(sock_fd); + } +} + + +static sw_result +sw_freebsd_autoip_network_interface_socket_event_handler( + sw_socket_handler handler, + sw_salt salt, + sw_socket socket, + sw_socket_event events, + sw_opaque extra) +{ + static sw_mac_address ProbeSenderMAC =3D { 0, 0, 0, 0, 0, 0 }; + + sw_freebsd_autoip_network_interface self =3D (sw_freebsd_autoip_network_i= nterface) handler; + char *ptr, *limit; + struct bpf_hdr *hdr; + sw_arp_packet *packet;=20 + char smyip[18], spacketip[18]; + char smymac[18], spacketmac[18]; + int bytes; + sw_result err =3D SW_OKAY; +=09 + sw_assert(self !=3D NULL); + + /* + * ignore invocations if not our socket + */ + sw_check(self->m_isock =3D=3D sw_socket_desc(socket), exit, err =3D SW_OK= AY); + + bytes =3D read(self->m_isock, self->m_buf, self->m_blen); + err =3D sw_translate_error(bytes >=3D 0, errno); + sw_check_okay_log(err, exit); + + + for (ptr =3D (char *)self->m_buf, limit =3D ptr + bytes; + ptr < limit; + ptr +=3D BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen)) { + hdr =3D (struct bpf_hdr *)ptr; + packet =3D (sw_arp_packet *)(ptr + hdr->bh_hdrlen); + + if (hdr->bh_caplen >=3D (sizeof(struct _sw_ethernet_header) + sizeof(str= uct _sw_arp_header))) + { + if (((ntohs(packet->m_arp_header.m_op)) =3D=3D SW_AUTOIP_ARP_REQUEST) || + ((ntohs(packet->m_arp_header.m_op)) =3D=3D SW_AUTOIP_ARP_REPLY)) + { + err =3D sw_autoip_network_interface_read_arp_packet(&self->m_super, pa= cket); + sw_check_okay(err, exit); + } + } + } + +exit: + + return err; +} diff -urN empty/freebsd_autoip.h src/autoipd/BSD/freebsd_autoip.h --- src/autoipd/BSD/freebsd_autoip.h Thu Jan 1 01:00:00 1970 +++ src/autoipd/BSD/freebsd_autoip.h Thu Dec 9 17:49:04 2004 @@ -0,0 +1,67 @@ +/* + * Copyright 2003, 2004 Porchdog Software. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modi= fication, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright noti= ce, + * this list of conditions and the following disclaimer. =20 + * 2. Redistributions in binary form must reproduce the above copyright n= otice, + * this list of conditions and the following disclaimer in the documen= tation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY PORCHDOG SOFTWARE ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLI= ED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE = DISCLAIMED. + * IN NO EVENT SHALL THE HOWL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DI= RECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INC= LUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS O= F USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY T= HEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING= NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN = IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation a= re those + * of the authors and should not be interpreted as representing official p= olicies, + * either expressed or implied, of Porchdog Software. + */ + +#ifndef _freebsd_autoip_h +#define _freebsd_autoip_h + + +#include "../autoip.h" +#include <salt/address.h> +#include <salt/socket.h> +#include <salt/interface.h>=20 +#include <net/if.h> + + +#if defined(__cplusplus) +extern "C" +{ +#endif + + +struct _sw_freebsd_autoip_network_interface; +typedef struct _sw_freebsd_autoip_network_interface * sw_freebsd_autoip_ne= twork_interface; + + +struct _sw_freebsd_autoip_network_interface +{ + struct _sw_autoip_network_interface m_super; + sw_socket m_socket; + sw_sockdesc_t m_osock; + sw_sockdesc_t m_isock; + + u_int m_blen; + unsigned char *m_buf; +}; + + +#if defined(__cplusplus) +} +#endif + +=20 +#endif Index: src/autoipd/BSD/Makefile.am =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: src/autoipd/BSD/Makefile.am diff -N src/autoipd/BSD/Makefile.am --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/autoipd/BSD/Makefile.am 12 Dec 2004 09:36:10 -0000 1.1 @@ -0,0 +1,4 @@ +sources_h =3D freebsd_autoip.h +sources_c =3D freebsd_autoip.c +DIST_SOURCES =3D $(sources_h) $(sources_c) Makefile.am +INCLUDES =3D -I$(top_srcdir)/include/ --dTy3Mrz/UPE2dbVg--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050107165703.GC16579>