/** * $Id: PyFlowmodule.c,v 1.2 2002/03/27 08:24:57 wyy Exp $ * * William Emmanuel S. YU * Ateneo de Manila University, Philippines * * Python Bindings for OSU Flowtools * Copyright (C) 2002 William Emmanuel S. Yu * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **/ #include #include #include #include "ftlib.h" #include "math.h" #define MAXSIZE 255 #define VERSION 1.0 /* declaring user defined datatype */ staticforward PyTypeObject PyFlow_PyFlowType; typedef struct { PyObject_HEAD float version; struct ftio ftio; struct ftset FTSetting; struct ftver FTVersion; int fd; } PyFlow_PyFlowObject; /* function prototypes */ static PyObject *PyFlow_system (PyObject*, PyObject*); static PyObject *PyFlow_open(PyObject*, PyObject*); static PyObject *PyFlow_read(PyObject*, PyObject*); static void PyFlow_delete_PyFlow(PyObject*); static PyObject *PyFlow_str_PyFlow(PyObject*); static int PyFlow_print_PyFlow(PyObject*, FILE*, int); /* the type object */ static PyTypeObject PyFlow_PyFlowType = { PyObject_HEAD_INIT(NULL) 0, "PyFlow", sizeof(PyFlow_PyFlowObject), 0, PyFlow_delete_PyFlow, /*tp_dealloc*/ PyFlow_print_PyFlow, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ PyFlow_str_PyFlow, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ }; /* pointer to error object */ static PyObject *PyFlowError; /* method table for Python module */ static PyMethodDef PyFlowMethods[] = { {"open", PyFlow_open, METH_VARARGS, "Open File Descriptor for reading flows."}, {"read", PyFlow_read, METH_VARARGS, "Read One Flow from PyFlow object."}, {"system", PyFlow_system, METH_VARARGS, "Execute a shell command. [test]"}, {NULL, NULL, 0, NULL} }; /* helper function */ void fixstring(char *buf) { char *ptr; ptr = buf; while ((*ptr != ' ') && (*ptr != '\0')) ptr++; *ptr = '\0'; } /* initialize module */ DL_EXPORT(void) initPyFlow (void) { PyObject *m, *d; PyFlow_PyFlowType.ob_type = &PyType_Type; m = Py_InitModule("PyFlow", PyFlowMethods); d = PyModule_GetDict(m); PyFlowError = PyErr_NewException("PyFlow.error", NULL, NULL); PyDict_SetItemString(d, "error", PyFlowError); } /* open a file as a PyFlow_PyFlowType */ static PyObject* PyFlow_open(PyObject* self, PyObject* args) { PyFlow_PyFlowObject* noddy; int fd = -1; char *path = NULL; if (!PyArg_ParseTuple(args,"i:open",&fd)) if (!PyArg_ParseTuple(args,"s:open",&path)) return NULL; #ifdef DEBUG printf ("DEBUG (open) fd: %d\n", fd); printf ("DEBUG (open) path: '%s'\n", path); #endif noddy = PyObject_New(PyFlow_PyFlowObject, &PyFlow_PyFlowType); noddy->version = VERSION; /* process file */ if (path != NULL) fd = open(path, O_RDWR, 0777); #ifdef DEBUG printf ("DEBUG (open) fd: %d\n", fd); #endif /* process file descriptor */ noddy->fd = fd; if (fd != -1) { if (ftio_init(&(noddy->ftio), fd, FT_IO_FLAG_READ) < 0) { fprintf(stderr, "ftio_init(): failed\n"); return NULL; } #ifdef DEBUG printf ("DEBUG (open) file descriptor set\n"); printf ("DEBUG (open) ftio structure set\n"); #endif } return (PyObject*)noddy; } /* read data from opened PyFlowObject */ static PyObject* PyFlow_read(PyObject* self, PyObject* args) { struct fts3rec_v5 *rec; PyFlow_PyFlowObject *obj = NULL; #ifdef DEBUG printf ("DEBUG (read) reading\n"); #endif if (!PyArg_ParseTuple(args, "O:read", &obj)) return NULL; #ifdef DEBUG printf ("DEBUG (read) version: %.2f\n", obj->version); printf ("DEBUG (read) from fd: %d\n", obj->fd); #endif /* if valid flow file */ if (obj->fd != -1) { rec = ftio_read(&(obj->ftio)); if (rec != NULL) { char dstaddrstr[64], srcaddrstr[64]; struct fttime ftt; time_t start, stop; /* formating of output data */ fmt_ipv4(srcaddrstr, rec->srcaddr, FMT_PAD_RIGHT); fixstring(srcaddrstr); fmt_ipv4(dstaddrstr, rec->dstaddr, FMT_PAD_RIGHT); fixstring(dstaddrstr); /* convert the times into a unix time */ ftt = ftltime(rec->sysUpTime, rec->unix_secs, rec->unix_nsecs, rec->First); start = ftt.secs; ftt = ftltime(rec->sysUpTime, rec->unix_secs, rec->unix_nsecs, rec->Last); stop = ftt.secs; return Py_BuildValue("(ll)(sli)(sli)i(ii)", start, stop, dstaddrstr, rec->dstport, rec->src_as, srcaddrstr, rec->srcport, rec->dst_as, rec->prot, rec->dPkts, rec->dOctets ); } } return Py_BuildValue("i", 0); } /* destroy PyFlowObject */ static void PyFlow_delete_PyFlow(PyObject* self) { ftio_close (&(struct ftio)(((PyFlow_PyFlowObject*)self)->ftio)); PyObject_Del(self); } /* representation of PyFlowObject */ static PyObject * PyFlow_str_PyFlow(PyObject *obj) { char temp[MAXSIZE]; sprintf (temp,"PyFlow Object Version: %.2f", ((PyFlow_PyFlowObject*)obj)->version); return PyString_FromString(temp); } /* handle print functions */ static int PyFlow_print_PyFlow(PyObject *obj, FILE *fp, int flags) { if (flags & Py_PRINT_RAW) fprintf(fp, "", ((PyFlow_PyFlowObject*)obj)->version); else fprintf(fp, "\"\"", ((PyFlow_PyFlowObject*)obj)->version); return 0; } /* system function call reimplemented in Python */ /* this is here just to test if my module writing is right */ static PyObject* PyFlow_system (PyObject *self, PyObject *args) { char *command; int sts; if (!PyArg_ParseTuple(args, "s", &command)) return NULL; sts = system(command); return Py_BuildValue("i", sts); } /* force calling of initialization module */ int main(int argc, char **argv) { /* Pass argv[0] to the Python interpreter */ Py_SetProgramName(argv[0]); /* Initialize the Python interpreter. Required. */ Py_Initialize(); /* Add a static module */ initPyFlow(); PySys_SetArgv(argc, argv); Py_Exit(0); return 0; }