~ubuntu-branches/ubuntu/hoary/s390-tools/hoary

« back to all changes in this revision

Viewing changes to osasnmpd/osasnmpd-2.6/ibmOSAMib.c

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2004-06-27 18:45:15 UTC
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20040627184515-q7lnvli1j94gr6dv
Tags: upstream-1.3.1
ImportĀ upstreamĀ versionĀ 1.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * File...........: ibmOSAMib.c
 
3
 * Author(s)......: Thomas Weber <tweber@de.ibm.com>
 
4
 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2002
 
5
 *
 
6
 * History of changes:
 
7
 * none                 
 
8
 *  
 
9
 * Basic MIB implementation module for the OSA-E subagent.  
 
10
 * The code in this module is typical for a ucd-snmp MIB implementation
 
11
 * information on how this works.                                      
 
12
 * Because the MIB layout is retrieved during startup of the subagent,
 
13
 * the magic indentifier is not used within this implementation.
 
14
 * The var_ function uses the vp->type instead to distinct the OIDs.
 
15
 * 
 
16
 * This program is free software; you can redistribute it and/or modify
 
17
 * it under the terms of the GNU General Public License as published by
 
18
 * the Free Software Foundation; either version 2, or (at your option)
 
19
 * any later version.
 
20
 *
 
21
 * This program is distributed in the hope that it will be useful,
 
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
24
 * GNU General Public License for more details.
 
25
 *
 
26
 * You should have received a copy of the GNU General Public License
 
27
 * along with this program; if not, write to the Free Software
 
28
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
29
 */
 
30
 
 
31
#include "ibmOSAMibUtil.h"
 
32
#include "ibmOSAMib.h"
 
33
 
 
34
/* ptr to OSA Express MIB information stored in linked lists */
 
35
TABLE_OID* oid_list_head;
 
36
 
 
37
/* ptr to interface information on this system */
 
38
IF_LIST* if_list;
 
39
int ifNumber;
 
40
 
 
41
 
 
42
 
 
43
/**********************************************************************
 
44
 * init_ibmOSAMib():
 
45
 *  Initialization routine. This function is called when the agent  
 
46
 *  starts up.
 
47
 *  parameters:
 
48
 *  IN  uses global MIB data                         
 
49
 *  OUT none                                
 
50
 *  returns: none                                                     
 
51
 *********************************************************************/
 
