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

📄 udp.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 <stdio.h>#include <stdlib.h>#include <pthread.h>#include <unistd.h>#include <netinet/in.h>#include "config.h"#include "locks.h"#include "list.h"#include "log.h"#include "stat.h"#include "in_ntoa.h"#include "hex.h"#include "lookup.h"#include "udp.h"struct gen_stat udp_stat;pthread_mutex_t udp_mutex =  PTHREAD_MUTEX_INITIALIZER;WINDOW *udp_gui_window = NULL;pthread_mutex_t udp_gui_mutex =  PTHREAD_MUTEX_INITIALIZER;struct list_t *udp_slist;pthread_mutex_t udp_mutex_slist =  PTHREAD_MUTEX_INITIALIZER;/****************************************************************************** UDP Packets *********************************************************************************************************/int udp_handle(struct pkt_ip *ip, struct pkt_udp *udp) {	void *pointer;	unsigned short length;	int index;	char *ip_source = NULL, *ip_dest = NULL;#ifdef UDP_CHECKSUM	unsigned short oldcheck;#endif	struct udp_conn conn_search, *conn_tmp;	pointer = (void *) udp + sizeof(struct pkt_udp);	udp_stat.packets++;		length = ntohs(udp->len) - 8;#ifdef UDP_CHECKSUM	/* udp packet do not requie a checksum when the cksum is == 0 */	if (udp->check != 0) {		oldcheck = udp->check;		udp->check = 0;		udp->check = udp_check(udp, length + 8, ip->saddr, ip->daddr);		if (oldcheck != udp->check) {			ip_source = lookup(ip->saddr, 0);			ip_dest = lookup(ip->daddr, 0);			log_error("FAILED UDP CHECKSUM: %s -> %s Packet: %u Sniffer: %u L:%u\n", ip_source, ip_dest, oldcheck, udp->check, length);			udp_stat.dropped++;			return -1;		}	}#endif	udp_stat.bytes += length + 8;	conn_search.saddr = ip->saddr;	conn_search.daddr = ip->daddr;	conn_search.sport = udp->source;	conn_search.dport = udp->dest;	SLOCK(&udp_mutex_slist);	index = list_search(udp_slist, &conn_search);	if (index < 0) {		/* we now need to search in a different order */		conn_search.saddr = ip->daddr;		conn_search.daddr = ip->saddr;		conn_search.sport = udp->dest;		conn_search.dport = udp->source;				index = list_search(udp_slist, &conn_search);	}		if (index < 0) {		conn_tmp = malloc(sizeof(struct udp_conn));		if (!conn_tmp) {			log_err("malloc");			SUNLOCK(&udp_mutex_slist);			return udp_gui_print(ip, udp, length);		}		conn_tmp->delme = 50;		conn_tmp->saddr = ip->saddr;		conn_tmp->saddr_str = in_ntoa(ip->saddr);		conn_tmp->saddr_name = NULL;		conn_tmp->daddr = ip->daddr;		conn_tmp->daddr_str = in_ntoa(ip->saddr);		conn_tmp->daddr_name = NULL;		conn_tmp->sport = udp->source;		conn_tmp->dport = udp->dest;		init_stat(&conn_tmp->stat_in, NULL);		init_stat(&conn_tmp->stat_out, NULL);		list_add_sort(udp_slist, conn_tmp);	} else {		conn_tmp = list_get(udp_slist, index);	}	if (!conn_tmp) { /* this should not occur */		log_unreach();		SUNLOCK(&udp_mutex_slist);		return udp_gui_print(ip, udp, length);	}	conn_tmp->delme = 50;	if (conn_tmp->saddr == ip->saddr) {		conn_tmp->stat_out.packets++;		conn_tmp->stat_out.bytes += length;	} else {		conn_tmp->stat_in.packets++;		conn_tmp->stat_in.bytes += length;	}	SUNLOCK(&udp_mutex_slist);	return udp_gui_print(ip, udp, length);}int udp_cmp(struct udp_conn *c1, struct udp_conn *c2) {	if (c1->saddr > c2->saddr) return -1;	if (c1->saddr < c2->saddr) return 1;	if (c1->daddr > c2->daddr) return -1;	if (c1->daddr < c2->daddr) return 1;	if (c1->sport > c2->sport) return -1;	if (c1->sport < c2->sport) return 1;	if (c1->dport > c2->dport) return -1;	if (c1->dport < c2->dport) return 1;	return 0;}int udp_dump_all(struct pkt_ip *ip, struct pkt_udp *udp, char *data, unsigned short data_len) {	char *ip_source = NULL;	char *ip_dest = NULL;	int length;	char buff[1024];	char *tmp;	ip_source = lookup(ip->saddr, 0);	ip_dest = lookup(ip->daddr, 0);	length = sprintf(&buff[0], "%s [%u] -> %s [%u] L:%u\n",		ip_source, ntohs(udp->source),		ip_dest, ntohs(udp->dest), data_len);	tmp = hex_conv(data, data_len);	if (length < 0) {		log_s("No Data in buffer");	} else {		//write(log_fd_udp, &buff, length);		//write(log_fd_udp, tmp, strlen(tmp));	}	if (tmp)		free(tmp);	return 0;}inline unsigned short udp_check(struct pkt_udp *th, unsigned short len, unsigned long saddr, unsigned long daddr) {	unsigned long sum = 0;	unsigned short *buff;	unsigned long ans;	/* add the sorce address */		buff = (unsigned short *) &saddr;	sum += *buff++;	sum += *buff;		/* add the dest address */	buff = (unsigned short *) &daddr;	sum += *buff++;	sum += *buff;	/* add the zero + protocol */	sum += IP_UDP * 256;	/* add the length */	sum += htons(len) & 0xffff;	/* add the rest of the packet */	buff = (unsigned short *) th;	while(len > 1) {		sum += *buff++;		len -= 2;	}	if (len == 1) /* do we need to mop up an odd byte ? */		sum += (*buff & 0xff);		sum = (sum >> 16) + (sum & 0xffff);	sum += (sum >> 16);	ans = (~sum) & 0xffff;	if (ans == 0) /* if udp cksum == 0 then it gets passed as all 1's */		ans = ~0;	return ans;}void udp_gui_conn	(struct gui_t *p, int y, int x) {	WINDOW *draw;	char *foot_back, buff[80];	int length, i, offset = 0;	int cury;	struct udp_conn *udp;	draw = newwin(p->twin->_maxy - 1, p->twin->_maxx - 1, 1, 1);	if (!draw) {		log_s("subwin failed");		return;	}	wbkgd(draw, COLOR_PAIR(COL_BACK));	werase(draw);	wrefresh(draw);	foot_back = p->footer;		while (1) {		werase(draw);		cury = 0;		i = offset;		if (offset > 0)			mvwprintw(draw, 1, draw->_maxx - 12, "--more--");								stat_process(&udp_stat);		snprintf(&buff[0], 80, "UDP Packets: %llu Data: %llu %s Drop: %llu",				udp_stat.packets, udp_stat.readable, udp_stat.messure, udp_stat.dropped);		gui_footer(p, &buff[0]);				SLOCK(&udp_mutex_slist);		length = list_len(udp_slist);		while(cury < draw->_maxy && i < length) {			udp = list_get(udp_slist, i);			stat_process(&udp->stat_in);			stat_process(&udp->stat_out);						if (udp->saddr_name) {				mvwprintw(draw, cury++, 0, "/%24.24s [%u]   \t%4lli:%llu %s\t%.0f:%.2f/Sec",						udp->saddr_name, ntohs(udp->sport),						udp->stat_out.packets, udp->stat_out.readable,						udp->stat_out.messure, udp->stat_out.rate_packets,						udp->stat_out.rate_kb);			} else {				udp->saddr_name = lookup(udp->saddr, 1);				mvwprintw(draw, cury++, 0, "/%24.24s [%u]   \t%4lli:%llu %s\t%.0f:%.2f/Sec",						udp->saddr_str, ntohs(udp->sport),						udp->stat_out.packets, udp->stat_out.readable,						udp->stat_out.messure, udp->stat_out.rate_packets,						udp->stat_out.rate_kb);							}			if (udp->daddr_name) {				mvwprintw(draw, cury++, 0, "\\%24.24s [%u]   \t%4lli:%llu %s\t%.0f:%.2f/Sec",						udp->daddr_name, ntohs(udp->dport),						udp->stat_in.packets, udp->stat_in.readable,						udp->stat_in.messure, udp->stat_in.rate_packets,						udp->stat_in.rate_kb);			} else {				udp->daddr_name = lookup(udp->daddr, 1);				mvwprintw(draw, cury++, 0, "\\%24.24s [%u]   \t%4lli:%llu %s\t%.0f:%.2f/Sec",						udp->daddr_str, ntohs(udp->dport),						udp->stat_in.packets, udp->stat_in.readable,						udp->stat_in.messure, udp->stat_in.rate_packets,						udp->stat_in.rate_kb);							}			i++;		}		SUNLOCK(&udp_mutex_slist);		if (cury == 0) /* do we have any entries ? */			mvwprintw(draw, cury++, 0, " -- No Entries --");		else			mvwprintw(draw, cury++, 0, " -- END --");		if (cury > draw->_maxy - 1)			mvwprintw(draw, draw->_maxy , draw->_maxx - 8, "--more--");		wrefresh(draw);		switch(gui_scroll(250, 0, length, &offset)) {			case -1: /* error / timeout */				break;			case 0: /* it did something */				break;			default:				goto get_out;				break;		} /* end of switch gui_utils_scroll */	} /* end of while(1) */get_out:	gui_footer(p, foot_back);	werase(draw);	wrefresh(draw);	delwin(draw);	return;}void udp_gui(struct gui_t *p, int y, int x) {	WINDOW *draw;	char *foot_back, buff[80];	SLOCK(&udp_gui_mutex);	draw = newwin(p->twin->_maxy - 1, p->twin->_maxx - 1, 1, 1);	if (!draw) {		log_s("subwin failed");		SUNLOCK(&udp_gui_mutex);		return;	}	wbkgd(draw, COLOR_PAIR(COL_BACK));	scrollok(draw, TRUE);	werase(draw);	wrefresh(draw);	foot_back = p->footer;	udp_gui_window = draw;	SUNLOCK(&udp_gui_mutex);	while (1) {		if (gui_wait(250, 0) == 1) {			switch(getch()) {				default:					goto get_out;					break;			}		} else {			stat_process(&udp_stat);			SLOCK(&udp_gui_mutex);			wrefresh(draw);			snprintf(&buff[0], 80, "UDP Packets: %llu Data: %llu %s Drop: %llu",							udp_stat.packets, udp_stat.readable, udp_stat.messure, udp_stat.dropped);			gui_footer(p, &buff[0]);			SUNLOCK(&udp_gui_mutex);		}	}get_out:	gui_footer(p, foot_back);	SLOCK(&udp_gui_mutex);	udp_gui_window = NULL;	SUNLOCK(&udp_gui_mutex);		werase(draw);	wrefresh(draw);	delwin(draw);	return;}int udp_gui_print(struct pkt_ip *ip, struct pkt_udp *udp, unsigned short length) {	if (!udp_gui_window)		return 0;	SLOCK(&udp_gui_mutex);	gui_print(udp_gui_window, "%13s(%5u) -> %13s(%5u) L:%u\n",		lookup(ip->saddr, 0), ntohs(udp->source),		lookup(ip->daddr, 0), ntohs(udp->dest), length);	SUNLOCK(&udp_gui_mutex);	return 0;}int udp_tidy() {	struct udp_conn *tmp;	int i, max = 15;	SLOCK(&udp_mutex_slist);	for(i=0;i<list_len(udp_slist);i++) {		tmp = list_get(udp_slist, i);		if (!tmp) {			SUNLOCK(&udp_mutex_slist);			return -1;		}		if (tmp->delme < 1) {			list_del(udp_slist, i);			i--;			if (tmp->saddr_str)				free(tmp->saddr_str);			if (tmp->daddr_str)				free(tmp->daddr_str);			free(tmp);		} else {			tmp->delme--;		}		if (max < 1) {			SUNLOCK(&udp_mutex_slist);			max = 15;			SLOCK(&udp_mutex_slist);		}	}	SUNLOCK(&udp_mutex_slist);	return 0;}int udp_init() {	SLOCK(&udp_mutex_slist);	udp_slist = list_init();	list_setcmp(udp_slist, (void *) udp_cmp);	SUNLOCK(&udp_mutex_slist);	return 0;}

⌨️ 快捷键说明

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