[netperf-dev] netperf2 commit notice r264 - trunk/src
raj at netperf.org
raj at netperf.org
Mon Mar 17 18:16:08 PDT 2008
Author: raj
Date: 2008-03-17 18:16:07 -0700 (Mon, 17 Mar 2008)
New Revision: 264
Modified:
trunk/src/netrt_rtmget.c
Log:
appears that egress interface is working on Solaris10 but not yet AIX 5.3
Modified: trunk/src/netrt_rtmget.c
===================================================================
--- trunk/src/netrt_rtmget.c 2008-03-17 23:27:04 UTC (rev 263)
+++ trunk/src/netrt_rtmget.c 2008-03-18 01:16:07 UTC (rev 264)
@@ -11,9 +11,116 @@
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
+#include <sys/ioctl.h>
+#if defined(HAVE_SYS_SOCKIO_H)
+#include <sys/sockio.h>
+#endif
+
+/* more UNP leverage */
char *
find_egress_interface_by_addr(struct sockaddr *addr) {
+
+ char *buf,*ptr;
+ int lastlen,len,cmplen;
+ int sockfd;
+ struct ifconf ifc;
+ struct ifreq *ifr;
+ struct sockaddr_in *sin,*tsin;
+#ifdef AF_INET6
+ struct sockaddr_in6 *sin6,*tsin6;
+#endif
+ void *addr1,*addr2;
+
+ sin = (struct sockaddr_in *)addr;
+#ifdef AF_INET6
+ sin6 = (struct sockaddr_in6 *)sin;
+#endif
+ printf("Looking for %s\n",inet_ntoa(sin->sin_addr));
+
+ sockfd = socket(AF_INET,SOCK_DGRAM,0);
+ if (sockfd < 0)
+ return strdup("socket");
+
+ lastlen = 0;
+ len = 100 * sizeof(struct ifreq);
+ while (1) {
+ buf = malloc(len);
+ if (NULL == buf)
+ return strdup("malloc");
+
+ ifc.ifc_len = len;
+ ifc.ifc_buf = buf;
+
+ if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
+ if (errno != EINVAL || lastlen != 0) {
+ free(buf);
+ return strdup("SIOCIFCONF");
+ }
+ }
+ else {
+ if (ifc.ifc_len == lastlen)
+ break; /* the ioctl was happy */
+ lastlen = ifc.ifc_len;
+ }
+ len += 10 * sizeof(struct ifreq);
+ free(buf);
+ }
+
+#if defined(NETPERF_STANDALONE_DEBUG)
+ printf("ioctl was OK, len is %d\n", ifc.ifc_len);
+#endif
+
+ for (ptr = buf; ptr < buf + ifc.ifc_len; ) {
+ ifr = (struct ifreq *) ptr;
+
+ switch (ifr->ifr_addr.sa_family) {
+#ifdef AF_INET6
+ case AF_INET6:
+ addr1 = &(sin6->sin6_addr);
+ tsin6 = (struct sockaddr_in6 *)&(ifr->ifr_addr);
+ addr2 = &(tsin6->sin6_addr);
+ cmplen = sizeof(tsin6->sin6_addr);
+ len = sizeof(struct sockaddr_in6);
+ break;
+#endif
+ case AF_INET:
+ default:
+ addr1 = &(sin->sin_addr.s_addr);
+ tsin = (struct sockaddr_in *)&(ifr->ifr_addr);
+ addr2 = &(tsin->sin_addr.s_addr);
+ cmplen = sizeof(struct in_addr);
+ len = sizeof(struct sockaddr_in);
+ break;
+ }
+
+ ptr += sizeof(ifr->ifr_name) + len;
+
+ if (ifr->ifr_addr.sa_family != sin->sin_family)
+ continue;
+ else {
+
+#if defined(NETPERF_STANDALONE_DEBUG)
+ printf("addr1 %p addr2 %p len %d\n",addr1,addr2,cmplen);
+#endif
+ if (0 == memcmp(addr1,addr2,cmplen)) {
+ struct ifreq flagsreq;
+ flagsreq = *ifr;
+ /* we've gotten this far - ass-u-me this will work? */
+ ioctl(sockfd,SIOCGIFFLAGS, &flagsreq);
+ if (flagsreq.ifr_flags & IFF_UP) {
+#if defined(NETPERF_STANDALONE_DEBUG)
+ printf("Interface name %s family %d\n",ifr->ifr_name,ifr->ifr_addr.sa_family);
+ close(sockfd);
+ /* we should probably close the memory leak one of these days */
+ return strdup(ifr->ifr_name);
+ }
+#endif
+ }
+ }
+ }
+ close(sockfd);
+ free(buf);
return strdup("EgressByAddr");
}
@@ -62,6 +169,7 @@
int copy_len;
char *buffer;
void *next_hop;
+ struct sockaddr_storage holdme;
struct sockaddr_in *sin;
struct sockaddr_in6 *sin6;
@@ -93,8 +201,10 @@
copy_len = sizeof(struct sockaddr_in6);
}
#endif
- else
+ else {
+ free(buffer);
return strdup("Unknown AF");
+ }
rtm->rtm_version = RTM_VERSION;
rtm->rtm_type = RTM_GET;
@@ -107,14 +217,18 @@
/* send the message */
ret = write(sockfd,rtm,rtm->rtm_msglen);
- if (ret != rtm->rtm_msglen)
+ if (ret != rtm->rtm_msglen) {
+ free(buffer);
return(strdup("write"));
+ }
/* seek the reply */
do {
ret = read(sockfd, rtm, BUFLEN);
- if (ret < sizeof(struct rt_msghdr))
+ if (ret < sizeof(struct rt_msghdr)) {
+ free(buffer);
return strdup("read");
+ }
} while (rtm->rtm_type != RTM_GET ||
rtm->rtm_seq != 12865 ||
rtm->rtm_pid != getpid());
More information about the netperf-dev
mailing list