52
void init_ibmOSAMib(void) {
 
53
 
 
54
  int i,
 
55
    sd,         /* socket descriptor */
 
56
    error_code, /* holds errno value */
 
57
    osaexp_num, /* number of OSA Express devices */
 
58
    retc;       /* return code from register_tables */
 
59
 
 
60
  struct ifreq ifr;             /* request structure for ioctl */
 
61
  IPA_CMD_REG* ipa_reg_mib;     /* structure for IPA REGISTER MIB command header */ 
 
62
  char*        buffer;          /* a data buffer */
 
63
  char         time_buf[TIME_BUF_SIZE]; /* date/time buffer */
 
64
 
 
65
  /* init head for Toplevel OID linked list */
 
66
  oid_list_head = init_oid_list();
 
67
  if ( oid_list_head == NULL )
 
68
    {
 
69
      fprintf( stderr, "init_ibmOSAMib(): "
 
70
               "malloc() for OID list head failed\n"
 
71
               "Cannot start subagent...exiting...\n");
 
72
      exit(1); 
 
73
    }
 
74
 
 
75
  /* GET ucd-snmp ifNumber/ifIndex/ifDescr from IF-MIB for all interfaces */
 
76
  /* on this system                                                       */
 
77
  ifNumber = query_IF_MIB( &if_list );
 
78
  if ( ifNumber < 0 )
 
79
    {
 
80
      fprintf( stderr, "init_ibmOSAMib(): "
 
81
               "could not obtain interface info from IF-MIB\n"
 
82
               "check if: snmpd daemon is started and subagent "
 
83
               "access control is correct\n"
 
84
               "see agent log file for more details\n"
 
85
               "Cannot start subagent...exiting...\n");
 
86
      exit(1);
 
87
    }
 
88
  else if ( ifNumber == 0 ) 
 
89
    {
 
90
      get_time( time_buf );         
 
91
      snmp_log( LOG_ERR, "%s init_ibmOSAMib(): "
 
92
                "SNMP reports no devices within IF-MIB"
 
93
                " - starting subagent anyway\n", time_buf );
 
94
      return;
 
95
    } /* end if */
 
96
 
 
97
  /* query OSA-E device driver for OSA-E devices and mark them in IF-MIB interface list */
 
98
  osaexp_num = query_OSA_EXP ( &if_list, ifNumber );
 
99
  if ( osaexp_num < 0 )
 
100
    {
 
101
      fprintf( stderr, "init_ibmOSAMib(): "
 
102
               "OSA-E device driver query interface ioctl() failed\n"
 
103
               "check agent log file for more details\n"
 
104
               "Cannot start subagent...exiting...\n");
 
105
      exit(1); 
 
106
    }
 
107
  else if ( osaexp_num == 0 )
 
108
    {
 
109
      fprintf( stderr, "init_ibmOSAMib(): bad or no OSA-E devices reported\n"
 
110
                       "check agent log file for more details\n"
 
111
                       "Cannot start subagent...exiting...\n");
 
112
      exit(1);
 
113
    } 
 
114
  /* end if */
 
115
  
 
116
  /* allocate area, that should contain retrieved MIB data for a single interface */
 
117
  buffer = (char*) malloc ( MIB_AREA_LEN );
 
118
  if ( buffer == NULL )
 
119
    {
 
120
      fprintf( stderr, "init_ibmOSAMib(): "
 
121
               "malloc() for REGISTER MIB data buffer "
 
122
               "failed\ninit_ibmOSAMib(): requested %d bytes\n"
 
123
               "Cannot start subagent...exiting...\n", 
 
124
               MIB_AREA_LEN );
 
125
      exit(1);
 
126
    } /* end if */
 
127
 
 
128
  /* open socket for ioctl */
 
129
  sd = socket( AF_INET, SOCK_STREAM, 0 );
 
130
  if ( sd < 0 )
 
131
    {
 
132
      error_code = errno;
 
133
      fprintf( stderr, "init_ibmOSAMIB(): "
 
134
               "error opening socket() - reason %s\n"
 
135
               "Cannot start subagent...exiting...\n", 
 
136
               strerror( error_code ) );
 
137
      exit(1);
 
138
    } /* end if */
 
139
  
 
140
  /* walk through interface list and query MIB data for all OSA-E devices */
 
141
  /* register MIB data with subagent driving code afterwards              */  
 
142
  for ( i=0; i < ifNumber; i++ )
 
143
    {
 
144
      if ( if_list[i].is_OSAEXP == TRUE )
 
145
        {
 
146
          /* clear buffer */
 
147
          memset( buffer, 0, MIB_AREA_LEN ); 
 
148
 
 
149
          /* setup ioctl buffer with request and input parameters */
 
150
          ipa_reg_mib = (IPA_CMD_REG*) buffer;                /* map command structure */
 
151
          ipa_reg_mib->ioctl_cmd.data_len  =                  /* length of IPA data area */ 
 
152
                       MIB_AREA_LEN - offsetof( IOCTL_CMD_HDR, ipa_cmd_hdr );
 
153
          ipa_reg_mib->ioctl_cmd.req_len =                    /* length of IPA subcommand */
 
154
                       sizeof( ipa_reg_mib->ioctl_cmd );  
 
155
 
 
156
          ipa_reg_mib->ioctl_cmd.ipa_cmd_hdr.request  = IPA_REG_MIB; /* IPA subcommand code */
 
157
          ipa_reg_mib->ioctl_cmd.ipa_cmd_hdr.ifIndex  = if_list[i].ifIndex; /* assign IF-MIB ifIndex */
 
158
          ipa_reg_mib->ioctl_cmd.ipa_cmd_hdr.ret_code = 0;
 
159
          ipa_reg_mib->ioctl_cmd.ipa_cmd_hdr.seq_num  = 0;           /* sequence number not used */
 
160
          
 
161
          /* do ioctl */
 
162
          strcpy( ifr.ifr_name, if_list[i].if_Name );         /* add interface name */       
 
163
          ifr.ifr_ifru.ifru_data = (char*) buffer;            /* add data buffer    */ 
 
164
          
 
165
          if ( ioctl( sd, SIOC_QETH_ADP_SET_SNMP_CONTROL, &ifr ) < 0 )
 
166
            {
 
167
              error_code = errno;
 
168
 
 
169
              /* see if we got a common I/O error */
 
170
              if ( error_code == -EIO )
 
171
                {
 
172
                   get_time( time_buf );
 
173
                   snmp_log( LOG_ERR, "%s init_ibmOSAMib(): "
 
174
                             "ioctl() failed - reason %s for interface %s\n"
 
175
                             "init_ibmOSAMib(): start subagent anyway\n",
 
176
                              time_buf, strerror( error_code ), if_list[i].if_Name );
 
177
                   close( sd );
 
178
                   free( buffer );
 
179
                   return;
 
180
                   break;     
 
181
                } /* end if */
 
182
 
 
183
              /* let's see, if we got a return code from IPAssists */
 
184
              /* or if MIB buffer is exhausted */
 
185
              switch ( ipa_reg_mib->ioctl_cmd.ipa_cmd_hdr.ret_code ) {
 
186
              case IPA_FAILED:
 
187
                fprintf( stderr, "init_ibmOSAMib(): "
 
188
                         "ioctl() failed - IPA command failed "
 
189
                         "init_ibmOSAMib(): "
 
190
                         "Can't get MIB information for network interface %s\n"
 
191
                         "Cannot start subagent...exiting...\n", if_list[i].if_Name );
 
192
                break;
 
193
                
 
194
              case IPA_NOT_SUPP:
 
195
                fprintf( stderr, "init_ibmOSAMib(): "
 
196
                         "ioctl() failed - IPA command not supported "
 
197
                         "init_ibmOSAMib(): "
 
198
                         "Can't get MIB information for network interface %s\n"
 
199
                         "Cannot start subagent...exiting...\n", if_list[i].if_Name );
 
200
                break;
 
201
                
 
202
              case IPA_NO_DATA:
 
203
                get_time( time_buf );
 
204
                snmp_log( LOG_ERR, "%s init_ibmOSAMib(): "
 
205
                          "ioctl() failed - valid IPA command, but no"
 
206
                          " SNMP data is available for interface %s\n"
 
207
                          "init_ibmOSAMib(): start subagent anyway\n", 
 
208
                          time_buf, if_list[i].if_Name );
 
209
                close( sd );
 
210
                free( buffer );
 
211
                return;
 
212
                break;
 
213
                
 
214
              case -ENOMEM: /* should not happen in the near future ;-) */
 
215
                fprintf( stderr, "init_ibmOSAMib(): "
 
216
                         "ioctl() failed - MIB data size > "
 
217
                         "constant MIB_AREA_LEN\n"
 
218
                         "init_ibmOSAMib(): "
 
219
                         "Enlarge constant for MIB_AREA_LEN within "
 
220
                         "ibmOSAMibDefs.h and recompile the subagent\n"
 
221
                         "init_ibmOSAMib(): "
 
222
                         "Can't get MIB information for network interfaces\n"
 
223
                         "Cannot start subagent...exiting...\n" );
 
224
 
 
225
              default:
 
226
                fprintf( stderr, "init_ibmOSAMib(): "
 
227
                         "ioctl() failed - reason %s\n"
 
228
                         "init_ibmOSAMib(): "
 
229
                         "Can't get MIB information for network interface %s\n"
 
230
                         "Cannot start subagent...exiting...\n",
 
231
                         strerror( error_code ), if_list[i].if_Name );
 
232
                break;
 
233
              } /* end switch */
 
234
 
 
235
              exit(1);
 
236
            } 
 
237
          else if( ipa_reg_mib->ioctl_cmd.ipa_cmd_hdr.ret_code != 0 )
 
238
            {
 
239
              /* now check IPA SNMP subcommand return code */
 
240
              switch ( ipa_reg_mib->ioctl_cmd.ipa_cmd_hdr.ret_code ) {
 
241
                
 
242
              case IPA_SNMP_INV_TOPOID: 
 
243
              case IPA_SNMP_INV_GROUP: 
 
244
              case IPA_SNMP_INV_SUFFIX:
 
245
              case IPA_SNMP_INV_INST:
 
246
              case IPA_SNMP_OID_NREAD:
 
247
              case IPA_SNMP_OID_NWRIT:
 
248
                get_time( time_buf );      
 
249
                snmp_log( LOG_ERR, "%s init_ibmOSAMib(): "
 
250
                          "IPA SNMP subcommand failed\n" 
 
251
                          "init_ibmOSAMib(): "
 
252
                          "IPA SNMP subcommand  return code 0x%x\n"
 
253
                          "init_ibmOSAMib(): "
 
254
                          "Can't get MIB information for network interface %s\n"
 
255
                          "Cannot start subagent...exiting...\n", time_buf,
 
256
                          ipa_reg_mib->ioctl_cmd.ipa_cmd_hdr.ret_code, 
 
257
                          if_list[i].if_Name );
 
258
                break;
 
259
                
 
260
              case IPA_SNMP_NOT_SUPP:
 
261
                get_time( time_buf );
 
262
                snmp_log( LOG_ERR, "%s init_ibmOSAMib(): "
 
263
                          "IPA SNMP subcommand failed - subcommand 0x%x "
 
264
                          "not supported\ninit_ibmOSAMib(): "
 
265
                          "Can't get MIB information for network interface %s\n"
 
266
                          "Cannot start subagent...exiting...\n", time_buf,
 
267
                          ipa_reg_mib->ioctl_cmd.ipa_cmd_hdr.request,
 
268
                          if_list[i].if_Name );
 
269
                break;
 
270
                
 
271
              case IPA_SNMP_NO_DATA:
 
272
                get_time( time_buf );
 
273
                snmp_log( LOG_ERR, "%s init_ibmOSAMib(): "
 
274
                          "IPA SNMP subcommand failed - no data available\n"
 
275
                          "init_ibmOSAMib(): "
 
276
                          "Can't get MIB information for network interface %s\n"
 
277
                          "Cannot start subagent...exiting...\n", time_buf,
 
278
                          if_list[i].if_Name );
 
279
                break;
 
280
                
 
281
              default:
 
282
                get_time( time_buf );
 
283
                snmp_log( LOG_ERR, "%s init_ibmOSAMib(): "
 
284
                          "IPA SNMP subcommand failed - undefined return code"
 
285
                          " 0x%x\ninit_ibmOSAMib(): "
 
286
                          "Can't get MIB information for network interface %s\n"
 
287
                          "Cannot start subagent...exiting...\n", time_buf,
 
288
                          ipa_reg_mib->ioctl_cmd.ipa_cmd_hdr.ret_code,
 
289
                          if_list[i].if_Name );
 
290
                break;
 
291
                
 
292
              } /* end switch */
 
293
 
 
294
              exit(1);
 
295
 
 
296
            } /* end if */
 
297
          
 
298
          /* save microcode level */
 
299
          if_list[i].ipa_ver = ipa_reg_mib->ioctl_cmd.ipa_cmd_hdr.ipa_ver;
 
300
 
 
301
          
 
302
          /* register initial table information, that we got from IPAssists */
 
303
          retc = register_tables ( buffer, oid_list_head ); 
 
304
          if ( retc != 0 )
 
305
            {
 
306
              fprintf( stderr, "init_ibmOSAMib(): "
 
307
                       "register MIB data with subagent driving "
 
308
                       "code failed\ninit_ibmOSAMib(): for ifIndex %d ifDescr %s\n"
 
309
                       "check agent log file for more details\n"
 
310
                       "Cannot start subagent...exiting...\n", 
 
311
                       if_list[i].ifIndex, if_list[i].if_Name );
 
312
              exit(1); 
 
313
            } /* end if */
 
314
        } /* end if */
 
315
      
 
316
    } /* end for */ 
 
317
 
 
318
  /* log IPA microcode level per interface */
 
319
  for ( i=0; i < ifNumber; i++ )
 
320
    {
 
321
       if ( if_list[i].is_OSAEXP == TRUE )
 
322
          snmp_log( LOG_INFO, "OSA-E microcode level is %x for interface %s\n",
 
323
                              if_list[i].ipa_ver,
 
324
                              if_list[i].if_Name );
 
325
    } /* end for */ 
 
326
 
 
327
  /* free resources */
 
328
  close( sd );
 
329
  free( buffer );
 
330
  
 
331
} /* end init_ibmOSAMib */
 
