--- configure.in.orig Fri Mar 28 11:54:05 2003 +++ configure.in Fri Mar 28 12:09:37 2003 @@ -21,6 +21,9 @@ AC_SUBST(MYSQLLIB) AC_SUBST(MYSQLCFLAGS) AC_SUBST(MYSQLINCLUDE) +AC_SUBST(PGSQLLIB) +AC_SUBST(PGSQLCFLAGS) +AC_SUBST(PGSQLINCLUDE) dnl extra argument: --with-mysql WITH_MYSQL= @@ -34,6 +37,18 @@ ] ) +dnl extra argument: --with-pgsql +WITH_PGSQL= +AC_ARG_WITH(pgsql, +[ --with-pgsql[=PATH] Compile in PostgreSQL support. (default=no)], +[ if test -x "$withval"; then + WHERE_PGSQL=$withval + else + WHERE_PGSQL="/usr" + fi +] +) + dnl Checks for libraries. if test "x$WHERE_MYSQL" != "x"; then @@ -47,6 +62,16 @@ ) fi +if test "x$WHERE_PGSQL" != "x"; then + LIBS="-L$WHERE_PGSQL/lib/pgsql" + AC_CHECK_LIB(pq, PQsetdbLogin, + [ + PGSQLCFLAGS="-L$WHERE_PGSQL/lib -I$WHERE_PGSQL/include/pgsql" + PGSQLLIB="-lpq" + AC_DEFINE(HAVE_PGSQL) + ] + ) +fi AC_CHECK_LIB(y, main,YLIB="$YLIB -ly",) AC_CHECK_LIB(z, zlibVersion) --- src/Makefile.am.orig Fri Mar 28 12:01:29 2003 +++ src/Makefile.am Fri Mar 28 12:09:52 2003 @@ -102,8 +102,8 @@ flow_export_SOURCES = flow-export.c flow_export_LDFLAGS = -L../lib -flow_export_CFLAGS = @MYSQLCFLAGS@ -flow_export_LDADD = -lft @MYSQLLIB@ +flow_export_CFLAGS = @MYSQLCFLAGS@ @PGSQLCFLAGS@ +flow_export_LDADD = -lft @MYSQLLIB@ @PGSQLLIB@ flow_export_DEPENDENCIES = ftbuild.h flow_header_SOURCES = flow-header.c --- src/flow-export.c.orig Fri Mar 28 11:39:33 2003 +++ src/flow-export.c Fri Mar 28 12:21:21 2003 @@ -60,6 +60,19 @@ #endif /* MYSQL */ +#ifdef HAVE_PGSQL + +#include + +#define DB_DEFAULT_DBHOST "localhost" +#define DB_DEFAULT_DBNAME "netflow" +#define DB_DEFAULT_DBPORT "5432" +#define DB_DEFAULT_DBTABLE "raw" +#define DB_DEFAULT_DBUSER "netflow" +#define DB_DEFAULT_DBPWD "netflow" + +#endif /* PGSQL*/ + #if HAVE_LL_STRTOUL #define strtoull strtoul #endif /* HAVE_LL_STRTOULL */ @@ -88,6 +101,7 @@ int format2(struct ftio *ftio, struct options *opt); int format3(struct ftio *ftio, struct options *opt); int format4(struct ftio *ftio, struct options *opt); +int format5(struct ftio *ftio, struct options *opt); int ftxfield_tocflow(u_int64 xfields, u_int32 *cfmask); @@ -97,9 +111,9 @@ void usage(void); -#define NFORMATS 5 /* nformats - 1 */ +#define NFORMATS 6 /* nformats - 1 */ struct jump format[] = {{format0}, {format1}, {format2}, {format3}, - {format4}}; + {format4}, {format5}}; int main(int argc, char **argv) { @@ -835,6 +849,109 @@ } /* format4 */ +/* + * function: format5 + * + * export flows into PostgreSQL Database + */ +int format5(struct ftio *ftio, struct options *opt) +{ +#ifdef HAVE_PGSQL + struct fts3rec_offsets fo; + struct ftver ftv; + char fields[1024], values[1024], query[3*1024]; + char *rec; + char *db_host, *db_name, *db_table, *db_user, *db_pwd, *db_tmp, *tmp; + char *db_port; + int len; + + PGconn *conn; + PGresult *res; + + db_host = DB_DEFAULT_DBHOST; + db_name = DB_DEFAULT_DBNAME; + db_port = DB_DEFAULT_DBPORT; + db_user = DB_DEFAULT_DBUSER; + db_table = DB_DEFAULT_DBTABLE; + db_pwd = DB_DEFAULT_DBPWD; + + /* parse URI string */ + + if (strlen(opt->dbaseURI)) { + + tmp = opt->dbaseURI; + + db_user = strsep(&tmp, ":"); + db_pwd = strsep(&tmp, ":"); + db_host = strsep(&tmp, ":"); + db_port = strsep(&tmp, ":"); + db_name = strsep(&tmp, ":"); + db_table = strsep(&tmp, ":"); + + if (!db_user || !db_pwd || !db_host || !db_tmp || !db_name || !db_table) { + fterr_warnx("Missing field in dbaseURI, expecting user:pwd:host:port:name:table."); + return -1; + } + + } /* dbaseURI */ + + ftio_get_ver(ftio, &ftv); + + fts3rec_compute_offsets(&fo, &ftv); + + /* remove invalid fields */ + opt->ft_mask &= ftrec_xfield(&ftv); + + /* generate the field names once */ + fmt_xfields_type(fields, opt->ft_mask); + + /* open PostgreSQL database */ + conn = PQsetdbLogin(db_host, db_port, (char *) NULL, (char *) NULL, db_name, db_user, db_pwd); + + if (PQstatus(conn) == CONNECTION_BAD) + fterr_errx(1,"PQsetdbLogin(): %s\n", PQerrorMessage(conn)); + + /* foreach flow */ + while ((rec = ftio_read(ftio))) { + + len = fmt_xfields_val(values, rec, &fo, opt->ft_mask, 1); + + /* form SQL query and execute it */ + if (len) { + strcpy (query, "INSERT INTO "); + strcat (query, db_table); + strcat (query, "("); + strcat (query, fields); + strcat (query, ") VALUES ("); + strcat (query, values); + strcat (query, ")"); + printf("field=%s\n val=%s\n query=%s\n", fields, values, query); + + res = PQexec(conn, query); + if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { + PQclear(res); + fterr_errx(1,"PQexec(): %s\n", PQerrorMessage(conn)); + } + + } + + ++opt->records; + + } /* while */ + + /* close database */ + PQfinish(conn); + +#else /* PGSQL */ + + fterr_warnx("Format not supported"); + +#endif /* PGSQL */ + + return 0; + +} /* format5 */ + int fmt_xfields_type(char *buf, u_int64 xfield) { int comma; @@ -1302,7 +1419,7 @@ void usage(void) { - fprintf(stderr, "Usage: flow-export [-h] [-d debug_level] [-f format] [-m mask_fields] -u [mySQL URI]\n"); + fprintf(stderr, "Usage: flow-export [-h] [-d debug_level] [-f format] [-m mask_fields] -u [database URI]\n"); fprintf(stderr, "\n%s version %s: built by %s\n", PACKAGE, VERSION, FT_PROG_BUILD); --- acconfig.h.orig Fri Mar 28 12:05:36 2003 +++ acconfig.h Fri Mar 28 12:05:48 2003 @@ -17,6 +17,9 @@ /* MYSQL */ #undef HAVE_MYSQL +/* PGSQL */ +#undef HAVE_PGSQL + /* DEC */ #undef HAVE_LL_STRTOUL