int gcache_del(struct gcache *gc, char *keystr) { int rc; MDB_val key; MDB_txn *txn; rc = mdb_txn_begin(gc->env, NULL, 0, &txn); if (rc != 0) { olog(LOG_ERR, "gcache_del: mdb_txn_begin: %s", mdb_strerror(rc)); return (rc); } key.mv_data = keystr; key.mv_size = strlen(keystr); rc = mdb_del(txn, gc->dbi, &key, NULL); if (rc != 0 && rc != MDB_NOTFOUND) { olog(LOG_ERR, "gcache_del: mdb_del: %s", mdb_strerror(rc)); /* fall through to commit */ } rc = mdb_txn_commit(txn); if (rc) { olog(LOG_ERR, "gcache_del: mdb_txn_commit: (%d) %s", rc, mdb_strerror(rc)); mdb_txn_abort(txn); } return (rc); }
static void hpc_tail_logs_dumpper() { uint64_t nts = dsn_now_ns(); std::stringstream log; log << ::dsn::tools::spec().coredump_dir << "/hpc_tail_logs." << nts << ".log"; std::ofstream olog(log.str().c_str()); std::vector<int> threads; tail_log_manager::instance().get_all_keys(threads); for (auto& tid : threads) { __tail_log_info__* log; if (!tail_log_manager::instance().get(tid, log)) continue; tail_log_hdr *hdr = log->last_hdr, *tmp = log->last_hdr; while (tmp != nullptr && tmp != hdr) { if (!tmp->is_valid()) break; char* llog = (char*)(tmp)-tmp->length; olog << llog << std::endl; // try previous log tmp = tmp->prev; }; } olog.close(); }
void gcache_load(char *path, char *lmdbname) { struct gcache *gc; char buf[8192], *bp; if ((gc = gcache_open(path, lmdbname, FALSE)) == NULL) { olog(LOG_ERR, "gcache_load: gcache_open"); return; } while (fgets(buf, sizeof(buf), stdin) != NULL) { if ((bp = strchr(buf, '\r')) != NULL) *bp = 0; if ((bp = strchr(buf, '\n')) != NULL) *bp = 0; if ((bp = strchr(buf, ' ')) != NULL) { *bp = 0; if (gcache_put(gc, buf, bp+1) != 0) { fprintf(stderr, "Cannot load key\n"); } } } gcache_close(gc); }
long gcache_get(struct gcache *gc, char *k, char *buf, long buflen) { MDB_val key, data; MDB_txn *txn; int rc; long len = -1; if (gc == NULL) return (-1); rc = mdb_txn_begin(gc->env, NULL, MDB_RDONLY, &txn); if (rc) { olog(LOG_ERR, "gcache_get: mdb_txn_begin: (%d) %s", rc, mdb_strerror(rc)); return (-1); } key.mv_data = k; key.mv_size = strlen(k); rc = mdb_get(txn, gc->dbi, &key, &data); if (rc != 0) { if (rc != MDB_NOTFOUND) { printf("get: %s\n", mdb_strerror(rc)); } else { // printf(" [%s] not found\n", k); } } else { len = (data.mv_size < buflen) ? data.mv_size : buflen; memcpy(buf, data.mv_data, len); // printf("%s\n", (char *)data.mv_data); } mdb_txn_commit(txn); return (len); }
int emit_init() { char *host, *buf = strdup(config.emit_option), *bp; int port; if ((bp = strchr(buf, '/')) == NULL) { fprintf(stderr, "Redis emitter option is bad (no slash)\n"); return (1); } *bp = 0; port = atoi(bp+1); host = buf; config.rediscon = redisConnect(host, port); if (config.rediscon->err) { fprintf(stderr, "Cannot connect to Redis at %s:%d: %s\n", host, port, config.rediscon->errstr); return (1); } olog("[*] Connected to Redis at %s:%d with nsid=%s (topic=%s)\n\n", host, port, config.nsid, config.emit_topic); free(buf); return (0); }
int load_config() { FILE *configfile; if ((configfile = fopen(configpath, "r")) != NULL) { int i=0; char buf; DEF_LANG=(char *)malloc(50); PRINTER=(char *)malloc(50); GFX_VIEWER=(char *)malloc(50); BROWSER=(char *)malloc(50); while ( buf != 10) { buf=fgetc(configfile); if (buf != 10) DEF_LANG[i]=buf; i++; } i=0; buf=0; while ( buf != 10) { buf=fgetc(configfile); if (buf != 10) PRINTER[i]=buf; i++; } i=0; buf=0; while ( buf != 10) { buf=fgetc(configfile); if (buf != 10) GFX_VIEWER[i]=buf; i++; } i=0; buf=0; while ( buf != 10) { buf=fgetc(configfile); if (buf != 10) BROWSER[i]=buf; i++; } fclose(configfile); } else { olog(14); print_status_bar("Could not open configfile"); return 14; } return 0; }
void hooks_exit(struct luadata *ld, char *reason) { if (ld) { l_function(ld->L, "otr_exit"); olog(LOG_NOTICE, "unloading Lua: %s", reason); free(ld->script); lua_close(ld->L); free(ld); } }
JsonNode *gcache_json_get(struct gcache *gc, char *k) { MDB_val key, data; MDB_txn *txn; int rc; JsonNode *json = NULL; if (gc == NULL) return (NULL); rc = mdb_txn_begin(gc->env, NULL, MDB_RDONLY, &txn); if (rc) { olog(LOG_ERR, "gcache_json_get: mdb_txn_begin: (%d) %s", rc, mdb_strerror(rc)); return (NULL); } key.mv_data = k; key.mv_size = strlen(k); rc = mdb_get(txn, gc->dbi, &key, &data); if (rc != 0) { if (rc != MDB_NOTFOUND) { olog(LOG_ERR, "gcache_json_get(%s): %s", k, mdb_strerror(rc)); } else { // printf(" [%s] not found\n", k); json = NULL; } } else { // printf("%s\n", (char *)data.mv_data); if ((json = json_decode((char *)data.mv_data)) == NULL) { olog(LOG_ERR, "gcache_json_get: Cannot decode JSON from lmdb"); } } mdb_txn_commit(txn); return (json); }
int gcache_put(struct gcache *gc, char *keystr, char *payload) { int rc; MDB_val key, data; MDB_txn *txn; if (gc == NULL) return (1); if (strcmp(payload, "DELETE") == 0) return gcache_del(gc, keystr); rc = mdb_txn_begin(gc->env, NULL, 0, &txn); if (rc != 0) { olog(LOG_ERR, "gcache_put: mdb_txn_begin: %s", mdb_strerror(rc)); return (-1); } key.mv_data = keystr; key.mv_size = strlen(keystr); data.mv_data = payload; data.mv_size = strlen(payload) + 1; /* including nul-byte so we can * later decode string directly * from this buffer */ rc = mdb_put(txn, gc->dbi, &key, &data, 0); if (rc != 0) { olog(LOG_ERR, "gcache_put: mdb_put: %s", mdb_strerror(rc)); /* fall through to commit */ } rc = mdb_txn_commit(txn); if (rc) { olog(LOG_ERR, "gcache_put: mdb_txn_commit: (%d) %s", rc, mdb_strerror(rc)); mdb_txn_abort(txn); } return (rc); }
void game_over() { if (config.inpacket == 0) { expire_all_dns_records(); print_pdns_stats(); if (config.handle != NULL) pcap_close(config.handle); config.handle = NULL; end_all_sessions(); free_config(); olog("\n[*] passivedns ended.\n"); exit(0); } config.intr_flag |= INTERRUPT_END; }
void storage_init(int revgeo) { char path[BUFSIZ]; setenv("TZ", "UTC", 1); if (revgeo) { snprintf(path, BUFSIZ, "%s/ghash", STORAGEDIR); gc = gcache_open(path, NULL, TRUE); if (gc == NULL) { olog(LOG_ERR, "storage_init(): gc is NULL"); } } }
int emit_init() { config.zcontext = zmq_init(1); config.zpublisher = zmq_socket(config.zcontext, ZMQ_PUB); if (zmq_bind(config.zpublisher, config.emit_option) != 0) { perror("zmq_bind"); return (1); } sleep(2); olog("[*] Bound as 0MQ publisher at %s with nsid=%s\n\n", config.emit_option, config.nsid); config.ztopic = strdup("dns1"); return (0); }
Bool DBConnection_ORACLE::connect(char **args, int numargs) { if (isConnected) return True; // MW-2014-01-30: [[ Sqlite382 ]] Relaxed revdb_connect() so it only checks for at least // one argument - we need at least 4 though. if (numargs < 4) return False; char *t_user; t_user = args[2]; char *t_password; t_password = args[3]; char *t_database; t_database = args[1]; char *t_host; t_host = args[0]; if (t_user[0] == '\0') t_user = NULL; if (t_password[0] == '\0') t_password = NULL; memset(hda,0,HDA_SIZE); sword t_error; t_error = olog(&lda, hda, (ub1 *)t_user, -1, (ub1 *)t_password, -1, (ub1 *)t_host, -1, OCI_LM_DEF); if (t_error != 0) { // OK-2010-02-24: Oracle connection should return an error message if it failed. // The 600 char buffer size was taken from example code on Oracle's site. char *t_error_message; t_error_message = (char *)malloc(600); oerhms(&lda, lda .rc, (OraText *)t_error_message, 600); m_error = t_error_message; return False; } connectionType = CT_ORACLE, isConnected = True; return True; }
static int l_function(lua_State *L, char *name) { int rc = 0; lua_getglobal(L, name); if (lua_type(L, -1) != LUA_TFUNCTION) { olog(LOG_ERR, "Cannot invoke Lua function %s: %s\n", name, lua_tostring(L, -1)); rc = 1; } else { lua_call(L, 0, 1); rc = (int)lua_tonumber(L, -1); lua_pop(L, 1); } lua_settop(L, 0); return (rc); }
FILE *pathn(char *mode, char *prefix, UT_string *user, UT_string *device, char *suffix) { static UT_string *path = NULL; time_t now; utstring_renew(path); ut_lower(user); if (device) { ut_lower(device); utstring_printf(path, "%s/%s/%s/%s", STORAGEDIR, prefix, UB(user), UB(device)); } else { utstring_printf(path, "%s/%s/%s", STORAGEDIR, prefix, UB(user)); } ut_clean(path); if (mkpath(UB(path)) < 0) { olog(LOG_ERR, "Cannot create directory at %s: %m", UB(path)); return (NULL); } #if 0 if (device) { utstring_printf(path, "/%s-%s.%s", UB(user), UB(device), suffix); } else { utstring_printf(path, "/%s.%s", UB(user), suffix); } #endif if (strcmp(prefix, "rec") == 0) { time(&now); utstring_printf(path, "/%s.%s", yyyymm(now), suffix); } else { utstring_printf(path, "/%s.%s", UB(user), suffix); } ut_clean(path); return (fopen(UB(path), mode)); }
int gcache_json_put(struct gcache *gc, char *keystr, JsonNode *json) { int rc; char *js; if (gc == NULL) return (1); if ((js = json_stringify(json, NULL)) == NULL) { olog(LOG_ERR, "gcache_json_put: CAN'T stringify JSON"); return (1); } rc = gcache_put(gc, keystr, js); free(js); return (rc); }
int emit_init() { char *host, *buf = strdup(config.emit_option), *bp; int port, rc; if ((bp = strchr(buf, '/')) == NULL) { fprintf(stderr, "MQTT emitter option is bad (no slash)\n"); return (1); } *bp = 0; port = atoi(bp+1); host = buf; mosquitto_lib_init(); config.mosq = mosquitto_new(NULL, true, NULL); if (!config.mosq) { fprintf(stderr, "Error: Out of memory.\n"); mosquitto_lib_cleanup(); return 1; } rc = mosquitto_connect(config.mosq, host, port, 60); if (rc) { if (rc == MOSQ_ERR_ERRNO) { char err[1024]; strerror_r(errno, err, 1024); fprintf(stderr, "Error connecting to %s:%d: %s\n", host, port, err); } else { fprintf(stderr, "Unable to connect (%d).\n", rc); } mosquitto_lib_cleanup(); return rc; } mosquitto_loop_start(config.mosq); olog("[*] Connected to MQTT at %s:%d with nsid=%s (topic=%s)\n\n", host, port, config.nsid, config.emit_topic); free(buf); return (0); }
int dataHandler(long param, ooid_t ooid, const oval_t * pval) { owquark_t info; char str_buf[80]; oval_t tmp_val; all_change_qty++; owatchGetInfoByOoid(ooid, &info); tmp_val.type = 's'; strcpy(str_buf, "???"); owatchConvertValue(pval, &tmp_val, str_buf, sizeof(str_buf)); if (++data_count % 10000 == 0 && print_all) { olog("ooid=%ld name=\"%s\" type='%c' undef=%d len=%d value=\"%s\"", ooid, info.desc, pval->type, pval->undef, pval->len, str_buf); } return 0; }
void a_dump_payload(const uint8_t* data,uint16_t dlen) { uint8_t tbuf[PKT_MAXPAY+2]; uint8_t* t = tbuf; uint8_t i; uint8_t max = dlen > PKT_MAXPAY ? PKT_MAXPAY : dlen; if (!dlen) { olog(" # No Payload...\n"); return; } for (i=0;i<max;i++) { if (isprint(*data)) *(t++) = *data; else if (!*data) *(t++) = '?'; else *(t++) = '.'; data++; } *t = 0; plog( " # Payload: \"%s\"%s",tbuf,dlen > PKT_MAXPAY ? "...\n" : "\n"); }
static void do_hook(char *hookname, struct udata *ud, char *topic, JsonNode *fullo) { struct luadata *ld = ud->luadata; char *_type = "unknown"; JsonNode *j; lua_settop(ld->L, 0); lua_getglobal(ld->L, hookname); if (lua_type(ld->L, -1) != LUA_TFUNCTION) { olog(LOG_NOTICE, "cannot invoke %s in Lua script", hookname); return; } lua_pushstring(ld->L, topic); /* arg1: topic */ if ((j = json_find_member(fullo, "_type")) != NULL) { if (j->tag == JSON_STRING) _type = j->string_; } lua_pushstring(ld->L, _type); /* arg2: record type */ lua_newtable(ld->L); /* arg3: table */ json_foreach(j, fullo) { lua_pushstring(ld->L, j->key); /* table key */ if (j->tag == JSON_STRING) { lua_pushstring(ld->L, j->string_); } else if (j->tag == JSON_NUMBER) { lua_pushnumber(ld->L, j->number_); } else if (j->tag == JSON_NULL) { lua_pushnil(ld->L); } else if (j->tag == JSON_BOOL) { lua_pushboolean(ld->L, j->bool_); } lua_rawset(ld->L, -3); }
void game_over() { if (config.inpacket == 0) { expire_all_dns_records(); print_pdns_stats(); if (config.handle != NULL) pcap_close(config.handle); config.handle = NULL; #ifdef HAVE_PFRING if (config.use_pfring && config.pfhandle != NULL) { pfring_breakloop(config.pfhandle); pfring_close(config.pfhandle); } #endif /* HAVE_PFRING */ end_all_sessions(); if (config.logfile_fd != NULL && config.logfile_fd != stdout) fclose(config.logfile_fd); if (config.logfile_nxd_fd != NULL && config.logfile_nxd_fd != stdout) fclose(config.logfile_nxd_fd); free_config(); olog("\n[*] passivedns ended.\n"); exit(0); } config.intr_flag |= INTERRUPT_END; }
void gcache_dump(char *path, char *lmdbname) { struct gcache *gc; MDB_val key, data; MDB_txn *txn; MDB_cursor *cursor; int rc; if ((gc = gcache_open(path, lmdbname, TRUE)) == NULL) { fprintf(stderr, "Cannot open lmdb/%s at %s\n", lmdbname ? lmdbname : "NULL", path); return; } key.mv_size = 0; key.mv_data = NULL; rc = mdb_txn_begin(gc->env, NULL, MDB_RDONLY, &txn); if (rc) { olog(LOG_ERR, "gcache_dump: mdb_txn_begin: (%d) %s", rc, mdb_strerror(rc)); gcache_close(gc); return; } rc = mdb_cursor_open(txn, gc->dbi, &cursor); /* -1 because we 0-terminate strings */ while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { printf("%*.*s %*.*s\n", (int)key.mv_size, (int)key.mv_size, (char *)key.mv_data, (int)data.mv_size - 1, (int)data.mv_size - 1, (char *)data.mv_data); } mdb_cursor_close(cursor); mdb_txn_commit(txn); gcache_close(gc); }
void show_version() { olog("\n"); olog("[*] PassiveDNS %s\n", VERSION); olog("[*] By Edward Bjarte Fjellskål <*****@*****.**>\n"); olog("[*] Using %s\n", pcap_lib_version()); olog("[*] Using ldns version %s\n",ldns_version()); #ifdef HAVE_PFRING /* Print PF_RING version if PF_RING is used */ if (config.use_pfring) { char pfv[50]; u_int32_t pf_version; pfring_version(config.pfhandle, &pf_version); snprintf(pfv, 50, "%d.%d.%d", (pf_version & 0xFFFF0000) >> 16, (pf_version & 0x0000FF00) >> 8, pf_version & 0x000000FF); olog("[*] Using PF_RING version %s\n", pfv); }
void get_defaults(char *filename, struct udata *ud) { config_t cfg, *cf; const char *value; #if LIBCONFIG_VER_MAJOR == 1 # if LIBCONFIG_VER_MINOR >= 4 int ival; # endif # else long ival; #endif if (access(filename, R_OK) == -1) { olog(LOG_ERR, "Cannot read defaults from %s: %s", filename, strerror(errno)); return; } config_init(cf = &cfg); if (!config_read_file(cf, filename)) { olog(LOG_ERR, "Syntax error in %s:%d - %s", filename, config_error_line(cf), config_error_text(cf)); config_destroy(cf); exit(2); } if (config_lookup_string(cf, "OTR_STORAGEDIR", &value) != CONFIG_FALSE) strcpy(STORAGEDIR, value); if (ud == NULL) { /* being invoked by ocat; return */ return; } #if WITH_MQTT if (config_lookup_string(cf, "OTR_HOST", &value) != CONFIG_FALSE) { if (ud->hostname) free(ud->hostname); ud->hostname = (value) ? strdup(value) : NULL; } if (config_lookup_int(cf, "OTR_PORT", &ival) != CONFIG_FALSE) { ud->port = ival; } if (config_lookup_string(cf, "OTR_USER", &value) != CONFIG_FALSE) { if (ud->username) free(ud->username); ud->username = (value) ? strdup(value) : NULL; } if (config_lookup_string(cf, "OTR_PASS", &value) != CONFIG_FALSE) { if (ud->password) free(ud->password); ud->password = (value) ? strdup(value) : NULL; } if (config_lookup_int(cf, "OTR_QOS", &ival) != CONFIG_FALSE) { ud->qos = ival; } if (config_lookup_string(cf, "OTR_CLIENTID", &value) != CONFIG_FALSE) { if (ud->clientid) free(ud->clientid); ud->clientid = (value) ? strdup(value) : NULL; } if (config_lookup_string(cf, "OTR_CAFILE", &value) != CONFIG_FALSE) { if (ud->cafile) free(ud->cafile); ud->cafile = (value) ? strdup(value) : NULL; } /* Topics is a blank-separated string of words; split and add to JSON array */ if (config_lookup_string(cf, "OTR_TOPICS", &value) != CONFIG_FALSE) { char *parts[40]; int np, n; if (ud->topics) json_delete(ud->topics); if ((np = splitter((char *)value, " ", parts)) < 1) { olog(LOG_ERR, "Illegal value in OTR_TOPICS"); exit(2); } ud->topics = json_mkarray(); for (n = 0; n < np; n++) { json_append_element(ud->topics, json_mkstring(parts[n])); } splitterfree(parts); } #endif /* WITH_MQTT */ if (config_lookup_string(cf, "OTR_GEOKEY", &value) != CONFIG_FALSE) { if (ud->geokey) free(ud->geokey); ud->geokey = (value) ? strdup(value) : NULL; } if (config_lookup_int(cf, "OTR_PRECISION", &ival) != CONFIG_FALSE) { geohash_setprec(ival); } #if WITH_HTTP if (config_lookup_string(cf, "OTR_HTTPHOST", &value) != CONFIG_FALSE) { if (ud->http_host) free(ud->http_host); ud->http_host = (value) ? strdup(value) : NULL; } if (config_lookup_int(cf, "OTR_HTTPPORT", &ival) != CONFIG_FALSE) { ud->http_port = ival; } if (config_lookup_string(cf, "OTR_HTTPLOGDIR", &value) != CONFIG_FALSE) { if (ud->http_logdir) free(ud->http_logdir); ud->http_logdir = (value) ? strdup(value) : NULL; } if (config_lookup_string(cf, "OTR_BROWSERAPIKEY", &value) != CONFIG_FALSE) { if (ud->browser_apikey) free(ud->browser_apikey); ud->browser_apikey = (value) ? strdup(value) : NULL; } #endif /* WITH_HTTP */ #if WITH_LUA if (config_lookup_string(cf, "OTR_LUASCRIPT", &value) != CONFIG_FALSE) { if (ud->luascript) free(ud->luascript); ud->luascript = (value) ? strdup(value) : NULL; } #endif config_destroy(cf); }
void usage() { olog("\n"); olog("USAGE:\n"); olog(" $ passivedns [options]\n\n"); olog(" OPTIONS:\n\n"); olog(" -i <iface> Network device <iface> (default: eth0).\n"); olog(" -r <file> Read pcap <file>.\n"); #ifdef HAVE_PFRING olog(" -n Use PF_RING.\n"); olog(" -c <cluster_id> Set PF_RING cluster_id.\n"); #endif /* HAVE_PFRING */ olog(" -l <file> Logfile normal queries (default: /var/log/passivedns.log).\n"); olog(" -L <file> Logfile for SRC Error queries (default: /var/log/passivedns.log).\n"); olog(" -y Log to syslog (uses local7 syslog facility).\n"); olog(" -Y Log NXDOMAIN to syslog.\n"); olog(" -d <delimiter> Delimiter between fields in log file (default: ||).\n"); #ifdef HAVE_JSON olog(" -j Use JSON as output in log file.\n"); olog(" -J Use JSON as output in NXDOMAIN log file.\n"); #endif /* HAVE_JSON */ olog(" -f <fields> Choose which fields to print (default: -f SMcsCQTAtn).\n"); olog(" -b 'BPF' Berkley Packet Filter (default: 'port 53').\n"); olog(" -p <file> Name of pid file (default: /var/run/passivedns.pid).\n"); olog(" -S <mem> Soft memory limit in MB (default: 256).\n"); olog(" -C <sec> Seconds to cache DNS objects in memory (default: %u).\n", DNSCACHETIMEOUT); olog(" -P <sec> Seconds between printing duplicate DNS info (default %u).\n", DNSPRINTTIME); olog(" -X <flags> Manually set DNS RR Types to care about (default: -X 46CDNPRS).\n"); olog(" -u <uid> User ID to drop privileges to.\n"); olog(" -g <gid> Group ID to drop privileges to.\n"); olog(" -T <dir> Directory to chroot into.\n"); olog(" -D Run as daemon.\n"); olog(" -V Show version and exit.\n"); olog(" -h This help message.\n\n"); olog(" FIELDS:\n"); olog("\n"); olog(" S: Timestamp(s) M: Timestamp(ms) c: Client IP s: Server IP\n"); olog(" C: Class Q: Query T: Type A: Answer\n"); olog(" t: TTL n: Count\n"); olog("\n"); olog(" FLAGS:\n"); olog("\n"); olog(" * For Record Types:\n"); olog(" 4:A 6:AAAA C:CNAME D:DNAME N:NAPTR O:SOA L:LOC F:SPF\n"); olog(" P:PTR R:RP S:SRV T:TXT M:MX n:NS d:DNSEC I:HINFO\n"); olog(" l:TLSA A:CAA H:SSHFP h:DHCID E:CERT K:KX b:AFSDB p:IPSECKEY\n"); olog(" L also enables GPOS\n"); olog(" d enables DS, DNSKEY, NSEC, NSEC3, NSEC3PARAM, RRSIG, DLV, CDS\n"); olog("\n"); olog(" * For Server Return Code (SRC) Errors:\n"); olog(" f:FORMERR s:SERVFAIL x:NXDOMAIN o:NOTIMPL r:REFUSED\n"); olog(" y:YXDOMAIN e:YXRRSET t:NXRRSET a:NOTAUTH z:NOTZONE\n"); olog("\n"); }
void print_pdns_stats() { olog("\n"); olog("-- Total DNS records allocated :%12u\n",config.p_s.dns_records); olog("-- Total DNS assets allocated :%12u\n",config.p_s.dns_assets); olog("-- Total DNS packets over IPv4/TCP :%12u\n",config.p_s.ip4_dns_tcp); olog("-- Total DNS packets over IPv6/TCP :%12u\n",config.p_s.ip6_dns_tcp); olog("-- Total DNS packets over TCP decoded :%12u\n",config.p_s.ip4_dec_tcp_ok + config.p_s.ip6_dec_tcp_ok); olog("-- Total DNS packets over TCP failed :%12u\n",config.p_s.ip4_dec_tcp_er + config.p_s.ip6_dec_tcp_er); olog("-- Total DNS packets over IPv4/UDP :%12u\n",config.p_s.ip4_dns_udp); olog("-- Total DNS packets over IPv6/UDP :%12u\n",config.p_s.ip6_dns_udp); olog("-- Total DNS packets over UDP decoded :%12u\n",config.p_s.ip4_dec_udp_ok + config.p_s.ip6_dec_udp_ok); olog("-- Total DNS packets over UDP failed :%12u\n",config.p_s.ip4_dec_udp_er + config.p_s.ip6_dec_udp_er); olog("-- Total packets received from libpcap :%12u\n",config.p_s.got_packets); olog("-- Total Ethernet packets received :%12u\n",config.p_s.eth_recv); olog("-- Total VLAN packets received :%12u\n",config.p_s.vlan_recv); }
oret_t ohubHandleMsgSend(struct OhubNetWatch_st * pnwatch, OhubAgent_t * pagent, /* FIXME: asymmetric ! */ int kind, int type, int len, char *buf, const char *url) { static const char *me = "handleMsgSend"; ulong_t ulv; ushort_t usv; ulong_t m_op; int s_len, d_len, m_len; char *m_dest; OhubMsgNode_t *pnode = NULL; OhubMsgClassNode_t *pcn; OhubMsgClass_t *pclass; ulong_t reply[2]; int m_klass, m_type; oret_t rc; int err = OK; if ((pnwatch && pagent) || (!pnwatch && !pagent)) { ohubLog(1, "%s: invalid references", me); return ERROR; } if (len < 18) { ohubLog(5, "%s: too short message len=%d from %s", me, len, url); return ERROR; } ulv = *(ulong_t *)(buf + 0); m_op = OUNTOHL(ulv); usv = *(ushort_t *)(buf + 8); m_len = OUNTOHS(usv); usv = *(ushort_t *)(buf + 10); s_len = OUNTOHS(usv); usv = *(ushort_t *)(buf + 12); d_len = OUNTOHS(usv); usv = *(ushort_t *)(buf + 14); m_klass = OUNTOHS(usv); usv = *(ushort_t *)(buf + 16); m_type = OUNTOHS(usv); if (len != 18 + s_len + d_len + m_len) { ohubLog(5, "%s: invalid message len=%d from %s", me, len, url); return ERROR; } if (d_len > 0) { /* targeted message */ m_dest = buf + 18 + s_len; for (pnode = ohub_msg_nodes; NULL != pnode; pnode = pnode->next) { if (0 == strncmp(pnode->name, m_dest, d_len) && 0 == pnode->name[d_len]) { break; } } if (NULL == pnode) { if (ohub_verb > 4) { char *dest = oxnew(char, d_len); oxbcopy(m_dest, dest, d_len); dest[d_len] = '\0'; olog("%s: no target `%s' for msg(slen=%d,dlen=%d) from `%s'", me, dest, s_len, d_len, url); oxfree(dest); } err = OLANG_ERR_RCVR_OFF; } else if (pnode->is_full) {
void usage() { olog("\n"); olog("USAGE:\n"); olog(" $ passivedns [options]\n\n"); olog(" passivedns version %s\n",VERSION); olog(" %s\n", pcap_lib_version()); olog("\n"); olog(" OPTIONS:\n"); olog("\n"); olog(" -i <iface> Network device <iface> (default: eth0).\n"); olog(" -r <file> Read pcap <file>.\n"); olog(" -l <file> Name of the logfile (default: /var/log/passivedns.log).\n"); olog(" -L <file> Name of NXDOMAIN logfile (default: /var/log/passivedns.log).\n"); olog(" -b 'BPF' Berkley Packet Filter (default: 'port 53').\n"); olog(" -p <file> Name of pid file (default: /var/run/passivedns.pid).\n"); olog(" -S <mem> Soft memory limit in MB (default: 256).\n"); olog(" -C <sec> Seconds to cache DNS objects in memory (default %u).\n",DNSCACHETIMEOUT); olog(" -P <sec> Seconds between printing duplicate DNS info (default %u).\n",DNSPRINTTIME); olog(" -X <flags> Manually set DNS RR Types to care about(Default -X 46CDNPRS).\n"); olog(" -u <uid> User ID to drop privileges to.\n"); olog(" -g <gid> Group ID to drop privileges to.\n"); olog(" -T <dir> Directory to chroot into.\n"); olog(" -D Run as daemon.\n"); olog(" -h This help message.\n\n"); olog(" FLAGS:\n"); olog("\n"); olog(" 4:A 6:AAAA C:CNAME D:DNAME N:NAPTR O:SOA\n"); olog(" P:PTR R:RP S:SRV T:TXT M:MX n:NS\n"); olog(" x:NXD\n"); olog("\n"); }
/* magic main */ int main(int argc, char *argv[]) { int ch = 0; // verbose_already = 0; int daemon = 0; memset(&config, 0, sizeof(globalconfig)); //set_default_config_options(); config.inpacket = config.intr_flag = 0; config.dnslastchk = 0; //char *pconfile; #define BPFF "port 53" config.bpff = BPFF; config.logfile = "/var/log/passivedns.log"; config.logfile_nxd = "/var/log/passivedns.log"; config.pidfile = "/var/run/passivedns.pid"; config.mem_limit_max = (256 * 1024 * 1024); // 256 MB - default try to limit dns caching to this config.dnsprinttime = DNSPRINTTIME; config.dnscachetimeout = DNSCACHETIMEOUT; config.dnsf = 0; config.dnsf |= DNS_CHK_A; config.dnsf |= DNS_CHK_AAAA; config.dnsf |= DNS_CHK_PTR; config.dnsf |= DNS_CHK_CNAME; config.dnsf |= DNS_CHK_DNAME; config.dnsf |= DNS_CHK_NAPTR; config.dnsf |= DNS_CHK_RP; config.dnsf |= DNS_CHK_SRV; // config.dnsf |= DNS_CHK_TXT; // config.dnsf |= DNS_CHK_SOA; // config.dnsf |= DNS_CHK_NS; // config.dnsf |= DNS_CHK_MX; // config.dnsf |= DNS_CHK_NXDOMAIN; signal(SIGTERM, game_over); signal(SIGINT, game_over); signal(SIGQUIT, game_over); signal(SIGALRM, sig_alarm_handler); #define ARGS "i:r:l:L:hb:Dp:C:P:S:X:u:g:T:" while ((ch = getopt(argc, argv, ARGS)) != -1) switch (ch) { case 'i': config.dev = strdup(optarg); break; case 'r': config.pcap_file = strdup(optarg); break; case 'L': config.logfile_nxd = strdup(optarg); break; case 'l': config.logfile = strdup(optarg); break; case 'b': config.bpff = strdup(optarg); break; case 'p': config.pidfile = strdup(optarg); break; case 'C': config.dnscachetimeout = strtol(optarg, NULL, 0); break; case 'P': config.dnsprinttime = strtol(optarg, NULL, 0); break; case 'S': config.mem_limit_max = (strtol(optarg, NULL, 0) * 1024 * 1024); break; case 'X': parse_dns_flags(optarg); break; case 'D': daemon = 1; break; case 'T': config.chroot_dir = strdup(optarg); config.chroot_flag = 1; break; case 'u': config.user_name = strdup(optarg); config.drop_privs_flag = 1; break; case 'g': config.group_name = strdup(optarg); config.drop_privs_flag = 1; break; case 'h': usage(); exit(0); break; case '?': elog("unrecognized argument: '%c'\n", optopt); break; default: elog("Did not recognize argument '%c'\n", ch); } olog("\n[*] Running passivedns %s\n", VERSION); olog(" Using %s\n", pcap_lib_version()); if (config.pcap_file) { /* Read from PCAP file specified by '-r' switch. */ olog("[*] Reading from file %s\n", config.pcap_file); if (!(config.handle = pcap_open_offline(config.pcap_file, config.errbuf))) { olog("[*] Unable to open %s. (%s)", config.pcap_file, config.errbuf); } } else { /* * look up an available device if non specified */ if (config.dev == 0x0) config.dev = pcap_lookupdev(config.errbuf); olog("[*] Device: %s\n", config.dev); if ((config.handle = pcap_open_live(config.dev, SNAPLENGTH, 1, 500, config.errbuf)) == NULL) { olog("[*] Error pcap_open_live: %s \n", config.errbuf); exit(1); } /* * B0rk if we see an error... */ if (strlen(config.errbuf) > 0) { elog("[*] Error errbuf: %s \n", config.errbuf); exit(1); } if(config.chroot_dir){ olog("[*] Chrooting to dir '%s'..\n", config.chroot_dir); if(set_chroot()){ elog("[!] failed to chroot\n"); exit(1); } } if (config.drop_privs_flag) { olog("[*] Dropping privs...\n"); drop_privs(); } if (daemon) { if (!is_valid_path(config.pidfile)) elog("[*] Unable to create pidfile '%s'\n", config.pidfile); openlog("passivedns", LOG_PID | LOG_CONS, LOG_DAEMON); olog("[*] Daemonizing...\n\n"); daemonize(); } } if (config.handle == NULL) { game_over(); return (1); } /** segfaults on empty pcap! */ if ((pcap_compile(config.handle, &config.cfilter, config.bpff, 1, config.net_mask)) == -1) { olog("[*] Error pcap_compile user_filter: %s\n", pcap_geterr(config.handle)); exit(1); } if (pcap_setfilter(config.handle, &config.cfilter)) { olog("[*] Unable to set pcap filter! %s", pcap_geterr(config.handle)); } alarm(TIMEOUT); olog("[*] Sniffing...\n\n"); pcap_loop(config.handle, -1, got_packet, NULL); game_over(); return (0); }
static int perform_oracle_search(uschar *query, uschar *server, uschar **resultptr, uschar **errmsg, BOOL *defer_break) { Cda_Def *cda = NULL; struct cda_def *oracle_handle = NULL; Ora_Describe *desc = NULL; Ora_Define *def = NULL; void *hda = NULL; int i; int ssize = 0; int offset = 0; int yield = DEFER; unsigned int num_fields = 0; uschar *result = NULL; oracle_connection *cn = NULL; uschar *server_copy = NULL; uschar *sdata[4]; uschar tmp[1024]; /* Disaggregate the parameters from the server argument. The order is host, database, user, password. We can write to the string, since it is in a nextinlist temporary buffer. The copy of the string that is used for caching has the password removed. This copy is also used for debugging output. */ for (i = 3; i > 0; i--) { uschar *pp = Ustrrchr(server, '/'); if (pp == NULL) { *errmsg = string_sprintf("incomplete ORACLE server data: %s", server); *defer_break = TRUE; return DEFER; } *pp++ = 0; sdata[i] = pp; if (i == 3) server_copy = string_copy(server); /* sans password */ } sdata[0] = server; /* What's left at the start */ /* If the database is the empty string, set it NULL - the query must then define it. */ if (sdata[1][0] == 0) sdata[1] = NULL; /* See if we have a cached connection to the server */ for (cn = oracle_connections; cn != NULL; cn = cn->next) { if (strcmp(cn->server, server_copy) == 0) { oracle_handle = cn->handle; hda = cn->hda_mem; break; } } /* If no cached connection, we must set one up */ if (cn == NULL) { DEBUG(D_lookup) debug_printf("ORACLE new connection: host=%s database=%s " "user=%s\n", sdata[0], sdata[1], sdata[2]); /* Get store for a new connection, initialize it, and connect to the server */ oracle_handle = store_get(sizeof(struct cda_def)); hda = store_get(HDA_SIZE); memset(hda,'\0',HDA_SIZE); /* * Perform a default (blocking) login * * sdata[0] = tnsname (service name - typically host name) * sdata[1] = dbname - not used at present * sdata[2] = username * sdata[3] = passwd */ if(olog(oracle_handle, hda, sdata[2], -1, sdata[3], -1, sdata[0], -1, (ub4)OCI_LM_DEF) != 0) { *errmsg = oracle_error(oracle_handle, oracle_handle->rc, US"connection failed"); *defer_break = FALSE; goto ORACLE_EXIT_NO_VALS; } /* Add the connection to the cache */ cn = store_get(sizeof(oracle_connection)); cn->server = server_copy; cn->handle = oracle_handle; cn->next = oracle_connections; cn->hda_mem = hda; oracle_connections = cn; } /* Else use a previously cached connection - we can write to the server string to obliterate the password because it is in a nextinlist temporary buffer. */ else { DEBUG(D_lookup) debug_printf("ORACLE using cached connection for %s\n", server_copy); } /* We have a connection. Open a cursor and run the query */ cda = store_get(sizeof(Cda_Def)); if (oopen(cda, oracle_handle, (text *)0, -1, -1, (text *)0, -1) != 0) { *errmsg = oracle_error(oracle_handle, cda->rc, "failed to open cursor"); *defer_break = FALSE; goto ORACLE_EXIT_NO_VALS; } if (oparse(cda, (text *)query, (sb4) -1, (sword)PARSE_NO_DEFER, (ub4)PARSE_V7_LNG) != 0) { *errmsg = oracle_error(oracle_handle, cda->rc, "query failed"); *defer_break = FALSE; oclose(cda); goto ORACLE_EXIT_NO_VALS; } /* Find the number of fields returned and sort out their types. If the number is one, we don't add field names to the data. Otherwise we do. */ def = store_get(sizeof(Ora_Define)*MAX_SELECT_LIST_SIZE); desc = store_get(sizeof(Ora_Describe)*MAX_SELECT_LIST_SIZE); if ((num_fields = describe_define(cda,def,desc)) == -1) { *errmsg = oracle_error(oracle_handle, cda->rc, "describe_define failed"); *defer_break = FALSE; goto ORACLE_EXIT; } if (oexec(cda)!=0) { *errmsg = oracle_error(oracle_handle, cda->rc, "oexec failed"); *defer_break = FALSE; goto ORACLE_EXIT; } /* Get the fields and construct the result string. If there is more than one row, we insert '\n' between them. */ while (cda->rc != NO_DATA_FOUND) /* Loop for each row */ { ofetch(cda); if(cda->rc == NO_DATA_FOUND) break; if (result != NULL) result = string_cat(result, &ssize, &offset, "\n", 1); /* Single field - just add on the data */ if (num_fields == 1) result = string_cat(result, &ssize, &offset, def[0].buf, def[0].col_retlen); /* Multiple fields - precede by file name, removing {lead,trail}ing WS */ else for (i = 0; i < num_fields; i++) { int slen; uschar *s = US desc[i].buf; while (*s != 0 && isspace(*s)) s++; slen = Ustrlen(s); while (slen > 0 && isspace(s[slen-1])) slen--; result = string_cat(result, &ssize, &offset, s, slen); result = string_cat(result, &ssize, &offset, US"=", 1); /* int and float type wont ever need escaping. Otherwise, quote the value if it contains spaces or is empty. */ if (desc[i].dbtype != INT_TYPE && desc[i].dbtype != FLOAT_TYPE && (def[i].buf[0] == 0 || strchr(def[i].buf, ' ') != NULL)) { int j; result = string_cat(result, &ssize, &offset, "\"", 1); for (j = 0; j < def[i].col_retlen; j++) { if (def[i].buf[j] == '\"' || def[i].buf[j] == '\\') result = string_cat(result, &ssize, &offset, "\\", 1); result = string_cat(result, &ssize, &offset, def[i].buf+j, 1); } result = string_cat(result, &ssize, &offset, "\"", 1); } else switch(desc[i].dbtype) { case INT_TYPE: sprintf(CS tmp, "%d", def[i].int_buf); result = string_cat(result, &ssize, &offset, tmp, Ustrlen(tmp)); break; case FLOAT_TYPE: sprintf(CS tmp, "%f", def[i].flt_buf); result = string_cat(result, &ssize, &offset, tmp, Ustrlen(tmp)); break; case STRING_TYPE: result = string_cat(result, &ssize, &offset, def[i].buf, def[i].col_retlen); break; default: *errmsg = string_sprintf("ORACLE: unknown field type %d", desc[i].dbtype); *defer_break = FALSE; result = NULL; goto ORACLE_EXIT; } result = string_cat(result, &ssize, &offset, " ", 1); } } /* If result is NULL then no data has been found and so we return FAIL. Otherwise, we must terminate the string which has been built; string_cat() always leaves enough room for a terminating zero. */ if (result == NULL) { yield = FAIL; *errmsg = "ORACLE: no data found"; } else { result[offset] = 0; store_reset(result + offset + 1); } /* Get here by goto from various error checks. */ ORACLE_EXIT: /* Close the cursor; don't close the connection, as it is cached. */ oclose(cda); ORACLE_EXIT_NO_VALS: /* Non-NULL result indicates a sucessful result */ if (result != NULL) { *resultptr = result; return OK; } else { DEBUG(D_lookup) debug_printf("%s\n", *errmsg); return yield; /* FAIL or DEFER */ } }