332
 
 
333
 
 
334
/**********************************************************************
 
335
 * var_ibmOSAMib():
 
336
 *  This function is called every time the agent gets a request for 
 
337
 *  any MIB data for the IBM OSA express MIB. It's up to this function
 
338
 *  to return the appropriate data back to the subagent driving code.
 
339
 *  This function supports all standard SNMIv2 data types.
 
340
 *  parameters:
 
341
 *  IN  variable vp       - entry in variableN array
 
342
 *  INOUT oid    *name    - OID from original request/OID being returned
 
343
 *  INOUT size_t *length  - length of orig. OID/length of ret. OID
 
344
 *  IN    int    exact    - exact/inexact request
 
345
 *  OUT   size_t *var_len - length of answer being returned
 
346
 *  OUT   WriteMethod **write_method - unused
 
347
 *  returns: NULL - vp entry does not match or instance wrong
 
348
 *                - something within ioctl handling failed
 
349
 *           else   data returned as answer
 
350
 *********************************************************************/
 
351
unsigned char* var_ibmOSAMib( struct variable *vp,
 
352
                                 oid         *name,
 
353
                                 size_t      *length,
 
354
                                 int         exact,
 
355
                                 size_t      *var_len,
 
356
                                 WriteMethod **write_method)
 
357
{
 
358
  /* variables for returning data back to the subagent driving code */
 
359
  static long long_ret;
 
360
  static unsigned char octetstr_buf[MAX_GET_DATA];
 
361
  static oid objid[MAX_OID_LEN];
 
362
  static struct counter64 osa_counter64;
 
363
  long             *ptr_long;
 
364
  int              *ptr_int;
 
365
  unsigned char    *ptr_uchar;
 
366
  
 
367
  int  ifIndex;     /* IF-MIB ifIndex of the OSA device that is queried for data */
 
368
  int  offset;      /* offset to returned data portion within GET command area */
 
369
  char time_buf[TIME_BUF_SIZE]; /* date/time buffer */
 
370
 
 
371
  IPA_CMD_GET  *get_cmd;        /* area for GET command */
 
372
  IPA_GET_DATA *get_res;        /* pointer to offset where data portion starts */
 
373
  void         *tmp_ptr;        
 
374
 
 
375
  /* 
 
376
   * This function compares the full OID that is passed in to the registered
 
377
   * OIDs from this subagent. 
 
378
   * It is the IBM OSA Express specific version of the default 
 
379
   * header_simple_table() function, that is normally used in case of a simple
 
380
   * table. Place a mutual exlusion lock around this operation to avoid 
 
381
   * interfering threads, when updating the internal MIB table thru thread 
 
382
   * update_mib_info()          
 
383
   */
 
384
 
 
385
  ifIndex = header_osa_table( vp, name, length, exact, var_len, write_method,
 
386
                              oid_list_head );
 
387
 
 
388
  if ( ifIndex == MATCH_FAILED ) 
 
389
    return NULL; 
 
390
 
 
391
 
 
392
  /* issue ioctl to query Get/Getnext request data */
 
393
  offset = do_GET_ioctl ( ifIndex, name, *length, &get_cmd );
 
394
  if ( offset < 0 )
 
395
    {
 
396
      return NULL; 
 
397
    }
 
398
 
 
399
  /*
 
400
   * return the result to subagent driving code 
 
401
   */
 
402
  
 
403
  /* map data portion returned by IPAssists */
 
404
  /* # ptr GET command area + offset returned data portion */
 
405
  /* # align PTR to 4 byte bdy where data portion starts   */
 
406
  tmp_ptr = (char*) get_cmd;
 
407
  tmp_ptr += offset;
 
408
  get_res = (IPA_GET_DATA*) (PTR_ALIGN4( tmp_ptr )); 
 
409
  
 
410
  switch( vp->type ) {
 
411
 
 
412
  case ASN_INTEGER: case ASN_COUNTER: case ASN_GAUGE: case ASN_TIMETICKS:  
 
413
    /* ASN_UNSIGNED is same as ASN_GAUGE (RFC1902) */
 
414
 
 
415
    if ( get_res->len == sizeof(int) ) 
 
416
      {
 
417
            ptr_int = (int*) get_res->data;
 
418
            long_ret = (long) *ptr_int;
 
419
      }
 
420
    else            
 
421
      {
 
422
            ptr_long = (long*) get_res->data;
 
423
            long_ret = (long) *ptr_long;
 
424
      } /* end if */
 
425
 
 
426
    free( get_cmd );
 
427
 
 
428
    return (unsigned char *) &long_ret;
 
429
    break;
 
430
 
 
431
  case ASN_COUNTER64:
 
432
 
 
433
    if ( get_res->len > 8 )
 
434
    {
 
435
      get_time( time_buf );         
 
436
      snmp_log( LOG_ERR, "%s var_ibmOSAMib(): "
 
437
                "IPA data length for ASN_COUNTER64 > 8 bytes\n"
 
438
                "var_ibmOSAMib(): rejected Get/Getnext request\n", time_buf );
 
439
      free( get_cmd );
 
440
      return NULL;
 
441
    } /* end if */
 
442
  
 
443
    /* IPA returns 8 bytes for COUNTER64 */ 
 
444
    ptr_int = (int*) get_res->data;
 
445
    osa_counter64.high = (int) *ptr_int;
 
446
    ptr_int++;
 
447
    osa_counter64.low  = (int) *ptr_int;
 
448
     
 
449
    *var_len = sizeof( osa_counter64 );
 
450
    free( get_cmd );
 
451
 
 
452
    return (unsigned char *) &osa_counter64; 
 
453
    break;
 
454
 
 
455
  case ASN_OPAQUE:    /* old v1 type/included for compability */ 
 
456
  case ASN_OCTET_STR: /* used for Binary data */ 
 
457
                      /* case Display String is handled within var_DisplayStr() */
 
458
   
 
459
    if ( get_res->len > MAX_GET_DATA )
 
460
    {
 
461
      get_time( time_buf );         
 
462
      snmp_log( LOG_ERR, "%s var_ibmOSAMib(): "
 
463
                "IPA data length %d  for ASN_OCTET_STR > "
 
464
                "MAX_GET_DATA (%d  bytes)\n"
 
465
                "var_ibmOSAMib(): rejected Get/Getnext request\n",
 
466
                time_buf, get_res->len, MAX_GET_DATA );
 
467
      free( get_cmd );
 
468
      return NULL;
 
469
    } /* end if */
 
470
 
 
471
    *var_len = get_res->len;
 
472
    ptr_uchar = (unsigned char*) get_res->data;
 
473
    memcpy( octetstr_buf, ptr_uchar, *var_len ); 
 
474
    free( get_cmd );
 
475
 
 
476
    return (unsigned char *) octetstr_buf;  
 
477
    break;
 
478
 
 
479
  case ASN_IPADDRESS:
 
480
 
 
481
    /* IPA IpAddress within 4 bytes hex data */
 
482
    ptr_int = (int*) get_res->data;
 
483
    long_ret = (long) *ptr_int;
 
484
    free( get_cmd );
 
485
 
 
486
    return (unsigned char *) &long_ret;
 
487
    break;
 
488
 
 
489
  case ASN_OBJECT_ID:
 
490
    
 
491
    /* IPA returned ObjectId as character string, have to convert... */
 
492
    *var_len = str_to_oid_conv ( get_res->data, objid );
 
493
    if ( *var_len == 0 )
 
494
    {
 
495
      get_time( time_buf );         
 
496
      snmp_log( LOG_ERR, "%s var_ibmOSAMib(): IPA returned bad ObjectId - "
 
497
                "cannot convert ucd-snmp oid type\n"
 
498
                "var_ibmOSAMib(): rejected Get/Getnext request\n", time_buf );
 
499
      free( get_cmd );
 
500
      return NULL;
 
501
    } /* end if */
 
502
 
 
503
    *var_len = (*var_len) * sizeof( oid );
 
504
    free( get_cmd );
 
505
 
 
506
    return (unsigned char *) &objid;
 
507
    break;
 
508
 
 
509
  default:
 
510
    get_time( time_buf );
 
511
    snmp_log( LOG_ERR, "%s var_ibmOSAMib(): "
 
512
              "got a not known ASN data type %x\n"
 
513
              "var_ibmOSAMib(): "
 
514
              "rejected Get/Getnext request\n", time_buf, vp->type );
 
515
 
 
516
  } /* end switch */
 
517
 
 
518
  free( get_cmd );
 
519
 
 
520
  return NULL;
 
521
 
 
522
} /* end var_ibmOSAMib */
 
