--- /usr/ports/net/ntop/work/RC2/ntop/globals-core.h.orig	Tue May 28 10:41:47 2002
+++ /usr/ports/net/ntop/work/RC2/ntop/globals-core.h	Sat Oct  5 19:01:19 2002
@@ -110,6 +110,7 @@
 extern void startSniffer(void);
 extern void deviceSanityCheck(char* string);
 extern u_int createDummyInterface(char *ifName);
+extern void getIfAddressesTable(void);
 
 /* leaks.c */
 extern void initLeaks(void);
--- /usr/ports/net/ntop/work/RC2/ntop/globals.h.orig	Tue Jun  4 15:01:43 2002
+++ /usr/ports/net/ntop/work/RC2/ntop/globals.h	Mon Oct  7 13:46:12 2002
@@ -111,6 +111,8 @@
   /* NICs */
   int numDevices;          /* # of Network interfaces enabled for sniffing */
   NtopInterface *device;   /* pointer to the table of Network interfaces */
+  int numAddresses;
+  struct sockaddr_in *ifAddressesTable;
 
   /* Database */
   GDBM_FILE gdbm_file, pwFile, eventFile, hostsInfoFile, addressCache, prefsFile;
@@ -302,6 +304,7 @@
   /* NetFlow */
   /* Flow emission */
   int netFlowOutSocket;
+  int routingSocket;
   u_int32_t globalFlowSequence, globalFlowPktCount;
   NetFlow5Record theRecord;
   struct sockaddr_in netFlowDest;
--- /usr/ports/net/ntop/work/RC2/ntop/initialize.c.orig	Mon Jun  3 09:39:37 2002
+++ /usr/ports/net/ntop/work/RC2/ntop/initialize.c	Wed Nov 13 16:17:40 2002
@@ -1267,3 +1267,53 @@
 
   return(deviceId);
 }
+
+#define ROUNDUP(a) \
+        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+
+void getIfAddressesTable(void) {
+    char *buf, *lim, *next;
+    size_t needed;
+    int i,mib[6];
+
+    struct rt_msghdr *rtm; 
+    struct if_msghdr *ifm;
+    struct ifa_msghdr *ifam;
+    struct sockaddr *packed;
+
+    traceEvent(TRACE_INFO, "Getting interface table via sysctl interface...\n");
+
+    myGlobals.ifAddressesTable = (struct sockaddr_in *) calloc(MAX_IF_ADDRS, sizeof(struct sockaddr_in));
+    myGlobals.numAddresses=0;
+
+    mib[0] = CTL_NET;
+    mib[1] = PF_ROUTE;
+    mib[2] = 0;
+    mib[3] = AF_INET;
+    mib[4] = NET_RT_IFLIST;
+    mib[5] = 0;
+
+    sysctl(mib, 6, NULL, &needed, NULL, 0);
+    buf = malloc(needed);
+    sysctl(mib, 6, buf, &needed, NULL, 0);
+    lim = buf + needed;
+
+    for( next = buf; next < lim; next += rtm->rtm_msglen ) {
+	rtm = (struct rt_msghdr *)next;
+
+	if (rtm->rtm_type == RTM_NEWADDR) {
+	    ifam = (struct ifa_msghdr *)next;
+	    packed = (struct sockaddr *)(next + sizeof(struct ifa_msghdr));
+	    for( i = 0; i < RTAX_MAX; i++ ) {
+		if (ifam->ifam_addrs & (1<<i)) {
+		    if (i==RTAX_IFA) {
+			memcpy(&myGlobals.ifAddressesTable[myGlobals.numAddresses],packed,packed->sa_len);
+			myGlobals.numAddresses++;
+		    }
+		    packed = (struct sockaddr *)(((char *)packed) + ROUNDUP(packed->sa_len));
+		}
+	    }    
+	}
+    }
+    free(buf);
+}
--- /usr/ports/net/ntop/work/RC2/ntop/main.c.orig	Fri May 31 17:00:20 2002
+++ /usr/ports/net/ntop/work/RC2/ntop/main.c	Sat Oct  5 19:04:34 2002
@@ -791,6 +791,7 @@
    * initialize memory and data
    */
   initDevices(myGlobals.devices);
+  getIfAddressesTable();
 
   traceEvent(TRACE_INFO, "ntop v.%s %s [%s] (%s build)",
 	     version, THREAD_MODE, osName, buildDate);
--- /usr/ports/net/ntop/work/RC2/ntop/netflow.c.orig	Fri Apr 12 16:00:58 2002
+++ /usr/ports/net/ntop/work/RC2/ntop/netflow.c	Wed Nov 13 16:37:34 2002
@@ -87,8 +87,10 @@
   if(myGlobals.netFlowOutSocket != 0) {
     sendNetFlow(TRUE);
     traceEvent(TRACE_INFO, "Cisco NetFlow exporter terminated.");
+    traceEvent(TRACE_INFO, "BSD routing socket closed.");
 #ifndef WIN32
     close(myGlobals.netFlowOutSocket);
+    close(myGlobals.routingSocket);
 #else
     closesocket(myGlobals.netFlowOutSocket);
 #endif
@@ -168,6 +170,100 @@
   }
 }
 
+static struct rt_msghdr* sendRtMessage (int rs, struct rt_msghdr* rtm, struct in_addr *dest_ip) {
+    struct sockaddr_in *dest;
+    struct sockaddr_dl *dest_if;
+
+    rtm->rtm_msglen = sizeof(struct rt_msghdr)+sizeof(struct sockaddr_in)+sizeof(struct sockaddr_dl);
+    rtm->rtm_version = RTM_VERSION;
+    rtm->rtm_type = RTM_GET;
+    rtm->rtm_addrs = RTA_DST + RTA_IFP;
+    rtm->rtm_pid = getpid();
+    rtm->rtm_seq = 1234;
+
+    dest=(struct sockaddr_in *)(rtm+1);
+    dest->sin_len=sizeof(struct sockaddr_in);
+    dest->sin_family = AF_INET;
+    dest->sin_port = htons(0);
+    memcpy(&dest->sin_addr,dest_ip,sizeof(struct in_addr));
+    
+    dest_if=(struct sockaddr_dl *)(dest+1);
+    dest_if->sdl_len=sizeof(struct sockaddr_dl);
+    dest_if->sdl_family=AF_LINK;
+    
+    if ((write(rs,rtm,rtm->rtm_msglen)) != rtm->rtm_msglen) {
+	free(rtm);
+	return(NULL);
+    }    
+
+    return(rtm);
+}
+
+static int getActualDestIfindex (struct in_addr *dest_ip) {
+    int ifIdx, actualIfIdx;
+    struct in_addr ifAddr;
+    struct sockaddr_in *dest;
+    char ifName[16];
+    struct rt_msghdr *rtm;                                                                                    
+    struct sockaddr_dl *dest_if;
+
+    for (ifIdx=0; ifIdx<=myGlobals.numAddresses; ifIdx++) {
+//	printf("%s - %s\n",inet_ntoa(dest->sin_addr),inet_ntoa(myGlobals.ifAddressesTable[ifIdx].sin_addr));
+	if (dest_ip->s_addr == myGlobals.ifAddressesTable[ifIdx].sin_addr.s_addr) {
+	    return(0);
+	    break;
+	}
+    }
+
+    rtm = (struct rt_msghdr *) calloc(1,(sizeof(struct rt_msghdr)+512));
+
+    if (rtm == NULL) {
+	return(128);
+    }
+    
+    rtm = sendRtMessage(myGlobals.routingSocket, rtm, dest_ip);
+    if (rtm == NULL) {
+	return(128);
+    }
+
+    dest=(struct sockaddr_in *)(rtm+1);
+    dest_if=(struct sockaddr_dl *)(dest+1);
+
+    do {
+	read(myGlobals.routingSocket,rtm,sizeof(struct rt_msghdr)+512);
+    } while (rtm->rtm_type != RTM_GET || rtm->rtm_seq != 1234 || rtm->rtm_pid != getpid());
+
+    if (dest_if->sdl_index == 0) {
+	rtm = sendRtMessage(myGlobals.routingSocket, rtm, (struct in_addr *) &(dest+1)->sin_addr);
+        do {
+    	    read(myGlobals.routingSocket,rtm,sizeof(struct rt_msghdr)+512);
+	} while (rtm->rtm_type != RTM_GET || rtm->rtm_seq != 1234 || rtm->rtm_pid != getpid());
+    }
+
+//    if_indextoname(dest_if->sdl_index,ifName);
+
+    actualIfIdx=dest_if->sdl_index;
+
+    
+    free(rtm);
+    return(actualIfIdx);
+}
+
+static int getActualSrcIfindex (int virtualIfIdx, struct in_addr *src_ip) {
+    int ifIdx,actualIfIdx;
+    
+    actualIfIdx=if_nametoindex(myGlobals.device[virtualIfIdx].name);    
+
+    for (ifIdx=0; ifIdx<=myGlobals.numAddresses; ifIdx++) {
+	if (src_ip->s_addr == myGlobals.ifAddressesTable[ifIdx].sin_addr.s_addr) {
+	    actualIfIdx=0;
+	    break;
+	}
+    }
+
+    return(actualIfIdx);
+}
+
 /* *********************************** */
 
 /* 
@@ -199,8 +295,8 @@
      && (theSession->bytesSent > 0)) {
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].srcaddr  = srcAddr;
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].dstaddr  = dstAddr;
-    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].input    = htons(actualDeviceId);
-    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].output   = htons(255 /* unknown device */);
+    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].input    = htons(getActualSrcIfindex(actualDeviceId,(struct in_addr *) &srcAddr));
+    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].output   = htons(getActualDestIfindex((struct in_addr *) &dstAddr));
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].dPkts    = htonl(theSession->pktSent);
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].dOctets  = htonl(theSession->bytesSent);
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].First    = htonl((theSession->firstSeen-myGlobals.initialSniffTime)*1000);
@@ -213,8 +309,8 @@
 
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].srcaddr = dstAddr;
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].dstaddr = srcAddr;
-    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].input   = htons(actualDeviceId);
-    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].output  = htons(255 /* unknown device */);
+    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].input   = htons(getActualDestIfindex((struct in_addr *) &dstAddr));
+    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].output  = htons(getActualSrcIfindex(actualDeviceId,(struct in_addr *) &srcAddr));
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].dPkts   = htonl(theSession->pktRcvd);
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].dOctets = htonl(theSession->bytesRcvd);
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].First   = htonl((theSession->firstSeen-myGlobals.initialSniffTime)*1000);
@@ -253,8 +349,8 @@
      && (length > 0)) {
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].srcaddr = srcAddr;
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].dstaddr = dstAddr;
-    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].input   = htons(actualDeviceId);
-    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].output  = htons(255 /* unknown device */);
+    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].input   = htons(getActualSrcIfindex(actualDeviceId,(struct in_addr *) &srcAddr));
+    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].output  = htons(getActualDestIfindex((struct in_addr *) &dstAddr));
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].dPkts   = htonl(1);
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].dOctets = htonl(length);
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].First   = htonl((myGlobals.actTime-myGlobals.initialSniffTime)*1000);
@@ -291,8 +387,8 @@
   if(srcAddr && dstAddr && length) {    
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].srcaddr = srcAddr;
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].dstaddr = dstAddr;
-    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].input   = htons(actualDeviceId);
-    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].output  = htons(255 /* unknown device */);
+    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].input   = htons(getActualSrcIfindex(actualDeviceId,(struct in_addr *) &srcAddr));
+    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].output  = htons(getActualDestIfindex((struct in_addr *) &dstAddr));
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].dPkts   = htonl(1);
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].dOctets = htonl(length);
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].First   = htonl((myGlobals.actTime-myGlobals.initialSniffTime)*1000);
@@ -331,8 +427,8 @@
   if(srcAddr && dstAddr && length) {    
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].srcaddr = srcAddr;
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].dstaddr = dstAddr;
-    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].input   = htons(actualDeviceId);
-    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].output  = htons(255 /* unknown device */);
+    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].input   = htons(getActualSrcIfindex(actualDeviceId,(struct in_addr *) &srcAddr));
+    myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].output  = htons(getActualDestIfindex((struct in_addr *) &dstAddr));
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].dPkts   = htonl(1);
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].dOctets = htonl(length);
     myGlobals.theRecord.flowRecord[myGlobals.globalFlowPktCount].First   = htonl((myGlobals.actTime-myGlobals.initialSniffTime)*1000);
