#include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include #endif #define NARGS 64 char *host_default = "127.0.0.1"; char *port_default = "47758"; char *host_str; char *port_str; // functions and notes // utility functions char *PING = "ping"; // ping bro instance connected to char *STATS = "show-cpu"; // cpu data char *MEM = "show-memory"; // memory data char *CONN = "show-conn"; // conection data char *HELP = "help"; // scan detect related functions char *ISHDROP = "is-dropped"; // see if provided IP has been dropped char *SCAN = "show-scan"; // show scan related numbers assosciated with an IP char *DROP = "drop"; // drop an IP char *UNDROP = "undrop"; // take an IP off the dropped host list, see below or this is pointless char *SCANRESET = "reset-scan"; // reset a given IP address' scan related values char *ALLOWDROP = "allow-drop"; // turn drop functionality on (default bahavior = F) char *SCANPAIR = "scan-pair"; // // sample policy modifications // note that *what* can be changes is more or less limited to tables and sets given that most of // what bro considers as dynamic can not be modified after runtime start. char *ONSCAN = "onscan"; // turn scan detection on char *OFFSCAN = "offscan"; // turn scan detection off char *TEST ="test"; char *AC ="ac"; char *NU ="null"; // prototypes size_t bufsplit(char *buf, size_t n, char **a); static void bro_pong_record(BroConn *conn, BroRecord *rec); static void addr_check_record(BroConn *conn, BroRecord *rec); static void return_cpu(BroConn *conn, double *interval); static void return_memory(BroConn *conn, BroRecord *rec); static void return_host_drop_check(BroConn *conn, BroRecord *rec); static void return_scan(BroConn *conn, BroRecord *rec); static void return_conn(BroConn *conn, BroRecord *rec); static void return_host_drop(BroConn *conn, BroRecord *rec); // ------------------------------------------------- // int main(int argc, char **argv) { int opt, port; BroConn *bc; extern char *optarg; extern int optind; char hostname[512]; host_str = host_default; port_str = port_default; bro_debug_calltrace = 1; bro_debug_messages = 1; while ( (opt = getopt(argc, argv, "p:h?")) != -1) { switch (opt) { case 'p': port_str = optarg; break; //default: //usage(); } } argc -= optind; argv += optind; if (argc > 0) host_str = argv[0]; port = strtol(port_str, NULL, 0); if (errno == ERANGE) { printf("Please provide a port number with -p.\n"); exit(-1); } snprintf(hostname, 512, "%s:%s", host_str, port_str); /* Connect to Bro */ if (! (bc = bro_connect_str(hostname, BRO_CFLAG_RECONNECT | BRO_CFLAG_ALWAYS_QUEUE))) { printf("Could not connect to Bro at %s:%s.\n", host_str, port_str); exit(-1); } // register the response events with the host we have connected to bro_event_registry_add(bc, "pong", (BroEventFunc) bro_pong_record); bro_event_registry_add(bc, "addr_checkR", (BroEventFunc) addr_check_record); bro_event_registry_add(bc, "return_cpu", (BroEventFunc) return_cpu); bro_event_registry_add(bc, "return_memory", (BroEventFunc) return_memory); bro_event_registry_add(bc, "return_host_drop_check", (BroEventFunc) return_host_drop_check); bro_event_registry_add(bc, "return_scan", (BroEventFunc) return_scan); bro_event_registry_add(bc, "return_conn", (BroEventFunc) return_conn); bro_event_registry_add(bc, "return_host_drop", (BroEventFunc) return_host_drop); bro_event_registry_request(bc); if (! bro_conn_await_handshake(bc, 10)) { printf("Could not complete handshake successfully.\n"); exit(-1); } printf("Handshake complete, starting shell...\n"); printf(" deliniate arguments w/ tabs\n"); // we are now connected to the bro instance, begin the command line fun //char** cp; int n, process; char *args[NARGS]; char command[BUFSIZ]; for (;;) { bro_conn_process_input(bc); printf("--> "); if ( fgets(command, sizeof(command), stdin) == NULL ) { putchar('\n'); exit(0); } // split up the command into words n = bufsplit(command, NARGS, args); // ignore blank lines if ( **args == '\0' ) continue; //int t; //for ( t=0;t<=n;++t) // printf("ARG(%d): |%s|\n", t,args[t]); // for now we assme that the command form is // command // not all that flexable... BroEvent *ev; BroRecord *rec = bro_record_new(); bro_conn_process_input(bc); process = 0; if ( strcmp(args[0],PING) == 0 ) { ev = bro_event_new("ping"); int seq = 1; double timestamp = bro_util_current_time(); bro_record_add_val(rec, "seq", BRO_TYPE_COUNT, &seq); bro_record_add_val(rec, "src_time", BRO_TYPE_TIME, ×tamp); bro_event_add_val(ev, BRO_TYPE_RECORD, rec); bro_record_free(rec); process=1; } else if ( strcmp(args[0],AC) == 0 ) { uint32 a = (uint32)inet_addr(args[1]); ev = bro_event_new("addr_check"); bro_record_add_val(rec, "checkA", BRO_TYPE_IPADDR, &a); bro_event_add_val(ev, BRO_TYPE_RECORD, rec); bro_record_free(rec); process=1; } else if ( strcmp(args[0], STATS) == 0 ) { ev = bro_event_new("show_cpu"); process=1; } else if ( strcmp(args[0], MEM) == 0 ) { ev = bro_event_new("show_memory"); process=1; } else if ( strcmp(args[0], NU) == 0 ) { ev = bro_event_new("null_event"); process=1; } else if ( strcmp(args[0], ISHDROP) == 0 ) { uint32 a = (uint32)inet_addr(args[1]); ev = bro_event_new("host_drop_check"); bro_record_add_val(rec, "checkA", BRO_TYPE_IPADDR, &a); bro_event_add_val(ev, BRO_TYPE_RECORD, rec); bro_record_free(rec); process=1; } else if ( strcmp(args[0], DROP) == 0 ) { uint32 a = (uint32)inet_addr(args[1]); ev = bro_event_new("host_drop"); bro_record_add_val(rec, "checkA", BRO_TYPE_IPADDR, &a); bro_event_add_val(ev, BRO_TYPE_RECORD, rec); bro_record_free(rec); process=1; } else if ( strcmp(args[0], UNDROP) == 0 ) { uint32 a = (uint32)inet_addr(args[1]); ev = bro_event_new("host_undrop"); bro_record_add_val(rec, "checkA", BRO_TYPE_IPADDR, &a); bro_event_add_val(ev, BRO_TYPE_RECORD, rec); bro_record_free(rec); process=1; } else if ( strcmp(args[0], SCAN) == 0 ) { // this looks at scan data assosciated with a // single IP address uint32 a = (uint32)inet_addr(args[1]); ev = bro_event_new("show_scan"); bro_record_add_val(rec, "checkA", BRO_TYPE_IPADDR, &a); bro_event_add_val(ev, BRO_TYPE_RECORD, rec); bro_record_free(rec); process=1; } else if ( strcmp(args[0], CONN) == 0 ) { ev = bro_event_new("show_conn"); process=1; } else if ( strcmp(args[0], ALLOWDROP) == 0 ) { ev = bro_event_new("allow_drop"); process=1; } if ( process != 0 ) { bro_event_send(bc, ev); bro_event_free(ev); bro_conn_process_input(bc); } else { printf("bad command\n"); } // this is in place to make sure that we wait around for // the external bro to (optionaly) return something sleep(1); } // end of shell loop bro_disconnect(bc); } // end of main size_t bufsplit(char *buf, size_t n, char **a) { int i; int nsplit; static char *splitch = "\t\n"; if ( buf != NULL && n == 0 ) { splitch = buf; return(1); } nsplit = 0; while ( nsplit < n ) { a[nsplit++] = buf; if ((buf = strpbrk(buf, splitch)) == NULL) break; *(buf++) = '\0'; if (*buf == '\0' ) break; } buf = strrchr(a[nsplit-1], '\0'); for (i=nsplit; i