#include #include #include #include #include #include #include #ifdef IN_UCD_SNMP_SOURCE /* If we're compiling this file inside the ucd-snmp source tree */ /* This should always be included first before anything else */ #include /* minimal include directives */ #include "mibincl.h" #include "util_funcs.h" #else /* !IN_UCD_SNMP_SOURCE */ #include #include #include #include #endif /* !IN_UCD_SNMP_SOURCE */ #include "lvs.h" /* * lvs_variables_oid: * this is the top level oid that we want to register under. This * is essentially a prefix, with the suffix appearing in the * variable below. */ oid lvs_variables_oid[] = { 1,3,6,1,4,1,8225,4711 }; /* * variable4 lvs_variables: * this variable defines function callbacks and type return information * for the lvs mib section */ struct variable4 lvs_variables[] = { /* magic number , variable type , ro/rw , callback fn , L, oidsuffix */ #define LVSVERSION 1 { LVSVERSION , ASN_OCTET_STR , RONLY , var_lvs, 1, { 1 } }, #define LVSNUMSERVICES 2 { LVSNUMSERVICES , ASN_INTEGER , RONLY , var_lvs, 1, { 2 } }, #define LVSHASHTABLESIZE 3 { LVSHASHTABLESIZE , ASN_INTEGER , RONLY , var_lvs, 1, { 3 } }, #define LVSSERVICENUMBER 9 { LVSSERVICENUMBER , ASN_INTEGER , RONLY , var_lvsServiceTable, 3, { 4,1,1 } }, #define LVSSERVICESCHEDTYPE 10 { LVSSERVICESCHEDTYPE , ASN_OCTET_STR , RONLY , var_lvsServiceTable, 3, { 4,1,2 } }, #define LVSSERVICEPROTO 11 { LVSSERVICEPROTO , ASN_INTEGER , RONLY , var_lvsServiceTable, 3, { 4,1,3 } }, #define LVSSERVICEADDR 12 { LVSSERVICEADDR , ASN_IPADDRESS , RONLY , var_lvsServiceTable, 3, { 4,1,4 } }, #define LVSSERVICEPORT 13 { LVSSERVICEPORT , ASN_INTEGER , RONLY , var_lvsServiceTable, 3, { 4,1,5 } }, #define LVSSERVICEFWMARK 14 { LVSSERVICEFWMARK , ASN_INTEGER , RONLY , var_lvsServiceTable, 3, { 4,1,6 } }, #define LVSSERVICEPERSISTTIMEOUT 15 { LVSSERVICEPERSISTTIMEOUT, ASN_INTEGER , RONLY , var_lvsServiceTable, 3, { 4,1,7 } }, #define LVSSERVICEPERSISTNETMASK 16 { LVSSERVICEPERSISTNETMASK, ASN_IPADDRESS , RONLY , var_lvsServiceTable, 3, { 4,1,8 } }, #define LVSSERVICENUMDESTS 17 { LVSSERVICENUMDESTS, ASN_INTEGER , RONLY , var_lvsServiceTable, 3, { 4,1,9 } }, #define LVSSERVICESTATSCONNS 18 { LVSSERVICESTATSCONNS, ASN_INTEGER , RONLY , var_lvsServiceTable, 3, { 4,1,10 } }, #define LVSSERVICESTATSINPKTS 19 { LVSSERVICESTATSINPKTS, ASN_COUNTER , RONLY , var_lvsServiceTable, 3, { 4,1,11 } }, #define LVSSERVICESTATSOUTPKTS 20 { LVSSERVICESTATSOUTPKTS, ASN_COUNTER , RONLY , var_lvsServiceTable, 3, { 4,1,12 } }, #define LVSSERVICESTATSINBYTES 21 { LVSSERVICESTATSINBYTES, ASN_COUNTER64 , RONLY , var_lvsServiceTable, 3, { 4,1,13 } }, #define LVSSERVICESTATSOUTBYTES 22 { LVSSERVICESTATSOUTBYTES, ASN_COUNTER64 , RONLY , var_lvsServiceTable, 3, { 4,1,14 } }, }; /* (L = length of the oidsuffix) */ /* * init_lvs(): * Initialization routine. This is called when the agent starts up. * At a minimum, registration of your variables should take place here. */ void init_lvs(void) { /* register ourselves with the agent to handle our mib tree */ REGISTER_MIB("lvs", lvs_variables, variable4, lvs_variables_oid); /* place any other initialization junk you need here */ if (ipvs_init()) { DEBUGMSGTL(("lvs","init lvs failed\n")); } else { DEBUGMSGTL(("lvs","init lvs done\n")); } } /* * var_lvs(): * This function is called every time the agent gets a request for * a scalar variable that might be found within your mib section * registered above. It is up to you to do the right thing and * return the correct value. * You should also correct the value of "var_len" if necessary. * * Please see the documentation for more information about writing * module extensions, and check out the examples in the examples * and mibII directories. */ unsigned char * var_lvs(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { /* variables we may use later */ static long long_ret; static u_long ulong_ret; static unsigned char string[SPRINT_MAX_LEN]; static oid objid[MAX_OID_LEN]; static struct counter64 c64; extern struct ip_vs_getinfo ipvs_info; struct ip_vs_get_services *get; if (header_generic(vp,name,length,exact,var_len,write_method) == MATCH_FAILED ) return NULL; if (ipvs_refresh_num_services()) return NULL; get = ipvs_get_services(); /* * this is where we do the value assignments for the mib results. */ switch(vp->magic) { case LVSVERSION: sprintf(string,"%d.%d.%d",NVERSION(ipvs_info.version)); free(get); *var_len = strlen(string); return (unsigned char *) string; case LVSNUMSERVICES: long_ret = get->num_services; free(get); return (unsigned char *) &long_ret; case LVSHASHTABLESIZE: long_ret = ipvs_info.size; free(get); return (unsigned char *) &long_ret; default: ERROR_MSG(""); } free(get); return NULL; } /* * var_lvsServiceTable(): * Handle this table separately from the scalar value case. * The workings of this are basically the same as for var_lvs above. */ unsigned char * var_lvsServiceTable(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { /* variables we may use later */ static long long_ret; static u_long ulong_ret; static unsigned char string[SPRINT_MAX_LEN]; static oid objid[MAX_OID_LEN]; static struct counter64 c64; extern struct ip_vs_getinfo ipvs_info; struct ip_vs_get_services *get; struct ip_vs_service_user *service; int index; //long long int test = 4294967299; /* * This assumes that the table is a 'simple' table. * See the implementation documentation for the meaning of this. * You will need to provide the correct value for the TABLE_SIZE parameter * * If this table does not meet the requirements for a simple table, * you will need to provide the replacement code yourself. * Mib2c is not smart enough to write this for you. * Again, see the implementation documentation for what is required. */ if (header_simple_table(vp,name,length,exact,var_len,write_method, ipvs_info.num_services) == MATCH_FAILED ) return NULL; if (ipvs_refresh_num_services()) return NULL; index = name[*length-1]; get = ipvs_get_services(); service = ipvs_get_service( get->entrytable[index-1].fwmark, get->entrytable[index-1].protocol, get->entrytable[index-1].addr, get->entrytable[index-1].port); /* * this is where we do the value assignments for the mib results. */ switch(vp->magic) { case LVSSERVICENUMBER: long_ret = index; free(service); free(get); return (unsigned char *) &long_ret; case LVSSERVICESCHEDTYPE: sprintf(string,"%s", service->sched_name); *var_len = strlen(string); free(get); free(service); return (unsigned char *) string; case LVSSERVICEPROTO: if ( service->fwmark) { long_ret=LVS_SNMP_NOTDEFINED; } else { long_ret=service->protocol; } free(get); free(service); return (unsigned char *) &long_ret; case LVSSERVICEADDR: long_ret = service->addr; if ( service->fwmark ) {long_ret=LVS_SNMP_NOTDEFINED ;} free(get); free(service); return (unsigned char *) &long_ret; case LVSSERVICEPORT: long_ret = ntohs(service->port); if ( service->fwmark ) {long_ret=LVS_SNMP_NOTDEFINED;} free(get); free(service); return (unsigned char *) &long_ret; case LVSSERVICEFWMARK: long_ret = service->fwmark; free(get); free(service); return (unsigned char *) &long_ret; case LVSSERVICEPERSISTTIMEOUT: long_ret = service->timeout; free(get); free(service); return (unsigned char *) &long_ret; case LVSSERVICEPERSISTNETMASK: long_ret = service->netmask; free(get); free(service); return (unsigned char *) &long_ret; case LVSSERVICENUMDESTS: long_ret = service->num_dests; free(get); free(service); return (unsigned char *) &long_ret; case LVSSERVICESTATSCONNS: long_ret = service->stats.conns; free(get); free(service); return (unsigned char *) &long_ret; case LVSSERVICESTATSINPKTS: long_ret = service->stats.inpkts; free(get); free(service); return (unsigned char *) &long_ret; case LVSSERVICESTATSOUTPKTS: long_ret = service->stats.outpkts; free(get); free(service); return (unsigned char *) &long_ret; case LVSSERVICESTATSINBYTES: c64.low = service->stats.inbytes; c64.high = service->stats.inbytes >> 32; *var_len = sizeof(c64); free(get); free(service); return (unsigned char *) &c64; case LVSSERVICESTATSOUTBYTES: c64.low = service->stats.outbytes; c64.high = service->stats.outbytes >> 32; *var_len = sizeof(c64); free(get); free(service); return (unsigned char *) &c64; default: ERROR_MSG(""); } free(get); free(service); return NULL; }