523
 
 
524
 
 
525
/**********************************************************************
 
526
 * var_DisplayStr():
 
527
 *  This function handles the special case for Display Strings, which are 
 
528
 *  a textual convention to Octet Strings. The binary data case for 
 
529
 *  Octet Strings is handled within var_ibmOSAMib(). 
 
530
 *  It's up to this function to return the appropriate data back to the 
 
531
 *  subagent driving code.
 
532
 *  parameters:
 
533
 *  IN  variable vp       - entry in variableN array
 
534
 *  INOUT oid    *name    - OID from original request/OID being returned
 
535
 *  INOUT size_t *length  - length of orig. OID/length of ret. OID
 
536
 *  IN    int    exact    - exact/inexact request
 
537
 *  OUT   size_t *var_len - length of answer being returned
 
538
 *  OUT   WriteMethod **write_method - unused
 
539
 *  returns: NULL - vp entry does not match or instance wrong
 
540
 *                - something within ioctl handling failed
 
541
 *           else   data returned as answer
 
542
 *********************************************************************/
 
543
unsigned char* var_DisplayStr( struct variable *vp,
 
544
                               oid         *name,
 
545
                               size_t      *length,
 
546
                               int         exact,
 
547
                               size_t      *var_len,
 
548
                               WriteMethod **write_method)
 
