📄 ipfwacc.c
字号:
/**************************************************************************** * Module for ucd-snmpd reading IP Firewall accounting rules. * * It reads "/proc/net/ip_acct". If the file has a wrong format it silently * * returns erroneous data but doesn't do anything harmfull. Based (on the * * output of) mib2c, wombat.c, proc.c and the Linux kernel. * * Author: Cristian.Estan@net.utcluj.ro * ***************************************************************************/#include <config.h>#if TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# if HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#include "mibincl.h"#include "util_funcs.h"#include "ipfwacc.h"/* According to the 2.0.33 Linux kernel, assuming we use ipv4 any line from * "/proc/net/ip_acct should fit into * 8+1+8+2+8+1+8+1+16+1+8+1+4+1+2+1+2+1+20+20+10*(1+5)+2+2+2+2=182 * characters+ newline. */#define IPFWRULELEN 200#define IP_FW_F_ALL 0x0000 /* This is a universal packet firewall*/#define IP_FW_F_TCP 0x0001 /* This is a TCP packet firewall */#define IP_FW_F_UDP 0x0002 /* This is a UDP packet firewall */#define IP_FW_F_ICMP 0x0003 /* This is a ICMP packet firewall */#define IP_FW_F_KIND 0x0003 /* Mask to isolate firewall kind */#define IP_FW_F_SRNG 0x0008 /* The first two src ports are a min * * and max range (stored in host byte * * order). */#define IP_FW_F_DRNG 0x0010 /* The first two dst ports are a min * * and max range (stored in host byte * * order). * * (ports[0] <= port <= ports[1]) */#define IP_FW_F_BIDIR 0x0040 /* For bidirectional firewalls */#define IP_FW_F_ACCTIN 0x1000 /* Account incoming packets only. */#define IP_FW_F_ACCTOUT 0x2000 /* Account outgoing packets only. */static unsigned char rule[IPFWRULELEN]; /*Buffer for reading a line from * /proc/net/ip_acct. Care has been taken * not to read beyond the end of this * buffer, even if rules are in an * unexpected format *//* This function reads the rule with the given number into the buffer. It * returns the number of rule read or 0 if the number is invalid or other * problems occur. If the argument is 0 it returns the number of accounting * rules. No caching of rules is done. */static int readrule(unsigned int number){ int i; FILE* f= fopen("/proc/net/ip_acct","rt"); if (!f) return 0; /*get rid of "IP accounting rules" line*/ if (!fgets(rule,sizeof(rule),f)) { fclose(f); return 0; } for(i=1;i!=number;i++) if (!fgets(rule,sizeof(rule),f)) { fclose(f); return (number?0:(i-1)); } if (!fgets(rule,sizeof(rule),f)) { fclose(f); return 0; } fclose(f); return i;}static unsigned long ret_val; /* Used by var_ipfwacc to return ulongs *//* This function converts the hexadecimal representation of an IP address from * the rule buffer to an unsigned long. The result is stored in the ret_val * variable. The parameter indicates the position where the address starts. It * only works with uppercase letters and assumes input is correct. Had to use * this because stol returns a signed long. */static inline void atoip (int pos){ int i; ret_val=0; for (i=0;i<32;i+=8) { unsigned long value = (((rule[pos])>='0'&&rule[pos]<='9')? rule[pos]-'0':rule[pos]-'A'+10); pos++; value= (value<<4) + (((rule[pos])>='0'&&rule[pos]<='9')? rule[pos]-'0':rule[pos]-'A'+10); pos++; ret_val |= (value<<i); }}/* This function parses the flags field from the line in the buffer */static unsigned long int getflags (void){ unsigned long int flags; int i=37; /* position in the rule */ /* skipping via name */ while (rule[i]!=' '&&i<IPFWRULELEN-12) i++; /* skipping via address */ i+=10; for (flags=0;rule[i]!=' '&&i<IPFWRULELEN-1;i++) { int value = (((rule[i])>='0'&&rule[i]<='9')? rule[i]-'0':rule[i]-'A'+10); flags=(flags<<4)+value; } return flags;}/* This function reads into ret_val a field from the rule buffer. The field * is a base 10 long integer and the parameter skip tells us how many fields * to skip after the "via addrress" field (including the flag field) */static void getnumeric(int skip){ int i=37; /* position in the rule */ /* skipping via name */ while (rule[i]!=' '&&i<IPFWRULELEN-12) i++; /* skipping via address */ i+=10; while (skip>0) { skip--; /* skipping field, than subsequent spaces */ while (rule[i]!=' '&&i<IPFWRULELEN-2) i++; while (rule[i]==' '&&i<IPFWRULELEN-1) i++; } for (ret_val=0;rule[i]!=' '&& i<IPFWRULELEN-1;i++) ret_val=ret_val*10+rule[i]-'0';}/* this variable defines function callbacks and type return information for the ipfwaccounting mib */struct variable2 ipfwacc_variables[] = { { IPFWACCINDEX, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCINDEX}}, { IPFWACCSRCADDR, ASN_IPADDRESS, RONLY, var_ipfwacc, 1, {IPFWACCSRCADDR}}, { IPFWACCSRCNM, ASN_IPADDRESS, RONLY, var_ipfwacc, 1, {IPFWACCSRCNM}}, { IPFWACCDSTADDR, ASN_IPADDRESS, RONLY, var_ipfwacc, 1, {IPFWACCDSTADDR}}, { IPFWACCDSTNM, ASN_IPADDRESS, RONLY, var_ipfwacc, 1, {IPFWACCDSTNM}}, { IPFWACCVIANAME, ASN_OCTET_STR, RONLY, var_ipfwacc, 1, {IPFWACCVIANAME}}, { IPFWACCVIAADDR, ASN_IPADDRESS, RONLY, var_ipfwacc, 1, {IPFWACCVIAADDR}}, { IPFWACCPROTO, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCPROTO}}, { IPFWACCBIDIR, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCBIDIR}}, { IPFWACCDIR, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCDIR}}, { IPFWACCBYTES, ASN_COUNTER, RONLY, var_ipfwacc, 1, {IPFWACCBYTES}}, { IPFWACCPACKETS, ASN_COUNTER, RONLY, var_ipfwacc, 1, {IPFWACCPACKETS}}, { IPFWACCNSRCPRTS, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCNSRCPRTS}}, { IPFWACCNDSTPRTS, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCNDSTPRTS}}, { IPFWACCSRCISRNG, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCSRCISRNG}}, { IPFWACCDSTISRNG, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCDSTISRNG}}, { IPFWACCPORT1, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCPORT1}}, { IPFWACCPORT2, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCPORT2}}, { IPFWACCPORT3, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCPORT3}}, { IPFWACCPORT4, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCPORT4}}, { IPFWACCPORT5, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCPORT5}}, { IPFWACCPORT6, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCPORT6}}, { IPFWACCPORT7, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCPORT7}}, { IPFWACCPORT8, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCPORT8}}, { IPFWACCPORT9, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCPORT9}}, { IPFWACCPORT10, ASN_INTEGER, RONLY, var_ipfwacc, 1, {IPFWACCPORT10}}};oid ipfwacc_variables_oid[] = { 1,3,6,1,4,1,2021,13,1,1,1 };void init_ipfwacc( void ){ REGISTER_MIB( "misc/ipfwacc", ipfwacc_variables, variable2, ipfwacc_variables_oid);}u_char * var_ipfwacc(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { *write_method = 0; /* assume it isnt writable for the time being */ *var_len = sizeof(ret_val); /* assume an integer and change later if not */ if (header_simple_table(vp,name,length,exact,var_len,write_method,readrule(0))) return (NULL); if (readrule(name[*length-1])){ /* this is where we do the value assignments for the mib results. */ switch(vp->magic) { case IPFWACCINDEX: ret_val = name[*length-1]; return((u_char *) (&ret_val)); case IPFWACCSRCADDR: atoip(0); return((u_char *) (&ret_val)); case IPFWACCSRCNM: atoip(9); return((u_char *) (&ret_val)); case IPFWACCDSTADDR: atoip(19); return((u_char *) (&ret_val)); case IPFWACCDSTNM: atoip(28); return((u_char *) (&ret_val)); case IPFWACCVIANAME: { int i=37; /* position in the rule */ while (rule[i]!=' '&&i<IPFWRULELEN-1) i++; rule[i]=0; return (rule+37); } case IPFWACCVIAADDR: { int i=37; /* position in the rule */ while (rule[i]!=' '&&i<IPFWRULELEN-9) i++; atoip(i+1); return((u_char *) (&ret_val)); } case IPFWACCPROTO: switch (getflags()&IP_FW_F_KIND){ case IP_FW_F_ALL: ret_val=2; return ((u_char *) (&ret_val)); case IP_FW_F_TCP: ret_val=3; return ((u_char *) (&ret_val)); case IP_FW_F_UDP: ret_val=4; return ((u_char *) (&ret_val)); case IP_FW_F_ICMP: ret_val=5; return ((u_char *) (&ret_val)); default: ret_val=1; return((u_char *) (&ret_val)); } case IPFWACCBIDIR: ret_val=((getflags()&IP_FW_F_BIDIR)?2:1); return ((u_char *) (&ret_val)); case IPFWACCDIR: ret_val=(getflags()&(IP_FW_F_ACCTIN|IP_FW_F_ACCTOUT)); if (ret_val==IP_FW_F_ACCTIN) ret_val=2; else if (ret_val==IP_FW_F_ACCTOUT) ret_val=3; else ret_val=1; return ((u_char *) (&ret_val)); case IPFWACCBYTES: getnumeric(4); return ((u_char *) (&ret_val)); case IPFWACCPACKETS: getnumeric(3); return ((u_char *) (&ret_val)); case IPFWACCNSRCPRTS: getnumeric(1); return ((u_char *) (&ret_val)); case IPFWACCNDSTPRTS: getnumeric(2); return ((u_char *) (&ret_val)); case IPFWACCSRCISRNG: ret_val=((getflags()&IP_FW_F_SRNG)?1:2); return ((u_char *) (&ret_val)); case IPFWACCDSTISRNG: ret_val=((getflags()&IP_FW_F_DRNG)?1:2); return ((u_char *) (&ret_val)); case IPFWACCPORT1: case IPFWACCPORT2: case IPFWACCPORT3: case IPFWACCPORT4: case IPFWACCPORT5: case IPFWACCPORT6: case IPFWACCPORT7: case IPFWACCPORT8: case IPFWACCPORT9: case IPFWACCPORT10: getnumeric(5+(vp->magic)-IPFWACCPORT1); return ((u_char *) (&ret_val)); } } return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -