--- /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<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 #include #include +#include +#include +#include #include #include @@ -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