Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

537 lines
14 KiB

  1. /*++
  2. Copyright (c) 1992-1996 Microsoft Corporation
  3. Module Name:
  4. sess_tbl.c
  5. Abstract:
  6. All routines to support opertions on the LM MIB session table.
  7. Environment:
  8. User Mode - Win32
  9. Revision History:
  10. 10-May-1996 DonRyan
  11. Removed banner from Technology Dynamics, Inc.
  12. --*/
  13. //--------------------------- WINDOWS DEPENDENCIES --------------------------
  14. //--------------------------- STANDARD DEPENDENCIES -- #include<xxxxx.h> ----
  15. #include <stdio.h>
  16. #include <memory.h>
  17. //--------------------------- MODULE DEPENDENCIES -- #include"xxxxx.h" ------
  18. #include <snmp.h>
  19. #include <snmputil.h>
  20. #include "mibfuncs.h"
  21. //--------------------------- SELF-DEPENDENCY -- ONE #include"module.h" -----
  22. #include "sess_tbl.h"
  23. //--------------------------- PUBLIC VARIABLES --(same as in module.h file)--
  24. // Prefix to the Session table
  25. static UINT sessSubids[] = { 2, 20, 1 };
  26. static AsnObjectIdentifier MIB_SessPrefix = { 3, sessSubids };
  27. SESSION_TABLE MIB_SessionTable = { 0, NULL };
  28. //--------------------------- PRIVATE CONSTANTS -----------------------------
  29. #define SESS_FIELD_SUBID (MIB_SessPrefix.idLength+MIB_OidPrefix.idLength)
  30. #define SESS_FIRST_FIELD SESS_CLIENT_FIELD
  31. #define SESS_LAST_FIELD SESS_STATE_FIELD
  32. //--------------------------- PRIVATE STRUCTS -------------------------------
  33. //--------------------------- PRIVATE VARIABLES -----------------------------
  34. //--------------------------- PRIVATE PROTOTYPES ----------------------------
  35. UINT MIB_sess_get(
  36. IN OUT RFC1157VarBind *VarBind
  37. );
  38. int MIB_sess_match(
  39. IN AsnObjectIdentifier *Oid,
  40. OUT UINT *Pos,
  41. IN BOOL Next
  42. );
  43. UINT MIB_sess_copyfromtable(
  44. IN UINT Entry,
  45. IN UINT Field,
  46. OUT RFC1157VarBind *VarBind
  47. );
  48. //--------------------------- PRIVATE PROCEDURES ----------------------------
  49. //--------------------------- PUBLIC PROCEDURES -----------------------------
  50. //
  51. // MIB_sess_func
  52. // High level routine for handling operations on the session table
  53. //
  54. // Notes:
  55. //
  56. // Return Codes:
  57. // None.
  58. //
  59. // Error Codes:
  60. // None.
  61. //
  62. UINT MIB_sess_func(
  63. IN UINT Action,
  64. IN MIB_ENTRY *MibPtr,
  65. IN OUT RFC1157VarBind *VarBind
  66. )
  67. {
  68. int Found;
  69. UINT Entry;
  70. UINT Field;
  71. UINT ErrStat;
  72. switch ( Action )
  73. {
  74. case MIB_ACTION_GETFIRST:
  75. // Fill the Session table with the info from server
  76. if ( SNMPAPI_ERROR == MIB_sess_lmget() )
  77. {
  78. ErrStat = SNMP_ERRORSTATUS_GENERR;
  79. goto Exit;
  80. }
  81. // If no elements in table, then return next MIB var, if one
  82. if ( MIB_SessionTable.Len == 0 )
  83. {
  84. if ( MibPtr->MibNext == NULL )
  85. {
  86. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  87. goto Exit;
  88. }
  89. // Do get first on the next MIB var
  90. ErrStat = (*MibPtr->MibNext->MibFunc)( Action, MibPtr->MibNext,
  91. VarBind );
  92. break;
  93. }
  94. //
  95. // Place correct OID in VarBind
  96. // Assuming the first field in the first record is the "start"
  97. {
  98. UINT temp_subs[] = { SESS_FIRST_FIELD };
  99. AsnObjectIdentifier FieldOid = { 1, temp_subs };
  100. SnmpUtilOidFree( &VarBind->name );
  101. SnmpUtilOidCpy( &VarBind->name, &MIB_OidPrefix );
  102. SnmpUtilOidAppend( &VarBind->name, &MIB_SessPrefix );
  103. SnmpUtilOidAppend( &VarBind->name, &FieldOid );
  104. SnmpUtilOidAppend( &VarBind->name, &MIB_SessionTable.Table[0].Oid );
  105. }
  106. //
  107. // Let fall through on purpose
  108. //
  109. case MIB_ACTION_GET:
  110. ErrStat = MIB_sess_get( VarBind );
  111. break;
  112. case MIB_ACTION_GETNEXT:
  113. // Fill the Session table with the info from server
  114. if ( SNMPAPI_ERROR == MIB_sess_lmget() )
  115. {
  116. ErrStat = SNMP_ERRORSTATUS_GENERR;
  117. goto Exit;
  118. }
  119. // Determine which field
  120. Field = VarBind->name.ids[SESS_FIELD_SUBID];
  121. // Lookup OID in table
  122. if (Field < SESS_FIRST_FIELD)
  123. {
  124. Entry = 0; // will take the first entry into the table
  125. Field = SESS_FIRST_FIELD; // and the first column of the table
  126. Found = MIB_TBL_POS_BEFORE;
  127. }
  128. else if (Field > SESS_LAST_FIELD)
  129. Found = MIB_TBL_POS_END;
  130. else
  131. Found = MIB_sess_match( &VarBind->name, &Entry, TRUE );
  132. // Index not found, but could be more fields to base GET on
  133. if ((Found == MIB_TBL_POS_BEFORE && MIB_SessionTable.Len == 0) ||
  134. Found == MIB_TBL_POS_END )
  135. {
  136. // Index not found in table, get next from field
  137. // Field ++;
  138. // Make sure not past last field
  139. // if ( Field > SESS_LAST_FIELD )
  140. // {
  141. // Get next VAR in MIB
  142. ErrStat = (*MibPtr->MibNext->MibFunc)( MIB_ACTION_GETFIRST,
  143. MibPtr->MibNext,
  144. VarBind );
  145. break;
  146. // }
  147. }
  148. // Get next TABLE entry
  149. if ( Found == MIB_TBL_POS_FOUND )
  150. {
  151. Entry ++;
  152. if ( Entry > MIB_SessionTable.Len-1 )
  153. {
  154. Entry = 0;
  155. Field ++;
  156. /* item not implemented. Skip */
  157. if (Field == SESS_NUMCONS_FIELD) {
  158. Field++;
  159. }
  160. if ( Field > SESS_LAST_FIELD )
  161. {
  162. // Get next VAR in MIB
  163. ErrStat = (*MibPtr->MibNext->MibFunc)( MIB_ACTION_GETFIRST,
  164. MibPtr->MibNext,
  165. VarBind );
  166. break;
  167. }
  168. }
  169. }
  170. //
  171. // Place correct OID in VarBind
  172. // Assuming the first field in the first record is the "start"
  173. {
  174. UINT temp_subs[1];
  175. AsnObjectIdentifier FieldOid;
  176. temp_subs[0] = Field;
  177. FieldOid.idLength = 1;
  178. FieldOid.ids = temp_subs;
  179. SnmpUtilOidFree( &VarBind->name );
  180. SnmpUtilOidCpy( &VarBind->name, &MIB_OidPrefix );
  181. SnmpUtilOidAppend( &VarBind->name, &MIB_SessPrefix );
  182. SnmpUtilOidAppend( &VarBind->name, &FieldOid );
  183. SnmpUtilOidAppend( &VarBind->name, &MIB_SessionTable.Table[Entry].Oid );
  184. }
  185. ErrStat = MIB_sess_copyfromtable( Entry, Field, VarBind );
  186. break;
  187. case MIB_ACTION_SET:
  188. // Make sure OID is long enough
  189. if ( SESS_FIELD_SUBID + 1 > VarBind->name.idLength )
  190. {
  191. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  192. goto Exit;
  193. }
  194. // Get field number
  195. Field = VarBind->name.ids[SESS_FIELD_SUBID];
  196. // If the field being set is not the STATE field, error
  197. if ( Field != SESS_STATE_FIELD )
  198. {
  199. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  200. goto Exit;
  201. }
  202. // Check for proper type before setting
  203. if ( ASN_INTEGER != VarBind->value.asnType )
  204. {
  205. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  206. goto Exit;
  207. }
  208. // Make sure that the value is valid
  209. if ( VarBind->value.asnValue.number < SESS_STATE_ACTIVE &&
  210. VarBind->value.asnValue.number > SESS_STATE_DELETED )
  211. {
  212. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  213. goto Exit;
  214. }
  215. ErrStat = MIB_sess_lmset( &VarBind->name, Field, &VarBind->value );
  216. break;
  217. default:
  218. ErrStat = SNMP_ERRORSTATUS_GENERR;
  219. }
  220. Exit:
  221. return ErrStat;
  222. } // MIB_sess_func
  223. //
  224. // MIB_sess_get
  225. // Retrieve session table information.
  226. //
  227. // Notes:
  228. //
  229. // Return Codes:
  230. // None.
  231. //
  232. // Error Codes:
  233. // None.
  234. //
  235. UINT MIB_sess_get(
  236. IN OUT RFC1157VarBind *VarBind
  237. )
  238. {
  239. UINT Entry;
  240. int Found;
  241. UINT ErrStat;
  242. if (VarBind->name.ids[SESS_FIELD_SUBID] < SESS_FIRST_FIELD ||
  243. VarBind->name.ids[SESS_FIELD_SUBID] > SESS_LAST_FIELD)
  244. {
  245. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  246. goto Exit;
  247. }
  248. // Fill the Session table with the info from server
  249. if ( SNMPAPI_ERROR == MIB_sess_lmget() )
  250. {
  251. ErrStat = SNMP_ERRORSTATUS_GENERR;
  252. goto Exit;
  253. }
  254. Found = MIB_sess_match( &VarBind->name, &Entry, FALSE );
  255. // Look for a complete OID match
  256. if ( Found != MIB_TBL_POS_FOUND )
  257. {
  258. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  259. goto Exit;
  260. }
  261. if ( VarBind->name.ids[SESS_FIELD_SUBID] == SESS_NUMCONS_FIELD )
  262. {
  263. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  264. goto Exit;
  265. }
  266. // Copy data from table
  267. ErrStat = MIB_sess_copyfromtable( Entry, VarBind->name.ids[SESS_FIELD_SUBID],
  268. VarBind );
  269. Exit:
  270. return ErrStat;
  271. } // MIB_sess_get
  272. //
  273. // MIB_sess_match
  274. // Match the target OID with a location in the Session table
  275. //
  276. // Notes:
  277. //
  278. // Return Codes:
  279. // None.
  280. //
  281. // Error Codes:
  282. // None
  283. //
  284. int MIB_sess_match(
  285. IN AsnObjectIdentifier *Oid,
  286. OUT UINT *Pos,
  287. IN BOOL Next
  288. )
  289. {
  290. AsnObjectIdentifier TempOid;
  291. int nResult;
  292. // Remove prefix including field reference
  293. TempOid.idLength = Oid->idLength - MIB_OidPrefix.idLength -
  294. MIB_SessPrefix.idLength - 1;
  295. TempOid.ids = &Oid->ids[MIB_OidPrefix.idLength+MIB_SessPrefix.idLength+1];
  296. *Pos = 0;
  297. while ( *Pos < MIB_SessionTable.Len )
  298. {
  299. nResult = SnmpUtilOidCmp( &TempOid, &MIB_SessionTable.Table[*Pos].Oid );
  300. if ( !nResult )
  301. {
  302. nResult = MIB_TBL_POS_FOUND;
  303. if (Next) {
  304. while ( ( (*Pos) + 1 < MIB_SessionTable.Len ) &&
  305. !SnmpUtilOidCmp( &TempOid, &MIB_SessionTable.Table[(*Pos)+1].Oid)) {
  306. (*Pos)++;
  307. }
  308. }
  309. goto Exit;
  310. }
  311. if ( nResult < 0 )
  312. {
  313. nResult = MIB_TBL_POS_BEFORE;
  314. goto Exit;
  315. }
  316. (*Pos)++;
  317. }
  318. nResult = MIB_TBL_POS_END;
  319. Exit:
  320. return nResult;
  321. }
  322. //
  323. // MIB_sess_copyfromtable
  324. // Copy requested data from table structure into Var Bind.
  325. //
  326. // Notes:
  327. //
  328. // Return Codes:
  329. // None.
  330. //
  331. // Error Codes:
  332. // None.
  333. //
  334. UINT MIB_sess_copyfromtable(
  335. IN UINT Entry,
  336. IN UINT Field,
  337. OUT RFC1157VarBind *VarBind
  338. )
  339. {
  340. UINT ErrStat;
  341. // Get the requested field and save in var bind
  342. switch( Field )
  343. {
  344. case SESS_CLIENT_FIELD:
  345. // Alloc space for string
  346. VarBind->value.asnValue.string.stream = SnmpUtilMemAlloc( sizeof(char)
  347. * MIB_SessionTable.Table[Entry].svSesClientName.length );
  348. if ( VarBind->value.asnValue.string.stream == NULL )
  349. {
  350. ErrStat = SNMP_ERRORSTATUS_GENERR;
  351. goto Exit;
  352. }
  353. // Copy string into return position
  354. memcpy( VarBind->value.asnValue.string.stream,
  355. MIB_SessionTable.Table[Entry].svSesClientName.stream,
  356. MIB_SessionTable.Table[Entry].svSesClientName.length );
  357. // Set string length
  358. VarBind->value.asnValue.string.length =
  359. MIB_SessionTable.Table[Entry].svSesClientName.length;
  360. VarBind->value.asnValue.string.dynamic = TRUE;
  361. // Set type of var bind
  362. VarBind->value.asnType = ASN_RFC1213_DISPSTRING;
  363. break;
  364. case SESS_USER_FIELD:
  365. // Alloc space for string
  366. VarBind->value.asnValue.string.stream = SnmpUtilMemAlloc( sizeof(char)
  367. * MIB_SessionTable.Table[Entry].svSesUserName.length );
  368. if ( VarBind->value.asnValue.string.stream == NULL )
  369. {
  370. ErrStat = SNMP_ERRORSTATUS_GENERR;
  371. goto Exit;
  372. }
  373. // Copy string into return position
  374. memcpy( VarBind->value.asnValue.string.stream,
  375. MIB_SessionTable.Table[Entry].svSesUserName.stream,
  376. MIB_SessionTable.Table[Entry].svSesUserName.length );
  377. // Set string length
  378. VarBind->value.asnValue.string.length =
  379. MIB_SessionTable.Table[Entry].svSesUserName.length;
  380. VarBind->value.asnValue.string.dynamic = TRUE;
  381. // Set type of var bind
  382. VarBind->value.asnType = ASN_RFC1213_DISPSTRING;
  383. break;
  384. case SESS_NUMCONS_FIELD:
  385. VarBind->value.asnValue.number =
  386. MIB_SessionTable.Table[Entry].svSesNumConns;
  387. VarBind->value.asnType = ASN_INTEGER;
  388. break;
  389. case SESS_NUMOPENS_FIELD:
  390. VarBind->value.asnValue.number =
  391. MIB_SessionTable.Table[Entry].svSesNumOpens;
  392. VarBind->value.asnType = ASN_INTEGER;
  393. break;
  394. case SESS_TIME_FIELD:
  395. VarBind->value.asnValue.number =
  396. MIB_SessionTable.Table[Entry].svSesTime;
  397. VarBind->value.asnType = ASN_RFC1155_COUNTER;
  398. break;
  399. case SESS_IDLETIME_FIELD:
  400. VarBind->value.asnValue.number =
  401. MIB_SessionTable.Table[Entry].svSesIdleTime;
  402. VarBind->value.asnType = ASN_RFC1155_COUNTER;
  403. break;
  404. case SESS_CLIENTTYPE_FIELD:
  405. VarBind->value.asnValue.number =
  406. MIB_SessionTable.Table[Entry].svSesClientType;
  407. VarBind->value.asnType = ASN_INTEGER;
  408. break;
  409. case SESS_STATE_FIELD:
  410. VarBind->value.asnValue.number =
  411. MIB_SessionTable.Table[Entry].svSesState;
  412. VarBind->value.asnType = ASN_INTEGER;
  413. break;
  414. default:
  415. SNMPDBG(( SNMP_LOG_TRACE, "LMMIB2: Internal Error Session Table\n" ));
  416. ErrStat = SNMP_ERRORSTATUS_GENERR;
  417. goto Exit;
  418. }
  419. ErrStat = SNMP_ERRORSTATUS_NOERROR;
  420. Exit:
  421. return ErrStat;
  422. } // MIB_sess_copyfromtable
  423. //-------------------------------- END --------------------------------------