Leaked source code of windows server 2003
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.

588 lines
16 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. AsnObjectIdentifier tmpOid;
  101. tmpOid = VarBind->name; // keep a copy (structure copy)
  102. if (! SnmpUtilOidCpy( &VarBind->name, &MIB_OidPrefix ))
  103. {
  104. VarBind->name = tmpOid; // restore
  105. ErrStat = SNMP_ERRORSTATUS_RESOURCEUNAVAILABLE;
  106. goto Exit;
  107. }
  108. if (! SnmpUtilOidAppend( &VarBind->name, &MIB_SessPrefix ))
  109. {
  110. SnmpUtilOidFree(&VarBind->name);
  111. VarBind->name = tmpOid; // restore
  112. ErrStat = SNMP_ERRORSTATUS_RESOURCEUNAVAILABLE;
  113. goto Exit;
  114. }
  115. if (! SnmpUtilOidAppend( &VarBind->name, &FieldOid ))
  116. {
  117. SnmpUtilOidFree(&VarBind->name);
  118. VarBind->name = tmpOid; // restore
  119. ErrStat = SNMP_ERRORSTATUS_RESOURCEUNAVAILABLE;
  120. goto Exit;
  121. }
  122. if (! SnmpUtilOidAppend( &VarBind->name, &MIB_SessionTable.Table[0].Oid ))
  123. {
  124. SnmpUtilOidFree(&VarBind->name);
  125. VarBind->name = tmpOid; // restore
  126. ErrStat = SNMP_ERRORSTATUS_RESOURCEUNAVAILABLE;
  127. goto Exit;
  128. }
  129. // free the original VarBind->name
  130. SnmpUtilOidFree(&tmpOid);
  131. }
  132. //
  133. // Let fall through on purpose
  134. //
  135. case MIB_ACTION_GET:
  136. ErrStat = MIB_sess_get( VarBind );
  137. break;
  138. case MIB_ACTION_GETNEXT:
  139. // Fill the Session table with the info from server
  140. if ( SNMPAPI_ERROR == MIB_sess_lmget() )
  141. {
  142. ErrStat = SNMP_ERRORSTATUS_GENERR;
  143. goto Exit;
  144. }
  145. // Determine which field
  146. Field = VarBind->name.ids[SESS_FIELD_SUBID];
  147. // Lookup OID in table
  148. if (Field < SESS_FIRST_FIELD)
  149. {
  150. Entry = 0; // will take the first entry into the table
  151. Field = SESS_FIRST_FIELD; // and the first column of the table
  152. Found = MIB_TBL_POS_BEFORE;
  153. }
  154. else if (Field > SESS_LAST_FIELD)
  155. Found = MIB_TBL_POS_END;
  156. else
  157. Found = MIB_sess_match( &VarBind->name, &Entry, TRUE );
  158. // Index not found, but could be more fields to base GET on
  159. if ((Found == MIB_TBL_POS_BEFORE && MIB_SessionTable.Len == 0) ||
  160. Found == MIB_TBL_POS_END )
  161. {
  162. // Index not found in table, get next from field
  163. // Field ++;
  164. // Make sure not past last field
  165. // if ( Field > SESS_LAST_FIELD )
  166. // {
  167. // Get next VAR in MIB
  168. ErrStat = (*MibPtr->MibNext->MibFunc)( MIB_ACTION_GETFIRST,
  169. MibPtr->MibNext,
  170. VarBind );
  171. break;
  172. // }
  173. }
  174. // Get next TABLE entry
  175. if ( Found == MIB_TBL_POS_FOUND )
  176. {
  177. Entry ++;
  178. if ( Entry > MIB_SessionTable.Len-1 )
  179. {
  180. Entry = 0;
  181. Field ++;
  182. /* item not implemented. Skip */
  183. if (Field == SESS_NUMCONS_FIELD) {
  184. Field++;
  185. }
  186. if ( Field > SESS_LAST_FIELD )
  187. {
  188. // Get next VAR in MIB
  189. ErrStat = (*MibPtr->MibNext->MibFunc)( MIB_ACTION_GETFIRST,
  190. MibPtr->MibNext,
  191. VarBind );
  192. break;
  193. }
  194. }
  195. }
  196. //
  197. // Place correct OID in VarBind
  198. // Assuming the first field in the first record is the "start"
  199. {
  200. UINT temp_subs[1];
  201. AsnObjectIdentifier FieldOid;
  202. AsnObjectIdentifier tmpOid;
  203. temp_subs[0] = Field;
  204. FieldOid.idLength = 1;
  205. FieldOid.ids = temp_subs;
  206. tmpOid = VarBind->name; // keep a copy (structure copy)
  207. if (! SnmpUtilOidCpy( &VarBind->name, &MIB_OidPrefix ))
  208. {
  209. VarBind->name = tmpOid; // restore
  210. ErrStat = SNMP_ERRORSTATUS_RESOURCEUNAVAILABLE;
  211. goto Exit;
  212. }
  213. if (! SnmpUtilOidAppend( &VarBind->name, &MIB_SessPrefix ))
  214. {
  215. SnmpUtilOidFree(&VarBind->name);
  216. VarBind->name = tmpOid; // restore
  217. ErrStat = SNMP_ERRORSTATUS_RESOURCEUNAVAILABLE;
  218. goto Exit;
  219. }
  220. if (! SnmpUtilOidAppend( &VarBind->name, &FieldOid ))
  221. {
  222. SnmpUtilOidFree(&VarBind->name);
  223. VarBind->name = tmpOid; // restore
  224. ErrStat = SNMP_ERRORSTATUS_RESOURCEUNAVAILABLE;
  225. goto Exit;
  226. }
  227. if (! SnmpUtilOidAppend( &VarBind->name, &MIB_SessionTable.Table[Entry].Oid ))
  228. {
  229. SnmpUtilOidFree(&VarBind->name);
  230. VarBind->name = tmpOid; // restore
  231. ErrStat = SNMP_ERRORSTATUS_RESOURCEUNAVAILABLE;
  232. goto Exit;
  233. }
  234. // free the original VarBind->name
  235. SnmpUtilOidFree(&tmpOid);
  236. }
  237. ErrStat = MIB_sess_copyfromtable( Entry, Field, VarBind );
  238. break;
  239. case MIB_ACTION_SET:
  240. // Make sure OID is long enough
  241. if ( SESS_FIELD_SUBID + 1 > VarBind->name.idLength )
  242. {
  243. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  244. goto Exit;
  245. }
  246. // Get field number
  247. Field = VarBind->name.ids[SESS_FIELD_SUBID];
  248. // If the field being set is not the STATE field, error
  249. if ( Field != SESS_STATE_FIELD )
  250. {
  251. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  252. goto Exit;
  253. }
  254. // Check for proper type before setting
  255. if ( ASN_INTEGER != VarBind->value.asnType )
  256. {
  257. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  258. goto Exit;
  259. }
  260. // Make sure that the value is valid
  261. if ( VarBind->value.asnValue.number < SESS_STATE_ACTIVE &&
  262. VarBind->value.asnValue.number > SESS_STATE_DELETED )
  263. {
  264. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  265. goto Exit;
  266. }
  267. ErrStat = MIB_sess_lmset( &VarBind->name, Field, &VarBind->value );
  268. break;
  269. default:
  270. ErrStat = SNMP_ERRORSTATUS_GENERR;
  271. }
  272. Exit:
  273. return ErrStat;
  274. } // MIB_sess_func
  275. //
  276. // MIB_sess_get
  277. // Retrieve session table information.
  278. //
  279. // Notes:
  280. //
  281. // Return Codes:
  282. // None.
  283. //
  284. // Error Codes:
  285. // None.
  286. //
  287. UINT MIB_sess_get(
  288. IN OUT RFC1157VarBind *VarBind
  289. )
  290. {
  291. UINT Entry;
  292. int Found;
  293. UINT ErrStat;
  294. if (VarBind->name.ids[SESS_FIELD_SUBID] < SESS_FIRST_FIELD ||
  295. VarBind->name.ids[SESS_FIELD_SUBID] > SESS_LAST_FIELD)
  296. {
  297. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  298. goto Exit;
  299. }
  300. // Fill the Session table with the info from server
  301. if ( SNMPAPI_ERROR == MIB_sess_lmget() )
  302. {
  303. ErrStat = SNMP_ERRORSTATUS_GENERR;
  304. goto Exit;
  305. }
  306. Found = MIB_sess_match( &VarBind->name, &Entry, FALSE );
  307. // Look for a complete OID match
  308. if ( Found != MIB_TBL_POS_FOUND )
  309. {
  310. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  311. goto Exit;
  312. }
  313. if ( VarBind->name.ids[SESS_FIELD_SUBID] == SESS_NUMCONS_FIELD )
  314. {
  315. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  316. goto Exit;
  317. }
  318. // Copy data from table
  319. ErrStat = MIB_sess_copyfromtable( Entry, VarBind->name.ids[SESS_FIELD_SUBID],
  320. VarBind );
  321. Exit:
  322. return ErrStat;
  323. } // MIB_sess_get
  324. //
  325. // MIB_sess_match
  326. // Match the target OID with a location in the Session table
  327. //
  328. // Notes:
  329. //
  330. // Return Codes:
  331. // None.
  332. //
  333. // Error Codes:
  334. // None
  335. //
  336. int MIB_sess_match(
  337. IN AsnObjectIdentifier *Oid,
  338. OUT UINT *Pos,
  339. IN BOOL Next
  340. )
  341. {
  342. AsnObjectIdentifier TempOid;
  343. int nResult;
  344. // Remove prefix including field reference
  345. TempOid.idLength = Oid->idLength - MIB_OidPrefix.idLength -
  346. MIB_SessPrefix.idLength - 1;
  347. TempOid.ids = &Oid->ids[MIB_OidPrefix.idLength+MIB_SessPrefix.idLength+1];
  348. *Pos = 0;
  349. while ( *Pos < MIB_SessionTable.Len )
  350. {
  351. nResult = SnmpUtilOidCmp( &TempOid, &MIB_SessionTable.Table[*Pos].Oid );
  352. if ( !nResult )
  353. {
  354. nResult = MIB_TBL_POS_FOUND;
  355. if (Next) {
  356. while ( ( (*Pos) + 1 < MIB_SessionTable.Len ) &&
  357. !SnmpUtilOidCmp( &TempOid, &MIB_SessionTable.Table[(*Pos)+1].Oid)) {
  358. (*Pos)++;
  359. }
  360. }
  361. goto Exit;
  362. }
  363. if ( nResult < 0 )
  364. {
  365. nResult = MIB_TBL_POS_BEFORE;
  366. goto Exit;
  367. }
  368. (*Pos)++;
  369. }
  370. nResult = MIB_TBL_POS_END;
  371. Exit:
  372. return nResult;
  373. }
  374. //
  375. // MIB_sess_copyfromtable
  376. // Copy requested data from table structure into Var Bind.
  377. //
  378. // Notes:
  379. //
  380. // Return Codes:
  381. // None.
  382. //
  383. // Error Codes:
  384. // None.
  385. //
  386. UINT MIB_sess_copyfromtable(
  387. IN UINT Entry,
  388. IN UINT Field,
  389. OUT RFC1157VarBind *VarBind
  390. )
  391. {
  392. UINT ErrStat;
  393. // Get the requested field and save in var bind
  394. switch( Field )
  395. {
  396. case SESS_CLIENT_FIELD:
  397. // Alloc space for string
  398. VarBind->value.asnValue.string.stream = SnmpUtilMemAlloc( sizeof(char)
  399. * MIB_SessionTable.Table[Entry].svSesClientName.length );
  400. if ( VarBind->value.asnValue.string.stream == NULL )
  401. {
  402. ErrStat = SNMP_ERRORSTATUS_GENERR;
  403. goto Exit;
  404. }
  405. // Copy string into return position
  406. memcpy( VarBind->value.asnValue.string.stream,
  407. MIB_SessionTable.Table[Entry].svSesClientName.stream,
  408. MIB_SessionTable.Table[Entry].svSesClientName.length );
  409. // Set string length
  410. VarBind->value.asnValue.string.length =
  411. MIB_SessionTable.Table[Entry].svSesClientName.length;
  412. VarBind->value.asnValue.string.dynamic = TRUE;
  413. // Set type of var bind
  414. VarBind->value.asnType = ASN_RFC1213_DISPSTRING;
  415. break;
  416. case SESS_USER_FIELD:
  417. // Alloc space for string
  418. VarBind->value.asnValue.string.stream = SnmpUtilMemAlloc( sizeof(char)
  419. * MIB_SessionTable.Table[Entry].svSesUserName.length );
  420. if ( VarBind->value.asnValue.string.stream == NULL )
  421. {
  422. ErrStat = SNMP_ERRORSTATUS_GENERR;
  423. goto Exit;
  424. }
  425. // Copy string into return position
  426. memcpy( VarBind->value.asnValue.string.stream,
  427. MIB_SessionTable.Table[Entry].svSesUserName.stream,
  428. MIB_SessionTable.Table[Entry].svSesUserName.length );
  429. // Set string length
  430. VarBind->value.asnValue.string.length =
  431. MIB_SessionTable.Table[Entry].svSesUserName.length;
  432. VarBind->value.asnValue.string.dynamic = TRUE;
  433. // Set type of var bind
  434. VarBind->value.asnType = ASN_RFC1213_DISPSTRING;
  435. break;
  436. case SESS_NUMCONS_FIELD:
  437. VarBind->value.asnValue.number =
  438. MIB_SessionTable.Table[Entry].svSesNumConns;
  439. VarBind->value.asnType = ASN_INTEGER;
  440. break;
  441. case SESS_NUMOPENS_FIELD:
  442. VarBind->value.asnValue.number =
  443. MIB_SessionTable.Table[Entry].svSesNumOpens;
  444. VarBind->value.asnType = ASN_INTEGER;
  445. break;
  446. case SESS_TIME_FIELD:
  447. VarBind->value.asnValue.number =
  448. MIB_SessionTable.Table[Entry].svSesTime;
  449. VarBind->value.asnType = ASN_RFC1155_COUNTER;
  450. break;
  451. case SESS_IDLETIME_FIELD:
  452. VarBind->value.asnValue.number =
  453. MIB_SessionTable.Table[Entry].svSesIdleTime;
  454. VarBind->value.asnType = ASN_RFC1155_COUNTER;
  455. break;
  456. case SESS_CLIENTTYPE_FIELD:
  457. VarBind->value.asnValue.number =
  458. MIB_SessionTable.Table[Entry].svSesClientType;
  459. VarBind->value.asnType = ASN_INTEGER;
  460. break;
  461. case SESS_STATE_FIELD:
  462. VarBind->value.asnValue.number =
  463. MIB_SessionTable.Table[Entry].svSesState;
  464. VarBind->value.asnType = ASN_INTEGER;
  465. break;
  466. default:
  467. SNMPDBG(( SNMP_LOG_TRACE, "LMMIB2: Internal Error Session Table\n" ));
  468. ErrStat = SNMP_ERRORSTATUS_GENERR;
  469. goto Exit;
  470. }
  471. ErrStat = SNMP_ERRORSTATUS_NOERROR;
  472. Exit:
  473. return ErrStat;
  474. } // MIB_sess_copyfromtable
  475. //-------------------------------- END --------------------------------------