Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
c531c117
Commit
c531c117
authored
May 20, 2008
by
Juan Lang
Committed by
Alexandre Julliard
Jun 25, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
inetmib1: Support the MIB2 interface table.
parent
f913252e
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
293 additions
and
1 deletion
+293
-1
main.c
dlls/inetmib1/main.c
+191
-1
main.c
dlls/inetmib1/tests/main.c
+102
-0
No files found.
dlls/inetmib1/main.c
View file @
c531c117
...
...
@@ -17,7 +17,7 @@
*/
#include "config.h"
#include <assert.h>
#include <stdarg.h>
#include <limits.h>
#include "windef.h"
...
...
@@ -57,6 +57,47 @@ static void copyInt(AsnAny *value, void *src)
value
->
asnValue
.
number
=
*
(
DWORD
*
)
src
;
}
static
void
setStringValue
(
AsnAny
*
value
,
BYTE
type
,
DWORD
len
,
BYTE
*
str
)
{
AsnAny
strValue
;
strValue
.
asnType
=
type
;
strValue
.
asnValue
.
string
.
stream
=
str
;
strValue
.
asnValue
.
string
.
length
=
len
;
strValue
.
asnValue
.
string
.
dynamic
=
TRUE
;
SnmpUtilAsnAnyCpy
(
value
,
&
strValue
);
}
static
void
copyLengthPrecededString
(
AsnAny
*
value
,
void
*
src
)
{
DWORD
len
=
*
(
DWORD
*
)
src
;
setStringValue
(
value
,
ASN_OCTETSTRING
,
len
,
(
BYTE
*
)
src
+
sizeof
(
DWORD
));
}
typedef
void
(
*
copyValueFunc
)(
AsnAny
*
value
,
void
*
src
);
struct
structToAsnValue
{
size_t
offset
;
copyValueFunc
copy
;
};
static
AsnInteger32
mapStructEntryToValue
(
struct
structToAsnValue
*
map
,
UINT
mapLen
,
void
*
record
,
UINT
id
,
BYTE
bPduType
,
SnmpVarBind
*
pVarBind
)
{
/* OIDs are 1-based */
if
(
!
id
)
return
SNMP_ERRORSTATUS_NOSUCHNAME
;
--
id
;
if
(
id
>=
mapLen
)
return
SNMP_ERRORSTATUS_NOSUCHNAME
;
if
(
!
map
[
id
].
copy
)
return
SNMP_ERRORSTATUS_NOSUCHNAME
;
map
[
id
].
copy
(
&
pVarBind
->
value
,
(
BYTE
*
)
record
+
map
[
id
].
offset
);
return
SNMP_ERRORSTATUS_NOERROR
;
}
static
UINT
mib2
[]
=
{
1
,
3
,
6
,
1
,
2
,
1
};
static
UINT
mib2System
[]
=
{
1
,
3
,
6
,
1
,
2
,
1
,
1
};
...
...
@@ -127,9 +168,158 @@ static BOOL mib2IfNumberQuery(BYTE bPduType, SnmpVarBind *pVarBind,
return
TRUE
;
}
static
void
copyOperStatus
(
AsnAny
*
value
,
void
*
src
)
{
value
->
asnType
=
ASN_INTEGER
;
/* The IPHlpApi definition of operational status differs from the MIB2 one,
* so map it to the MIB2 value.
*/
switch
(
*
(
DWORD
*
)
src
)
{
case
MIB_IF_OPER_STATUS_OPERATIONAL
:
value
->
asnValue
.
number
=
MIB_IF_ADMIN_STATUS_UP
;
break
;
case
MIB_IF_OPER_STATUS_CONNECTING
:
case
MIB_IF_OPER_STATUS_CONNECTED
:
value
->
asnValue
.
number
=
MIB_IF_ADMIN_STATUS_TESTING
;
break
;
default:
value
->
asnValue
.
number
=
MIB_IF_ADMIN_STATUS_DOWN
;
};
}
static
struct
structToAsnValue
mib2IfEntryMap
[]
=
{
{
FIELD_OFFSET
(
MIB_IFROW
,
dwIndex
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwDescrLen
),
copyLengthPrecededString
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwType
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwMtu
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwSpeed
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwPhysAddrLen
),
copyLengthPrecededString
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwAdminStatus
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwOperStatus
),
copyOperStatus
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwLastChange
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwInOctets
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwInUcastPkts
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwInNUcastPkts
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwInDiscards
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwInErrors
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwInUnknownProtos
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwOutOctets
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwOutUcastPkts
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwOutNUcastPkts
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwOutDiscards
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwOutErrors
),
copyInt
},
{
FIELD_OFFSET
(
MIB_IFROW
,
dwOutQLen
),
copyInt
},
};
static
UINT
mib2IfEntry
[]
=
{
1
,
3
,
6
,
1
,
2
,
1
,
2
,
2
,
1
};
static
BOOL
mib2IfEntryQuery
(
BYTE
bPduType
,
SnmpVarBind
*
pVarBind
,
AsnInteger32
*
pErrorStatus
)
{
AsnObjectIdentifier
entryOid
=
DEFINE_OID
(
mib2IfEntry
);
TRACE
(
"(0x%02x, %s, %p)
\n
"
,
bPduType
,
SnmpUtilOidToA
(
&
pVarBind
->
name
),
pErrorStatus
);
switch
(
bPduType
)
{
case
SNMP_PDU_GET
:
case
SNMP_PDU_GETNEXT
:
if
(
!
ifTable
)
{
/* There is no interface present, so let the caller deal
* with finding the successor.
*/
*
pErrorStatus
=
SNMP_ERRORSTATUS_NOSUCHNAME
;
}
else
if
(
!
SnmpUtilOidNCmp
(
&
pVarBind
->
name
,
&
entryOid
,
entryOid
.
idLength
))
{
UINT
tableIndex
=
0
,
item
=
0
;
*
pErrorStatus
=
0
;
if
(
pVarBind
->
name
.
idLength
==
entryOid
.
idLength
||
pVarBind
->
name
.
idLength
==
entryOid
.
idLength
+
1
)
{
/* Either the table or an element within the table is specified,
* but the instance is not.
*/
if
(
bPduType
==
SNMP_PDU_GET
)
{
/* Can't get an interface entry without specifying the
* instance.
*/
*
pErrorStatus
=
SNMP_ERRORSTATUS_NOSUCHNAME
;
}
else
{
/* Get the first interface */
tableIndex
=
1
;
if
(
pVarBind
->
name
.
idLength
==
entryOid
.
idLength
+
1
)
item
=
pVarBind
->
name
.
ids
[
entryOid
.
idLength
];
else
item
=
1
;
}
}
else
{
tableIndex
=
pVarBind
->
name
.
ids
[
entryOid
.
idLength
+
1
];
item
=
pVarBind
->
name
.
ids
[
entryOid
.
idLength
];
if
(
bPduType
==
SNMP_PDU_GETNEXT
)
{
tableIndex
++
;
item
=
1
;
}
}
if
(
!*
pErrorStatus
)
{
assert
(
tableIndex
);
assert
(
item
);
if
(
tableIndex
>
ifTable
->
dwNumEntries
)
*
pErrorStatus
=
SNMP_ERRORSTATUS_NOSUCHNAME
;
else
{
*
pErrorStatus
=
mapStructEntryToValue
(
mib2IfEntryMap
,
DEFINE_SIZEOF
(
mib2IfEntryMap
),
&
ifTable
->
table
[
tableIndex
-
1
],
item
,
bPduType
,
pVarBind
);
if
(
bPduType
==
SNMP_PDU_GETNEXT
)
{
AsnObjectIdentifier
oid
;
SnmpUtilOidCpy
(
&
pVarBind
->
name
,
&
entryOid
);
oid
.
idLength
=
1
;
oid
.
ids
=
&
item
;
SnmpUtilOidAppend
(
&
pVarBind
->
name
,
&
oid
);
oid
.
idLength
=
1
;
oid
.
ids
=
&
ifTable
->
table
[
tableIndex
-
1
].
dwIndex
;
SnmpUtilOidAppend
(
&
pVarBind
->
name
,
&
oid
);
}
}
}
}
else
{
*
pErrorStatus
=
SNMP_ERRORSTATUS_NOSUCHNAME
;
/* Caller deals with OID if bPduType == SNMP_PDU_GETNEXT, so don't
* need to set it here.
*/
}
break
;
case
SNMP_PDU_SET
:
*
pErrorStatus
=
SNMP_ERRORSTATUS_READONLY
;
break
;
default:
FIXME
(
"0x%02x: unsupported PDU type
\n
"
,
bPduType
);
*
pErrorStatus
=
SNMP_ERRORSTATUS_NOSUCHNAME
;
}
return
TRUE
;
}
/* This list MUST BE lexicographically sorted */
static
struct
mibImplementation
supportedIDs
[]
=
{
{
DEFINE_OID
(
mib2IfNumber
),
mib2IfNumberInit
,
mib2IfNumberQuery
},
{
DEFINE_OID
(
mib2IfEntry
),
NULL
,
mib2IfEntryQuery
},
};
static
UINT
minSupportedIDLength
;
...
...
dlls/inetmib1/tests/main.c
View file @
c531c117
...
...
@@ -60,7 +60,11 @@ static void testQuery(void)
UINT
mib2System
[]
=
{
1
,
3
,
6
,
1
,
2
,
1
,
1
};
UINT
mib2If
[]
=
{
1
,
3
,
6
,
1
,
2
,
1
,
2
};
UINT
mib2IfTable
[]
=
{
1
,
3
,
6
,
1
,
2
,
1
,
2
,
2
};
UINT
mib2IfDescr
[]
=
{
1
,
3
,
6
,
1
,
2
,
1
,
2
,
2
,
1
,
2
};
UINT
mib2IfAdminStatus
[]
=
{
1
,
3
,
6
,
1
,
2
,
1
,
2
,
2
,
1
,
7
};
UINT
mib2IfOperStatus
[]
=
{
1
,
3
,
6
,
1
,
2
,
1
,
2
,
2
,
1
,
8
};
SnmpVarBind
vars
[
3
],
vars2
[
3
];
UINT
entry
;
pQuery
=
(
void
*
)
GetProcAddress
(
inetmib1
,
"SnmpExtensionQuery"
);
if
(
!
pQuery
)
...
...
@@ -119,6 +123,104 @@ static void testQuery(void)
/* The index is 1-based rather than 0-based */
ok
(
index
==
1
,
"expected index 1, got %d
\n
"
,
index
);
/* A Get fails on something that specifies a table (but not a particular
* entry in it)...
*/
vars
[
0
].
name
.
idLength
=
sizeof
(
mib2IfDescr
)
/
sizeof
(
mib2IfDescr
[
0
]);
vars
[
0
].
name
.
ids
=
mib2IfDescr
;
vars
[
1
].
name
.
idLength
=
sizeof
(
mib2IfAdminStatus
)
/
sizeof
(
mib2IfAdminStatus
[
0
]);
vars
[
1
].
name
.
ids
=
mib2IfAdminStatus
;
vars
[
2
].
name
.
idLength
=
sizeof
(
mib2IfOperStatus
)
/
sizeof
(
mib2IfOperStatus
[
0
]);
vars
[
2
].
name
.
ids
=
mib2IfOperStatus
;
list
.
len
=
3
;
SetLastError
(
0xdeadbeef
);
error
=
0xdeadbeef
;
index
=
0xdeadbeef
;
ret
=
pQuery
(
SNMP_PDU_GET
,
&
list
,
&
error
,
&
index
);
ok
(
ret
,
"SnmpExtensionQuery failed: %d
\n
"
,
GetLastError
());
ok
(
error
==
SNMP_ERRORSTATUS_NOSUCHNAME
,
"expected SNMP_ERRORSTATUS_NOSUCHNAME, got %d
\n
"
,
error
);
ok
(
index
==
1
,
"expected index 1, got %d
\n
"
,
index
);
/* but a GetNext succeeds with the same values, because GetNext gets the
* entry after the specified OID, not the entry specified by it. The
* successor to the table is the first entry in the table.
* The OIDs need to be allocated, because GetNext modifies them to indicate
* the end of data.
*/
SnmpUtilOidCpy
(
&
vars2
[
0
].
name
,
&
vars
[
0
].
name
);
SnmpUtilOidCpy
(
&
vars2
[
1
].
name
,
&
vars
[
1
].
name
);
SnmpUtilOidCpy
(
&
vars2
[
2
].
name
,
&
vars
[
2
].
name
);
list
.
list
=
vars2
;
moreData
=
TRUE
;
entry
=
1
;
do
{
SetLastError
(
0xdeadbeef
);
error
=
0xdeadbeef
;
index
=
0xdeadbeef
;
ret
=
pQuery
(
SNMP_PDU_GETNEXT
,
&
list
,
&
error
,
&
index
);
ok
(
ret
,
"SnmpExtensionQuery failed: %d
\n
"
,
GetLastError
());
ok
(
error
==
SNMP_ERRORSTATUS_NOERROR
,
"expected SNMP_ERRORSTATUS_NOERROR, got %d
\n
"
,
error
);
ok
(
index
==
0
,
"expected index 0, got %d
\n
"
,
index
);
if
(
!
ret
)
moreData
=
FALSE
;
else
if
(
error
)
moreData
=
FALSE
;
else
if
(
SnmpUtilOidNCmp
(
&
vars2
[
0
].
name
,
&
vars
[
0
].
name
,
vars
[
0
].
name
.
idLength
))
moreData
=
FALSE
;
else
if
(
SnmpUtilOidNCmp
(
&
vars2
[
1
].
name
,
&
vars
[
1
].
name
,
vars
[
1
].
name
.
idLength
))
moreData
=
FALSE
;
else
if
(
SnmpUtilOidNCmp
(
&
vars2
[
2
].
name
,
&
vars
[
2
].
name
,
vars
[
2
].
name
.
idLength
))
moreData
=
FALSE
;
if
(
moreData
)
{
/* Check the OIDs. For these types of values (display strings and
* integers) they increase by 1 for each element of the table.
*/
ok
(
vars2
[
0
].
name
.
idLength
==
vars
[
0
].
name
.
idLength
+
1
,
"expected length %d, got %d
\n
"
,
vars
[
0
].
name
.
idLength
+
1
,
vars2
[
0
].
name
.
idLength
);
ok
(
vars2
[
0
].
name
.
ids
[
vars2
[
0
].
name
.
idLength
-
1
]
==
entry
,
"expected %d, got %d
\n
"
,
entry
,
vars2
[
0
].
name
.
ids
[
vars2
[
0
].
name
.
idLength
-
1
]);
ok
(
vars2
[
1
].
name
.
idLength
==
vars
[
1
].
name
.
idLength
+
1
,
"expected length %d, got %d
\n
"
,
vars
[
1
].
name
.
idLength
+
1
,
vars2
[
1
].
name
.
idLength
);
ok
(
vars2
[
1
].
name
.
ids
[
vars2
[
1
].
name
.
idLength
-
1
]
==
entry
,
"expected %d, got %d
\n
"
,
entry
,
vars2
[
1
].
name
.
ids
[
vars2
[
1
].
name
.
idLength
-
1
]);
ok
(
vars2
[
2
].
name
.
idLength
==
vars
[
2
].
name
.
idLength
+
1
,
"expected length %d, got %d
\n
"
,
vars
[
2
].
name
.
idLength
+
1
,
vars2
[
2
].
name
.
idLength
);
ok
(
vars2
[
2
].
name
.
ids
[
vars2
[
2
].
name
.
idLength
-
1
]
==
entry
,
"expected %d, got %d
\n
"
,
entry
,
vars2
[
2
].
name
.
ids
[
vars2
[
2
].
name
.
idLength
-
1
]);
++
entry
;
/* Check the types while we're at it */
ok
(
vars2
[
0
].
value
.
asnType
==
ASN_OCTETSTRING
,
"expected ASN_OCTETSTRING, got %02x
\n
"
,
vars2
[
0
].
value
.
asnType
);
ok
(
vars2
[
1
].
value
.
asnType
==
ASN_INTEGER
,
"expected ASN_INTEGER, got %02x
\n
"
,
vars2
[
1
].
value
.
asnType
);
ok
(
vars2
[
2
].
value
.
asnType
==
ASN_INTEGER
,
"expected ASN_INTEGER, got %02x
\n
"
,
vars2
[
2
].
value
.
asnType
);
/* Check that the operational status of an interface correctly
* follows the MIB2 definition of it, rather than the values
* defined for IPHlpApi's dwOperStatus field.
*/
ok
(
vars2
[
2
].
value
.
asnValue
.
unsigned32
<=
2
,
"expected a value of 0, 1, or 2, got %u
\n
"
,
vars2
[
2
].
value
.
asnValue
.
unsigned32
);
}
}
while
(
moreData
);
SnmpUtilVarBindFree
(
&
vars2
[
0
]);
SnmpUtilVarBindFree
(
&
vars2
[
1
]);
SnmpUtilVarBindFree
(
&
vars2
[
2
]);
/* Even though SnmpExtensionInit says this DLL supports the MIB2 system
* variables, the first variable it returns a value for is the first
* interface.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment