Messages in this thread | | | Date | Thu, 8 Apr 1999 11:38:17 -0700 (PDT) | From | David Ford <> | Subject | Re: /proc/net/dev info missing?? |
| |
On Thu, 8 Apr 1999, Meelis Roos wrote: > SA> I'm running kernel 2.2.5 on caldera openlinux. I have ip-aliases enabled > SA> and 1 alias (eth0:1) set up, which has worked fine. > SA> I also run ucd-snmp to retrieve traffic info for eth0 and eth0:1 (trying) > SA> I, however, cannot pull traffic info (packets/octets/etc) for an aliased > SA> interface. > > Aliases are not interfaces any morem they are just alternate addresses > for the same interface. All the accounting is done for real interfaces. > All the packets/octets/etc go through eth0 on the interface level.
in order to get traffic stats for different IPs now, you have to kludge a script combined with ipchains.
add rules to match either src or dst addr as you wish, e.g.
ipchains -A input -d 207.213.14.7 ipchains -A output -s 207.213.14.7
now gawk the 8th and 10th field, e.g.
gawk '{print $8,$10}' /proc/net/ip_fwchains # num pkts/num bytes
naturally you'll want to distinguish between addresses, that could be an excercise for the reader, or you can adapt the attached program to your use.
-d -- This is Linux Country. On a quiet night, you can hear Windows NT reboot! Do you remember how to -think- ? Do you remember how to experiment? Linux __ is an operating system that brings back the fun and adventure in computing. \/ for linux-kernel: please read linux/Documentation/* before posting problems // (c) Killerlabs 1999, free use, modification and distribution, please // email <david@killerlabs.com> any changes
/* mrtg would like to see output in the following format:
* if you want to monitor something which does not provide data via snmp you can use some external program to do the data gathering. The external command must return 4 lines of output: Line 1 current state of the first variable, normally 'incoming bytes count' Line 2 current state of the second variable, normally 'outgoing bytes count' Line 3 string (in any human readable format), telling the uptime of the target. Line 4 string, telling the name of the target. -- add rules similar to the following to match in/out traffic
ipchains -A input -d 207.213.14.7 ipchains -A output -s 207.213.14.7
# cat /proc/net/ip_fwchains input 00000000/00000000->CFD50E07/FFFFFFFF - 10 0 0 0 4 0\ 336 0-65535 0-65535 AFF X00 00000000 0 0 - input 00000000/00000000->CFD50E02/FFFFFFFF - 10 0 0 0 21 0\ 2568 0-65535 0-65535 AFF X00 00000000 0 0 - output CFD50E07/FFFFFFFF->00000000/00000000 - 10 0 0 0 4 0\ 336 0-65535 0-65535 AFF X00 00000000 0 0 - output CFD50E02/FFFFFFFF->00000000/00000000 - 10 0 0 0 21 0\ 1883 0-65535 0-65535 AFF X00 00000000 0 0 -
*/
#include <stdio.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>
#include <asm/types.h>
void usage(void);
main(int argc, char **argv) { FILE *fp; size_t packets_in, packets_out, octets_in, octets_out; size_t pkts, bytes; time_t count; __u32 saddr,smask, daddr,dmask; __u32 IP; int flag_EOF, conversions, kill=0; int days,hours,minutes,seconds; uid_t myuid; struct in_addr inp;
// no, my fscanf matching isn't pretty, you're invited to enlighten me char *format= "%*10s\ %08x/%08x->%08x/%08x%\ *[^0-9]%*i%*i %*i %*i%*[^0-9]\ %li%*[^0-9]%*i%li\ %*[^\n]\n";
if( argc>1 && strlen(argv[1]) >15 ){ // // bad user. fprintf(stdout, "ahem. too much input for <IP>\n"); usage(); exit(-1); }
if( argc>2 && strlen(argv[2]) >31 ){ // // bad user. fprintf(stdout, "ahem. too much input for <name>\n"); usage(); exit(-1); }
if(argc!=3){ usage(); exit(-1); }
myuid= getuid(); if(myuid!=0){ fprintf(stdout, "2.2 kernels require root access for ipchains /proc\n"); usage(); exit(-1); }
IP=inet_aton(argv[1], &inp); if(IP) IP=ntohl(inp.s_addr);
if(!IP){ fprintf(stdout, "invalid IP specified, try again\n"); usage(); exit(-1); }
// // get bytes count
fp=fopen("/proc/net/ip_fwchains", "r"); if(!fp){ fprintf(stdout, "can't read /proc/net/ip_fwchains, is ip firewalling" " compiled into your kernel?\n"); exit(-1); }
flag_EOF= !EOF; count=0;
while(flag_EOF != EOF){ conversions=fscanf(fp, format, &saddr,&smask, &daddr,&dmask, &pkts,&bytes); #if (DEBUG) fprintf(stdout, "%i conversions\n", conversions); #endif if(conversions==6){ #if (DEBUG) fprintf(stdout, "s->%08lx, d->%08lx\n", saddr, daddr); #endif if(saddr==IP && smask==0xffffffff){ packets_out=pkts; octets_out=bytes; count++; } if(daddr==IP && dmask==0xffffffff){ packets_in=pkts; octets_in=bytes; count++; } } if(kill++ > 2000){ fprintf(stdout, "too many iterations searching for data\n"); fprintf(stdout, "ask <david@killerlabs.com> to update software to match" " kernel changes\n"); fprintf(stdout, "or fix this bug. include `cat /proc/net/ip_fwchains`" " in your email.\n"); exit(-1); }
if(count >2){ fprintf(stdout, "too many rules match address requested: %i matches\n", count); exit(-1); }
flag_EOF=conversions; }
if(count <2){ fprintf(stdout, "insufficient rules to match address requested: %s\n", argv[1]); exit(-1); }
fprintf(stdout, "%li\n%li\n", octets_in, octets_out); fclose(fp);
// // now get the current machine uptime
fp=fopen("/proc/uptime", "r"); if(!fp){ fprintf(stdout, "my glasses broke. can't read /proc/uptime\n"); exit(-1); }
flag_EOF= !EOF;
conversions=fscanf(fp, "%li%*[^\n]\n", &count); if(conversions !=1 ) exit(-1);
days=count/(86400); hours=(count- (days*86400)) /3600; minutes=(count- ((days*86400)+(hours*3600)) )/60; seconds= count- ((days*86400)+(hours*3600)+(minutes*60));
if (days >99) fprintf(stdout, "%3i days", days); else if (days >10) fprintf(stdout, "%2i days", days); else if (days >1) fprintf(stdout, "%1i days", days); else if (days == 1) fprintf(stdout, "%1i day", days);
if (hours >10) fprintf(stdout, ", %2i hours", hours); else if (hours >1) fprintf(stdout, ", %1i hours", hours); else if (hours == 1) fprintf(stdout, ", %1i hour", hours);
if (minutes >10) fprintf(stdout, ", %2i minutes", minutes); else if (minutes >1) fprintf(stdout, ", %1i minutes", minutes); else if (minutes == 1) fprintf(stdout, ", %1i minute", minutes);
if (seconds >10) fprintf(stdout, ", %2i seconds", seconds); else if (seconds >1) fprintf(stdout, ", %1i seconds", seconds); else if (seconds == 1) fprintf(stdout, ", %1i second", seconds);
fprintf(stdout, ".\n"); fclose(fp);
// // The identifing string anyone? :)
fprintf(stdout, "%s\n", argv[2]);
fflush(stdout); exit(0); }
void usage(void){ fprintf(stdout, "usage:\n gci <IP:16> <name:32> \n(be sure to run as root)\n\n"); }
| |