⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lookup.c

📁 * A ncurses user interface. * Network statistics to view the amount of packets and data in many
💻 C
字号:
/*  This file is part of sniffer, a packet capture utility and  network moniter  The author can be contacted at <mistral@stev.org>  the lastest version is avilable from   http://stev.org  This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2 of the License, or  (at your option) any later version.  This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "config.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <pthread.h>#include <netdb.h>#include <arpa/inet.h>#include "list.h"#include "locks.h"#include "in_ntoa.h"#include "log.h"#include "lookup.h"/* we also have the lookup code in here */#define MAX_WORK 10pthread_t lookup_thread;pthread_mutex_t lookup_mutex =  PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t lookup_failed_mutex =  PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t lookup_todo_mutex =  PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t lookup_active_mutex = PTHREAD_MUTEX_INITIALIZER;struct list_t *lookup_list;struct list_t *lookup_failed;struct list_t *lookup_todo;struct list_t *lookup_active;/* this is the start of a thread */void *lookup_init(void *arg) {	struct lookup *tmp;	int i, work;	SLOCK(&lookup_mutex);	SLOCK(&lookup_todo_mutex);	SLOCK(&lookup_failed_mutex);	SLOCK(&lookup_active_mutex);	lookup_list = list_init();	list_setcmp(lookup_list, (void *) lookup_cmp);	lookup_failed = list_init();	lookup_todo = list_init();	lookup_active = list_init();	list_setcmp(lookup_active, (void *) lookup_cmp);	SUNLOCK(&lookup_active_mutex);	SUNLOCK(&lookup_failed_mutex);	SUNLOCK(&lookup_todo_mutex);	SUNLOCK(&lookup_mutex);	for(;;) {		work = 0;		SLOCK(&lookup_todo_mutex);		for(i=0;i<list_len(lookup_todo);i++) {			tmp = list_get(lookup_todo, i);			if (!tmp) {				log_unreach();				goto end_todo;			}			if (tmp->name == NULL && tmp->working == 0) {				/* if we fail it will go onto a failed list				a fererance is always stored in the main list anyway */				list_del(lookup_todo, i);				SUNLOCK(&lookup_todo_mutex);				if (lookup_dns(tmp) < 0) {					SLOCK(&lookup_failed_mutex);					list_add(lookup_failed, tmp);					SUNLOCK(&lookup_failed_mutex);					work++;					goto end_todo;				}				SLOCK(&lookup_todo_mutex);			}		}		SUNLOCK(&lookup_todo_mutex);end_todo:	/* FIXME re que failed lookups */	if (work == 0)		sleep(1);	} /* end of for(;;) */	return 0;}void lookup_tidy() {	int work = 0, i;	struct lookup *tmp;	SLOCK(&lookup_active_mutex);	for(i=0;list_len(lookup_active);i++) {		tmp = list_get(lookup_active, i);		if (!tmp) {			SUNLOCK(&lookup_active_mutex);			return;		}		if (tmp->score > 0) {			tmp->score--;		} else {			if (list_del(lookup_active, i))				i--;		}		if (work > MAX_WORK) {			SLOCK(&lookup_active_mutex);			work = 0;			SUNLOCK(&lookup_active_mutex);		}	}	SUNLOCK(&lookup_active_mutex);	return;}int lookup_dns(struct lookup *p) {	struct hostent *hostent;	hostent = gethostbyaddr((char *) &p->ip, sizeof(struct in_addr), AF_INET);	if (!hostent) {		p->failed++;		return -1;	} else { /* the lookup worked */		p->name = malloc(strlen(hostent->h_name) + 1);		if (!p->name) {			log_errno("malloc");			return -1;		} else {			strcpy(p->name, hostent->h_name);		}		p->time = time(NULL);		p->working = 0;		p->failed = 0;	}	return 0;}int lookup_cmp(struct lookup *c1, struct lookup *c2) {	unsigned long d1, d2;	d1 = htonl(c1->ip);	d2 = htonl(c2->ip);	if (d1 >  d2) return -1;	if (d1 <  d2) return 1;	return 0;}struct lookup *lookup_get(unsigned long ip) {	struct lookup *tmp;	struct lookup check;	int i = 0;	check.ip = ip;	SLOCK(&lookup_active_mutex);	i = list_search(lookup_active, &check);	if (i >= 0) {		tmp = list_get(lookup_active, i);		if (tmp) {			if (tmp->score < 100)				tmp->score++;			SUNLOCK(&lookup_active_mutex);			return tmp;		}	}	SLOCK(&lookup_mutex); /* grab the lock */	i = list_search(lookup_list, &check);	if (i >= 0) {		tmp = list_get(lookup_list, i);		if (tmp) {			tmp->score = 50;			list_add_sort(lookup_active, tmp);			SUNLOCK(&lookup_mutex);			SUNLOCK(&lookup_active_mutex);			return tmp;		}		log_unreach();		return NULL;	}	/* we dont know about that host so lets create a new entry */	tmp = lookup_create(ip);	if (!tmp) {		SUNLOCK(&lookup_mutex);		SUNLOCK(&lookup_active_mutex);		return NULL;	}	list_add_sort(lookup_list, tmp);	list_add_sort(lookup_active, tmp);	SUNLOCK(&lookup_mutex);	SUNLOCK(&lookup_active_mutex);	SLOCK(&lookup_todo_mutex);	list_add(lookup_todo, tmp);	SUNLOCK(&lookup_todo_mutex);	return tmp; /* we never did get a name to still return null */}/* the ip address passed to this should be in network byte order *//* this will not copy the ip / name *//* if fail is set return null not an ip address */char *lookup(unsigned long ip, int fail) {	struct lookup *tmp;	tmp = lookup_get(ip);	if (!tmp)		return NULL;	if (tmp->name)		return tmp->name;	if (!fail)		return tmp->ip_str;	return NULL;}inline void lookup_stats(unsigned long daddr, unsigned long dbytes,			 unsigned long saddr, unsigned long sbytes) {	struct lookup *tmp;	tmp = lookup_get(daddr);	if (tmp) {		tmp->in.packets++;		tmp->in.bytes += dbytes;	}	tmp = lookup_get(saddr);	if (tmp) {		tmp->out.packets++;		tmp->out.bytes += sbytes;	}	return;}/* the whole list is already locked when we are in the function !! */inline struct lookup *lookup_create(unsigned long ip) {	struct lookup *tmp;	tmp = malloc(sizeof(struct lookup));	if (!tmp) {		log_errno("malloc");		return NULL;	}	tmp->ip_str = in_ntoa(ip);	if (!tmp->ip_str) {		free(tmp);		return NULL;	}	tmp->ip = ip;	tmp->name = NULL;	tmp->time = 0;	tmp->working = 0;	tmp->failed = 0;	tmp->score = 100;	init_stat(&tmp->in, "IN");	init_stat(&tmp->out, "OUT");	return tmp;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -