ports/122197: patch to lookup for interface and src ip
Dmitry
hanabana at mail.ru
Fri Mar 28 15:40:02 UTC 2008
>Number: 122197
>Category: ports
>Synopsis: patch to lookup for interface and src ip
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-ports-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Fri Mar 28 15:40:01 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator: Dmitry
>Release: FreeBSD 6.3, FreeBSD 7.0
>Organization:
home
>Environment:
FreeBSD gatenew.aphn 6.3-STABLE FreeBSD 6.3-STABLE #0: Thu Feb 28 22:35:03 MSK 2008 root at gatenew.aphn:/var/tmp/obj/usr/src/sys/SRV i386
>Description:
This patch adds arping ability to find himself interface name and source IP for specified destination IP.
>How-To-Repeat:
>Fix:
Patch attached with submission follows:
--- arping-2/arping.c.orig 2007-09-13 20:43:37.000000000 +0400
+++ arping-2/arping.c 2008-03-28 18:23:02.000000000 +0300
@@ -48,6 +48,17 @@
#include <libnet.h>
#endif
+#ifdef __FreeBSD__
+#include <errno.h>
+#include <string.h>
+#include <sys/sysctl.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+
#ifdef WIN32
#include <win32/libnet.h>
#endif
@@ -232,6 +243,132 @@
}
#endif
+#ifdef __FreeBSD__
+static const char*
+FBSD_lookupIface(in_addr_t dstip, char* ebuf, in_addr_t *ifce_ip) {
+ int mib[6] = {
+ CTL_NET,
+ PF_ROUTE,
+ 0, /* Protocol */
+ 0, /* Address family */
+ NET_RT_IFLIST,
+ 0
+ };
+ char *buf, *lim;
+ int bufSize;
+ int c;
+ static char ifName[IFNAMSIZ];
+
+
+ for(c=0;;) {
+ if( sysctl(mib,6,NULL,&bufSize,NULL,0) < 0 ) {
+ strcpy(ebuf,"sysctl: get buffer size error");
+ return NULL;
+ }
+ if( (buf = malloc(bufSize)) == NULL ) {
+ strcpy(ebuf, "malloc: error");
+ return NULL;
+ }
+ if( sysctl(mib,6,buf,&bufSize,NULL,0) == 0 )
+ break;
+ if( errno != ENOMEM || ++c >= 10 ) {
+ strcpy(ebuf,"sysctl: get ifaces error");
+ return NULL;
+ }
+ fprintf(stderr,"sysctl: buffer size changed");
+ free(buf);
+ sleep(1);
+ }
+
+ lim = buf + bufSize;
+
+ while( buf < lim ) {
+ struct sockaddr_dl *sdl;
+ int i;
+
+ struct if_msghdr * ifh = (struct if_msghdr *)buf;
+ if( ifh->ifm_type != RTM_IFINFO ) {
+ strcpy(ebuf,"Wrong data in NET_RT_IFLIST");
+ return NULL;
+ }
+ if( ifh->ifm_data.ifi_datalen == 0 )
+ ifh->ifm_data.ifi_datalen = sizeof(struct if_data);
+ sdl =
+ (struct sockaddr_dl *)(
+ buf +
+ sizeof(struct if_msghdr) -
+ sizeof(struct if_data) +
+ ifh->ifm_data.ifi_datalen
+ );
+
+ i = sdl->sdl_nlen < sizeof(ifName)?sdl->sdl_nlen:(sizeof(ifName)-1);
+ memcpy(ifName,sdl->sdl_data,i);
+ ifName[i] = 0;
+
+ buf += ifh->ifm_msglen;
+ i = 0;
+ while( buf < lim ) {
+ struct ifa_msghdr *ifht = (struct ifa_msghdr *)buf;
+ char* addrPtr;
+ int c;
+ struct sockaddr_in *if_addr = NULL;
+ struct sockaddr_in *if_nmsk = NULL;
+ struct sockaddr_in *if_bcst = NULL;
+
+ if( ifht->ifam_type != RTM_NEWADDR )
+ break;
+
+ addrPtr = buf + sizeof(struct ifa_msghdr);
+ buf += ifht->ifam_msglen;
+
+ if( ifh->ifm_flags & (IFF_LOOPBACK|IFF_POINTOPOINT) )
+ continue;
+
+ for(c=1;c<(1<<RTAX_MAX);c<<=1) {
+ switch(c & ifht->ifam_addrs) {
+ case 0:
+ continue;
+ case RTA_NETMASK:
+ if_nmsk = (struct sockaddr_in *)addrPtr;
+ break;
+ case RTA_IFA:
+ if_addr = (struct sockaddr_in *)addrPtr;
+ break;
+ case RTA_BRD:
+ if_bcst = (struct sockaddr_in *)addrPtr;
+ break;
+ }
+ addrPtr += SA_SIZE((struct sockaddr *)addrPtr);
+ }
+
+
+ if( if_addr && if_addr->sin_family == AF_INET ) {
+ if(
+ ( dstip & if_nmsk->sin_addr.s_addr )
+ ==
+ ( if_addr->sin_addr.s_addr & if_nmsk->sin_addr.s_addr )
+ ) {
+ if( verbose )
+ printf(
+ "Specified addr matches interface %s,\n"
+ "ifce addr %s, mask %s, brcast %s\n",
+ ifName,
+ inet_ntoa(if_addr->sin_addr),
+ inet_ntoa(if_nmsk->sin_addr),
+ inet_ntoa(if_bcst->sin_addr)
+ );
+ if( ifce_ip != 0 )
+ *ifce_ip = if_addr->sin_addr.s_addr;
+ return ifName;
+ }
+ }
+ }
+ }
+ strcpy(ebuf,"Network not found");
+ return NULL;
+}
+#endif
+
#ifdef WIN32
static BOOL WINAPI arping_console_ctrl_handler(DWORD dwCtrlType)
@@ -1143,7 +1280,18 @@
if (dont_use_arping_lookupdev) {
ifname = arping_lookupdev_default(srcip,dstip,ebuf);
} else {
+#ifndef __FreeBSD__
ifname = arping_lookupdev(srcip,dstip,ebuf);
+#else
+ {
+ in_addr_t ifce_ip = 0;
+ ifname = FBSD_lookupIface(dstip,ebuf,&ifce_ip);
+ if( !srcip_given ) {
+ srcip = ifce_ip;
+ srcip_given = 1;
+ }
+ }
+#endif
}
if (!ifname) {
fprintf(stderr, "arping: arping_lookupdev(): %s\n",
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-ports-bugs
mailing list