/* * Copyright (c) 2001 Fenris, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include "db.h" #include "globals.h" #include "queue.h" void into_db(Packet_Headers *p, struct timeval *ts) { struct db_item *item; if ((item = malloc(sizeof(struct db_item))) == NULL) die("malloc"); item->p = p; item->ts = *ts; free(ts); pthread_mutex_lock(db_mutex); STAILQ_INSERT_TAIL(&db_q, item, entries); pthread_mutex_unlock(db_mutex); return; } void init_db(struct db_info **db, char *filename) { int fd; int i; char str[256]; char *user; char *pass; char *host; char *port; char *name; char *type; if ((*db = malloc(sizeof(struct db_info))) == NULL) die("malloc"); if (((*db)->user = malloc(DB_INFO_LEN)) == NULL) die("malloc"); if (((*db)->passwd = malloc(DB_INFO_LEN)) == NULL) die("malloc"); if (((*db)->host = malloc(DB_INFO_LEN)) == NULL) die("malloc"); if (((*db)->db = malloc(DB_INFO_LEN)) == NULL) die("malloc"); (*db)->user = NULL; (*db)->passwd = NULL; (*db)->host = NULL; (*db)->port = 3306; (*db)->db = "tvark"; (*db)->type = DB_MYSQL; if (filename == NULL) return; if ((fd = open(filename, O_RDONLY)) == -1) die("open"); read(fd, str, 256); for (i = 0; i < 256; ++i) { if (str[i] == '\n') { str[i] = '\0'; break; } } user = strtok(str, "@"); host = strtok(NULL, " \t"); name = strtok(NULL, ""); if (user != NULL) { user = strtok(user, ":"); pass = strtok(NULL, ""); } if (host != NULL) { host = strtok(host, ":"); port = strtok(NULL, ""); } if (name != NULL) { name = strtok(name, " \t"); type = strtok(NULL, ""); } if (user != NULL) (*db)->user = strdup(user); if (pass != NULL) (*db)->passwd = strdup(pass); if (host != NULL) (*db)->host = strdup(host); if (port != NULL) (*db)->port = atoi(port); if (name != NULL) (*db)->db = strdup(name); if (type != NULL) { if (!strcmp(type, "mysql")) (*db)->type = DB_MYSQL; else die("bad database type"); } close(fd); return; } void *db_engine(void *arg) { struct db_info *db; struct db_item *item; MYSQL mysql; db = arg; /* Open database connection. */ switch (db->type) { case DB_MYSQL: mysql_init(&mysql); if (mysql_real_connect(&mysql, db->host, db->user, db->passwd, db->db, db->port, NULL, 0) == NULL) die("could not connect to database"); break; default: die("unknown database type"); } for (;;) { while (STAILQ_EMPTY(&db_q)); pthread_mutex_lock(db_mutex); item = STAILQ_FIRST(&db_q); STAILQ_REMOVE_HEAD(&db_q, entries); pthread_mutex_unlock(db_mutex); /* Switch on db type and insert data from item->p */ switch (db->type) { case DB_MYSQL: insert_mysql(&mysql, item); break; default: die("unknown database type"); } free(item->p); free(item); } /* Close database connection. */ switch (db->type) { case DB_MYSQL: mysql_close(&mysql); break; default: die("unknown database type"); } return NULL; } void insert_mysql(MYSQL *mysql, struct db_item *item) { Packet_Headers *p; struct timeval ts; char query[256]; p = item->p; ts = item->ts; snprintf(query, 256, "insert into eth_header values(%d.%d, " "\"%02x:%02x:%02x:%02x:%02x:%02x\", " "\"%02x:%02x:%02x:%02x:%02x:%02x\", %u)", ts.tv_sec, ts.tv_usec, p->ll.eth->eth_src[0], p->ll.eth->eth_src[1], p->ll.eth->eth_src[2], p->ll.eth->eth_src[3], p->ll.eth->eth_src[4], p->ll.eth->eth_src[5], p->ll.eth->eth_dst[0], p->ll.eth->eth_dst[1], p->ll.eth->eth_dst[2], p->ll.eth->eth_dst[3], p->ll.eth->eth_dst[4], p->ll.eth->eth_dst[5], p->ll.eth->eth_typ); mysql_query(mysql, query); free(p->ll.eth); if (p->type == tcp_t || p->type == udp_t || p->type == icmp_t || p->type == igmp_t) { snprintf(query, 256, "insert into ip_header values(%d.%d, " "%u, %u, %d, %u, %u, %u, %d, %d, %u, " "%u, %u, %u, %u, %u, \"\", " /* src */ "%u, %u, %u, %u, %u, \"\")", /* dst */ ts.tv_sec, ts.tv_usec, p->nl.ip->ip_hdr_len, p->nl.ip->ip_ver, p->nl.ip->ip_tos, p->nl.ip->ip_pkt_len, p->nl.ip->ip_id, p->nl.ip->ip_frg_off, p->nl.ip->ip_ttl, p->nl.ip->ip_protocol, p->nl.ip->ip_chksum, p->nl.ip->ip_src, p->nl.ip->ip_src >> 24, p->nl.ip->ip_src << 8 >> 24, p->nl.ip->ip_src << 16 >> 24, p->nl.ip->ip_src << 24 >> 24, p->nl.ip->ip_dst, p->nl.ip->ip_dst >> 24, p->nl.ip->ip_dst << 8 >> 24, p->nl.ip->ip_dst << 16 >> 24, p->nl.ip->ip_dst << 24 >> 24); mysql_query(mysql, query); free(p->nl.ip); } switch (p->type) { case arp_t: snprintf(query, 256, "insert into arp_header values(%d.%d, " "%u, %u, %d, %d, %u, " "\"%02x:%02x:%02x:%02x:%02x:%02x\", " "\"%02x:%02x:%02x:%02x:%02x:%02x\", " "%u, %u)", ts.tv_sec, ts.tv_usec, p->nl.arp->arp_hrd_typ, p->nl.arp->arp_prt_typ, p->nl.arp->arp_hrd_len, p->nl.arp->arp_prt_len, p->nl.arp->arp_typ, p->nl.arp->arp_sdr_mac[0], p->nl.arp->arp_sdr_mac[1], p->nl.arp->arp_sdr_mac[2], p->nl.arp->arp_sdr_mac[3], p->nl.arp->arp_sdr_mac[4], p->nl.arp->arp_sdr_mac[5], p->nl.arp->arp_tgt_mac[0], p->nl.arp->arp_tgt_mac[1], p->nl.arp->arp_tgt_mac[2], p->nl.arp->arp_tgt_mac[3], p->nl.arp->arp_tgt_mac[4], p->nl.arp->arp_tgt_mac[5], (p->nl.arp->arp_sdr_ip[0] << 24) + (p->nl.arp->arp_sdr_ip[1] << 16) + (p->nl.arp->arp_sdr_ip[2] << 8) + (p->nl.arp->arp_sdr_ip[3]), (p->nl.arp->arp_tgt_ip[0] << 24) + (p->nl.arp->arp_tgt_ip[1] << 16) + (p->nl.arp->arp_tgt_ip[2] << 8) + (p->nl.arp->arp_tgt_ip[3])); mysql_query(mysql, query); free(p->nl.arp); break; case tcp_t: snprintf(query, 256, "insert into tcp_header values(%d.%d, " "%u, %u, %u, %u, %u, %u, %u, %u, %u, %u)", ts.tv_sec, ts.tv_usec, p->tl.tcp->tcp_src_port, p->tl.tcp->tcp_dst_port, p->tl.tcp->tcp_seq_num, p->tl.tcp->tcp_ack_num, p->tl.tcp->tcp_reserved, p->tl.tcp->tcp_hdr_len, p->tl.tcp->tcp_flags, p->tl.tcp->tcp_win_siz, p->tl.tcp->tcp_chksum, p->tl.tcp->tcp_urg_ptr); mysql_query(mysql, query); free(p->tl.tcp); break; case udp_t: snprintf(query, 256, "insert into udp_header values(%d.%d, " "%u, %u, %u, %u)", ts.tv_sec, ts.tv_usec, p->tl.udp->udp_src_port, p->tl.udp->udp_dst_port, p->tl.udp->udp_len, p->tl.udp->udp_chksum); mysql_query(mysql, query); free(p->tl.udp); break; case icmp_t: snprintf(query, 256, "insert into icmp_header values(%d.%d, " "%u, %u, %u)", ts.tv_sec, ts.tv_usec, p->tl.icmp->icmp_typ, p->tl.icmp->icmp_code, p->tl.icmp->icmp_chksum); mysql_query(mysql, query); free(p->tl.icmp); break; case igmp_t: snprintf(query, 256, "insert into igmp_header values(%d.%d, " "%u, %u, %u, %u)", ts.tv_sec, ts.tv_usec, p->tl.igmp->igmp_typ, p->tl.igmp->igmp_ver, p->tl.igmp->igmp_chksum, p->tl.igmp->igmp_addr); mysql_query(mysql, query); free(p->tl.igmp); break; case unknown_t: /* FALLTHROUGH */ default: break; } return; }