int PG_evaluate_history(int primitive) { if (lh.sql_history) { if (primitive) { strncat(insert_clause, ", ", SPACELEFT(insert_clause)); strncat(values[primitive].string, ", ", sizeof(values[primitive].string)); strncat(where[primitive].string, " AND ", sizeof(where[primitive].string)); } if (!sql_history_since_epoch) strncat(where[primitive].string, "ABSTIME(%u)::Timestamp::Timestamp without time zone = ", SPACELEFT(where[primitive].string)); else strncat(where[primitive].string, "%u = ", SPACELEFT(where[primitive].string)); strncat(where[primitive].string, "stamp_inserted", SPACELEFT(where[primitive].string)); strncat(insert_clause, "stamp_updated, stamp_inserted", SPACELEFT(insert_clause)); if (!sql_history_since_epoch) strncat(values[primitive].string, "ABSTIME(%u)::Timestamp, ABSTIME(%u)::Timestamp", SPACELEFT(values[primitive].string)); else strncat(values[primitive].string, "%u, %u", SPACELEFT(values[primitive].string)); where[primitive].type = values[primitive].type = TIMESTAMP; values[primitive].handler = where[primitive].handler = count_timestamp_handler; primitive++; } return primitive; }
int PG_cache_dbop_copy(struct DBdesc *db, struct db_cache *cache_elem, struct insert_data *idata) { PGresult *ret; char *ptr_values, *ptr_where; char default_delim[] = ",", delim_buf[SRVBUFLEN]; int num=0, have_flows=0; if (config.what_to_count & COUNT_FLOWS) have_flows = TRUE; if (!config.sql_delimiter) snprintf(delim_buf, SRVBUFLEN, "%s", default_delim); else snprintf(delim_buf, SRVBUFLEN, "%s", config.sql_delimiter); /* constructing SQL query */ ptr_where = where_clause; ptr_values = values_clause; memset(where_clause, 0, sizeof(where_clause)); memset(values_clause, 0, sizeof(values_clause)); memcpy(&values, ©_values, sizeof(values)); while (num < idata->num_primitives) { (*where[num].handler)(cache_elem, idata, num, &ptr_values, &ptr_where); num++; } #if defined HAVE_64BIT_COUNTERS if (have_flows) snprintf(ptr_values, SPACELEFT(values_clause), "%s%llu%s%llu%s%llu\n", delim_buf, cache_elem->packet_counter, delim_buf, cache_elem->bytes_counter, delim_buf, cache_elem->flows_counter); else snprintf(ptr_values, SPACELEFT(values_clause), "%s%llu%s%llu\n", delim_buf, cache_elem->packet_counter, delim_buf, cache_elem->bytes_counter); #else if (have_flows) snprintf(ptr_values, SPACELEFT(values_clause), "%s%lu%s%lu%s%lu\n", delim_buf, cache_elem->packet_counter, delim_buf, cache_elem->bytes_counter, delim_buf, cache_elem->flows_counter); else snprintf(ptr_values, SPACELEFT(values_clause), "%s%lu%s%lu\n", delim_buf, cache_elem->packet_counter, delim_buf, cache_elem->bytes_counter); #endif strncpy(sql_data, values_clause, SPACELEFT(sql_data)); if (PQputCopyData(db->desc, sql_data, strlen(sql_data)) < 0) { // avoid strlen() db->errmsg = PQerrorMessage(db->desc); Log(LOG_DEBUG, "DEBUG ( %s/%s ): FAILED query follows:\n%s\n", config.name, config.type, sql_data); if (db->errmsg) Log(LOG_ERR, "ERROR ( %s/%s ): %s\n", config.name, config.type, db->errmsg); sql_db_fail(db); return TRUE; } idata->iqn++; idata->een++; Log(LOG_DEBUG, "DEBUG ( %s/%s ): %s\n", config.name, config.type, sql_data); return FALSE; }
int MY_evaluate_history(int primitive) { if (config.sql_history) { if (primitive) { strncat(insert_clause, ", ", SPACELEFT(insert_clause)); strncat(values[primitive].string, ", ", sizeof(values[primitive].string)); strncat(where[primitive].string, " AND ", sizeof(where[primitive].string)); } if (!config.sql_history_since_epoch) strncat(where[primitive].string, "FROM_UNIXTIME(%u) = ", SPACELEFT(where[primitive].string)); else strncat(where[primitive].string, "%u = ", SPACELEFT(where[primitive].string)); strncat(where[primitive].string, "stamp_inserted", SPACELEFT(where[primitive].string)); strncat(insert_clause, "stamp_updated, stamp_inserted", SPACELEFT(insert_clause)); if (!config.sql_history_since_epoch) strncat(values[primitive].string, "FROM_UNIXTIME(%u), FROM_UNIXTIME(%u)", SPACELEFT(values[primitive].string)); else strncat(values[primitive].string, "%u, %u", SPACELEFT(values[primitive].string)); where[primitive].type = values[primitive].type = TIMESTAMP; values[primitive].handler = where[primitive].handler = count_timestamp_handler; primitive++; } return primitive; }
int MY_compose_static_queries() { int primitives=0, have_flows=0; if (lh.what_to_count & COUNT_FLOWS || (lh.sql_table_version >= 4 && !lh.sql_optimize_clauses)) { lh.what_to_count |= COUNT_FLOWS; have_flows = TRUE; if (lh.sql_table_version < 4 && !lh.sql_optimize_clauses) { printf("ERROR: The accounting of flows requires SQL table v4. Exiting.\n"); exit(1); } } /* "INSERT INTO ... VALUES ... " and "... WHERE ..." stuff */ strncpy(where[primitives].string, " WHERE ", sizeof(where[primitives].string)); snprintf(insert_clause, sizeof(insert_clause), "INSERT INTO %s (", sql_table); strncpy(values[primitives].string, " VALUES (", sizeof(values[primitives].string)); primitives = MY_evaluate_history(primitives); primitives = MY_evaluate_primitives(primitives); strncat(insert_clause, ", packets, bytes", SPACELEFT(insert_clause)); if (have_flows) strncat(insert_clause, ", flows", SPACELEFT(insert_clause)); strncat(insert_clause, ")", SPACELEFT(insert_clause)); /* "LOCK ..." stuff */ snprintf(lock_clause, sizeof(lock_clause), "LOCK TABLES %s WRITE", sql_table); strncpy(unlock_clause, "UNLOCK TABLES", sizeof(unlock_clause)); /* "UPDATE ... SET ..." stuff */ snprintf(update_clause, sizeof(update_clause), "UPDATE %s ", sql_table); #if defined HAVE_64BIT_COUNTERS strncat(update_clause, "SET packets=packets+%llu, bytes=bytes+%llu", SPACELEFT(update_clause)); if (have_flows) strncat(update_clause, ", flows=flows+%llu", SPACELEFT(update_clause)); #else strncat(update_clause, "SET packets=packets+%lu, bytes=bytes+%lu", SPACELEFT(update_clause)); if (have_flows) strncat(update_clause, ", flows=flows+%lu", SPACELEFT(update_clause)); #endif if (lh.sql_history) { if (!sql_history_since_epoch) strncat(update_clause, ", stamp_updated=NOW()", SPACELEFT(update_clause)); else strncat(update_clause, ", stamp_updated=UNIX_TIMESTAMP(NOW())", SPACELEFT(update_clause)); } return primitives; }
int SQLI_evaluate_history(int primitive) { if (config.sql_history || config.nfacctd_sql_log) { if (primitive) { strncat(insert_clause, ", ", SPACELEFT(insert_clause)); strncat(values[primitive].string, ", ", sizeof(values[primitive].string)); strncat(where[primitive].string, " AND ", sizeof(where[primitive].string)); } if (!config.sql_history_since_epoch) strncat(where[primitive].string, "DATETIME(%u, 'unixepoch', 'localtime') = ", SPACELEFT(where[primitive].string)); else strncat(where[primitive].string, "%u = ", SPACELEFT(where[primitive].string)); strncat(where[primitive].string, "stamp_inserted", SPACELEFT(where[primitive].string)); strncat(insert_clause, "stamp_updated, stamp_inserted", SPACELEFT(insert_clause)); if (!config.sql_history_since_epoch) strncat(values[primitive].string, "DATETIME(%u, 'unixepoch', 'localtime'), DATETIME(%u, 'unixepoch', 'localtime')", SPACELEFT(values[primitive].string)); else strncat(values[primitive].string, "%u, %u", SPACELEFT(values[primitive].string)); where[primitive].type = values[primitive].type = TIMESTAMP; values[primitive].handler = where[primitive].handler = count_timestamp_handler; primitive++; } return primitive; }
int PG_cache_dbop(struct DBdesc *db, struct db_cache *cache_elem, struct insert_data *idata) { PGresult *ret; char *ptr_values, *ptr_where, *err_string; int num=0, have_flows=0; if (lh.what_to_count & COUNT_FLOWS) have_flows = TRUE; /* constructing SQL query */ ptr_where = where_clause; ptr_values = values_clause; while (num < idata->num_primitives) { (*where[num].handler)(cache_elem, idata, num, &ptr_values, &ptr_where); num++; } if (have_flows) snprintf(sql_data, sizeof(sql_data), update_clause, cache_elem->packet_counter, cache_elem->bytes_counter, cache_elem->flows_counter, time(NULL)); else snprintf(sql_data, sizeof(sql_data), update_clause, cache_elem->packet_counter, cache_elem->bytes_counter, time(NULL)); strncat(sql_data, where_clause, SPACELEFT(sql_data)); /* sending UPDATE query */ if (!sql_dont_try_update) { ret = PQexec(db->desc, sql_data); if (PQresultStatus(ret) != PGRES_COMMAND_OK) { err_string = PQresultErrorMessage(ret); PQclear(ret); printf("FAILED query follows:\n%s\n", sql_data); printf("%s\n", err_string); return TRUE; } PQclear(ret); } if (sql_dont_try_update || (!PG_affected_rows(ret))) { /* UPDATE failed, trying with an INSERT query */ strncpy(sql_data, insert_clause, sizeof(sql_data)); #if defined HAVE_64BIT_COUNTERS if (have_flows) snprintf(ptr_values, SPACELEFT(values_clause), ", %llu, %llu, %llu)", cache_elem->packet_counter, cache_elem->bytes_counter, cache_elem->flows_counter); else snprintf(ptr_values, SPACELEFT(values_clause), ", %llu, %llu)", cache_elem->packet_counter, cache_elem->bytes_counter); #else if (have_flows) snprintf(ptr_values, SPACELEFT(values_clause), ", %lu, %lu, %lu)", cache_elem->packet_counter, cache_elem->bytes_counter, cache_elem->flows_counter); else snprintf(ptr_values, SPACELEFT(values_clause), ", %lu, %lu)", cache_elem->packet_counter, cache_elem->bytes_counter); #endif strncat(sql_data, values_clause, SPACELEFT(sql_data)); ret = PQexec(db->desc, sql_data); if (PQresultStatus(ret) != PGRES_COMMAND_OK) { err_string = PQresultErrorMessage(ret); PQclear(ret); printf("FAILED query follows:\n%s\n", sql_data); printf("%s\n", err_string); return TRUE; } PQclear(ret); } if (debug) printf("%s\n\n", sql_data); return FALSE; }
int MY_cache_dbop(struct DBdesc *db, struct db_cache *cache_elem, struct insert_data *idata) { char *ptr_values, *ptr_where; int num=0, ret=0, have_flows=0; if (lh.what_to_count & COUNT_FLOWS) have_flows = TRUE; /* constructing sql query */ ptr_where = where_clause; ptr_values = values_clause; while (num < idata->num_primitives) { (*where[num].handler)(cache_elem, idata, num, &ptr_values, &ptr_where); num++; } if (have_flows) snprintf(sql_data, sizeof(sql_data), update_clause, cache_elem->packet_counter, cache_elem->bytes_counter, cache_elem->flows_counter); else snprintf(sql_data, sizeof(sql_data), update_clause, cache_elem->packet_counter, cache_elem->bytes_counter); strncat(sql_data, where_clause, SPACELEFT(sql_data)); if (!sql_dont_try_update) { ret = mysql_query(db->desc, sql_data); if (ret) return ret; } if (sql_dont_try_update || (mysql_affected_rows(db->desc) == 0)) { /* UPDATE failed, trying with an INSERT query */ strncpy(sql_data, insert_clause, sizeof(sql_data)); #if defined HAVE_64BIT_COUNTERS if (have_flows) snprintf(ptr_values, SPACELEFT(values_clause), ", %llu, %llu, %llu)", cache_elem->packet_counter, cache_elem->bytes_counter, cache_elem->flows_counter); else snprintf(ptr_values, SPACELEFT(values_clause), ", %llu, %llu)", cache_elem->packet_counter, cache_elem->bytes_counter); #else if (have_flows) snprintf(ptr_values, SPACELEFT(values_clause), ", %lu, %lu, %lu)", cache_elem->packet_counter, cache_elem->bytes_counter, cache_elem->flows_counter); else snprintf(ptr_values, SPACELEFT(values_clause), ", %lu, %lu)", cache_elem->packet_counter, cache_elem->bytes_counter); #endif strncat(sql_data, values_clause, SPACELEFT(sql_data)); ret = mysql_query(db->desc, sql_data); if (ret) return ret; } if (debug) { printf("**********\n"); printf("%s\n", sql_data); } return ret; }
int MY_evaluate_primitives(int primitive) { u_int64_t what_to_count = 0; short int assume_custom_table = FALSE; if (lh.sql_optimize_clauses) { what_to_count = lh.what_to_count; assume_custom_table = TRUE; } else { /* we are requested to avoid optimization; then we'll construct an all-true "what to count" bitmap */ if (lh.what_to_count & COUNT_SRC_AS) what_to_count |= COUNT_SRC_AS; else if (lh.what_to_count & COUNT_SUM_HOST) what_to_count |= COUNT_SUM_HOST; else if (lh.what_to_count & COUNT_SUM_NET) what_to_count |= COUNT_SUM_NET; else if (lh.what_to_count & COUNT_SUM_AS) what_to_count |= COUNT_SUM_AS; else what_to_count |= COUNT_SRC_HOST; if (lh.what_to_count & COUNT_DST_AS) what_to_count |= COUNT_DST_AS; else what_to_count |= COUNT_DST_HOST; what_to_count |= COUNT_SRC_MAC; what_to_count |= COUNT_DST_MAC; what_to_count |= COUNT_SRC_PORT; what_to_count |= COUNT_DST_PORT; what_to_count |= COUNT_IP_TOS; what_to_count |= COUNT_IP_PROTO; what_to_count |= COUNT_ID; what_to_count |= COUNT_VLAN; if (lh.what_to_count & COUNT_SUM_PORT) what_to_count |= COUNT_SUM_PORT; if (lh.what_to_count & COUNT_SUM_MAC) what_to_count |= COUNT_SUM_MAC; } /* 1st part: arranging pointers to an opaque structure and composing the static selection (WHERE) string */ #if defined (HAVE_L2) if (what_to_count & (COUNT_SRC_MAC|COUNT_SUM_MAC)) { if (primitive) { strncat(insert_clause, ", ", SPACELEFT(insert_clause)); strncat(values[primitive].string, ", ", sizeof(values[primitive].string)); strncat(where[primitive].string, " AND ", sizeof(where[primitive].string)); } strncat(insert_clause, "mac_src", SPACELEFT(insert_clause)); strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string)); strncat(where[primitive].string, "mac_src=\'%s\'", SPACELEFT(where[primitive].string)); values[primitive].type = where[primitive].type = COUNT_SRC_MAC; values[primitive].handler = where[primitive].handler = count_src_mac_handler; primitive++; } if (what_to_count & COUNT_DST_MAC) { if (primitive) { strncat(insert_clause, ", ", SPACELEFT(insert_clause)); strncat(values[primitive].string, ", ", sizeof(values[primitive].string)); strncat(where[primitive].string, " AND ", sizeof(where[primitive].string)); } strncat(insert_clause, "mac_dst", SPACELEFT(insert_clause)); strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string)); strncat(where[primitive].string, "mac_dst=\'%s\'", SPACELEFT(where[primitive].string)); values[primitive].type = where[primitive].type = COUNT_DST_MAC; values[primitive].handler = where[primitive].handler = count_dst_mac_handler; primitive++; } if (what_to_count & COUNT_VLAN) { int count_it = FALSE; if ((lh.sql_table_version < 2) && !assume_custom_table) { if (lh.what_to_count & COUNT_VLAN) { printf("ERROR: The use of VLAN accounting requires SQL table v2. Exiting.\n"); exit(1); } else what_to_count ^= COUNT_VLAN; } else count_it = TRUE; if (count_it) { if (primitive) { strncat(insert_clause, ", ", SPACELEFT(insert_clause)); strncat(values[primitive].string, ", ", sizeof(values[primitive].string)); strncat(where[primitive].string, " AND ", sizeof(where[primitive].string)); } strncat(insert_clause, "vlan", SPACELEFT(insert_clause)); strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string)); strncat(where[primitive].string, "vlan=%u", SPACELEFT(where[primitive].string)); values[primitive].type = where[primitive].type = COUNT_VLAN; values[primitive].handler = where[primitive].handler = count_vlan_handler; primitive++; } } #endif if (what_to_count & (COUNT_SRC_HOST|COUNT_SRC_NET|COUNT_SUM_HOST|COUNT_SUM_NET)) { if (primitive) { strncat(insert_clause, ", ", SPACELEFT(insert_clause)); strncat(values[primitive].string, ", ", sizeof(values[primitive].string)); strncat(where[primitive].string, " AND ", sizeof(where[primitive].string)); } strncat(insert_clause, "ip_src", SPACELEFT(insert_clause)); strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string)); strncat(where[primitive].string, "ip_src=\'%s\'", SPACELEFT(where[primitive].string)); values[primitive].type = where[primitive].type = COUNT_SRC_HOST; values[primitive].handler = where[primitive].handler = count_src_host_handler; primitive++; } if (what_to_count & (COUNT_DST_HOST|COUNT_DST_NET)) { if (primitive) { strncat(insert_clause, ", ", SPACELEFT(insert_clause)); strncat(values[primitive].string, ", ", sizeof(values[primitive].string)); strncat(where[primitive].string, " AND ", sizeof(where[primitive].string)); } strncat(insert_clause, "ip_dst", SPACELEFT(insert_clause)); strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string)); strncat(where[primitive].string, "ip_dst=\'%s\'", SPACELEFT(where[primitive].string)); values[primitive].type = where[primitive].type = COUNT_DST_HOST; values[primitive].handler = where[primitive].handler = count_dst_host_handler; primitive++; } if (what_to_count & (COUNT_SRC_AS|COUNT_SUM_AS)) { if (primitive) { strncat(insert_clause, ", ", SPACELEFT(insert_clause)); strncat(values[primitive].string, ", ", sizeof(values[primitive].string)); strncat(where[primitive].string, " AND ", sizeof(where[primitive].string)); } if (lh.sql_table_version >= 6) { strncat(insert_clause, "as_src", SPACELEFT(insert_clause)); strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string)); strncat(where[primitive].string, "as_src=%u", SPACELEFT(where[primitive].string)); } else { strncat(insert_clause, "ip_src", SPACELEFT(insert_clause)); strncat(values[primitive].string, "\'%u\'", SPACELEFT(values[primitive].string)); strncat(where[primitive].string, "ip_src=\'%u\'", SPACELEFT(where[primitive].string)); } values[primitive].type = where[primitive].type = COUNT_SRC_AS; values[primitive].handler = where[primitive].handler = count_src_as_handler; primitive++; } if (what_to_count & COUNT_DST_AS) { if (primitive) { strncat(insert_clause, ", ", SPACELEFT(insert_clause)); strncat(values[primitive].string, ", ", sizeof(values[primitive].string)); strncat(where[primitive].string, " AND ", sizeof(where[primitive].string)); } if (lh.sql_table_version >= 6) { strncat(insert_clause, "as_dst", SPACELEFT(insert_clause)); strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string)); strncat(where[primitive].string, "as_dst=%u", SPACELEFT(where[primitive].string)); } else { strncat(insert_clause, "ip_dst", SPACELEFT(insert_clause)); strncat(values[primitive].string, "\'%u\'", SPACELEFT(values[primitive].string)); strncat(where[primitive].string, "ip_dst=\'%u\'", SPACELEFT(where[primitive].string)); } values[primitive].type = where[primitive].type = COUNT_DST_AS; values[primitive].handler = where[primitive].handler = count_dst_as_handler; primitive++; } if (what_to_count & (COUNT_SRC_PORT|COUNT_SUM_PORT)) { if (primitive) { strncat(insert_clause, ", ", SPACELEFT(insert_clause)); strncat(values[primitive].string, ", ", sizeof(values[primitive].string)); strncat(where[primitive].string, " AND ", sizeof(where[primitive].string)); } strncat(insert_clause, "src_port", SPACELEFT(insert_clause)); strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string)); strncat(where[primitive].string, "src_port=%u", SPACELEFT(where[primitive].string)); values[primitive].type = where[primitive].type = COUNT_SRC_PORT; values[primitive].handler = where[primitive].handler = count_src_port_handler; primitive++; } if (what_to_count & COUNT_DST_PORT) { if (primitive) { strncat(insert_clause, ", ", SPACELEFT(insert_clause)); strncat(values[primitive].string, ", ", sizeof(values[primitive].string)); strncat(where[primitive].string, " AND ", sizeof(where[primitive].string)); } strncat(insert_clause, "dst_port", SPACELEFT(insert_clause)); strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string)); strncat(where[primitive].string, "dst_port=%u", SPACELEFT(where[primitive].string)); values[primitive].type = where[primitive].type = COUNT_DST_PORT; values[primitive].handler = where[primitive].handler = count_dst_port_handler; primitive++; } if (what_to_count & COUNT_IP_TOS) { int count_it = FALSE; if ((lh.sql_table_version < 3) && !assume_custom_table) { if (lh.what_to_count & COUNT_IP_TOS) { printf("ERROR: The use of ToS/DSCP accounting requires SQL table v3. Exiting.\n"); exit(1); } else what_to_count ^= COUNT_IP_TOS; } else count_it = TRUE; if (count_it) { if (primitive) { strncat(insert_clause, ", ", SPACELEFT(insert_clause)); strncat(values[primitive].string, ", ", sizeof(values[primitive].string)); strncat(where[primitive].string, " AND ", sizeof(where[primitive].string)); } strncat(insert_clause, "tos", SPACELEFT(insert_clause)); strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string)); strncat(where[primitive].string, "tos=%u", SPACELEFT(where[primitive].string)); values[primitive].type = where[primitive].type = COUNT_IP_TOS; values[primitive].handler = where[primitive].handler = count_ip_tos_handler; primitive++; } } if (what_to_count & COUNT_IP_PROTO) { if (primitive) { strncat(insert_clause, ", ", SPACELEFT(insert_clause)); strncat(values[primitive].string, ", ", sizeof(values[primitive].string)); strncat(where[primitive].string, " AND ", sizeof(where[primitive].string)); } strncat(insert_clause, "ip_proto", SPACELEFT(insert_clause)); strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string)); strncat(where[primitive].string, "ip_proto=\'%s\'", SPACELEFT(where[primitive].string)); values[primitive].type = where[primitive].type = COUNT_IP_PROTO; values[primitive].handler = where[primitive].handler = MY_count_ip_proto_handler; primitive++; } if (what_to_count & COUNT_ID) { int count_it = FALSE; if ((lh.sql_table_version < 2) && !assume_custom_table) { if (lh.what_to_count & COUNT_ID) { printf("ERROR: The use of IDs requires SQL table version 2. Exiting.\n"); exit(1); } else what_to_count ^= COUNT_ID; } else count_it = TRUE; if (count_it) { if (primitive) { strncat(insert_clause, ", ", SPACELEFT(insert_clause)); strncat(values[primitive].string, ", ", sizeof(values[primitive].string)); strncat(where[primitive].string, " AND ", sizeof(where[primitive].string)); } strncat(insert_clause, "agent_id", SPACELEFT(insert_clause)); strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string)); strncat(where[primitive].string, "agent_id=%u", SPACELEFT(where[primitive].string)); values[primitive].type = where[primitive].type = COUNT_ID; values[primitive].handler = where[primitive].handler = count_id_handler; primitive++; } } return primitive; }
int PG_compose_static_queries() { int primitives=0, set_primitives=0, set_event_primitives=0, have_flows=0, lock=0; char default_delim[] = ",", delim_buf[SRVBUFLEN]; if (config.what_to_count & COUNT_FLOWS || (config.sql_table_version >= 4 && config.sql_table_version < SQL_TABLE_VERSION_BGP && !config.sql_optimize_clauses)) { config.what_to_count |= COUNT_FLOWS; have_flows = TRUE; if ((config.sql_table_version < 4 || config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !config.sql_optimize_clauses) { Log(LOG_ERR, "ERROR ( %s/%s ): The accounting of flows requires SQL table v4. Exiting.\n", config.name, config.type); exit_plugin(1); } } /* "INSERT INTO ... VALUES ... ", "COPY ... ", "... WHERE ..." stuff */ strncpy(where[primitives].string, " WHERE ", sizeof(where[primitives].string)); snprintf(copy_clause, sizeof(copy_clause), "COPY %s (", config.sql_table); snprintf(insert_clause, sizeof(insert_clause), "INSERT INTO %s (", config.sql_table); strncpy(values[primitives].string, " VALUES (", sizeof(values[primitives].string)); primitives = PG_evaluate_history(primitives); primitives = sql_evaluate_primitives(primitives); strncat(copy_clause, ", packets, bytes", SPACELEFT(copy_clause)); if (have_flows) strncat(copy_clause, ", flows", SPACELEFT(copy_clause)); if (!config.sql_delimiter || !config.sql_use_copy) snprintf(delim_buf, SRVBUFLEN, ") FROM STDIN DELIMITER \'%s\'", default_delim); else snprintf(delim_buf, SRVBUFLEN, ") FROM STDIN DELIMITER \'%s\'", config.sql_delimiter); strncat(copy_clause, delim_buf, SPACELEFT(copy_clause)); strncpy(insert_counters_clause, ", packets, bytes", SPACELEFT(insert_counters_clause)); if (have_flows) strncat(insert_counters_clause, ", flows", SPACELEFT(insert_counters_clause)); strncat(insert_counters_clause, ")", SPACELEFT(insert_counters_clause)); strncpy(insert_nocounters_clause, ")", SPACELEFT(insert_nocounters_clause)); /* "LOCK ..." stuff */ if (config.sql_dont_try_update) snprintf(lock_clause, sizeof(lock_clause), "BEGIN;"); else { if (config.sql_locking_style) lock = sql_select_locking_style(config.sql_locking_style); switch (lock) { case PM_LOCK_NONE: snprintf(lock_clause, sizeof(lock_clause), "BEGIN;"); break; case PM_LOCK_ROW_EXCLUSIVE: snprintf(lock_clause, sizeof(lock_clause), "BEGIN; LOCK %s IN ROW EXCLUSIVE MODE;", config.sql_table); break; case PM_LOCK_EXCLUSIVE: default: snprintf(lock_clause, sizeof(lock_clause), "BEGIN; LOCK %s IN EXCLUSIVE MODE;", config.sql_table); break; } } /* "UPDATE ... SET ..." stuff */ snprintf(update_clause, sizeof(update_clause), "UPDATE %s ", config.sql_table); set_primitives = sql_compose_static_set(have_flows); set_event_primitives = sql_compose_static_set_event(); if (config.sql_history) { if (!config.sql_history_since_epoch) { strncpy(set[set_primitives].string, ", ", SPACELEFT(set[set_primitives].string)); strncat(set[set_primitives].string, "stamp_updated=CURRENT_TIMESTAMP(0)", SPACELEFT(set[set_primitives].string)); set[set_primitives].type = TIMESTAMP; set[set_primitives].handler = count_noop_setclause_handler; set_primitives++; if (set_event_primitives) strncpy(set_event[set_event_primitives].string, ", ", SPACELEFT(set_event[set_event_primitives].string)); else strncpy(set_event[set_event_primitives].string, "SET ", SPACELEFT(set_event[set_event_primitives].string)); strncat(set_event[set_event_primitives].string, "stamp_updated=CURRENT_TIMESTAMP(0)", SPACELEFT(set_event[set_event_primitives].string)); set_event[set_event_primitives].type = TIMESTAMP; set_event[set_event_primitives].handler = count_noop_setclause_handler; set_event_primitives++; } else { strncpy(set[set_primitives].string, ", ", SPACELEFT(set[set_primitives].string)); strncat(set[set_primitives].string, "stamp_updated=DATE_PART('epoch',NOW())::BIGINT", SPACELEFT(set[set_primitives].string)); set[set_primitives].type = TIMESTAMP; set[set_primitives].handler = count_noop_setclause_handler; set_primitives++; if (set_event_primitives) strncpy(set_event[set_event_primitives].string, ", ", SPACELEFT(set_event[set_event_primitives].string)); else strncpy(set_event[set_event_primitives].string, "SET ", SPACELEFT(set_event[set_event_primitives].string)); strncat(set_event[set_event_primitives].string, "stamp_updated=DATE_PART('epoch',NOW())::BIGINT", SPACELEFT(set_event[set_event_primitives].string)); set_event[set_event_primitives].type = TIMESTAMP; set_event[set_event_primitives].handler = count_noop_setclause_handler; set_primitives++; } } /* values for COPY */ memcpy(©_values, &values, sizeof(copy_values)); { int num, x, y; char *ptr; ptr = strchr(copy_values[0].string, '('); ptr++; strcpy(copy_values[0].string, ptr); for (num = 0; num < primitives; num++) { for (x = 0; copy_values[num].string[x] != '\0'; x++) { if (copy_values[num].string[x] == ' ' || copy_values[num].string[x] == '\'') { for (y = x + 1; copy_values[num].string[y] != '\0'; y++) copy_values[num].string[y-1] = copy_values[num].string[y]; copy_values[num].string[y-1] = '\0'; x--; } } copy_values[num].string[x] = '\0'; } } return primitives; }
int PG_evaluate_history(int primitive) { if (config.sql_history) { if (primitive) { strncat(copy_clause, ", ", SPACELEFT(copy_clause)); strncat(insert_clause, ", ", SPACELEFT(insert_clause)); strncat(values[primitive].string, ", ", sizeof(values[primitive].string)); strncat(where[primitive].string, " AND ", sizeof(where[primitive].string)); } if (!config.sql_history_since_epoch) strncat(where[primitive].string, "ABSTIME(%u)::Timestamp::Timestamp without time zone = ", SPACELEFT(where[primitive].string)); else strncat(where[primitive].string, "%u = ", SPACELEFT(where[primitive].string)); strncat(where[primitive].string, "stamp_inserted", SPACELEFT(where[primitive].string)); strncat(copy_clause, "stamp_updated, stamp_inserted", SPACELEFT(copy_clause)); strncat(insert_clause, "stamp_updated, stamp_inserted", SPACELEFT(insert_clause)); if (config.sql_use_copy) { char default_delim[] = ",", delim_buf[SRVBUFLEN]; if (!config.sql_delimiter || !config.sql_use_copy) snprintf(delim_buf, SRVBUFLEN, "%s ", default_delim); else snprintf(delim_buf, SRVBUFLEN, "%s ", config.sql_delimiter); if (!config.sql_history_since_epoch) { strncat(values[primitive].string, "%s", SPACELEFT(values[primitive].string)); strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string)); strncat(values[primitive].string, "%s", SPACELEFT(values[primitive].string)); values[primitive].handler = where[primitive].handler = count_copy_timestamp_handler; } else { strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string)); strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string)); strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string)); values[primitive].handler = where[primitive].handler = count_timestamp_handler; } } else { if (!config.sql_history_since_epoch) strncat(values[primitive].string, "ABSTIME(%u)::Timestamp, ABSTIME(%u)::Timestamp", SPACELEFT(values[primitive].string)); else strncat(values[primitive].string, "%u, %u", SPACELEFT(values[primitive].string)); values[primitive].handler = where[primitive].handler = count_timestamp_handler; } where[primitive].type = values[primitive].type = TIMESTAMP; primitive++; } return primitive; }
int PG_cache_dbop(struct DBdesc *db, struct db_cache *cache_elem, struct insert_data *idata) { PGresult *ret; char *ptr_values, *ptr_where, *ptr_set, *ptr_insert; int num=0, num_set=0, have_flows=0; if (config.what_to_count & COUNT_FLOWS) have_flows = TRUE; /* constructing SQL query */ ptr_where = where_clause; ptr_values = values_clause; ptr_set = set_clause; ptr_insert = insert_full_clause; memset(where_clause, 0, sizeof(where_clause)); memset(values_clause, 0, sizeof(values_clause)); memset(set_clause, 0, sizeof(set_clause)); memset(insert_full_clause, 0, sizeof(insert_full_clause)); for (num = 0; num < idata->num_primitives; num++) (*where[num].handler)(cache_elem, idata, num, &ptr_values, &ptr_where); if (cache_elem->flow_type == NF9_FTYPE_EVENT || cache_elem->flow_type == NF9_FTYPE_OPTION) { for (num_set = 0; set_event[num_set].type; num_set++) (*set_event[num_set].handler)(cache_elem, idata, num_set, &ptr_set, NULL); } else { for (num_set = 0; set[num_set].type; num_set++) (*set[num_set].handler)(cache_elem, idata, num_set, &ptr_set, NULL); } /* sending UPDATE query a) if not switched off and b) if we actually have something to update */ if (!config.sql_dont_try_update && num_set) { strncpy(sql_data, update_clause, SPACELEFT(sql_data)); strncat(sql_data, set_clause, SPACELEFT(sql_data)); strncat(sql_data, where_clause, SPACELEFT(sql_data)); ret = PQexec(db->desc, sql_data); if (PQresultStatus(ret) != PGRES_COMMAND_OK) { db->errmsg = PQresultErrorMessage(ret); PQclear(ret); Log(LOG_DEBUG, "DEBUG ( %s/%s ): FAILED query follows:\n%s\n", config.name, config.type, sql_data); if (db->errmsg) Log(LOG_ERR, "ERROR ( %s/%s ): %s\n\n", config.name, config.type, db->errmsg); sql_db_fail(db); return TRUE; } PQclear(ret); } if (config.sql_dont_try_update || !num_set || (!PG_affected_rows(ret))) { /* UPDATE failed, trying with an INSERT query */ if (cache_elem->flow_type == NF9_FTYPE_EVENT || cache_elem->flow_type == NF9_FTYPE_OPTION) { strncpy(insert_full_clause, insert_clause, SPACELEFT(insert_full_clause)); strncat(insert_full_clause, insert_nocounters_clause, SPACELEFT(insert_full_clause)); strncat(ptr_values, ")", SPACELEFT(values_clause)); } else { strncpy(insert_full_clause, insert_clause, SPACELEFT(insert_full_clause)); strncat(insert_full_clause, insert_counters_clause, SPACELEFT(insert_full_clause)); #if defined HAVE_64BIT_COUNTERS if (have_flows) snprintf(ptr_values, SPACELEFT(values_clause), ", %llu, %llu, %llu)", cache_elem->packet_counter, cache_elem->bytes_counter, cache_elem->flows_counter); else snprintf(ptr_values, SPACELEFT(values_clause), ", %llu, %llu)", cache_elem->packet_counter, cache_elem->bytes_counter); #else if (have_flows) snprintf(ptr_values, SPACELEFT(values_clause), ", %lu, %lu, %lu)", cache_elem->packet_counter, cache_elem->bytes_counter, cache_elem->flows_counter); else snprintf(ptr_values, SPACELEFT(values_clause), ", %lu, %lu)", cache_elem->packet_counter, cache_elem->bytes_counter); #endif } strncpy(sql_data, insert_full_clause, sizeof(sql_data)); strncat(sql_data, values_clause, SPACELEFT(sql_data)); ret = PQexec(db->desc, sql_data); if (PQresultStatus(ret) != PGRES_COMMAND_OK) { db->errmsg = PQresultErrorMessage(ret); PQclear(ret); Log(LOG_DEBUG, "DEBUG ( %s/%s ): FAILED query follows:\n%s\n", config.name, config.type, sql_data); if (db->errmsg) Log(LOG_ERR, "ERROR ( %s/%s ): %s\n\n", config.name, config.type, db->errmsg); sql_db_fail(db); return TRUE; } PQclear(ret); idata->iqn++; } else idata->uqn++; idata->een++; Log(LOG_DEBUG, "DEBUG ( %s/%s ): %s\n\n", config.name, config.type, sql_data); return FALSE; }
int SQLI_compose_static_queries() { int primitives=0, set_primitives=0, have_flows=0; if (config.what_to_count & COUNT_FLOWS || (config.sql_table_version >= 4 && config.sql_table_version < SQL_TABLE_VERSION_BGP && !config.sql_optimize_clauses)) { config.what_to_count |= COUNT_FLOWS; have_flows = TRUE; if ((config.sql_table_version < 4 || config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !config.sql_optimize_clauses) { Log(LOG_ERR, "ERROR ( %s/%s ): The accounting of flows requires SQL table v4. Exiting.\n", config.name, config.type); exit_plugin(1); } } /* "INSERT INTO ... VALUES ... " and "... WHERE ..." stuff */ strncpy(where[primitives].string, " WHERE ", sizeof(where[primitives].string)); snprintf(insert_clause, sizeof(insert_clause), "INSERT INTO %s (", config.sql_table); strncpy(values[primitives].string, " VALUES (", sizeof(values[primitives].string)); primitives = SQLI_evaluate_history(primitives); primitives = sql_evaluate_primitives(primitives); strncat(insert_clause, ", packets, bytes", SPACELEFT(insert_clause)); if (have_flows) strncat(insert_clause, ", flows", SPACELEFT(insert_clause)); strncat(insert_clause, ")", SPACELEFT(insert_clause)); /* "LOCK ..." stuff */ if (config.sql_locking_style) Log(LOG_WARNING, "WARN ( %s/%s ): sql_locking_style is not supported. Ignored.\n", config.name, config.type); snprintf(lock_clause, sizeof(lock_clause), "BEGIN", config.sql_table); strncpy(unlock_clause, "COMMIT", sizeof(unlock_clause)); /* "UPDATE ... SET ..." stuff */ snprintf(update_clause, sizeof(update_clause), "UPDATE %s ", config.sql_table); set_primitives = sql_compose_static_set(have_flows); if (config.sql_history || config.nfacctd_sql_log) { if (!config.nfacctd_sql_log) { if (!config.sql_history_since_epoch) { strncpy(set[set_primitives].string, ", ", SPACELEFT(set[set_primitives].string)); strncat(set[set_primitives].string, "stamp_updated=DATETIME('now', 'localtime')", SPACELEFT(set[set_primitives].string)); set[set_primitives].type = TIMESTAMP; set[set_primitives].handler = count_noop_setclause_handler; set_primitives++; } else { strncpy(set[set_primitives].string, ", ", SPACELEFT(set[set_primitives].string)); strncat(set[set_primitives].string, "stamp_updated=STRFTIME('%%s', 'now')", SPACELEFT(set[set_primitives].string)); set[set_primitives].type = TIMESTAMP; set[set_primitives].handler = count_noop_setclause_handler; set_primitives++; } } else { if (!config.sql_history_since_epoch) { strncpy(set[set_primitives].string, ", ", SPACELEFT(set[set_primitives].string)); strncat(set[set_primitives].string, "stamp_updated=DATETIME(%u, 'unixepoch', 'localtime')", SPACELEFT(set[set_primitives].string)); set[set_primitives].type = TIMESTAMP; set[set_primitives].handler = count_timestamp_setclause_handler; set_primitives++; } else { strncpy(set[set_primitives].string, ", ", SPACELEFT(set[set_primitives].string)); strncat(set[set_primitives].string, "stamp_updated=%u", SPACELEFT(set[set_primitives].string)); set[set_primitives].type = TIMESTAMP; set[set_primitives].handler = count_timestamp_setclause_handler; set_primitives++; } } } return primitives; }
int SQLI_cache_dbop(struct DBdesc *db, struct db_cache *cache_elem, struct insert_data *idata) { char *ptr_values, *ptr_where, *ptr_mv, *ptr_set; int num=0, ret=0, have_flows=0, len=0; if (idata->mv.last_queue_elem) { ret = sqlite3_exec(db->desc, multi_values_buffer, NULL, NULL, NULL); Log(LOG_DEBUG, "DEBUG ( %s/%s ): %d INSERT statements sent to the SQLite database.\n", config.name, config.type, idata->mv.buffer_elem_num); if (ret) goto signal_error; idata->iqn++; idata->mv.buffer_elem_num = FALSE; idata->mv.buffer_offset = 0; return FALSE; } if (config.what_to_count & COUNT_FLOWS) have_flows = TRUE; /* constructing sql query */ ptr_where = where_clause; ptr_values = values_clause; ptr_set = set_clause; memset(where_clause, 0, sizeof(where_clause)); memset(values_clause, 0, sizeof(values_clause)); memset(set_clause, 0, sizeof(set_clause)); for (num = 0; num < idata->num_primitives; num++) (*where[num].handler)(cache_elem, idata, num, &ptr_values, &ptr_where); for (num = 0; set[num].type; num++) (*set[num].handler)(cache_elem, idata, num, &ptr_set, NULL); /* sending UPDATE query */ if (!config.sql_dont_try_update) { strncpy(sql_data, update_clause, SPACELEFT(sql_data)); strncat(sql_data, set_clause, SPACELEFT(sql_data)); strncat(sql_data, where_clause, SPACELEFT(sql_data)); ret = sqlite3_exec(db->desc, sql_data, NULL, NULL, NULL); if (ret) goto signal_error; } if (config.sql_dont_try_update || (sqlite3_changes(db->desc) == 0)) { /* UPDATE failed, trying with an INSERT query */ #if defined HAVE_64BIT_COUNTERS if (have_flows) snprintf(ptr_values, SPACELEFT(values_clause), ", %llu, %llu, %llu)", cache_elem->packet_counter, cache_elem->bytes_counter, cache_elem->flows_counter); else snprintf(ptr_values, SPACELEFT(values_clause), ", %llu, %llu)", cache_elem->packet_counter, cache_elem->bytes_counter); #else if (have_flows) snprintf(ptr_values, SPACELEFT(values_clause), ", %lu, %lu, %lu)", cache_elem->packet_counter, cache_elem->bytes_counter, cache_elem->flows_counter); else snprintf(ptr_values, SPACELEFT(values_clause), ", %lu, %lu)", cache_elem->packet_counter, cache_elem->bytes_counter); #endif strncpy(sql_data, insert_clause, sizeof(sql_data)); strncat(sql_data, values_clause, SPACELEFT(sql_data)); if (config.sql_multi_values) { multi_values_handling: len = config.sql_multi_values-idata->mv.buffer_offset; if (strlen(values_clause) < len) { if (idata->mv.buffer_elem_num) { strcpy(multi_values_buffer+idata->mv.buffer_offset, "; "); idata->mv.buffer_offset++; idata->mv.buffer_offset++; } ptr_mv = multi_values_buffer+idata->mv.buffer_offset; strcpy(multi_values_buffer+idata->mv.buffer_offset, sql_data); idata->mv.buffer_offset += strlen(ptr_mv); idata->mv.buffer_elem_num++; } else { if (idata->mv.buffer_elem_num) { ret = sqlite3_exec(db->desc, multi_values_buffer, NULL, NULL, NULL); Log(LOG_DEBUG, "DEBUG ( %s/%s ): %d INSERT statements sent to the SQLite database.\n", config.name, config.type, idata->mv.buffer_elem_num); if (ret) goto signal_error; idata->iqn++; idata->mv.buffer_elem_num = FALSE; idata->mv.head_buffer_elem = FALSE; idata->mv.buffer_offset = 0; goto multi_values_handling; } else { Log(LOG_ERR, "ERROR ( %s/%s ): 'sql_multi_values' is too small (%d). Try with a larger value.\n", config.name, config.type, config.sql_multi_values); exit_plugin(1); } } } else { ret = sqlite3_exec(db->desc, sql_data, NULL, NULL, NULL); Log(LOG_DEBUG, "( %s/%s ): %s\n\n", config.name, config.type, sql_data); if (ret) goto signal_error; idata->iqn++; } } else { Log(LOG_DEBUG, "( %s/%s ): %s\n\n", config.name, config.type, sql_data); idata->uqn++; } idata->een++; // cache_elem->valid = FALSE; /* committed */ return ret; signal_error: if (!idata->mv.buffer_elem_num) Log(LOG_DEBUG, "DEBUG ( %s/%s ): FAILED query follows:\n%s\n", config.name, config.type, sql_data); else { if (!idata->recover || db->type != BE_TYPE_PRIMARY) { /* DB failure: we will rewind the multi-values buffer */ idata->current_queue_elem = idata->mv.head_buffer_elem; idata->mv.buffer_elem_num = 0; } } SQLI_get_errmsg(db); if (db->errmsg) Log(LOG_ERR, "ERROR ( %s/%s ): %s\n\n", config.name, config.type, db->errmsg); return ret; }
/*VARARGS1*/ void setproctitle(const char *fmt, ...) { # if SPT_TYPE != SPT_NONE register char *p; register int i; SETPROC_STATIC char buf[SPT_BUFSIZE]; VA_LOCAL_DECL # if SPT_TYPE == SPT_PSTAT union pstun pst; # endif # if SPT_TYPE == SPT_SCO off_t seek_off; static int kmem = -1; static int kmempid = -1; struct user u; # endif p = buf; /* print application name heading for grep */ // (void) strcpy(p, ApplicationPrefix); (void) strcpy(p, "SuckMT : "); p += strlen(p); /* print the argument string */ VA_START(fmt); (void) vsnprintf(p, SPACELEFT(buf, p), fmt, ap); VA_END; i = strlen(buf); # if SPT_TYPE == SPT_PSTAT pst.pst_command = buf; pstat(PSTAT_SETCMD, pst, i, 0, 0); # endif # if SPT_TYPE == SPT_PSSTRINGS PS_STRINGS->ps_nargvstr = 1; PS_STRINGS->ps_argvstr = buf; # endif # if SPT_TYPE == SPT_SYSMIPS sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf); # endif # if SPT_TYPE == SPT_SCO if (kmem < 0 || kmempid != getpid()) { if (kmem >= 0) close(kmem); kmem = open(_PATH_KMEM, O_RDWR, 0); if (kmem < 0) return; (void) fcntl(kmem, F_SETFD, 1); kmempid = getpid(); } buf[PSARGSZ - 1] = '\0'; seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u; if (lseek(kmem, (off_t) seek_off, SEEK_SET) == seek_off) (void) write(kmem, buf, PSARGSZ); # endif # if SPT_TYPE == SPT_REUSEARGV if (i > LastArgv - Argv[0] - 2) { i = LastArgv - Argv[0] - 2; buf[i] = '\0'; } (void) strcpy(Argv[0], buf); p = &Argv[0][i]; while (p < LastArgv) *p++ = SPT_PADCHAR; Argv[1] = NULL; # endif # if SPT_TYPE == SPT_CHANGEARGV Argv[0] = buf; Argv[1] = 0; # endif # endif /* SPT_TYPE != SPT_NONE */ }
int MY_compose_static_queries() { int primitives=0, set_primitives=0, set_event_primitives=0, have_flows=0; if (config.what_to_count & COUNT_FLOWS || (config.sql_table_version >= 4 && config.sql_table_version < SQL_TABLE_VERSION_BGP && !config.sql_optimize_clauses)) { config.what_to_count |= COUNT_FLOWS; have_flows = TRUE; if ((config.sql_table_version < 4 || config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !config.sql_optimize_clauses) { Log(LOG_ERR, "ERROR ( %s/%s ): The accounting of flows requires SQL table v4. Exiting.\n", config.name, config.type); exit_plugin(1); } } /* "INSERT INTO ... VALUES ... " and "... WHERE ..." stuff */ strncpy(where[primitives].string, " WHERE ", sizeof(where[primitives].string)); snprintf(insert_clause, sizeof(insert_clause), "INSERT INTO `%s` (", config.sql_table); strncpy(values[primitives].string, " VALUES (", sizeof(values[primitives].string)); primitives = MY_evaluate_history(primitives); primitives = sql_evaluate_primitives(primitives); strncpy(insert_counters_clause, ", packets, bytes", SPACELEFT(insert_counters_clause)); if (have_flows) strncat(insert_counters_clause, ", flows", SPACELEFT(insert_counters_clause)); strncat(insert_counters_clause, ")", SPACELEFT(insert_counters_clause)); strncpy(insert_nocounters_clause, ")", SPACELEFT(insert_nocounters_clause)); /* "LOCK ..." stuff */ snprintf(lock_clause, sizeof(lock_clause), "LOCK TABLES `%s` WRITE", config.sql_table); strncpy(unlock_clause, "UNLOCK TABLES", sizeof(unlock_clause)); /* "UPDATE ... SET ..." stuff */ snprintf(update_clause, sizeof(update_clause), "UPDATE `%s` ", config.sql_table); set_primitives = sql_compose_static_set(have_flows); set_event_primitives = sql_compose_static_set_event(); if (config.sql_history) { if (!config.sql_history_since_epoch) { strncpy(set[set_primitives].string, ", ", SPACELEFT(set[set_primitives].string)); strncat(set[set_primitives].string, "stamp_updated=NOW()", SPACELEFT(set[set_primitives].string)); set[set_primitives].type = TIMESTAMP; set[set_primitives].handler = count_noop_setclause_handler; set_primitives++; if (set_event_primitives) strncpy(set_event[set_event_primitives].string, ", ", SPACELEFT(set_event[set_event_primitives].string)); else strncpy(set_event[set_event_primitives].string, "SET ", SPACELEFT(set_event[set_event_primitives].string)); strncat(set_event[set_event_primitives].string, "stamp_updated=NOW()", SPACELEFT(set_event[set_event_primitives].string)); set_event[set_event_primitives].type = TIMESTAMP; set_event[set_event_primitives].handler = count_noop_setclause_event_handler; set_event_primitives++; } else { strncpy(set[set_primitives].string, ", ", SPACELEFT(set[set_primitives].string)); strncat(set[set_primitives].string, "stamp_updated=UNIX_TIMESTAMP(NOW())", SPACELEFT(set[set_primitives].string)); set[set_primitives].type = TIMESTAMP; set[set_primitives].handler = count_noop_setclause_handler; set_primitives++; if (set_event_primitives) strncpy(set_event[set_event_primitives].string, ", ", SPACELEFT(set_event[set_event_primitives].string)); else strncpy(set_event[set_event_primitives].string, "SET ", SPACELEFT(set_event[set_event_primitives].string)); strncat(set_event[set_event_primitives].string, "stamp_updated=UNIX_TIMESTAMP(NOW())", SPACELEFT(set_event[set_event_primitives].string)); set_event[set_event_primitives].type = TIMESTAMP; set_event[set_event_primitives].handler = count_noop_setclause_event_handler; set_event_primitives++; } } return primitives; }
int MY_cache_dbop(struct DBdesc *db, struct db_cache *cache_elem, struct insert_data *idata) { char *ptr_values, *ptr_where, *ptr_mv, *ptr_set, *ptr_insert; int num=0, num_set=0, ret=0, have_flows=0, len=0; if (idata->mv.last_queue_elem) { ret = mysql_query(db->desc, multi_values_buffer); Log(LOG_DEBUG, "DEBUG ( %s/%s ): %d VALUES statements sent to the MySQL server.\n", config.name, config.type, idata->mv.buffer_elem_num); if (ret) goto signal_error; idata->iqn++; idata->mv.buffer_elem_num = FALSE; idata->mv.buffer_offset = 0; return FALSE; } if (config.what_to_count & COUNT_FLOWS) have_flows = TRUE; /* constructing sql query */ ptr_where = where_clause; ptr_values = values_clause; ptr_set = set_clause; ptr_insert = insert_full_clause; memset(where_clause, 0, sizeof(where_clause)); memset(values_clause, 0, sizeof(values_clause)); memset(set_clause, 0, sizeof(set_clause)); memset(insert_full_clause, 0, sizeof(insert_full_clause)); for (num = 0; num < idata->num_primitives; num++) (*where[num].handler)(cache_elem, idata, num, &ptr_values, &ptr_where); if (cache_elem->flow_type == NF9_FTYPE_EVENT || cache_elem->flow_type == NF9_FTYPE_OPTION) { for (num_set = 0; set_event[num_set].type; num_set++) (*set_event[num_set].handler)(cache_elem, idata, num_set, &ptr_set, NULL); } else { for (num_set = 0; set[num_set].type; num_set++) (*set[num_set].handler)(cache_elem, idata, num_set, &ptr_set, NULL); } /* sending UPDATE query a) if not switched off and b) if we actually have something to update */ if (!config.sql_dont_try_update && num_set) { strncpy(sql_data, update_clause, SPACELEFT(sql_data)); strncat(sql_data, set_clause, SPACELEFT(sql_data)); strncat(sql_data, where_clause, SPACELEFT(sql_data)); ret = mysql_query(db->desc, sql_data); if (ret) goto signal_error; } if (config.sql_dont_try_update || !num_set || (mysql_affected_rows(db->desc) == 0)) { /* UPDATE failed, trying with an INSERT query */ if (cache_elem->flow_type == NF9_FTYPE_EVENT || cache_elem->flow_type == NF9_FTYPE_OPTION) { strncpy(insert_full_clause, insert_clause, SPACELEFT(insert_full_clause)); strncat(insert_full_clause, insert_nocounters_clause, SPACELEFT(insert_full_clause)); strncat(ptr_values, ")", SPACELEFT(values_clause)); } else { strncpy(insert_full_clause, insert_clause, SPACELEFT(insert_full_clause)); strncat(insert_full_clause, insert_counters_clause, SPACELEFT(insert_full_clause)); #if defined HAVE_64BIT_COUNTERS if (have_flows) snprintf(ptr_values, SPACELEFT(values_clause), ", %llu, %llu, %llu)", cache_elem->packet_counter, cache_elem->bytes_counter, cache_elem->flows_counter); else snprintf(ptr_values, SPACELEFT(values_clause), ", %llu, %llu)", cache_elem->packet_counter, cache_elem->bytes_counter); #else if (have_flows) snprintf(ptr_values, SPACELEFT(values_clause), ", %lu, %lu, %lu)", cache_elem->packet_counter, cache_elem->bytes_counter, cache_elem->flows_counter); else snprintf(ptr_values, SPACELEFT(values_clause), ", %lu, %lu)", cache_elem->packet_counter, cache_elem->bytes_counter); #endif } if (config.sql_multi_values) { multi_values_handling: len = config.sql_multi_values-idata->mv.buffer_offset; if (!idata->mv.buffer_elem_num) { if (strlen(insert_full_clause) < len) { strncpy(multi_values_buffer, insert_full_clause, config.sql_multi_values); strcat(multi_values_buffer, " VALUES"); idata->mv.buffer_offset += strlen(multi_values_buffer); idata->mv.head_buffer_elem = idata->current_queue_elem; } else { Log(LOG_ERR, "ERROR ( %s/%s ): 'sql_multi_values' is too small (%d). Try with a larger value.\n", config.name, config.type, config.sql_multi_values); exit_plugin(1); } } len = config.sql_multi_values-idata->mv.buffer_offset; if (strlen(values_clause) < len) { if (idata->mv.buffer_elem_num) { strcpy(multi_values_buffer+idata->mv.buffer_offset, ","); idata->mv.buffer_offset++; } ptr_mv = multi_values_buffer+idata->mv.buffer_offset; strcpy(multi_values_buffer+idata->mv.buffer_offset, values_clause+7); /* cut the initial 'VALUES' */ idata->mv.buffer_offset += strlen(ptr_mv); idata->mv.buffer_elem_num++; } else { if (idata->mv.buffer_elem_num) { ret = mysql_query(db->desc, multi_values_buffer); Log(LOG_DEBUG, "DEBUG ( %s/%s ): %d VALUES statements sent to the MySQL server.\n", config.name, config.type, idata->mv.buffer_elem_num); if (ret) goto signal_error; idata->iqn++; idata->mv.buffer_elem_num = FALSE; idata->mv.head_buffer_elem = FALSE; idata->mv.buffer_offset = 0; goto multi_values_handling; } else { Log(LOG_ERR, "ERROR ( %s/%s ): 'sql_multi_values' is too small (%d). Try with a larger value.\n", config.name, config.type, config.sql_multi_values); exit_plugin(1); } } } else { strncpy(sql_data, insert_full_clause, sizeof(sql_data)); strncat(sql_data, values_clause, SPACELEFT(sql_data)); ret = mysql_query(db->desc, sql_data); if (ret) goto signal_error; Log(LOG_DEBUG, "DEBUG ( %s/%s ): %s\n\n", config.name, config.type, sql_data); idata->iqn++; } } else { Log(LOG_DEBUG, "DEBUG ( %s/%s ): %s\n\n", config.name, config.type, sql_data); idata->uqn++; } idata->een++; // cache_elem->valid = FALSE; /* committed */ return ret; signal_error: if (!idata->mv.buffer_elem_num) Log(LOG_DEBUG, "DEBUG ( %s/%s ): FAILED query follows:\n%s\n", config.name, config.type, sql_data); else { if (!idata->recover || db->type != BE_TYPE_PRIMARY) { /* DB failure: we will rewind the multi-values buffer */ idata->current_queue_elem = idata->mv.head_buffer_elem; idata->mv.buffer_elem_num = 0; } } MY_get_errmsg(db); if (db->errmsg) Log(LOG_ERR, "ERROR ( %s/%s ): %s\n\n", config.name, config.type, db->errmsg); if (mysql_errno(db->desc) == 1062) return FALSE; /* not signalling duplicate entry problems */ else return ret; }