@@ -342,3 +438,4 @@
     myGlobals.globalFlowPktCount++; sendNetFlow(FALSE);
   }
 }
+
--- /usr/ports/net/ntop/work/RC2/ntop/ntop.c.orig	Mon Jun  3 09:39:37 2002
+++ /usr/ports/net/ntop/work/RC2/ntop/ntop.c	Wed Nov 13 16:27:16 2002
@@ -1029,6 +1029,7 @@
 
   free(myGlobals.pcapLogBasePath);
   free(myGlobals.dbPath);
+  free(myGlobals.ifAddressesTable);
 
   myGlobals.endNtop = 1;
 
--- /usr/ports/net/ntop/work/RC2/ntop/ntop.h.orig	Tue Jun  4 15:01:43 2002
+++ /usr/ports/net/ntop/work/RC2/ntop/ntop.h	Sat Oct  5 19:24:03 2002
@@ -281,6 +281,9 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <net/if.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+#include <sys/sysctl.h>
 
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
@@ -492,8 +495,10 @@
 
 #ifdef WIN32
 #define MAX_NUM_DEVICES 1
+#define MAX_IF_ADDRS 1
 #else
-#define MAX_NUM_DEVICES 32       /* NIC devices */
+#define MAX_NUM_DEVICES 64       /* NIC devices */
+#define MAX_IF_ADDRS 256
 #endif
 #define MAX_NUM_ROUTERS 512
 
--- /usr/ports/net/ntop/work/RC2/ntop/plugins/netflowPlugin.c.orig	Thu May 16 10:55:42 2002
+++ /usr/ports/net/ntop/work/RC2/ntop/plugins/netflowPlugin.c	Thu Oct  3 15:57:45 2002
@@ -95,6 +95,13 @@
 
 /* ****************************** */
 
+void setRoutingSocket () {
+    myGlobals.routingSocket = socket(PF_ROUTE,SOCK_RAW,AF_INET);
+    traceEvent(TRACE_INFO, "BSD routing socket opened");
+}
+
+/* ****************************** */
+
 static void* netflowMainLoop(void* notUsed _UNUSED_) {
   fd_set netflowMask;
   int rc, len;
@@ -285,6 +292,7 @@
     myGlobals.netFlowDest.sin_addr.s_addr = inet_addr(value);
 
   setNetFlowOutSocket();
+  setRoutingSocket();
 
   for(i=0; i<myGlobals.numDevices; i++)
     if(!myGlobals.device[i].virtualDevice) {
