Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 28 Mar 2008 15:39:05 GMT
From:      Dmitry <hanabana@mail.ru>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   ports/122197: patch to lookup for interface and src ip 
Message-ID:  <200803281539.m2SFd5xZ031072@www.freebsd.org>
Resent-Message-ID: <200803281540.m2SFe2gx076873@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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@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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200803281539.m2SFd5xZ031072>