549
{
 
550
  /* variables for returning a display string to the subagent driving code */
 
551
  static unsigned char string[SPRINT_MAX_LEN];
 
552
  char                 time_buf[TIME_BUF_SIZE]; /* date/time buffer */
 
553
  
 
554
  int  ifIndex;     /* IF-MIB ifIndex of the OSA device that is queried for data */
 
555
  int  offset;      /* offset to returned data portion within GET command area */
 
556
 
 
557
  IPA_CMD_GET  *get_cmd;        /* area for GET command */
 
558
  IPA_GET_DATA *get_res;        /* pointer to offset where data portion starts */
 
559
  void         *tmp_ptr;
 
560
 
 
561
  /* 
 
562
   * This function compares the full OID that is passed in to the registered
 
563
   * OIDs from this subagent. 
 
564
   * It is the IBM OSA Express specific version of the default 
 
565
   * header_simple_table() function, that is normally used in case of a simple
 
566
   * table. Place a mutual exlusion lock around this operation to avoid 
 
567
   * interfering threads, when updating the internal MIB table thru thread 
 
568
   * update_mib_info()          
 
569
   */
 
570
 
 
571
  ifIndex = header_osa_table( vp, name, length, exact, var_len, write_method,
 
572
                              oid_list_head );
 
573
 
 
574
  if ( ifIndex == MATCH_FAILED )
 
575
    return NULL;
 
576
 
 
577
 
 
578
  /* issue ioctl to query Get/Getnext request data */
 
579
  offset = do_GET_ioctl ( ifIndex, name, *length, &get_cmd );
 
580
  if ( offset < 0 )
 
581
    {
 
582
      return NULL;
 
583
    }
 
584
  
 
585
  /*
 
586
   * return the result to subagent driving code 
 
587
   */
 
588
 
 
589
  /* map data portion returned by IPAssists */
 
590
  /* # ptr GET command area + offset returned data portion */
 
591
  /* # align PTR to 4 byte bdy where data portion starts   */
 
592
  tmp_ptr = (char*) get_cmd;
 
593
  tmp_ptr += offset;
 
594
  get_res = (IPA_GET_DATA*) (PTR_ALIGN4( tmp_ptr )); 
 
595
 
 
596
  if ( vp->type == ASN_OCTET_STR)  
 
597
    {
 
598
      if ( get_res->len > SPRINT_MAX_LEN )
 
599
        {
 
600
          get_time( time_buf ); 
 
601
          snmp_log( LOG_ERR, "%s var_DisplayStr(): "
 
602
                    "IPA data length %d  for Display "
 
603
                    "String > SPRINT_MAX_LEN (%d  bytes)\n"
 
604
                    "var_ibmOSAMib(): rejected Get/Getnext request\n"
 
605
                    ,time_buf, get_res->len, SPRINT_MAX_LEN );
 
606
          free( get_cmd );
 
607
          return NULL;
 
608
        } /* end if */
 
609
 
 
610
      strncpy( string, get_res->data, get_res->len );
 
611
      string[ get_res->len ] = '\0';
 
612
      *var_len = strlen( string ); 
 
613
      free( get_cmd );
 
614
 
 
615
      return (unsigned char *) string;  
 
616
    }
 
617
  else
 
618
    {
 
619
      get_time( time_buf );         
 
620
      snmp_log( LOG_ERR, "%s var_DisplayStr(): "
 
621
                "expected a Display String here, "
 
622
                "but got a different ASN data type: %x\n"
 
623
                "var_DisplayStr(): "
 
624
                "rejected Get/Getnext request\n", time_buf, vp->type );
 
625
    } /* end if */
 
626
 
 
627
  free( get_cmd );
 
628
 
 
629
  return NULL;
 
630
 
 
631
} /* end var_DisplayStr */
 
632
 
 
633
 
 
634
/**********************************************************************
 
635
 * do_GET_ioctl()
 
636
 *  This function handles the communication with an OSA Express Card
 
637
 *  to query the appropriate MIB information from IPAssists.
 
638
 *  An ioctl is used in order to qet the appropriate information.
 
639
 *  parameters:
 
640
 *  IN    int ifIndex       - IF-MIB interface index 
 
641
 *  IN    oid    *name      - OID being returned
 
642
 *  IN    size_t len        - length of ret. OID
 
643
 *  INOUT IPA_CMD_GET** cmd - GET command area
 
644
 *  returns:  cmd_len - return offset to returned data
 
645
 *           -1 -  ioctl() was not successful
 
646
 *********************************************************************/
 
647
int do_GET_ioctl ( int ifIndex, oid *name, size_t len, IPA_CMD_GET **cmd )
 
648
{
 
649
  int  sd;                                   /* socket descriptor */
 
650
  int  i, error_code;
 
651
  char oid_str[MAX_OID_STR_LEN];             /* may hold an OID as string */
 
652
  char time_buf[TIME_BUF_SIZE];              /* date/time buffer */
 
653
  char device[IFNAME_MAXLEN] = "not_found";  /* device name for ioctl */
 
654
  struct ifreq ifr;                          /* request structure for ioctl */
 
655
  
 
656
  
 
657
  /* search device name in in global interface list for ifIndex */
 
658
  for ( i=0; i < ifNumber; i++ )
 
659
    {
 
660
      if ( if_list[i].ifIndex == ifIndex )
 
661
        {
 
662
          strcpy( device, if_list[i].if_Name );
 
663
          break;
 
664
        }
 
665
    } /* end for */
 
666
  
 
667
  if ( strcmp( device, "not_found" ) == 0 )
 
668
    {
 
669
      get_time( time_buf );         
 
670
      snmp_log( LOG_ERR, "%s do_GET_ioctl(): "
 
671
                "ifIndex %d is not recorded in "
 
672
                "interface list\n"
 
673
                "OSA Subagent MIB information may be incomplete!\n"
 
674
                ,time_buf, ifIndex );
 
675
      return -1;
 
676
    } 
 
677
 
 
678
  /*
 
679
   * query IPAssists for data appropriate to the OID that we just validated
 
680
   */
 
681
 
 
682
  /* convert Get/GetNext OID to a string used by IPA */
 
683
  if( oid_to_str_conv ( name, len, oid_str ) == FALSE )
 
684
    {
 
685
      get_time( time_buf );         
 
686
      snmp_log( LOG_ERR, "%s do_GET_ioctl(): "
 
687
                "cannot convert OID to string object\n"
 
688
                "do_GET_ioctl(): rejected request\n", time_buf );
 
689
      return -1;
 
690
    } 
 
691
 
 
692
  /* allocate memory for Get/GetNext command area */
 
693
  *cmd = ( IPA_CMD_GET* ) malloc( GET_AREA_LEN ); 
 
694
  if ( *cmd == NULL ) 
 
695
    {
 
696
      get_time( time_buf );          
 
697
      snmp_log( LOG_ERR, 
 
698
                "%s do_GET_ioctl(): "
 
699
                "malloc() for GET command area failed\n"
 
700
                "do_GET_ioctl(): rejected request for .%s\n",
 
701
                time_buf, oid_str );
 
702
      return -1;
 
703
    } /* end if */
 
704
 
 
705
  /* set up input parameters in Get/GetNext command area */
 
706
  /* size of IPA data area */  
 
707
  (*cmd)->ioctl_cmd.data_len =             
 
708
          GET_AREA_LEN - offsetof( IOCTL_CMD_HDR, ipa_cmd_hdr );
 
709
 
 
710
  /* size of IPA GET subcommand padded to 4-byte bdy */
 
711
  (*cmd)->ioctl_cmd.req_len =  
 
712
    (sizeof((*cmd)->ioctl_cmd) + strlen( oid_str ) + 1 + 3)&(~3); 
 
713
 
 
714
  /* set up input parameters in Get/GetNext command area */
 
715
  (*cmd)->ioctl_cmd.ipa_cmd_hdr.request  = IPA_GET_OID;  /* IPA subcommand code   */
 
716
  (*cmd)->ioctl_cmd.ipa_cmd_hdr.ifIndex  = ifIndex;      /* assign IF-MIB ifIndex */
 
717
  (*cmd)->ioctl_cmd.ipa_cmd_hdr.ret_code = 0;               
 
718
  (*cmd)->ioctl_cmd.ipa_cmd_hdr.seq_num  = 0;            /* sequence# is not used */ 
 
719
  strcpy( (*cmd)->full_oid, oid_str );                   /* requested OID         */
 
720
                                                         /* (fully qualified)     */
 
721
 
 
722
  /*
 
723
   *  issue Get/GetNext command against IPAssists 
 
724
   */
 
725
 
 
726
  /* create socket for ioctl */
 
727
  sd = socket( AF_INET, SOCK_STREAM, 0 );
 
728
  if ( sd < 0 )
 
729
    {
 
730
      error_code = errno;
 
731
      get_time( time_buf );
 
732
      snmp_log(LOG_ERR, "%s do_GET_ioctl(): "
 
733
               "error opening socket() - reason %s\n"
 
734
               "do_GET_ioctl(): rejected request for .%s\n", 
 
735
               time_buf, strerror( error_code ), oid_str );
 
736
      free( *cmd );
 
737
      return -1;
 
738
    } /* end if */
 
739
  
 
740
  /* do ioctl */
 
741
  strcpy( ifr.ifr_name, device );       
 
742
  ifr.ifr_ifru.ifru_data = (char*) (*cmd);
 
743
  if ( ioctl( sd, SIOC_QETH_ADP_SET_SNMP_CONTROL, &ifr ) < 0 )
 
744
    {
 
745
      error_code = errno;
 
746
      get_time( time_buf );
 
747
 
 
748
      /* see if we got a common I/O error */
 
749
      if ( error_code == -EIO )
 
750
        {
 
751
           snmp_log( LOG_ERR, "%s do_GET_ioctl(): "
 
752
                     "ioctl() failed - reason %s\n"
 
753
                     "do_GET_ioctl(): rejected request for .%s\n",
 
754
                     time_buf, strerror( error_code ), oid_str );
 
755
           close( sd );
 
756
           free( *cmd );
 
757
           return -1;
 
758
        } /* end if */
 
759
      
 
760
      /* let's see, if we got a return code from IPAssists */
 
761
      /* or if MIB buffer is exhausted */
 
762
      switch ( (*cmd)->ioctl_cmd.ipa_cmd_hdr.ret_code ) {
 
763
        
 
764
      case IPA_FAILED:
 
765
        snmp_log( LOG_ERR, "%s do_GET_ioctl(): "
 
766
                  "ioctl() failed - IPA command failed\n"
 
767
                  "do_GET_ioctl(): rejected request for .%s\n",
 
768
                  time_buf, oid_str );
 
769
        break;
 
770
 
 
771
      case IPA_NOT_SUPP:
 
772
        snmp_log( LOG_ERR, "%s do_GET_ioctl(): "
 
773
                  "ioctl() failed - IPA command not supported\n"
 
774
                  "do_GET_ioctl(): rejected request for .%s\n",
 
775
                  time_buf,  oid_str );
 
776
        break;
 
777
                
 
778
      case IPA_NO_DATA:
 
779
        snmp_log( LOG_ERR, "%s do_GET_ioctl(): "
 
780
                  "ioctl() failed - valid IPA command, but no "
 
781
                  "SNMP data is available\n"
 
782
                  "do_GET_ioctl(): rejected request for .%s\n",
 
783
                  time_buf, oid_str ); 
 
784
        break;
 
785
 
 
786
      case -ENOMEM:
 
787
        snmp_log( LOG_ERR, "%s do_GET_ioctl(): "
 
788
                  "ioctl() failed - response data > "
 
789
                  "constant MAX_GET_DATA %d\n"
 
790
                  "do_GET_ioctl(): rejected request for .%s\n",
 
791
                  time_buf, MAX_GET_DATA, oid_str );        
 
792
        break;
 
793
 
 
794
      default:
 
795
        snmp_log(LOG_ERR, "%s do_GET_ioctl(): "
 
796
                 "ioctl() failed - reason %s\n"
 
797
                 "do_GET_ioctl(): rejected request for .%s\n", 
 
798
                 time_buf, strerror( error_code ), oid_str );
 
799
        break;
 
800
      } /* end switch */
 
801
 
 
802
      close( sd );
 
803
      free( *cmd );
 
804
      return -1;
 
805
 
 
806
    } /* end if */ 
 
807
 
 
808
  /* close socket */
 
809
  close( sd );
 
810
  
 
811
  /* now check IPA SNMP subcommand return code */
 
812
  switch ( (*cmd)->ioctl_cmd.ipa_cmd_hdr.ret_code ) {
 
813
    
 
814
  case IPA_SNMP_SUCCESS:
 
815
    /* return offset to data portion */
 
816
    return ( sizeof( IPA_CMD_GET ) + strlen( oid_str ) + 1 );
 
817
    break;
 
818
 
 
819
  case IPA_SNMP_INV_TOPOID: 
 
820
  case IPA_SNMP_INV_GROUP: 
 
821
  case IPA_SNMP_INV_SUFFIX:
 
822
  case IPA_SNMP_INV_INST:
 
823
  case IPA_SNMP_OID_NREAD:
 
824
  case IPA_SNMP_OID_NWRIT:
 
825
    get_time( time_buf );
 
826
    snmp_log( LOG_ERR, "%s do_GET_ioctl(): "
 
827
              "IPA SNMP subcommand failed - cannot handle OID\n"
 
828
              "do_GET_ioctl(): IPA SNMP subcommand return code 0x%x\n"
 
829
              "do_GET_ioctl(): rejected request for .%s\n",
 
830
              time_buf, (*cmd)->ioctl_cmd.ipa_cmd_hdr.ret_code, oid_str );
 
831
    break;
 
832
 
 
833
  case IPA_SNMP_NOT_SUPP:
 
834
    get_time( time_buf );
 
835
    snmp_log( LOG_ERR, "%s do_GET_ioctl(): "
 
836
              "IPA SNMP subcommand failed - subcommand 0x%x not supported\n"
 
837
              "do_GET_ioctl(): rejected request for .%s\n", 
 
838
              time_buf, (*cmd)->ioctl_cmd.ipa_cmd_hdr.request, oid_str );
 
839
    break;
 
840
    
 
841
  case IPA_SNMP_NO_DATA:
 
842
    get_time( time_buf );
 
843
    snmp_log( LOG_ERR, "%s do_GET_ioctl(): "
 
844
              "IPA SNMP subcommand failed - no data available\n"
 
845
              "do_GET_ioctl(): rejected request for .%s\n", 
 
846
              time_buf, oid_str );
 
847
    break;
 
848
    
 
849
  default:
 
850
    get_time( time_buf );
 
851
    snmp_log( LOG_ERR, "%s do_GET_ioctl(): "
 
852
              "IPA SNMP subcommand failed - undefined return code 0x%x\n"
 
853
              "do_GET_ioctl(): rejected request for .%s\n", 
 
854
              time_buf, (*cmd)->ioctl_cmd.ipa_cmd_hdr.ret_code, oid_str );
 
855
    break;
 
856
    
 
857
  } /* end switch */
 
858
 
 
859
  /* return error */
 
860
  free( *cmd );
 
861
  return -1;
 
862
 
 
863
} /* end do_GET_ioctl */
 
