⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if80211table.c

📁 一个学习SNMP项目:tmoerlan.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	Copyright (c) 2003, Tijmen Moerland <moerland@yahoo.com>	Code is licensed under the BSD license.*//*!	\file if80211Table.c 	\brief Part of the snmp deamon handling l80211Iface<foo> requests	The other files for handling l80211Iface<foo> requests, i.e. for SSID, WEP keys and station table have a similar structure as this one. Please refer to this file for general documentation on those files.	This file implements the l80211Iface<variable name> table, containing management information about all the wireless interface present on the system. Note that this is the only table that has a single index (the number of the interface). All the other tables are double-indexed, with the first index for the interface number and the second table-specific.		Around this source file are some helpers, in this case the table iterator helper (this is a standard source file located in agent/helpers). After generating the skeleton code with mib2c, five functions have been created:	initialize_table_modulename		init_modulename		modulename_get_first_data_point		modulename_get_next_data_point	modulename_handler	For details, refer to the specific functions (also to understand how the helper calls each of these functions, and how an snmp request is processed and where values are returned or set).	Run snmpd with option '-Dif80211Table' to see debug messages from this table. Other tables have a similar option.*//* * Note: this file originally auto-generated by mib2c using *        : mib2c.iterate.conf,v 5.4 2002/09/11 22:42:04 hardaker Exp $ */#include <net-snmp/net-snmp-config.h>#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include "if80211Table.h"#include "lib80211.h"long if_index, if_nr;long indexarray[IF_MAXNR];/** Initialize the if80211Table table by defining its contents and how it's structured *//*!	\func void initialize_table_if80211Table(void) 	\brief Initializes the l80211Iface table, which contains management information about the wireless interfaces	Here, the table is initialized, with all the helpers. This means the table is made 'known' to the deamon, which	will then forward requests to this table. Run the deamon with option '-Dif80211Table' to see if it gets initialized properly.	In this function you can:		Set the OID number for this table		Set the type and number of the index(es)	Define which columns (start and endpoint) are visible for requests. Lower bound is usually one, but might be 2	if you want to hide the index. The index might be for internal use (e.g. to make every row unique) only, and of no interest to the management application.	Other initialization, e.g. malloc'ing memory, init'ing variables...*/voidinitialize_table_if80211Table(void){    static oid if80211Table_oid[] = {1,3,6,1,4,1,18003,2,1,1,1};//    static oid if80211Table_oid[] = {1,3,6,1,2,1,100,1};    netsnmp_table_registration_info *table_info;    netsnmp_handler_registration *my_handler;    netsnmp_iterator_info *iinfo;    /* create the table structure itself */    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);    iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);    /* if your table is read only, it's easiest to change the       HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */    my_handler = netsnmp_create_handler_registration("if80211Table",                                             if80211Table_handler,                                             if80211Table_oid,                                             OID_LENGTH(if80211Table_oid),                                             HANDLER_CAN_RWRITE);                if (!my_handler || !table_info || !iinfo)        return; /* mallocs failed */    /***************************************************     * Setting up the table's definition     */    netsnmp_table_helper_add_indexes(table_info,                                  ASN_INTEGER, /* index: ifIndex */                             0);    table_info->min_column = 1;    table_info->max_column = 16;    /* iterator access routines */    iinfo->get_first_data_point = if80211Table_get_first_data_point;    iinfo->get_next_data_point = if80211Table_get_next_data_point;    iinfo->table_reginfo = table_info;    /***************************************************     * registering the table with the master agent     */    DEBUGMSGTL(("if80211Table",                "Registering table if80211Table as a table iterator at OID ...%d.%d.%d.%d (l %d)\n"			, if80211Table_oid[6], if80211Table_oid[7], if80211Table_oid[8], if80211Table_oid[9], if80211Table_oid[10],		OID_LENGTH(if80211Table_oid)));     netsnmp_register_table_iterator(my_handler, iinfo);    int i;    for (i = 0; i < IF_MAXNR; i++)	indexarray[i] = i;}/** Initializes the if80211Table module *//*!	\func void init_if80211Table(void) 	\brief Initializes the module. Here all the table initialize functions are called (usually one).*/voidinit_if80211Table(void){  /* here we initialize all the tables we're planning on supporting */    initialize_table_if80211Table();}/*!	\func netsnmp_variable_list *if80211Table_get_first_data_point(void **my_loop_context, void **my_data_context,                          netsnmp_variable_list *put_index_data,                          netsnmp_iterator_info *mydata)	\brief Called whenever the iterator helper starts the loop (see extended description)	Whenever a request is sent to the snmp deamon, this request is sent on to the table iterator helper. This happens for all requests, GET, SET, WALKS, BULKrequests etc. The basic concept behind a table iterator is that is 'loops' through all available entries, finding the right one. This specific function is called whenever a loop is started. It's task is to initialize the put_index_data variable list. This list contains all the indexes of this table, type and number have been set in the initialize_table function. By calling snmp_set_var_value, once for each index variable, we can set these indexes to our first values. This might be a one (indexes never start at zero!), or in the case of the wireless interfaces it's the interface index number of the first wireless interface (so if we have an interface list in the machine of ed0, ed1, lo, wi0, wi1) than the first number will be 4.	Also, my_loop_context is made to point at a loop variable (this might be a simple integer counter, or an entrie in a linked list. Also, my_data_context is a pointer to a memory structure associated with the index. This might be anything that is useful in processing the SNMP request later on, in the handler function. NOTE: this can NOT be a pointer to a counter that is increased at every iteration!! So if we simply want this data_context to be the index number, we need to allocate seperate memory for this (below, a static array is used).*/netsnmp_variable_list *if80211Table_get_first_data_point(void **my_loop_context, void **my_data_context,                          netsnmp_variable_list *put_index_data,                          netsnmp_iterator_info *mydata){    netsnmp_variable_list *vptr;	int i;	if_index = 1;	if_nr = getNumIf80211();	if (if_nr <= 0)		return NULL;        *my_loop_context = (void *) &if_index;    *my_data_context = (void *) &indexarray[if_index];    DEBUGMSGTL(("if80211Table", "START: if_index=%ld\n", if_index));    vptr = put_index_data;    static long ifIndex;	//ifIndex corresponds to entry in ifTable    ifIndex = getPtrIf80211(if_index);    snmp_set_var_value(vptr, (u_char *) &ifIndex, sizeof(long));    vptr = vptr->next_variable;    return put_index_data;}/*!	\func netsnmp_variable_list * if80211Table_get_next_data_point(void **my_loop_context, void **my_data_context,                         netsnmp_variable_list *put_index_data,                         netsnmp_iterator_info *mydata)	\brief Called by the helper to 'iterate' throught the indexes.		Basically, this function points the iterator to the next index. As in get_first_data_point, put_index_data, my_loop_context and my_data_context are updated. But this time, we set the index to the next entry. So if the index is a simple continually increasing integer, we simply increase this integer ;-)	In the specific case of wireless interfaces, we 'hop' to the next interface number, which migth be more than 1 away.*/netsnmp_variable_list *if80211Table_get_next_data_point(void **my_loop_context, void **my_data_context,                         netsnmp_variable_list *put_index_data,                         netsnmp_iterator_info *mydata){    netsnmp_variable_list *vptr;	if (if_index >= if_nr) {//		DEBUGMSGTL(("if80211Table", "index overflow: %ld\n", if_index));		return NULL;	}	if_index++;        *my_loop_context = (void *) &if_index;    *my_data_context = (void *) &indexarray[if_index];    DEBUGMSGTL(("if80211Table", "NEXT: if_index=%ld\n", if_index));    vptr = put_index_data;    static long ifIndex;    ifIndex = getPtrIf80211(if_index);    snmp_set_var_value(vptr, (u_char *) &ifIndex, sizeof(long));    vptr = vptr->next_variable;    return put_index_data;}/** handles requests for the if80211Table table, if anything else needs to be done *//*!	\func int if80211Table_handler(    netsnmp_mib_handler               *handler,    netsnmp_handler_registration      *reginfo,    netsnmp_agent_request_info        *reqinfo,    netsnmp_request_info              *requests)    	\brief Called by the helper when it has found the right entry, this function should get/set the right column.	We'll walk through this function step by step. We'll see where the data_context pointer get's into play, where data is get, how a set works etc...	Inside the loop, the first thing is getting the data_context (note that this is always a pointer!). This is really nice if this is a structure containing all the information you need for a GET, as is the case in the staTable (there, the whole extended cache is returned, which includes almost all information provided by the table). If NULL is returned, you know that the requested row does not exist, and you can exit (or create a new row, if you allow for this and the request was a SET).		After this, information is retrieved about the request, this includes the column number. It is not recommended to rely to much on the row indexes returned by this table_info struct (especially in the case of an snmpwalk). Better is to include information about the index in the data_context structure.	If the request was a GET, you can return information via a call to snmp_set_var_typed_value. Note that you pass a pointer to this function, which points to the memory location of the to-be-returned data. This data should remain available after exiting this function! So if you use a locally declared variable, make sure it is STATIC! You also need to return the type of the variable, and the size. See source for examples.	Now a SET is a little more interesting. Where the GET is a single call to this function, a SET involves more requests. It starts with a Reserve1, Reserve2, Free, Action, Commit, Undo. Only Reserve1 and Action are used in this case, refer to net-snmp.org for details about the other requests.	Reserve1 is used to check type, value and length of the variable passed. We test here for example to see if the channel to be set is not out-of-bound. If a test fails, a call to netsnmp_set_request_error is used to pass an error and terminate the request. The error is sent to the requestor.	Action is called after this, to actually perform the request (do an ioctl call or something).*/intif80211Table_handler(    netsnmp_mib_handler               *handler,    netsnmp_handler_registration      *reginfo,    netsnmp_agent_request_info        *reqinfo,    netsnmp_request_info              *requests) {    netsnmp_request_info *request;    netsnmp_table_request_info *table_info;    netsnmp_variable_list *var;    char iface[IF_NAMELEN];    long *index, requestindex;    oid WEPIndex_oid[] = {1,3,6,1,4,1,18003,2,1,1,3,1,2,1,1};        static long l_ret;    static u_long ul_ret;    static oid oid_ret[20];    static char buf[100];    static u_char flags[4];    int len;    static long l_val;	//the (integer) request value is saved in this			//variable between all the set calls (RESERVE, ACTION...)        char *str;    int s;	//socket    int f;	//for walking through the 4 flags    int bit;	//for walking through the 8 bits in one flag (a byte)    u_char tempflags;	//temp storage used when converting the flags to LSB first        for(request = requests; request; request = request->next) {        var = request->requestvb;        if (request->processed != 0)            continue;        /* perform anything here that you need to do.  The request have           already been processed by the master table_dataset handler, but           this gives you chance to act on the request in some other way           if need be. */        /* the following extracts the my_data_context pointer set in           the loop functions above.  You can then use the results to           help return data for the columns of the if80211Table table in question */        index = (long *) netsnmp_extract_iterator_context(request);        if (index == NULL) {                netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);                continue;        }        /* extracts the information about the table from the request */        table_info = netsnmp_extract_table_info(request);        /* table_info->colnum contains the column number requested */        /* table_info->indexes contains a linked list of snmp variable           bindings for the indexes of the table.  Values in the list           have been set corresponding to the indexes of the           request */        if (table_info==NULL) {            continue;        }/*	requestindex = *table_info->indexes->val.integer;	if (requestindex != *index) {		snmp_log(LOG_ERR, "if80211Table: something very strange is happening, *index != requestindex (%ld != %ld)\n",			*index, requestindex);		continue;//			netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);	}*/	getNameIf80211(*index, iface);//	DEBUGMSGTL(("if80211Table", "iface=%s\n", iface));	        switch(reqinfo->mode) {            /* the table_iterator helper should change all GETNEXTs               into GETs for you automatically, so you don't have to               worry about the GETNEXT case.  Only GETs and SETs need               to be dealt with here */            case MODE_GET:                switch(table_info->colnum) {		    case COLUMN_IF80211FLAGS:			l_ret = getIfFlags(iface);			DEBUGMSGTL(("if80211Table", "flags=%x\n", l_ret));			flags[0] = l_ret & 0xff;                        flags[1] = (l_ret >> 8) & 0xff;                        flags[2] = (l_ret >> 16) & 0xff;                        flags[3] = l_ret >> 24;                        for (f = 0; f < 4; f++) {                                tempflags = 0;                                for (bit = 0; bit < 8; bit++)                                        tempflags |= ((flags[f] & (1 << bit)) >> bit) << (7 - bit);                                flags[f] = tempflags;                        }			snmp_set_var_typed_value(var, ASN_BIT_STR, flags, 4);			break;		    case COLUMN_DESIREDSSID:			bzero(buf, 100);			getDesiredSSID(iface, buf, &len);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -