00001
00002
00003
00004
00005
00006
00007 #include <net-snmp/net-snmp-config.h>
00008 #include <net-snmp/net-snmp-includes.h>
00009 #include <net-snmp/agent/net-snmp-agent-includes.h>
00010 #include "netSnmpHostsTable_access.h"
00011 #include "netSnmpHostsTable_enums.h"
00012 #include <netinet/in.h>
00013 #include <arpa/inet.h>
00014 #include <stdio.h>
00015 #include <unistd.h>
00016
00017 #define MAX_HOSTS_LINE 4096
00018
00019
00020 #define HOSTS_FILE "/etc/hosts"
00021
00022 typedef struct my_loop_info_s {
00023 FILE *filep;
00024 in_addr_t theaddr;
00025 char line[MAX_HOSTS_LINE];
00026 char hostname[64];
00027 int lineno;
00028 char *current_ptr;
00029 } my_loop_info;
00030
00031 typedef struct my_data_info_s {
00032 in_addr_t theaddr;
00033 in_addr_t theoldaddr;
00034 char hostname[64];
00035 int lineno;
00036 } my_data_info;
00037
00064 netsnmp_variable_list *
00065 netSnmpHostsTable_get_first_data_point(void **my_loop_context,
00066 void **my_data_context,
00067 netsnmp_variable_list *
00068 put_index_data,
00069 netsnmp_iterator_info *mydata)
00070 {
00071 my_loop_info *loopctx;
00072
00073 loopctx = SNMP_MALLOC_TYPEDEF(my_loop_info);
00074
00075 if (!loopctx)
00076 return NULL;
00077
00078 loopctx->filep = fopen("/etc/hosts","r");
00079
00080 if (!loopctx->filep) {
00081 free(loopctx);
00082 return NULL;
00083 }
00084
00085
00086
00087
00088 *my_loop_context = loopctx;
00089
00090 return netSnmpHostsTable_get_next_data_point(my_loop_context,
00091 my_data_context,
00092 put_index_data,
00093 mydata);
00094 }
00095
00103 netsnmp_variable_list *
00104 netSnmpHostsTable_get_next_data_point(void **my_loop_context,
00105 void **my_data_context,
00106 netsnmp_variable_list *
00107 put_index_data,
00108 netsnmp_iterator_info *mydata)
00109 {
00110 my_loop_info *loopctx = *my_loop_context;
00111 char tmpstring[64];
00112
00113 if (!loopctx)
00114 return NULL;
00115
00116 while(loopctx->filep) {
00117 if (!loopctx->current_ptr) {
00118 if (!fgets(loopctx->line, sizeof(loopctx->line), loopctx->filep)) {
00119
00120 fclose(loopctx->filep);
00121 loopctx->filep = NULL;
00122 return NULL;
00123 }
00124 loopctx->lineno++;
00125 loopctx->current_ptr = loopctx->line;
00126 loopctx->current_ptr = skip_white(loopctx->current_ptr);
00127
00128 if (loopctx->current_ptr == NULL || *loopctx->current_ptr == '#') {
00129 loopctx->current_ptr = NULL;
00130 continue;
00131 }
00132
00133 loopctx->current_ptr =
00134 copy_nword(loopctx->current_ptr, tmpstring, sizeof(tmpstring));
00135 loopctx->theaddr = inet_addr(tmpstring);
00136
00137 if (!loopctx->current_ptr)
00138 continue;
00139 }
00140
00141 loopctx->current_ptr =
00142 copy_nword(loopctx->current_ptr, loopctx->hostname, sizeof(loopctx->hostname));
00143
00144 snmp_set_var_value(put_index_data, (u_char *) loopctx->hostname,
00145 strlen(loopctx->hostname));
00146 return put_index_data;
00147 }
00148
00149
00150 *my_loop_context = NULL;
00151 return NULL;
00152 }
00153
00154 void *
00155 netSnmpHostsTable_context_convert_function(void *loop_context,
00156 netsnmp_iterator_info *iinfo)
00157 {
00158 my_loop_info *loopctx = loop_context;
00159 my_data_info *datactx = SNMP_MALLOC_TYPEDEF(my_data_info);
00160 if (!datactx)
00161 return NULL;
00162 datactx->theoldaddr = datactx->theaddr = loopctx->theaddr;
00163 datactx->lineno = loopctx->lineno;
00164 strcpy(datactx->hostname, loopctx->hostname);
00165 return datactx;
00166 }
00167
00176 void *
00177 netSnmpHostsTable_create_data_context(netsnmp_variable_list * index_data)
00178 {
00179 my_data_info *datactx = SNMP_MALLOC_TYPEDEF(my_data_info);
00180 if (!datactx)
00181 return NULL;
00182 strncpy(datactx->hostname, index_data->val.string,
00183 strlen(index_data->val.string));
00184 return datactx;
00185 }
00186
00187 void
00188 netSnmpHostsTable_data_free(void *data, netsnmp_iterator_info *iinfo)
00189 {
00190 free(data);
00191 }
00192
00193 void
00194 netSnmpHostsTable_loop_free(void *loopctx, netsnmp_iterator_info *iinfo)
00195 {
00196 free(loopctx);
00197 }
00198
00210 int
00211 netSnmpHostsTable_commit_row(void **my_data_context, int new_or_del)
00212 {
00214 FILE *in, *out;
00215 char line[MAX_HOSTS_LINE], line2[MAX_HOSTS_LINE];
00216 char myaddr[64], *cp;
00217 my_data_info *datactx = *my_data_context;
00218 size_t line2_sz;
00219 int foundit = 0;
00220
00221 if (datactx->theaddr == datactx->theoldaddr && new_or_del != -1)
00222 return SNMP_ERR_NOERROR;
00223
00224 if ((out = fopen(HOSTS_FILE ".snmp", "w")) == NULL)
00225 return SNMP_ERR_COMMITFAILED;
00226
00227 if ((in = fopen(HOSTS_FILE, "r")) == NULL)
00228 return SNMP_ERR_COMMITFAILED;
00229
00230 while(fgets(line, sizeof(line), in)) {
00231 copy_nword(line,myaddr,sizeof(myaddr));
00232 if (inet_addr(myaddr) == datactx->theaddr && new_or_del != -1) {
00233 foundit = 1;
00234
00235 line[strlen(line)-1] = '\0';
00236 fprintf(out, "%s %s\n", line, datactx->hostname);
00237 } else if (inet_addr(myaddr) == datactx->theoldaddr) {
00238
00239 int count = 0;
00240 cp = copy_nword(line, line2, sizeof(line2));
00241 if (strlen(line2) > sizeof(line2)-2) {
00242 errorit:
00243 fclose(in);
00244 fclose(out);
00245 unlink(HOSTS_FILE ".snmp");
00246 return SNMP_ERR_RESOURCEUNAVAILABLE;
00247 }
00248 line2_sz = strlen(line2);
00249 line2[line2_sz++] = '\t';
00250 while(cp) {
00251 cp = copy_nword(cp, &line2[line2_sz], sizeof(line2)-line2_sz);
00252 if (strcmp(&line2[line2_sz], datactx->hostname) == 0) {
00253
00254
00255 } else {
00256 if (strlen(line2) > sizeof(line2)-2) {
00257 goto errorit;
00258 }
00259 line2_sz = strlen(line2);
00260 line2[line2_sz++] = ' ';
00261 count++;
00262 }
00263 }
00264 if (count) {
00265
00266
00267 line2[line2_sz] = '\0';
00268 fprintf(out, "%s\n", line2);
00269 }
00270 } else {
00271 fputs(line, out);
00272 }
00273 }
00274
00275 if (!foundit && new_or_del != -1) {
00276
00277 fprintf(out, "%d.%d.%d.%d\t%s\n",
00278 (0x000000ff & datactx->theaddr),
00279 (0x0000ff00 & datactx->theaddr) >> 8,
00280 (0x00ff0000 & datactx->theaddr) >> 16,
00281 (0xff000000 & datactx->theaddr) >> 24,
00282 datactx->hostname);
00283 }
00284 fclose(out);
00285 fclose(in);
00286
00287
00288
00289
00290 if (!rename(HOSTS_FILE ".snmp", HOSTS_FILE))
00291 return SNMP_ERR_COMMITFAILED;
00292
00293
00294
00295
00296
00297 return SNMP_ERR_NOERROR;
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307 long *
00308 get_netSnmpHostAddressType(void *data_context, size_t * ret_len)
00309 {
00310 static long ret = NETSNMPHOSTADDRESSTYPE_IPV4;
00311 *ret_len = sizeof(ret);
00312 return &ret;
00313 }
00314
00315 int
00316 set_netSnmpHostAddressType(void *data_context, long *val, size_t val_len)
00317 {
00318 return SNMP_ERR_NOERROR;
00319 }
00320
00321 char *
00322 get_netSnmpHostAddress(void *data_context, size_t * ret_len)
00323 {
00324 my_data_info *datainfo = data_context;
00325 *ret_len = sizeof(in_addr_t);
00326 return (char *) &datainfo->theaddr;
00327 }
00328
00329 int
00330 set_netSnmpHostAddress(void *data_context, char *val, size_t val_len)
00331 {
00332 my_data_info *datainfo = data_context;
00333 memcpy(&datainfo->theaddr, val, val_len);
00334 return SNMP_ERR_NOERROR;
00335 }
00336
00337 long *
00338 get_netSnmpHostStorage(void *data_context, size_t * ret_len)
00339 {
00340 static long ret = ST_NONVOLATILE;
00341 *ret_len = sizeof(ret);
00342 return &ret;
00343 }
00344
00345 int
00346 set_netSnmpHostStorage(void *data_context, long *val, size_t val_len)
00347 {
00348 return SNMP_ERR_NOERROR;
00349 }
00350
00351 long *
00352 get_netSnmpHostRowStatus(void *data_context, size_t * ret_len)
00353 {
00354 static long ret = RS_ACTIVE;
00355 *ret_len = sizeof(ret);
00356 return &ret;
00357 }
00358
00359 int
00360 set_netSnmpHostRowStatus(void *data_context, long *val, size_t val_len)
00361 {
00362
00363 return SNMP_ERR_NOERROR;
00364 }