864
 
 
865
 
 
866
/**********************************************************************
 
867
 * write_ibmOSAMib():
 
868
 *  !!! Set processing is not supported in version 1.0.0 !!!
 
869
 *  !!! Function is defind as a skeleton for later use   !!!
 
870
 *  This function handles any SET requests raised against the      
 
871
 *  ibmOSAMib.                                                      
 
872
 *  The flow of actions is to preserve proper transaction handling 
 
873
 *  with other transactions in the same set request.
 
874
 *  parameters:
 
875
 *  IN    int    action       - current action state 
 
876
 *  IN    u_char *var_val     - new variable value                      
 
877
 *  IN    u_char var_val_type - data type of above variable          
 
878
 *  IN    size_t var_val_len  - length of variable value 
 
879
 *  IN    u_char *statP       - value that a GET request would return
 
880
 *                              for this variable                             
 
881
 *  IN    oid    *name        - OID to be set
 
882
 *  IN    size_t name_len     - len of OID to be set 
 
883
 *  returns: SNMP_ERR_WRONGTYPE  - wrong data type passed in     
 
884
 *           SNMP_ERR_GENERR     - general error occured
 
885
 *           SNMP_ERR_UNDOFAILED - undo operation failed
 
886
 *           SNMP_ERR_NOERROR    - variable set sucessful
 
887
 *********************************************************************/
 
