1 #include <net-snmp/net-snmp-config.h>
2 #include <net-snmp/net-snmp-includes.h>
3 #include <net-snmp/agent/net-snmp-agent-includes.h>
4 
5 #include "header_simple_table.h"
6 
7 #include <limits.h>
8 
9 /*******************************************************************-o-******
10  * header_simple_table
11  *
12  * Parameters:
13  *	  *vp		 Variable data.
14  *	  *name		 Fully instantiated OID name.
15  *	  *length	 Length of name.
16  *	   exact	 TRUE if an exact match is desired.
17  *	  *var_len	 Hook for size of returned data type.
18  *	(**write_method) Hook for write method (UNUSED).
19  *	   max
20  *
21  * Returns:
22  *	0	If name matches vp->name (accounting for 'exact') and is
23  *			not greater in length than 'max'.
24  *	1	Otherwise.
25  *
26  *
27  * Compare 'name' to vp->name for the best match or an exact match (if
28  *	requested).  Also check that 'name' is not longer than 'max' if
29  *	max is greater-than/equal 0.
30  * Store a successful match in 'name', and increment the OID instance if
31  *	the match was not exact.
32  *
33  * 'name' and 'length' are undefined upon failure.
34  *
35  */
36 int
header_simple_table(struct variable * vp,oid * name,size_t * length,int exact,size_t * var_len,WriteMethod ** write_method,int max)37 header_simple_table(struct variable *vp, oid * name, size_t * length,
38                     int exact, size_t * var_len,
39                     WriteMethod ** write_method, int max)
40 {
41     int             i, rtest;   /* Set to:      -1      If name < vp->name,
42                                  *              1       If name > vp->name,
43                                  *              0       Otherwise.
44                                  */
45     oid             newname[MAX_OID_LEN];
46 
47     for (i = 0, rtest = 0;
48          i < (int) vp->namelen && i < (int) (*length) && !rtest; i++) {
49         if (name[i] != vp->name[i]) {
50             if (name[i] < vp->name[i])
51                 rtest = -1;
52             else
53                 rtest = 1;
54         }
55     }
56     if (rtest > 0 ||
57         (exact == 1
58          && (rtest || (int) *length != (int) (vp->namelen + 1)))) {
59         if (var_len)
60             *var_len = 0;
61         return MATCH_FAILED;
62     }
63 
64     memset(newname, 0, sizeof(newname));
65 
66     if (((int) *length) <= (int) vp->namelen || rtest == -1) {
67         memmove(newname, vp->name, (int) vp->namelen * sizeof(oid));
68         newname[vp->namelen] = 1;
69         *length = vp->namelen + 1;
70     } else if (((int) *length) > (int) vp->namelen + 1) {       /* exact case checked earlier */
71         *length = vp->namelen + 1;
72         memmove(newname, name, (*length) * sizeof(oid));
73         if (name[*length - 1] < MAX_SUBID) {
74             newname[*length - 1] = name[*length - 1] + 1;
75         } else {
76             /*
77              * Careful not to overflow...
78              */
79             newname[*length - 1] = name[*length - 1];
80         }
81     } else {
82         *length = vp->namelen + 1;
83         memmove(newname, name, (*length) * sizeof(oid));
84         if (!exact) {
85             if (name[*length - 1] < MAX_SUBID) {
86                 newname[*length - 1] = name[*length - 1] + 1;
87             } else {
88                 /*
89                  * Careful not to overflow...
90                  */
91                 newname[*length - 1] = name[*length - 1];
92             }
93         } else {
94             newname[*length - 1] = name[*length - 1];
95         }
96     }
97     if ((max >= 0 && ((int)newname[*length - 1] > max)) ||
98                ( 0 == newname[*length - 1] )) {
99         if (var_len)
100             *var_len = 0;
101         return MATCH_FAILED;
102     }
103 
104     memmove(name, newname, (*length) * sizeof(oid));
105     if (write_method)
106         *write_method = (WriteMethod*)0;
107     if (var_len)
108         *var_len = sizeof(long);        /* default */
109     return (MATCH_SUCCEEDED);
110 }
111