00001
00002
00003
00004
00005
00006 #include "nm.h"
00007 #include "evl.h"
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 static void registerTclCommands (Tcl_Interp * interp, Nm_TclCD_t * cd);
00020 static int tclEvlMgrPrintRules (ClientData cd, Tcl_Interp * interp,
00021 int objc, Tcl_Obj * const objv[]);
00022 static int tclEvlMgrRegisterUcode (ClientData cd, Tcl_Interp * interp,
00023 int objc, Tcl_Obj * const objv[]);
00024 static int tclEvlRoute (ClientData cd, Tcl_Interp * interp, int objc,
00025 Tcl_Obj * const objv[]);
00026 static int tclEvlBuildManagerFromText (ClientData cd , Tcl_Interp * interp,
00027 int objc, Tcl_Obj * const objv[]);
00028 static int tclEvlBuildManagerFromFile (ClientData cd , Tcl_Interp * interp,
00029 int objc, Tcl_Obj * const objv[]);
00030 static int tclStopProfiler (ClientData cd , Tcl_Interp * interp, int objc,
00031 Tcl_Obj * const objv[]);
00032 static int tclCreatePktFromText (ClientData cd , Tcl_Interp * interp,
00033 int objc, Tcl_Obj * const objv[]);
00034 static int tclCreatePktArrayFromText (ClientData cd , Tcl_Interp * interp,
00035 int objc, Tcl_Obj * const objv[]);
00036 static int tclEvlDoTclActions (ClientData cd , Tcl_Interp * interp,
00037 int objc, Tcl_Obj * const objv[]);
00038 static int tclEvlComputeRuleSetForEth (ClientData cd, Tcl_Interp * interp,
00039 int objc, Tcl_Obj * const objv[]);
00040 static int tclEvlComputeRuleSetForEthSTRING (ClientData cd ,
00041 Tcl_Interp * interp, int objc,
00042 Tcl_Obj * const objv[]);
00043 static char *computeStringFromIpAddress (u_int32_t aNumIp);
00044 static int pktReadIpInfo (ClientData cd , Tcl_Interp * interp, int objc,
00045 Tcl_Obj * const objv[]);
00046 static int pktReadIpFlags (ClientData cd , Tcl_Interp * interp, int objc,
00047 Tcl_Obj * const objv[]);
00048 static int pktReadTcpFlags (ClientData cd , Tcl_Interp * interp, int objc,
00049 Tcl_Obj * const objv[]);
00050 static int tclTestC (ClientData cd , Tcl_Interp * interp, int objc,
00051 Tcl_Obj * const objv[]);
00052 static int tclTestTk (ClientData cd , Tcl_Interp * interp, int objc,
00053 Tcl_Obj * const objv[]);
00054
00055
00056 static int tclTestParser (ClientData cd , Tcl_Interp * interp, int objc,
00057 Tcl_Obj * const objv[]);
00058 static int tclGetFileAsText (ClientData cd , Tcl_Interp * interp, int objc,
00059 Tcl_Obj * const objv[]);
00060 static int tclBufferWritePkts (ClientData cd , Tcl_Interp * interp,
00061 int objc , Tcl_Obj * const objv[]);
00062 static int tclWritePkts (ClientData cd , Tcl_Interp * interp, int objc ,
00063 Tcl_Obj * const objv[]);
00064 static int tclTxPkt (ClientData cd , Tcl_Interp * interp, int objc ,
00065 Tcl_Obj * const objv[]);
00066 static int tclInjectPkts (ClientData cd , Tcl_Interp * interp,
00067 int objc , Tcl_Obj * const objv[]);
00068 static Pkt_TfcMode_t *readTfcModeParams (Tcl_Interp * interp);
00069 static int tclTestTclAction (ClientData cd , Tcl_Interp * interp,
00070 int objc , Tcl_Obj * const objv[]);
00071 static int tclStTestPerf (ClientData cd , Tcl_Interp * interp, int objc ,
00072 Tcl_Obj * const objv[]);
00073 static int tclStTest (ClientData cd , Tcl_Interp * interp, int objc ,
00074 Tcl_Obj * const objv[]);
00075 static int tclCompressTestPerf (ClientData cd , Tcl_Interp * interp,
00076 int objc , Tcl_Obj * const objv[]);
00077 static int tclCompressTestReduction (ClientData cd , Tcl_Interp * interp,
00078 int objc , Tcl_Obj * const objv[]);
00079 static int tclArrayTest (ClientData cd , Tcl_Interp * interp, int objc ,
00080 Tcl_Obj * const objv[]);
00081 static int tclEvlMgrInsertPktIntoInputBuffer (ClientData cd ,
00082 Tcl_Interp * interp,
00083 int objc ,
00084 Tcl_Obj * const objv[]);
00085 static double computeRate (int size, int numPackets, util_timing_t diffTime);
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 static st_table *tclToC = NIL (st_table);
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 int
00113 Nm_Tcl (Tcl_Interp * interp, Nm_TclCD_t * cd)
00114 {
00115 registerTclCommands (interp, cd);
00116
00117
00118 sourceTclrc (interp);
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 return TCL_OK;
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156 int
00157 sourceTclrc (Tcl_Interp * interp)
00158 {
00159 return Tcl_EvalFile (interp, ".tclrc");
00160 }
00161
00162
00163
00164
00165
00166
00167 static void
00168 registerTclCommands (Tcl_Interp * interp, Nm_TclCD_t * cd)
00169 {
00170 tclToC = Hash_InitTable ( ( int(*)() ) strcmp, ( int(*)() ) st_strhash);
00171 array_t *cmdNames = array_alloc (char *, 0);
00172 array_t *cmdFunctions = array_alloc (Tcl_ObjCmdProc *, 0);
00173
00174 array_insert_last (char *, cmdNames, "testact");
00175 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclTestTclAction);
00176
00177 array_insert_last (char *, cmdNames, "test_tk");
00178 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclTestTk );
00179
00180 array_insert_last (char *, cmdNames, "testC1");
00181 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclTestC );
00182
00183 array_insert_last (char *, cmdNames, "testC2");
00184 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclTestC );
00185
00186 array_insert_last (char *, cmdNames, "testC3");
00187 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclTestC );
00188
00189 array_insert_last (char *, cmdNames, "testParser");
00190 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclTestParser );
00191
00192 array_insert_last (char *, cmdNames, "getFileAsText");
00193 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclGetFileAsText );
00194
00195 array_insert_last (char *, cmdNames, "evlRoute");
00196 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclEvlRoute );
00197
00198 array_insert_last (char *, cmdNames, "evlBuildManagerFromText");
00199 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions,
00200 tclEvlBuildManagerFromText);
00201
00202 array_insert_last (char *, cmdNames, "testEvlBuildManagerFromFile");
00203 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions,
00204 tclEvlBuildManagerFromFile);
00205
00206 array_insert_last (char *, cmdNames, "evlBuildManagerFromFile");
00207 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions,
00208 tclEvlBuildManagerFromFile);
00209
00210 array_insert_last (char *, cmdNames, "evlComputeRuleSetForEth");
00211 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions,
00212 tclEvlComputeRuleSetForEth);
00213
00214 array_insert_last (char *, cmdNames, "evlComputeRuleSetForEthSTRING");
00215 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions,
00216 tclEvlComputeRuleSetForEthSTRING);
00217
00218 array_insert_last (char *, cmdNames, "createPktFromText");
00219 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclCreatePktFromText);
00220
00221 array_insert_last (char *, cmdNames, "createPktArrayFromText");
00222 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions,
00223 tclCreatePktArrayFromText);
00224
00225 array_insert_last (char *, cmdNames, "evlDoTclActions");
00226 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclEvlDoTclActions);
00227
00228 array_insert_last (char *, cmdNames, "pktReadSrcIp");
00229 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, pktReadIpInfo);
00230
00231 array_insert_last (char *, cmdNames, "pktReadContent");
00232 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, pktReadIpInfo);
00233
00234 array_insert_last (char *, cmdNames, "pktReadDestIp");
00235 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, pktReadIpInfo);
00236
00237 array_insert_last (char *, cmdNames, "pktReadTtl");
00238 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, pktReadIpInfo);
00239
00240 array_insert_last (char *, cmdNames, "pktReadOffset");
00241 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, pktReadIpInfo);
00242
00243 array_insert_last (char *, cmdNames, "pktReadLength");
00244 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, pktReadIpInfo);
00245
00246 array_insert_last (char *, cmdNames, "pktReadIpFlags");
00247 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, pktReadIpFlags);
00248
00249 array_insert_last (char *, cmdNames, "pktReadTcpDestPort");
00250 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, pktReadTcpInfo);
00251
00252 array_insert_last (char *, cmdNames, "pktReadTcpSrcPort");
00253 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, pktReadTcpInfo);
00254
00255 array_insert_last (char *, cmdNames, "pktReadTcpSeqNum");
00256 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, pktReadTcpInfo);
00257
00258 array_insert_last (char *, cmdNames, "pktReadTcpAckNum");
00259 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, pktReadTcpInfo);
00260
00261 array_insert_last (char *, cmdNames, "pktReadTcpFlags");
00262 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, pktReadTcpFlags);
00263
00264 array_insert_last (char *, cmdNames, "checkHardware");
00265 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, Perf_CheckHardware);
00266
00267 array_insert_last (char *, cmdNames, "timePerf");
00268 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, Perf_TimePerf);
00269
00270 array_insert_last (char *, cmdNames, "timePerf2");
00271 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, Perf_TimePerf2);
00272
00273 array_insert_last (char *, cmdNames, "spacePerf");
00274 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, Perf_SpacePerf);
00275
00276 array_insert_last (char *, cmdNames, "injectPkts");
00277 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclInjectPkts);
00278
00279 array_insert_last (char *, cmdNames, "txPkt");
00280 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclTxPkt);
00281
00282 array_insert_last (char *, cmdNames, "writePkts");
00283 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclWritePkts);
00284
00285 array_insert_last (char *, cmdNames, "bufferWritePkts");
00286 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclBufferWritePkts);
00287
00288 array_insert_last (char *, cmdNames, "timingCheck");
00289 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, Perf_CheckTimingCode);
00290
00291 array_insert_last (char *, cmdNames, "compTestPerf");
00292 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclCompressTestPerf);
00293
00294 array_insert_last (char *, cmdNames, "compTestReduction");
00295 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions,
00296 tclCompressTestReduction);
00297
00298 array_insert_last (char *, cmdNames, "evlMgrRegisterUcode");
00299 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclEvlMgrRegisterUcode);
00300
00301
00302 array_insert_last (char *, cmdNames, "register_c-ext");
00303 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclEvlMgrRegisterUcode);
00304
00305 array_insert_last (char *, cmdNames, "evlMgrPrintRules");
00306 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclEvlMgrPrintRules);
00307
00308 array_insert_last (char *, cmdNames, "evlMgrInsertPktIntoInputBuffer");
00309 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions,
00310 tclEvlMgrInsertPktIntoInputBuffer);
00311
00312 array_insert_last (char *, cmdNames, "array_test");
00313 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclArrayTest);
00314
00315 array_insert_last (char *, cmdNames, "st_test_perf");
00316 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclStTestPerf);
00317
00318 array_insert_last (char *, cmdNames, "st_test");
00319 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclStTest);
00320
00321 array_insert_last (char *, cmdNames, "stop_profiler");
00322 array_insert_last (Tcl_ObjCmdProc *, cmdFunctions, tclStopProfiler);
00323
00324
00325
00326
00327 int i;
00328 for (i = 0; i < array_n (cmdNames); i++)
00329 {
00330 char *cmdName = array_fetch (char *, cmdNames, i);
00331 Tcl_ObjCmdProc *cmdFunc =
00332 array_fetch (Tcl_ObjCmdProc *, cmdFunctions, i);
00333 Tcl_CreateObjCommand (interp, cmdName, cmdFunc, cd,
00334 NIL (Tcl_CmdDeleteProc));
00335 }
00336 }
00337
00338
00339
00340
00341
00342
00343
00344 static int
00345 tclEvlMgrPrintRules (ClientData cd,
00346 Tcl_Interp * interp,
00347 int objc, Tcl_Obj * const objv[])
00348 {
00349 assert (objc == 2);
00350
00351 Evl_Manager_t *mgr =
00352 (Evl_Manager_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, objv[1]);
00353
00354 int i;
00355 for ( i = 0 ; i < mgr->numAllRules; i++ ) {
00356 char *aRule = array_fetch( char *, mgr->rawRules, i );
00357 printf("Rule %d: %s\n", i, aRule );
00358 }
00359 return TCL_OK;
00360
00361 }
00362
00363
00364
00365
00366
00367
00368
00369 static int
00370 tclEvlMgrRegisterUcode (ClientData cd,
00371 Tcl_Interp * interp,
00372 int objc, Tcl_Obj * const objv[])
00373 {
00374 assert (objc == 4);
00375
00376 Evl_Manager_t *mgr =
00377 (Evl_Manager_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, objv[1]);
00378 char *ucodeName = strdup (objv[2]->bytes);
00379 char *ucodeLibrary = strdup (objv[3]->bytes);
00380
00381 Os_DynamicallyLinkFunction (mgr->ucodeNameToFunction, ucodeName,
00382 ucodeLibrary);
00383
00384 return TCL_OK;
00385
00386 }
00387
00388
00389
00390
00391
00392
00393 static int
00394 tclEvlRoute (ClientData cd,
00395 Tcl_Interp * interp, int objc, Tcl_Obj * const objv[])
00396 {
00397 int iBufSize = 2;
00398 Nm_TclGetIntVar (interp, "iBufSize", &iBufSize);
00399
00400 int ppCacheSize = 2;
00401 Nm_TclGetIntVar (interp, "ppCacheSize", &ppCacheSize);
00402
00403 int oBufSize = 2;
00404 Nm_TclGetIntVar (interp, "oBufSize", &oBufSize);
00405
00406 int actionBufSize = 2;
00407 Nm_TclGetIntVar (interp, "actionBufSize", &actionBufSize);
00408
00409 int numIterations = 1;
00410 Nm_TclGetIntVar (interp, "numIterations", &numIterations);
00411
00412 int maxNumPktsToRead = 1;
00413 Nm_TclGetIntVar (interp, "maxNumPktsToRead", &maxNumPktsToRead);
00414
00415 char *basicSliceString = "0.001";
00416 Nm_TclGetStringVar (interp, "basicSlice", &basicSliceString);
00417 double basicSlice;
00418 sscanf (basicSliceString, "%lf", &basicSlice);
00419
00420 int getPacketsWeight = 1;
00421 Nm_TclGetIntVar (interp, "getPacketsWeight", &getPacketsWeight);
00422
00423 int computeActionsWeight = 1;
00424 Nm_TclGetIntVar (interp, "computeActionsWeight", &computeActionsWeight);
00425
00426 int performActionsWeight = 1;
00427 Nm_TclGetIntVar (interp, "performActionsWeight", &performActionsWeight);
00428
00429 int queuingWeight = 1;
00430 Nm_TclGetIntVar (interp, "queuingWeight", &queuingWeight);
00431
00432 int writePacketsWeight = 1;
00433 Nm_TclGetIntVar (interp, "writePacketWeight", &writePacketsWeight);
00434
00435 int recordPktsWritten = 0;
00436 Nm_TclGetIntVar (interp, "recordPktsWritten", &recordPktsWritten);
00437
00438 int recordStats = 0;
00439 Nm_TclGetIntVar (interp, "recordStats", &recordStats);
00440 Evl_BridgeStats_t *stats;
00441 Evl_BridgeStats_t **statsPtr = NIL (Evl_BridgeStats_t *);
00442 if (recordStats)
00443 {
00444 statsPtr = &stats;
00445 }
00446
00447 assert (objc >= 2);
00448
00449 Evl_Manager_t *mgr =
00450 (Evl_Manager_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, objv[1]);
00451 array_t *pktArray = NIL (array_t);
00452 int useSynthetic = 0;
00453 array_t *ackSeqNumArray = NIL (array_t);
00454 if (objc == 3)
00455 {
00456
00457 pktArray = (array_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, objv[2]);
00458 useSynthetic = 1;
00459 if (recordPktsWritten)
00460 {
00461 ackSeqNumArray = array_alloc (Pkt_EthernetHdr_t *, 0);
00462 }
00463 }
00464
00465 array_t *inArray = array_alloc (char *, 0);
00466 array_t *outArray = array_alloc (char *, 0);
00467 if (!useSynthetic)
00468 {
00469 Nm_TclGetArrayVar (interp, "ineth", inArray);
00470 Nm_TclGetArrayVar (interp, "outeth", outArray);
00471 }
00472
00473
00474 Evl_Route (mgr, pktArray, iBufSize, ppCacheSize, oBufSize,
00475 actionBufSize, maxNumPktsToRead,
00476 numIterations, useSynthetic, inArray, outArray,
00477 basicSlice, getPacketsWeight, computeActionsWeight,
00478 performActionsWeight, queuingWeight, writePacketsWeight,
00479 ackSeqNumArray, statsPtr);
00480
00481 Tcl_Obj *resultObj = Tcl_NewStringObj ("", -1);
00482 if (statsPtr != NIL (Evl_BridgeStats_t *))
00483 {
00484 char statsString[1000];
00485 sprintf (statsString,
00486 "Start time\t\t= %f\n"
00487 "Finish time\t\t= %f\n"
00488 "Num entered\t\t= %d\n"
00489 "Num exited\t\t= %d\n"
00490 "Bytes written\t\t= %d\n"
00491 "Num Drop: FullRuleCacheArray\t= %d\n"
00492 "Num Drop: FullActionBuf\t\t= %d\n"
00493 "Num Drop: FullObuf\t\t= %d\n"
00494 "Num Drop: FullQueue\t\t= %d\n"
00495 "Num Drop: Action\t\t= %d\n"
00496 "Num Drop: OverRate\t\t= %d\n"
00497 "Num Drop: OverFlowRate\t\t= %d\n",
00498 util_timing_secs (stats->startTime),
00499 util_timing_secs (stats->finishTime),
00500 stats->numEntered,
00501 stats->numExited,
00502 stats->bytesWritten,
00503 stats->numDroppedFullRuleCacheArray,
00504 stats->numDroppedFullActionBuf,
00505 stats->numDroppedFullObuf,
00506 stats->numDroppedFullQueue,
00507 stats->numDroppedBecauseOfAction,
00508 stats->numDroppedOverRate, stats->numDroppedOverFlowRate);
00509
00510 char rateString[100];
00511 double delta =
00512 util_timing_secs (stats->lastPktWritten) -
00513 util_timing_secs (stats->firstPktRead);
00514 double rate = (8.0 * (double) stats->bytesWritten) / delta;
00515 sprintf (rateString, "%.1f", rate);
00516 char *memEffResult = strdup (rateString);
00517 Tcl_SetStringObj (resultObj, memEffResult, -1);
00518 }
00519 else if (ackSeqNumArray != NIL (array_t))
00520 {
00521
00522 char *seqTxt = (char *) malloc (1 + (array_n (ackSeqNumArray)) * 12);
00523 seqTxt[0] = '\0';
00524 char *tmp = seqTxt;
00525 int i;
00526 for (i = 0; i < array_n (ackSeqNumArray); i++)
00527 {
00528 Pkt_EthernetHdr_t *aPkt =
00529 array_fetch (Pkt_EthernetHdr_t *, ackSeqNumArray, i);
00530 if (Pkt_EthernetReadL3Type (aPkt) != Pkt_L3ProtIp_c)
00531 {
00532
00533 continue;
00534 }
00535 Pkt_TcpHdr_t *aTcpPkt = Pkt_EthernetExtractTcp (aPkt);
00536 sprintf (tmp, "%d%s",
00537 aTcpPkt->ackNum,
00538 ((i == (array_n (ackSeqNumArray) - 1)) ? "" : ","));
00539 tmp += strlen (tmp);
00540 }
00541 array_free (ackSeqNumArray);
00542 char *memEffResult = strdup (seqTxt);
00543 free (seqTxt);
00544 Tcl_SetStringObj (resultObj, memEffResult, -1);
00545 }
00546 else
00547 {
00548 Tcl_SetStringObj (resultObj, "", -1);
00549 }
00550 Tcl_SetObjResult (interp, resultObj);
00551
00552 return TCL_OK;
00553 }
00554
00555
00556
00557
00558
00559
00560 static int
00561 tclEvlBuildManagerFromText (ClientData cd ,
00562 Tcl_Interp * interp,
00563 int objc, Tcl_Obj * const objv[])
00564 {
00565 assert (objc == 2);
00566
00567 char *mgrText = Tcl_GetStringFromObj (objv[1], NIL (int));
00568 Evl_Manager_t *result = Evl_BuildManager (mgrText, interp, cd);
00569
00570 Nm_TclResult (interp, (Nm_TclCD_t *) cd, result);
00571
00572 return TCL_OK;
00573 }
00574
00575
00576
00577
00578
00579
00580 static int
00581 tclEvlBuildManagerFromFile (ClientData cd ,
00582 Tcl_Interp * interp,
00583 int objc, Tcl_Obj * const objv[])
00584 {
00585 assert (objc == 2);
00586
00587 char *fileName = Tcl_GetStringFromObj (objv[1], NIL (int));
00588 FILE *ruleFile = fopen (fileName, "r");
00589 if (ruleFile == NIL (FILE))
00590 {
00591 printf
00592 ("Error, could not open file %s, returning without building manager from file\n",
00593 fileName);
00594 return TCL_OK;
00595 }
00596 char *ruleFileInText = util_file_to_string (ruleFile);
00597 fclose (ruleFile);
00598
00599 Evl_Manager_t *result = Evl_BuildManager (ruleFileInText, interp, cd);
00600
00601 char *cmdName = Tcl_GetStringFromObj (objv[0], NIL (int));
00602 if (util_strequal (cmdName, "evlBuildManagerFromFile"))
00603 {
00604 Nm_TclResult (interp, cd, result);
00605 }
00606 else
00607 {
00608 assert (util_strequal (cmdName, "testEvlBuildManagerFromFile"));
00609 Tcl_Obj *resultObj = Tcl_GetObjResult (interp);
00610 Tcl_SetIntObj (resultObj, 0);
00611 }
00612
00613 return TCL_OK;
00614 }
00615
00616
00617
00618
00619
00620
00621 void
00622 Nm_TclResult (Tcl_Interp * interp, ClientData cd, void *ptr)
00623 {
00624 int resultId = Nm_TclCDStorePtr ((Nm_TclCD_t *) cd, ptr);
00625 Tcl_Obj *resultObj = Tcl_GetObjResult (interp);
00626 Tcl_SetIntObj (resultObj, resultId);
00627 }
00628
00629
00630
00631
00632
00633
00634 static int
00635 tclCreatePktFromText (ClientData cd ,
00636 Tcl_Interp * interp, int objc, Tcl_Obj * const objv[])
00637 {
00638 assert (objc == 2);
00639 char *pktText = Tcl_GetStringFromObj (objv[1], NIL (int));
00640 Pkt_EthernetHdr_t *result = Pkt_CreatePktFromString (pktText);
00641
00642 Nm_TclResult (interp, (Nm_TclCD_t *) cd, (void *) result);
00643
00644 return TCL_OK;
00645 }
00646
00647
00648
00649
00650
00651
00652 static int
00653 tclCreatePktArrayFromText (ClientData cd ,
00654 Tcl_Interp * interp,
00655 int objc, Tcl_Obj * const objv[])
00656 {
00657 assert (objc == 2);
00658
00659 array_t *result = array_alloc (Pkt_EthernetHdr_t *, 0);
00660
00661 int numPkts;
00662 Tcl_Obj **objArray;
00663 Tcl_ListObjGetElements (interp, objv[1], &numPkts, &objArray);
00664
00665 int i;
00666 for (i = 0; i < numPkts; i++)
00667 {
00668 Tcl_Obj *pktObj;
00669 int code = Tcl_ListObjIndex (interp, objv[1], i, &pktObj);
00670 char *pktText = Tcl_GetStringFromObj (pktObj, NIL (int));
00671 Pkt_EthernetHdr_t *pkt = Pkt_CreatePktFromString (pktText);
00672 array_insert_last (Pkt_EthernetHdr_t *, result, pkt);
00673 }
00674
00675 Nm_TclResult (interp, (Nm_TclCD_t *) cd, (void *) result);
00676
00677 return TCL_OK;
00678 }
00679
00680
00681
00682
00683
00684
00685
00686 static int
00687 tclEvlDoTclActions (ClientData cd ,
00688 Tcl_Interp * interp, int objc, Tcl_Obj * const objv[])
00689 {
00690 assert (objc == 4);
00691
00692 Evl_Manager_t *mgr =
00693 (Evl_Manager_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, objv[1]);
00694 array_t *applicableRules =
00695 (array_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, objv[2]);
00696 Pkt_EthernetHdr_t *pkt =
00697 (Pkt_EthernetHdr_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, objv[3]);
00698
00699 Tcl_Obj *listPtr = Tcl_NewListObj (0, (Tcl_Obj **) NULL);
00700
00701 char *tmp = (char *) malloc (2048 * mgr->numAllRules);
00702 tmp[0] = '\0';
00703 int i;
00704 for (i = 0; i < array_n (applicableRules); i++)
00705 {
00706 int ruleId = array_fetch (int, applicableRules, i);
00707 Rlp_Action_t *action =
00708 array_fetch (Rlp_Action_t *, mgr->actionArray, ruleId);
00709 if (action->type != Rlp_ActionUscript_c)
00710 {
00711 continue;
00712 }
00713 char *tclRuleString = action->uscript;
00714 sprintf (tmp, "%s", tclRuleString);
00715 Tcl_Obj *tmpObjv[2];
00716 Tcl_Obj *tmpPtr = Tcl_NewStringObj (strdup (tmp), -1);
00717 tmpObjv[0] = tmpPtr;
00718 int resultId = Nm_TclCDStorePtr ((Nm_TclCD_t *) cd, pkt);
00719 tmpObjv[1] = Tcl_NewIntObj (resultId);
00720 Tcl_EvalObjv (interp, 2, tmpObjv, 0);
00721 Tcl_ListObjAppendElement (interp, listPtr, tmpPtr);
00722 }
00723 array_free (applicableRules);
00724
00725 Tcl_SetObjResult (interp, listPtr);
00726
00727 return TCL_OK;
00728 }
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738 static int
00739 tclEvlComputeRuleSetForEth (ClientData cd,
00740 Tcl_Interp * interp,
00741 int objc, Tcl_Obj * const objv[])
00742 {
00743 assert (objc == 3);
00744
00745 Evl_Manager_t *mgr =
00746 (Evl_Manager_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, objv[1]);
00747 Pkt_EthernetHdr_t *pkt =
00748 (Pkt_EthernetHdr_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, objv[2]);
00749 array_t *applicableRules = array_alloc (int, 0);
00750 Pkt_ProcessPkt_t pp;
00751 pp.pkt = pkt;
00752 pp.applicableRules = applicableRules;
00753 Evl_ComputeRuleSetForEth (&pp, mgr);
00754
00755 array_t *result = array_dup (applicableRules);
00756 Nm_TclResult (interp, (Nm_TclCD_t *) cd, (void *) result);
00757
00758 return TCL_OK;
00759 }
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769 static int
00770 tclEvlComputeRuleSetForEthSTRING (ClientData cd ,
00771 Tcl_Interp * interp,
00772 int objc, Tcl_Obj * const objv[])
00773 {
00774 assert (objc == 3);
00775
00776 Evl_Manager_t *mgr =
00777 (Evl_Manager_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, objv[1]);
00778 Pkt_EthernetHdr_t *pkt =
00779 (Pkt_EthernetHdr_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, objv[2]);
00780
00781 array_t *applicableRules = array_alloc (int, 0);
00782 Pkt_ProcessPkt_t pp;
00783 pp.pkt = pkt;
00784 pp.applicableRules = applicableRules;
00785 pp.inIf = NIL (Pkt_LibPcap_t);
00786 Evl_ComputeRuleSetForEth (&pp, mgr);
00787
00788 char *result = (char *) malloc (mgr->numAllRules * 12);
00789 result[0] = '\0';
00790 char *tmp = result;
00791 int i;
00792 for (i = 0; i < array_n (applicableRules); i++)
00793 {
00794 int ruleid = array_fetch (int, applicableRules, i);
00795 sprintf (tmp, "%d%s", ruleid,
00796 ((i == (array_n (applicableRules) - 1)) ? "" : ","));
00797 tmp += strlen (tmp);
00798 }
00799 array_free (applicableRules);
00800 char *memEffResult = strdup (result);
00801 free (result);
00802
00803 Tcl_Obj *resultObj = Tcl_GetObjResult (interp);
00804 Tcl_SetStringObj (resultObj, memEffResult, -1);
00805
00806 return TCL_OK;
00807 }
00808
00809
00810
00811
00812
00813
00814 int
00815 Nm_TclGetStringVar (Tcl_Interp * interp, char *tclVarName, char **result)
00816 {
00817 const char *tmp = Tcl_GetVar (interp, tclVarName, 0);
00818 if (tmp != NIL (char))
00819 {
00820 *result = strdup (tmp);
00821 return true;
00822 }
00823 return false;
00824 }
00825
00826
00827
00828
00829
00830
00831 int
00832 Nm_TclGetDoubleVar (Tcl_Interp * interp, char *tclVarName, double *result)
00833 {
00834 const char *tmp = Tcl_GetVar (interp, tclVarName, 0);
00835 double tmpDouble;
00836 if (tmp != NIL (char))
00837 {
00838 sscanf (tmp, "%lf", &tmpDouble);
00839 *result = tmpDouble;
00840 return true;
00841 }
00842 return false;
00843 }
00844
00845
00846
00847
00848
00849
00850 int
00851 Nm_TclGetArrayVar (Tcl_Interp * interp, char *tclVarName, array_t * result)
00852 {
00853 const char *tmp = Tcl_GetVar (interp, tclVarName, 0);
00854 int listArgc;
00855 const char **listArgv;
00856 if (Tcl_SplitList (interp, tmp, &listArgc, &listArgv) != TCL_OK)
00857 {
00858 return false;
00859 }
00860 int i;
00861 for (i = 0; i < listArgc; i++)
00862 {
00863 printf ("%s\n", listArgv[i]);
00864 char *dupName = strdup (listArgv[i]);
00865 array_insert_last (char *, result, dupName);
00866 }
00867 return true;
00868
00869 }
00870
00871
00872
00873
00874
00875
00876 int
00877 Nm_TclGetIntVar (Tcl_Interp * interp, char *tclVarName, int *result)
00878 {
00879 const char *tmp = Tcl_GetVar (interp, tclVarName, 0);
00880 if (tmp != NIL (char))
00881 {
00882 *result = atoi (tmp);
00883 return true;
00884 }
00885 return false;
00886 }
00887
00888
00889
00890
00891
00892
00893 Nm_TclCD_t *
00894 Nm_TclCDInit ()
00895 {
00896 Nm_TclCD_t *result = (Nm_TclCD_t *) malloc (sizeof (Nm_TclCD_t));
00897 result->idToPtr = array_alloc (char *, 0);
00898 result->freeIds = array_alloc (int, 0);
00899
00900 return result;
00901 }
00902
00903
00904
00905
00906
00907
00908
00909 int
00910 Nm_TclCDStorePtr (Nm_TclCD_t * cd, void *ptr)
00911 {
00912 int result;
00913 int index;
00914
00915 if (array_n (cd->freeIds) == 0)
00916 {
00917 result = array_n (cd->idToPtr) + Nm_TclNumRetCodes_c;
00918 array_insert_last (void *, cd->idToPtr, ptr);
00919 }
00920 else
00921 {
00922 index = array_delete_last (int, cd->freeIds);
00923 array_insert (void *, cd->idToPtr, index, ptr);
00924 result = index + Nm_TclNumRetCodes_c;
00925 }
00926 return result;
00927 }
00928
00929
00930
00931
00932
00933
00934 void *
00935 Nm_TclCDReadPtrFromObj (Tcl_Interp * interp,
00936 Nm_TclCD_t * cd, Tcl_Obj * const obj)
00937 {
00938 int id;
00939 assert (TCL_OK == Tcl_GetIntFromObj (interp, obj, &id));
00940 return Nm_TclCDReadPtr (cd, id);
00941 }
00942
00943
00944
00945
00946
00947
00948 void *
00949 Nm_TclCDReadPtr (Nm_TclCD_t * cd, int id)
00950 {
00951 int index = id - Nm_TclNumRetCodes_c;
00952 void *result = array_fetch (void *, cd->idToPtr, index);
00953 return result;
00954 }
00955
00956
00957
00958
00959
00960
00961 void
00962 Nm_TclCDReuseId (Nm_TclCD_t * cd, int id)
00963 {
00964 int index = id - Nm_TclNumRetCodes_c;
00965 array_insert_last (int, cd->freeIds, index);
00966 }
00967
00968
00969
00970
00971
00972
00973 static char *
00974 computeStringFromIpAddress (u_int32_t aNumIp)
00975 {
00976 char tmpbuf[40];
00977
00978 u_int32_t mask = 0377;
00979
00980 u_int32_t a1;
00981 u_int32_t a2;
00982 u_int32_t a3;
00983 u_int32_t a4;
00984
00985 a1 = aNumIp & mask;
00986 a2 = (aNumIp >> 8) & mask;
00987 a3 = (aNumIp >> 16) & mask;
00988 a4 = (aNumIp >> 24) & mask;
00989 sprintf (tmpbuf, "%u.%u.%u.%u", a4, a3, a2, a1);
00990
00991 return strdup (tmpbuf);
00992 }
00993
00994
00995
00996
00997
00998
00999 static int
01000 pktReadIpInfo (ClientData cd ,
01001 Tcl_Interp * interp, int objc, Tcl_Obj * const objv[])
01002 {
01003 assert (objc == 2);
01004
01005 Pkt_EthernetHdr_t *pkt =
01006 (Pkt_EthernetHdr_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, objv[1]);
01007 Pkt_IpHdr_t *ipPkt = Pkt_EthernetExtractIp (pkt);
01008 u_int32_t result;
01009 u_int16_t length;
01010 char tmpbuf[2000];
01011 char *cmdName = Tcl_GetStringFromObj (objv[0], NIL (int));
01012 int computeIpAddressFlag = false;
01013 int getContent = false;
01014 char *resultString;
01015
01016 if (util_strequal (cmdName, "pktReadSrcIp"))
01017 {
01018 result = ipPkt->sourceIp;
01019 computeIpAddressFlag = true;
01020 }
01021 else if (util_strequal (cmdName, "pktReadDestIp"))
01022 {
01023 result = ipPkt->destIp;
01024 computeIpAddressFlag = true;
01025 }
01026 else if (util_strequal (cmdName, "pktReadOffset"))
01027 {
01028 result = ipPkt->offset;
01029 assert (result < 65536);
01030 }
01031 else if (util_strequal (cmdName, "pktReadTtl"))
01032 {
01033 result = ipPkt->TTL;
01034 assert (result < 256);
01035 }
01036 else if (util_strequal (cmdName, "pktReadLength"))
01037 {
01038 result = ipPkt->length;
01039 assert (result < 65526);
01040 }
01041 else if (util_strequal (cmdName, "pktReadContent"))
01042 {
01043 getContent = true;
01044
01045 length = ipPkt->length;
01046 assert (length < 65526);
01047 resultString = (char *) malloc (length + 1);
01048 memcpy (resultString, ipPkt, length);
01049 unsigned int i;
01050 for (i = 0; i < length; i++)
01051 {
01052 if (!isprint (resultString[i]))
01053 {
01054 resultString[i] = '.';
01055 }
01056 }
01057 resultString[length] = '\0';
01058 }
01059 else
01060 {
01061 assert (0);
01062 }
01063
01064 if (!(getContent))
01065 {
01066 if (!computeIpAddressFlag)
01067 {
01068 sprintf (tmpbuf, "%u", result);
01069 resultString = strdup (tmpbuf);
01070 }
01071 else
01072 {
01073 resultString = computeStringFromIpAddress (result);
01074 }
01075 }
01076
01077 Tcl_Obj *resultObj = Tcl_GetObjResult (interp);
01078 Tcl_SetStringObj (resultObj, resultString, -1);
01079
01080 return TCL_OK;
01081 }
01082
01083
01084
01085
01086
01087
01088 static int
01089 pktReadIpFlags (ClientData cd ,
01090 Tcl_Interp * interp, int objc, Tcl_Obj * const objv[])
01091 {
01092 assert (objc == 2);
01093
01094 Pkt_EthernetHdr_t *pkt =
01095 (Pkt_EthernetHdr_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, objv[1]);
01096 Pkt_IpHdr_t *ipPkt = Pkt_EthernetExtractIp (pkt);
01097 char tmpbuf[64];
01098
01099
01100
01101
01102
01103 sprintf (tmpbuf, "RB:%d; DF:%d; MF:%d; offset:%d;", ipPkt->RB, ipPkt->DF,
01104 ipPkt->MF, ipPkt->offset);
01105
01106 char *resultString = strdup (tmpbuf);
01107 Tcl_Obj *resultObj = Tcl_GetObjResult (interp);
01108 Tcl_SetStringObj (resultObj, resultString, -1);
01109
01110 return TCL_OK;
01111 }
01112
01113
01114
01115
01116
01117
01118 int
01119 pktReadTcpInfo (ClientData cd ,
01120 Tcl_Interp * interp, int objc, Tcl_Obj * const objv[])
01121 {
01122 assert (objc == 2);
01123 char *cmdName = Tcl_GetStringFromObj (objv[0], NIL (int));
01124
01125 Pkt_EthernetHdr_t *pkt =
01126 (Pkt_EthernetHdr_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, objv[1]);
01127 Pkt_TcpHdr_t *tcpPkt = Pkt_EthernetExtractTcp (pkt);
01128 u_int32_t result;
01129
01130 if (util_strequal (cmdName, "pktReadTcpDestPort"))
01131 {
01132 result = tcpPkt->destPort;
01133 assert (result < 65536);
01134 }
01135 else if (util_strequal (cmdName, "pktReadTcpSrcPort"))
01136 {
01137 result = tcpPkt->srcPort;
01138 assert (result < 65536);
01139 }
01140 else if (util_strequal (cmdName, "pktReadTcpSeqNum"))
01141 {
01142 result = tcpPkt->seqNum;
01143 }
01144 else if (util_strequal (cmdName, "pktReadTcpAckNum"))
01145 {
01146 result = tcpPkt->ackNum;
01147 }
01148 else
01149 {
01150 assert (0);
01151 }
01152 char tmpbuf[40];
01153 sprintf (tmpbuf, "%u", result);
01154
01155 char *resultString = strdup (tmpbuf);
01156 Tcl_Obj *resultObj = Tcl_GetObjResult (interp);
01157 Tcl_SetStringObj (resultObj, resultString, -1);
01158
01159 return TCL_OK;
01160 }
01161
01162
01163
01164
01165
01166
01167 static int
01168 pktReadTcpFlags (ClientData cd ,
01169 Tcl_Interp * interp, int objc, Tcl_Obj * const objv[])
01170 {
01171 assert (objc == 2);
01172
01173 Pkt_EthernetHdr_t *pkt =
01174 (Pkt_EthernetHdr_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, objv[1]);
01175 Pkt_TcpHdr_t *tcp = Pkt_EthernetExtractTcp (pkt);
01176 char tmpbuf[100];
01177
01178
01179 sprintf (tmpbuf, "%s%s%s%s%s%s%s%s",
01180 (tcp->fin ? "fin," : "!fin,"),
01181 (tcp->syn ? "syn," : "!syn,"),
01182 (tcp->rst ? "rst," : "!rst,"),
01183 (tcp->psh ? "psh," : "!psh,"),
01184 (tcp->ack ? "ack," : "!ack,"),
01185 (tcp->urg ? "urg," : "!urg,"),
01186 (tcp->ece ? "ece," : "!ece,"), (tcp->cwr ? "cwr," : "!cwr"));
01187
01188 char *resultString = strdup (tmpbuf);
01189 Tcl_Obj *resultObj = Tcl_GetObjResult (interp);
01190 Tcl_SetStringObj (resultObj, resultString, -1);
01191
01192 return TCL_OK;
01193 }
01194
01195
01196
01197
01198
01199
01200 static int
01201 tclTestC (ClientData cd ,
01202 Tcl_Interp * interp, int objc, Tcl_Obj * const objv[])
01203 {
01204 int count = 1000;
01205 char *cmdName = Tcl_GetStringFromObj (objv[0], NIL (int));
01206 if (objc == 3)
01207 {
01208 assert (TCL_OK == Tcl_GetIntFromObj (interp, objv[2], &count));
01209 }
01210 int i;
01211
01212 if (util_strequal (cmdName, "testC1"))
01213 {
01214 for (i = 0; i < count; i++)
01215 {
01216 Tcl_EvalObjEx (interp, objv[1], 0);
01217 }
01218 }
01219 else if (util_strequal (cmdName, "testC2"))
01220 {
01221 for (i = 0; i < count; i++)
01222 {
01223 char *cmdString = Tcl_GetString (objv[1]);
01224 Tcl_Eval (interp, cmdString);
01225 }
01226 }
01227 else if (util_strequal (cmdName, "testC3"))
01228 {
01229 char *cmdString = Tcl_GetString (objv[1]);
01230 int cmdStringLength = strlen (cmdString);
01231 for (i = 0; i < count; i++)
01232 {
01233 Tcl_EvalEx (interp, cmdString, cmdStringLength, 0);
01234 }
01235 }
01236 else
01237 {
01238 printf ("Error in tclTestC\n");
01239 assert (0);
01240 }
01241
01242 return TCL_OK;
01243 }
01244
01245
01246
01247
01248
01249
01250
01251 static int
01252 tclTestParser (ClientData cd ,
01253 Tcl_Interp * interp, int objc, Tcl_Obj * const objv[])
01254 {
01255 assert (objc == 2);
01256
01257 char *fileName = Tcl_GetStringFromObj (objv[1], NIL (int));
01258 FILE *ruleFile = fopen (fileName, "r");
01259 if (ruleFile == NIL (FILE))
01260 {
01261 printf
01262 ("Error, could not open file %s, returning without testing parser\n",
01263 fileName);
01264 return TCL_OK;
01265 }
01266 char *ruleFileInText = util_file_to_string (ruleFile);
01267 array_t *result = util_process_file (ruleFileInText);
01268 free (ruleFileInText);
01269 fclose (ruleFile);
01270
01271
01272
01273 Tcl_Obj *resultObj = Tcl_GetObjResult (interp);
01274 Tcl_SetIntObj (resultObj, 0);
01275
01276 return TCL_OK;
01277 }
01278
01279
01280
01281
01282
01283
01284
01285 static int
01286 tclGetFileAsText (ClientData cd ,
01287 Tcl_Interp * interp, int objc, Tcl_Obj * const objv[])
01288 {
01289 assert (objc == 2);
01290
01291 char *fileName = Tcl_GetStringFromObj (objv[1], NIL (int));
01292 FILE *ruleFile = fopen (fileName, "r");
01293 if (ruleFile == NIL (FILE))
01294 {
01295 printf
01296 ("Error, could not open file %s, returning without generating string\n",
01297 fileName);
01298 return TCL_OK;
01299 }
01300 char *ruleFileInText = util_file_to_string (ruleFile);
01301 fclose (ruleFile);
01302
01303 Tcl_Obj *resultObj = Tcl_GetObjResult (interp);
01304 Tcl_SetStringObj (resultObj, ruleFileInText, strlen (ruleFileInText));
01305
01306 return TCL_OK;
01307 }
01308
01309
01310
01311
01312
01313
01314 static int
01315 tclBufferWritePkts (ClientData cd ,
01316 Tcl_Interp * interp,
01317 int objc , Tcl_Obj * const objv[])
01318 {
01319 int numPackets = 1;
01320 Nm_TclGetIntVar (interp, "numPackets", &numPackets);
01321
01322 char *fileName = "/dev/null";
01323 Nm_TclGetStringVar (interp, "fileName", &fileName);
01324
01325 FILE *destFile = fopen (fileName, "w");
01326
01327 int i;
01328 int aPktLength = 64;
01329 char aPkt[64];
01330
01331 for (i = 0; i < numPackets; i++)
01332 {
01333 int numWritten = fwrite (aPkt, 4, aPktLength, destFile);
01334 if (numWritten != aPktLength)
01335 {
01336 printf ("Unsucc write: numWritten = %d, aPktLength = %d\n",
01337 numWritten, aPktLength);
01338 }
01339 }
01340
01341 return TCL_OK;
01342 }
01343
01344
01345
01346
01347
01348
01349 static int
01350 tclWritePkts (ClientData cd ,
01351 Tcl_Interp * interp, int objc , Tcl_Obj * const objv[])
01352 {
01353 int numPackets = 1;
01354 Nm_TclGetIntVar (interp, "numpkt", &numPackets);
01355
01356 char *fileName = "/dev/null";
01357 Nm_TclGetStringVar (interp, "fileName", &fileName);
01358
01359 int destFile = open (fileName, O_RDWR, 0);
01360 if (destFile == -1)
01361 {
01362 destFile = creat (fileName, 0755);
01363 }
01364 if (destFile == -1)
01365 {
01366 printf ("Could not open or create file %s\n", fileName);
01367 }
01368
01369 int i;
01370 array_t *timeStamps = util_time_stamp_init (numPackets + 1);
01371
01372 int aPktLength = 64;
01373 char aPkt[64];
01374 printf ("About to write %d pkts to %s\n", numPackets, fileName);
01375 util_time_stamp_set (timeStamps, 0);
01376 for (i = 0; i < numPackets; i++)
01377 {
01378 int numWritten = write (destFile, aPkt, aPktLength);
01379 util_time_stamp_set (timeStamps, (i + 1));
01380 if (numWritten != aPktLength)
01381 {
01382 printf
01383 ("Unsucc write: numWritten = %d, aPktLength = %d, destFile = %d\n",
01384 numWritten, aPktLength, destFile);
01385 }
01386 }
01387 util_time_stamp_print (timeStamps);
01388 array_free (timeStamps);
01389
01390 return TCL_OK;
01391 }
01392
01393
01394
01395
01396
01397
01398 static int
01399 tclTxPkt (ClientData cd ,
01400 Tcl_Interp * interp, int objc , Tcl_Obj * const objv[])
01401 {
01402 char *ifName = "eth1";
01403 Nm_TclGetStringVar (interp, "ifname", &ifName);
01404 static Pkt_LibNet_t *alibnet;
01405
01406 if (alibnet == NIL (Pkt_LibNet_t))
01407 {
01408 alibnet = Pkt_InitLibNet (ifName);
01409 }
01410 else
01411 {
01412 if (util_strequal (ifName, alibnet->interfaceName))
01413 {
01414
01415 }
01416 else
01417 {
01418
01419 Pkt_LibNetFinish (alibnet);
01420 alibnet = Pkt_InitLibNet (ifName);
01421 }
01422 }
01423
01424 Pkt_EthernetHdr_t *pkt =
01425 (Pkt_EthernetHdr_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, objv[1]);
01426 int aPktLength = Pkt_EthernetPktHdrReadLength (pkt);
01427 Pkt_HTON (pkt);
01428 Pkt_EthPktWrite (pkt, aPktLength, alibnet);
01429 Pkt_NTOH (pkt);
01430
01431 return TCL_OK;
01432 }
01433
01434
01435
01436
01437
01438
01439 static int
01440 tclInjectPkts (ClientData cd ,
01441 Tcl_Interp * interp, int objc , Tcl_Obj * const objv[])
01442 {
01443
01444 int index;
01445
01446 int numPackets = 21;
01447 Nm_TclGetIntVar (interp, "numpkt", &numPackets);
01448
01449 char *ifName = "eth1";
01450 Nm_TclGetStringVar (interp, "ifname", &ifName);
01451
01452 int printTimeStamps = 0;
01453 Nm_TclGetIntVar (interp, "ts", &printTimeStamps);
01454
01455 double rate;
01456 double rateLimit = 0.0;
01457 Nm_TclGetDoubleVar (interp, "ratelimit", &rateLimit);
01458
01459 Pkt_TfcMode_t *tfcMode = readTfcModeParams (interp);
01460 Pkt_LibNet_t *alibnet = Pkt_InitLibNet (ifName);
01461
01462 array_t *pktArray =
01463 Pkt_SeedRandEthPktArray (Pkt_HostByteOrder_c, tfcMode->numSeeds, tfcMode);
01464
01465 int i;
01466 printf ("Writing %d pkts\n", numPackets);
01467 util_timing_t startTime;
01468 util_timing_t finishTime;
01469
01470 array_t *timeStamps;
01471
01472 if (printTimeStamps)
01473 {
01474 timeStamps = util_time_stamp_init (numPackets + 1);
01475 }
01476
01477 if (printTimeStamps)
01478 {
01479 util_time_stamp_set (timeStamps, 0);
01480 }
01481
01482 util_timing_set (&startTime);
01483 util_timing_t pauseTime = util_timing_pair (tfcMode->pktGap);
01484
01485 util_timing_t difftime;
01486
01487 Pkt_EthernetHdr_t *aPkt = Pkt_CreateRandEthPkt (pktArray);
01488 Pkt_IpHdr_t *ipPkt = Pkt_EthernetExtractIp (aPkt);
01489 int ipPktLength = ipPkt->length;
01490 int aPktLength = ipPktLength + sizeof (Pkt_EthernetHdr_t);
01491
01492 int count = 0;
01493 int bytesTx;
01494 while (1)
01495 {
01496 int bytesTx = Pkt_EthPktWrite (aPkt, aPktLength, alibnet);
01497 if (bytesTx != 0)
01498 {
01499 count++;
01500 if (count >= numPackets)
01501 {
01502 break;
01503 }
01504 }
01505 util_timing_pause (pauseTime);
01506 if (printTimeStamps)
01507 {
01508 util_time_stamp_set (timeStamps, (count + 1));
01509 }
01510 if (rateLimit != 0.0)
01511 {
01512 while (1)
01513 {
01514 util_timing_set (&finishTime);
01515 util_timing_t difftime =
01516 util_timing_diff (finishTime, startTime);
01517 rate = computeRate (tfcMode->size, count, difftime);
01518 if (rate < rateLimit)
01519 {
01520 break;
01521 }
01522 }
01523 }
01524 }
01525 util_timing_set (&finishTime);
01526 difftime = util_timing_diff (finishTime, startTime);
01527
01528 rate = computeRate (tfcMode->size, numPackets, difftime);
01529
01530 double kbits =
01531 (8.0 * (7 + 1 + 6 + 6 + 2 + (MAX (46, (40 + tfcMode->size))) + 12) *
01532 (((double) numPackets) / 1000.0));
01533 double difftimeDouble = util_timing_secs (difftime);
01534 printf ("Transmitted %d payload byte L4 packets: %.0f kbits "
01535 "(incl preamble,sfd,fcs,frame-gap) "
01536 "in %.2f seconds, rate = %.0f Mbps, %.4f Kpps\n",
01537 (tfcMode->size), kbits, difftimeDouble, rate,
01538 (0.001 * (double) numPackets) / difftimeDouble);
01539
01540 if (printTimeStamps)
01541 {
01542 util_time_stamp_print (timeStamps);
01543 array_free (timeStamps);
01544 }
01545
01546 Pkt_LibNetFinish (alibnet);
01547
01548 return TCL_OK;
01549 }
01550
01551
01552
01553
01554
01555
01556
01557 static Pkt_TfcMode_t *
01558 readTfcModeParams (Tcl_Interp * interp)
01559 {
01560 int size = 10;
01561 Nm_TclGetIntVar (interp, "pktsize", &size);
01562
01563 Pkt_TfcMode_t *tfcMode = (Pkt_TfcMode_t *) malloc (sizeof (Pkt_TfcMode_t));
01564 tfcMode->size = size;
01565
01566 char Nm_EvgaSrcMac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa };
01567 char Nm_EvgaDestMac[] = { 0x00, 0x15, 0x17, 0x20, 0xE1, 0x80 };
01568
01569
01570 tfcMode->srcMac = Nm_EvgaSrcMac;
01571 tfcMode->destMac = Nm_EvgaDestMac;
01572
01573 int numSeeds = 1;
01574 Nm_TclGetIntVar (interp, "numSeeds", &numSeeds);
01575 tfcMode->numSeeds = numSeeds;
01576
01577 double delay = 0.0;
01578 Nm_TclGetDoubleVar (interp, "pktgap", &delay);
01579 tfcMode->pktGap = delay * 0.000001;
01580
01581 return tfcMode;
01582 }
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592 static int
01593 tclTestTclAction (ClientData cd ,
01594 Tcl_Interp * interp,
01595 int objc , Tcl_Obj * const objv[])
01596 {
01597
01598 const int numArgsToTclFunction = 2;
01599 Tcl_Obj *tmpObjv[numArgsToTclFunction];
01600
01601 char *procedure = "dummy";
01602 Tcl_Obj *tmpPtr = Tcl_NewStringObj (strdup (procedure), -1);
01603 tmpObjv[0] = tmpPtr;
01604
01605 char *dummyarg = "dummyarg";
01606 tmpObjv[1] = Tcl_NewStringObj (strdup (dummyarg), -1);
01607
01608
01609
01610 int code = Tcl_EvalObjv (interp, numArgsToTclFunction, tmpObjv, 0);
01611 return code;
01612
01613 }
01614
01615
01616
01617
01618
01619
01620
01621 static int
01622 tclCompressTestPerf (ClientData cd ,
01623 Tcl_Interp * interp,
01624 int objc , Tcl_Obj * const objv[])
01625 {
01626 int len = 1000000;
01627 Nm_TclGetIntVar (interp, "length", &len);
01628 int count = 10;
01629 Nm_TclGetIntVar (interp, "count", &count);
01630 int srcLen = len;
01631 int destLen = 2 * len;
01632 char *src = (char *) malloc (srcLen);
01633 char *dest = (char *) malloc (destLen);
01634
01635 util_timing_t startTime;
01636 util_timing_t finishTime;
01637
01638 int i;
01639 util_timing_set (&startTime);
01640 for (i = 0; i < count; i++)
01641 {
01642
01643
01644 }
01645 util_timing_set (&finishTime);
01646 util_timing_t difftime = util_timing_diff (finishTime, startTime);
01647 double difftimeDouble = util_timing_secs (difftime);
01648 double rate = len * count / (difftimeDouble * 1000.0);
01649 printf ("compress %d iters, %d bytes per iter: rate %.4f MBytes/sec\n",
01650 count, len,
01651 ((double) count * (double) len) / (1000000.0 * difftimeDouble));
01652 fflush (stdout);
01653
01654 return TCL_OK;
01655 }
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666 static int
01667 tclCompressTestReduction (ClientData cd ,
01668 Tcl_Interp * interp,
01669 int objc , Tcl_Obj * const objv[])
01670 {
01671 char *fileName = "a.txt";
01672 Nm_TclGetStringVar (interp, "filename", &fileName);
01673 int blockSize = 1000;
01674 Nm_TclGetIntVar (interp, "blocksize", &blockSize);
01675
01676 int destLen = 2 * blockSize;
01677 char *dest = (char *) malloc (destLen);
01678
01679 FILE *f = fopen (fileName, "r");
01680 if (f == NIL (FILE))
01681 {
01682 printf ("Could not open file %s\n", fileName);
01683 return TCL_OK;
01684 }
01685
01686 char *text = util_file_to_string (f);
01687 int textLength = strlen (text);
01688 int i;
01689 int numBlocks = textLength / blockSize;
01690 textLength = numBlocks * blockSize;
01691
01692 int totalCompressedBytes = 0;
01693 for (i = 0; i < numBlocks; i++)
01694 {
01695
01696 totalCompressedBytes += (destLen > blockSize) ? blockSize : destLen;
01697 }
01698
01699 int fullFileLength = 2 * textLength;
01700 char *fullFile = (char *) malloc (2 * textLength);
01701
01702
01703 printf ("For file %s, using %d sized blocks:\n"
01704 "\tTotal length = %d\n"
01705 "\tCompressed flat = %d\n"
01706 "\tCompressed segments = %d)\n",
01707 fileName, blockSize, textLength, fullFileLength,
01708 totalCompressedBytes);
01709 return TCL_OK;
01710 }
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720 static int
01721 tclArrayTest (ClientData cd ,
01722 Tcl_Interp * interp, int objc , Tcl_Obj * const objv[])
01723 {
01724 Array_Test ();
01725 return TCL_OK;
01726 }
01727
01728
01729
01730
01731
01732
01733
01734
01735 static int
01736 tclEvlMgrInsertPktIntoInputBuffer (ClientData cd ,
01737 Tcl_Interp * interp,
01738 int objc , Tcl_Obj * const objv[])
01739 {
01740 assert (objc == 3);
01741 Tcl_Obj *mgrObj = objv[1];
01742 Tcl_Obj *pktObj = objv[2];
01743
01744 Evl_Manager_t *mgr = (Evl_Manager_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, mgrObj);
01745 Pkt_EthernetHdr_t *pkt = (Pkt_EthernetHdr_t *) Nm_TclCDReadPtrFromObj (interp, (Nm_TclCD_t *) cd, pktObj);
01746 Evl_Bridge_t *bridge = mgr->bridge;
01747
01748 Evl_BridgeInsertPktInIbuf (bridge, pkt);
01749 return TCL_OK;
01750 }
01751
01752
01753
01754
01755
01756
01757 static double
01758 computeRate (int size, int numPackets, util_timing_t diffTime)
01759 {
01760 double kbits = (8.0 * (7 + 1 + 6 + 6 + 2 + (MAX (46, (40 + size))) + 12) *
01761 (((double) numPackets) / 1000.0));
01762 double difftimeDouble = util_timing_secs (diffTime);
01763 double rate = kbits / (difftimeDouble * 1000.0);
01764
01765 return rate;
01766 }
01767
01768
01769
01770
01771
01772
01773
01774 static int
01775 tclStopProfiler (ClientData cd ,
01776 Tcl_Interp * interp, int objc , Tcl_Obj * const objv[])
01777 {
01778
01779
01780 return TCL_OK;
01781 }
01782
01783
01784
01785 static int
01786 tclStTest(ClientData cd ,
01787 Tcl_Interp * interp, int objc , Tcl_Obj * const objv[])
01788 {
01789 Hash_Test();
01790
01791 return TCL_OK;
01792 }
01793
01794
01795
01796 static int
01797 tclStTestPerf (ClientData cd ,
01798 Tcl_Interp * interp, int objc , Tcl_Obj * const objv[])
01799 {
01800 int numIter = 10;
01801 Nm_TclGetIntVar (interp, "num", &numIter);
01802 char *aString = (char *) malloc (100);
01803 int i;
01804 for (i = 0; i < 99; i++)
01805 {
01806 aString[i] = 'x';
01807 }
01808 aString[5] = '\0';
01809
01810 util_timing_t startTime;
01811 util_timing_t finishTime;
01812 util_timing_t difftime;
01813 double difftimeDouble;
01814
01815 st_table *stringTable = Hash_InitTable ( ( int(*)() ) strcmp, ( int(*)() ) st_strhash);
01816 util_timing_set (&startTime);
01817 for (i = 0; i < numIter; i++)
01818 {
01819 *(int *) (aString + 1) = i + 1;
01820 Hash_Insert (stringTable, aString, 0);
01821 }
01822 util_timing_set (&finishTime);
01823 difftime = util_timing_diff (finishTime, startTime);
01824 difftimeDouble = util_timing_secs (difftime);
01825 printf ("Time to insert foo %d times is %f => %f iter per sec\n",
01826 numIter, difftimeDouble, (numIter / difftimeDouble));
01827
01828 util_timing_set (&startTime);
01829 for (i = 0; i < numIter; i++)
01830 {
01831
01832 Hash_Lookup (stringTable, aString, 0);
01833 }
01834 util_timing_set (&finishTime);
01835 difftime = util_timing_diff (finishTime, startTime);
01836 difftimeDouble = util_timing_secs (difftime);
01837 printf ("Time to lookup foo %d times is %f => %f iter per sec\n",
01838 numIter, difftimeDouble, (numIter / difftimeDouble));
01839 return TCL_OK;
01840 }
01841
01842
01843
01844
01845
01846
01847 static int *dummy( Tcl_Interp *interp ) {
01848 return TCL_OK;
01849 }
01850
01851
01852
01853
01854
01855 static int
01856 tclTestTk (ClientData cd ,
01857 Tcl_Interp * interp, int objc , Tcl_Obj * const objv[])
01858 {
01859
01860
01861
01862
01863
01864 return TCL_OK;
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890 }
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952