[netperf-dev] netperf2 commit notice r263 - in trunk: . src
raj at netperf.org
raj at netperf.org
Mon Mar 17 16:27:05 PDT 2008
Author: raj
Date: 2008-03-17 16:27:04 -0700 (Mon, 17 Mar 2008)
New Revision: 263
Modified:
trunk/config.h.in
trunk/configure
trunk/configure.ac
trunk/src/netrt_rtmget.c
Log:
looks like we have egress interface lookup for HP-UX 11iv3 and the BSDish stacks and are only one step removed from there for AIX 5.3 and Solaris 10
Modified: trunk/config.h.in
===================================================================
--- trunk/config.h.in 2008-03-14 00:39:45 UTC (rev 262)
+++ trunk/config.h.in 2008-03-17 23:27:04 UTC (rev 263)
@@ -304,12 +304,6 @@
/* Use HP-UX's pstat interface to measure CPU util. */
#undef USE_PSTAT
-/* Use routing socket interface to determine egress interface. */
-#undef USE_RTMGET
-
-/* Use Linux's rtnetlink interface to determine egress interface. */
-#undef USE_RTNETLINK
-
/* Use MumbleBSD's sysctl interface to measure CPU util. */
#undef USE_SYSCTL
Modified: trunk/configure
===================================================================
--- trunk/configure 2008-03-14 00:39:45 UTC (rev 262)
+++ trunk/configure 2008-03-17 23:27:04 UTC (rev 263)
@@ -9508,64 +9508,29 @@
case "$enable_rtlookup" in
rtmget)
use_rtlookup=true
-
-cat >>confdefs.h <<\_ACEOF
-#define USE_RTMGET
-_ACEOF
-
;;
rtnetlink)
use_rtlookup=true
-
-cat >>confdefs.h <<\_ACEOF
-#define USE_RTNETLINK
-_ACEOF
-
;;
'')
# guess it automagically in a nice big case statement
case $target in
*-*-linux*)
use_rtlookup=true
-
-cat >>confdefs.h <<\_ACEOF
-#define USE_RTNETLINK
-_ACEOF
-
enable_rtlookup="rtnetlink - auto"
NETRTLKUP_SOURCE="rtnetlink"
;;
- *-*-hpux11.31)
+ *-*-hpux11.31 | *-*-solaris* | *-*-aix5*)
use_rtlookup=true
-
-cat >>confdefs.h <<\_ACEOF
-#define USE_RTMGET
-_ACEOF
-
enable_rtlookup="rtmget - auto"
NETRTLKUP_SOURCE="rtmget"
;;
- *-*-freebsd[4-7].* )
+ *-*-freebsd[4-7].* | *-*-darwin*)
use_rtlookup=true
-
-cat >>confdefs.h <<\_ACEOF
-#define USE_RTMGET
-_ACEOF
-
enable_rtlookup="rtmget - auto"
NETRTLKUP_SOURCE="rtmget"
;;
- *-*-darwin*)
- use_rtlookup=true
-
-cat >>confdefs.h <<\_ACEOF
-#define USE_RTMGET
-_ACEOF
-
- enable_rtlookup="rtmget - auto"
- NETRTLKUP_SOURCE="rtmget"
- ;;
*)
use_rtlookup=false
NETRTLKUP_SOURCE="none"
Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac 2008-03-14 00:39:45 UTC (rev 262)
+++ trunk/configure.ac 2008-03-17 23:27:04 UTC (rev 263)
@@ -732,40 +732,29 @@
case "$enable_rtlookup" in
rtmget)
use_rtlookup=true
- AC_DEFINE([USE_RTMGET],,[Use RTM_GET on a routing socket to get egress interface.])
;;
rtnetlink)
use_rtlookup=true
- AC_DEFINE([USE_RTNETLINK],,[Use Linux's rtnetlink interface to dettermine egress interface.])
;;
'')
# guess it automagically in a nice big case statement
case $target in
*-*-linux*)
use_rtlookup=true
- AC_DEFINE([USE_RTNETLINK],,[Use Linux's rtnetlink interface to determine egress interface.])
enable_rtlookup="rtnetlink - auto"
NETRTLKUP_SOURCE="rtnetlink"
;;
- *-*-hpux11.31)
+ *-*-hpux11.31 | *-*-solaris* | *-*-aix5*)
use_rtlookup=true
- AC_DEFINE([USE_RTMGET],,[Use routing sockets to determine egress interface.])
enable_rtlookup="rtmget - auto"
NETRTLKUP_SOURCE="rtmget"
;;
- *-*-freebsd[[4-7]].* )
+ *-*-freebsd[[4-7]].* | *-*-darwin*)
use_rtlookup=true
- AC_DEFINE([USE_RTMGET],,[Use routing socket interface to determine egress interface.])
enable_rtlookup="rtmget - auto"
NETRTLKUP_SOURCE="rtmget"
;;
- *-*-darwin*)
- use_rtlookup=true
- AC_DEFINE([USE_RTMGET],,[Use routing socket interface to determine egress interface.])
- enable_rtlookup="rtmget - auto"
- NETRTLKUP_SOURCE="rtmget"
- ;;
*)
use_rtlookup=false
NETRTLKUP_SOURCE="none"
Modified: trunk/src/netrt_rtmget.c
===================================================================
--- trunk/src/netrt_rtmget.c 2008-03-14 00:39:45 UTC (rev 262)
+++ trunk/src/netrt_rtmget.c 2008-03-17 23:27:04 UTC (rev 263)
@@ -1,10 +1,191 @@
+#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
#include <net/if.h>
+#include <net/if_dl.h>
#include <net/route.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
-char *
+char *
+find_egress_interface_by_addr(struct sockaddr *addr) {
+ return strdup("EgressByAddr");
+}
+
+#if defined(AF_LINK)
+char *
+find_egress_interface_by_link(struct sockaddr_dl *link) {
+
+ char buffer[IF_NAMESIZE];
+ char *cret;
+
+#if defined(NETPERF_STANDALONE_DEBUG)
+ printf("link index %d nlen %d alen %d slen %d\n",
+ link->sdl_index,
+ link->sdl_nlen,
+ link->sdl_alen,
+ link->sdl_slen);
+#endif
+
+ /* I suspect we could extract the name from the sockaddr_dl
+ directly, and perhaps should, but I really don't like mucking
+ about with pointers and offsets and characters so will just punt
+ to if_indextoname. raj 2008-03-17 */
+ if (link->sdl_index != 0) {
+ cret = if_indextoname(link->sdl_index,buffer);
+ if (NULL != cret)
+ return strdup(cret);
+ else
+ return strdup(strerror(errno));
+ }
+ else
+ return strdup("noindex");
+}
+
+#endif
+
+/* borrows heavily from W Richard Stevens' getrt.c of unp fame */
+
+#define BUFLEN (sizeof(struct rt_msghdr) + 512)
+
+char *
find_egress_interface(struct sockaddr *source, struct sockaddr *dest) {
- return strdup("NotImplemented");
+
+ int sockfd;
+ int ret;
+ struct rt_msghdr *rtm;
+ int copy_len;
+ char *buffer;
+ void *next_hop;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+
+ sockfd = socket(AF_ROUTE, SOCK_RAW, 0);
+ if (sockfd < 0)
+ return (strdup("socket"));
+
+ buffer = calloc(1,BUFLEN);
+ if (NULL == buffer)
+ return (strdup("calloc"));
+
+ rtm = (struct rt_msghdr *)buffer;
+
+ rtm->rtm_msglen = sizeof(struct rt_msghdr);
+ sin = (struct sockaddr_in *)dest;
+
+ if (AF_INET == sin->sin_family) {
+
+#if defined(NETPERF_STANDALONE_DEBUG)
+ printf("Resolving addr is %s\n",inet_ntoa(sin->sin_addr));
+#endif
+
+ rtm->rtm_msglen += sizeof(struct sockaddr_in);
+ copy_len = sizeof(struct sockaddr_in);
+ }
+#if defined(AF_INET6)
+ else if (AF_INET6 == sin->sin_family) {
+ rtm->rtm_msglen += sizeof(struct sockaddr_in6);
+ copy_len = sizeof(struct sockaddr_in6);
+ }
+#endif
+ else
+ return strdup("Unknown AF");
+
+ rtm->rtm_version = RTM_VERSION;
+ rtm->rtm_type = RTM_GET;
+ rtm->rtm_addrs = RTA_DST;
+ rtm->rtm_pid = getpid();
+ rtm->rtm_seq = 12865;
+
+ /* point just beyond the rt_msghdr. */
+ memcpy((rtm + 1), dest, copy_len);
+
+ /* send the message */
+ ret = write(sockfd,rtm,rtm->rtm_msglen);
+ if (ret != rtm->rtm_msglen)
+ return(strdup("write"));
+
+ /* seek the reply */
+ do {
+ ret = read(sockfd, rtm, BUFLEN);
+ if (ret < sizeof(struct rt_msghdr))
+ return strdup("read");
+ } while (rtm->rtm_type != RTM_GET ||
+ rtm->rtm_seq != 12865 ||
+ rtm->rtm_pid != getpid());
+ if ((rtm->rtm_flags & RTF_GATEWAY) &&
+ (rtm->rtm_addrs & RTA_GATEWAY)) {
+ /* we have a next hop gateway to resolve. we take advantage of the
+ observation that if there is a gateway address there "aways"
+ seems to be an RTA_DST in front of it */
+ sin = (struct sockaddr_in *)(rtm + 1);
+ sin6 = (struct sockaddr_in6 *)sin;
+ if (AF_INET == sin->sin_family)
+ return find_egress_interface(NULL,(struct sockaddr *)(sin + 1));
+ else
+ return find_egress_interface(NULL,(struct sockaddr *)(sin6 + 1));
+ }
+
+ /* once again, we take "advantage" of the item of interest "always"
+ being the second in the list. there seem to be two distinct
+ "camps" here - in one camp are AIX and Solaris (at least 5.3 and
+ 10 respectively) which only resolve as far down as a local
+ interface IP address. in the other camp are HP-UX 11iv3 (11.31)
+ and I'm _guessing_ BSD and OSX, who are kind enough to take
+ things down to an AF_LINK entry. */
+
+#if defined(NETPERF_STANDALONE_DEBUG)
+ printf("rtm_msglen %d\n",rtm->rtm_msglen);
+ printf("rtm_errno %d\n",rtm->rtm_errno);
+ printf("rtm_index %d\n",rtm->rtm_index);
+ printf("rtm_flags %x\n",rtm->rtm_flags);
+ printf("rtm_addrs %x\n",rtm->rtm_addrs);
+#endif
+
+ sin = (struct sockaddr_in *)(rtm +1);
+ sin = sin + 1;
+ sin6 = (struct sockaddr_in6 *)sin;
+
+#if defined(NETPERF_STANDALONE_DEBUG)
+ printf("address two %p family %d\n",sin,sin->sin_family);
+#endif
+
+ if (AF_INET == sin->sin_family)
+ return find_egress_interface_by_addr((struct sockaddr *)sin);
+#if defined(AF_INET6)
+ else if (AF_INET6 == sin6->sin6_family)
+ return find_egress_interface_by_addr((struct sockaddr *)sin6);
+#endif
+#if defined(AF_LINK)
+ else if (AF_LINK == sin->sin_family)
+ return find_egress_interface_by_link((struct sockaddr_dl *)sin);
+#endif
+ else
+ return strdup("LastHop AF");
}
+
+
+#if defined(NETPERF_STANDALONE_DEBUG)
+int
+main(int argc, char *argv[]) {
+
+ struct sockaddr_storage destination;
+ struct sockaddr_in *sin;
+ int ret;
+ char *egress_if;
+
+ sin = (struct sockaddr_in *)&destination;
+ sin->sin_family = AF_INET;
+ sin->sin_addr.s_addr = inet_addr(argv[1]);
+ printf("address is %s\n",inet_ntoa(sin->sin_addr));
+ egress_if = find_egress_interface(NULL,(struct sockaddr *)&destination);
+
+ printf("egress interface %p %s\n",egress_if,egress_if);
+
+}
+#endif
More information about the netperf-dev
mailing list