888
int write_ibmOSAMib( int      action,
 
889
                        u_char   *var_val,
 
890
                        u_char   var_val_type,
 
891
                        size_t   var_val_len,
 
892
                        u_char   *statP,
 
893
                        oid      *name,
 
894
                        size_t   name_len )
 
895
{
 
896
/*  static unsigned char string[SPRINT_MAX_LEN]; */
 
897
/*  int size; */
 
898
 
 
899
  switch ( action ) {
 
900
        case RESERVE1:
 
901
          /* check to see that everything is possible */
 
902
          break;
 
903
 
 
904
 
 
905
        case RESERVE2:
 
906
          /* allocate needed memory here */
 
907
          break;
 
908
 
 
909
 
 
910
        case FREE:
 
911
          /* Release any resources that have been allocated */
 
912
          break;
 
913
 
 
914
 
 
915
        case ACTION:
 
916
          /* Actually make the change requested. Note that anything done
 
917
             here must be reversable in the UNDO case */                  
 
918
          break;
 
919
 
 
920
 
 
921
        case UNDO:
 
922
          /* Back out any changes made in the ACTION case */
 
923
          break;
 
924
 
 
925
 
 
926
        case COMMIT:
 
927
          /* Things are working well, so it's now safe to make the change
 
928
             permanently.  Make sure that anything done here can't fail! */
 
929
          break;
 
930
  }
 
931
  return SNMP_ERR_NOERROR;
 
932
} /* end write_ibmOSAMib */
 
933
 
 
934
 
 
935
 
 
936
 
 
937
 
 
938