/* ** Copyright (C) 2006 by Carnegie Mellon University. ** ** @OPENSOURCE_HEADER_START@ ** ** Use of the SILK system and related source code is subject to the terms ** of the following licenses: ** ** GNU Public License (GPL) Rights pursuant to Version 2, June 1991 ** Government Purpose License Rights (GPLR) pursuant to DFARS 252.225-7013 ** ** NO WARRANTY ** ** ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER ** PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY ** PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN ** "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY ** KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT ** LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE, ** MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE ** OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT, ** SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY ** TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF ** WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES. ** LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF ** CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON ** CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE ** DELIVERABLES UNDER THIS LICENSE. ** ** Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie ** Mellon University, its trustees, officers, employees, and agents from ** all claims or demands made against them (and any related losses, ** expenses, or attorney's fees) arising out of, or relating to Licensee's ** and/or its sub licensees' negligent use or willful misuse of or ** negligent conduct or willful misconduct regarding the Software, ** facilities, or other rights or assistance granted by Carnegie Mellon ** University under this License, including, but not limited to, any ** claims of product liability, personal injury, death, damage to ** property, or violation of any laws or regulations. ** ** Carnegie Mellon University Software Engineering Institute authored ** documents are sponsored by the U.S. Department of Defense under ** Contract F19628-00-C-0003. Carnegie Mellon University retains ** copyrights in all material produced under this contract. The U.S. ** Government retains a non-exclusive, royalty-free license to publish or ** reproduce these documents, or allow others to do so, for U.S. ** Government purposes only pursuant to the copyright license under the ** contract clause at 252.227.7013. ** ** @OPENSOURCE_HEADER_END@ */ /* ** rwp2f_minbytes.c ** ** An example of a simple plug-in that can be used with rwptoflow. ** ** Mark Thomas ** September 2006 */ #include "silk.h" RCSIDENT("$SiLK: rwp2f_minbytes.c 4906 2006-09-19 20:32:16Z mthomas $"); #include "utils.h" #include "dynlib.h" #include "rwpack.h" #include "rwppacketheaders.h" /* EXPORTED FUNCTION DECLARATIONS */ /* these are called by dynlib */ int dynlib_api_version(void); int setup(dynlibInfoStruct *dlISP, dynlibSymbolId appType); void teardown(dynlibSymbolId appType); int initialize(dynlibInfoStruct *dlISP, dynlibSymbolId appType); void optionsUsage(dynlibSymbolId appType, FILE *fh); int ptoflow(rwRec *rwrec, void *pktsrc); /* LOCAL FUNCTION PROTOTYPES */ static int optionsHandler(clientData cData, int opt_index, char *opt_arg); /* LOCAL VARIABLE DEFINITIONS */ /* plugin's name */ static const char *pluginName = "rwpm_minbytes"; /* the minimum number of bytes a packet must have to pass, as entered * by the user */ static uint32_t byte_minimum = 0; /* OPTIONS SETUP */ typedef enum { OPT_MIN_BYTES } libOptionsEnum; static struct option libOptions[] = { {"byte-limit", REQUIRED_ARG, 0, OPT_MIN_BYTES}, {0,0,0,0} /* sentinel */ }; static const char *libHelp[] = { "ignore all flows that have fewer than this number of bytes", (char*)NULL }; /* FUNCTION DEFINITIONS */ /* * int dynlib_api_version(void); * * Return the dynlib API version that this plugin was compiled * against. */ int dynlib_api_version(void) { return DYNLIB_API_VERSION; } /* * int setup(dynlibInfoStruct *dlISP, dynlibSymbolId appType) * * Called by dynlib interface code to set up the plugin. This * routine should set up options handling if required. Arguments: * pointer to the dynamic library interface structure, application * type that is using this plugin. Returns DYNLIB_FAILED if * processing fails, DYNLIB_WONTPROCESS if the application should * do normal output, and DYNLIB_WILLPROCESS if this plugin takes * over output. */ int setup(dynlibInfoStruct *dlISP, dynlibSymbolId appType) { skAppContextSet(dynlibGetAppContext(dlISP)); assert((sizeof(libHelp)/sizeof(char *)) == (sizeof(libOptions)/sizeof(struct option))); if (appType != DYNLIB_PTOFLOW) { return DYNLIB_FAILED; } if (libOptions[0].name) { if (optionsRegister(libOptions, &optionsHandler, (clientData)dlISP)) { skAppPrintErr("unable to register options"); return DYNLIB_FAILED; } } return DYNLIB_WONTPROCESS; } /* * teardown(appType); * * Called by dynlib interface code to tear down this plugin. */ void teardown(dynlibSymbolId UNUSED(appType)) { return; } /* * initialize(dlISP, appType); * * Does any expensive initialization required by the plugin. * Returns 0 on success, 1 on failure. */ int initialize(dynlibInfoStruct UNUSED(*dlISP), dynlibSymbolId UNUSED(appType)) { /* Do expensive initialization */ return 0; } /* * optionsUsage(appType, fh); * * Called by the dynlib interface to allow this plugin to print the * options it accepts. */ void optionsUsage(dynlibSymbolId appType, FILE *fh) { int i; if (appType != DYNLIB_PTOFLOW) { return; } for (i = 0; libOptions[i].name; ++i) { fprintf(fh, "--%s %s. %s\n", libOptions[i].name, SK_OPTION_HAS_ARG(libOptions[i]), libHelp[i]); } } /* * status = optionsHandler(cData, opt_index, opt_arg); * * This function is passed to optionsRegister(); it will be called * by optionsParse() for each user-specified switch that the * application has registered; it should handle the switch as * required---typically by setting global variables---and return 1 * if the switch processing failed or 0 if it succeeded. Returning * a non-zero from from the handler causes optionsParse() to return * a negative value. * * The clientData in 'cData' is typically ignored; 'opt_index' is * the index number that was specified as the last value for each * struct option in appOptions[]; 'opt_arg' is the user's argument * to the switch for options that have a REQUIRED_ARG or an * OPTIONAL_ARG. */ static int optionsHandler(clientData cData, int opt_index, char *opt_arg) { dynlibInfoStruct *dlISP = (dynlibInfoStruct*)cData; const dynlibSymbolId appType = dynlibGetAppType(dlISP); if (appType != DYNLIB_PTOFLOW) { assert(appType == DYNLIB_PTOFLOW); skAppPrintErr("This application does not support %s", pluginName); return 1; } switch ((libOptionsEnum)opt_index) { case OPT_MIN_BYTES: if (skStringParseUint32(&byte_minimum, opt_arg, 0, 0)) { skAppPrintErr("Error parsing %s value '%s'", libOptions[opt_index].name, opt_arg); return 1; } } return 0; } int ptoflow(rwRec UNUSED(*rwrec), void *vpktsrc) { sk_pktsrc_t *pktsrc = (sk_pktsrc_t*)vpktsrc; ip_header_t *iph; iph = (ip_header_t*)(pktsrc->pcap_data + sizeof(eth_header_t)); if (iph->tlen < byte_minimum) { return 3; } return 0; }