Добавил:
korayakov
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <signal.h>
/* libpcap */
#include <pcap.h>
typedef struct sockaddr SA;
#include "sniff.h"
char *sniff_dev;
char errbuf[PCAP_ERRBUF_SIZE];
struct bpf_program pfilter;
char pfilter_app[] = "port 23";
bpf_u_int32 mask, net;
const struct ethhdr *eth_hdr; /* The ethernet header */
const struct iphdr *ip_hdr; /* The IP header */
const struct tcphdr *tcp_hdr; /* The TCP header */
const struct udphdr *udp_hdr; /* The UDP header */
const struct icmphdr *icmp_hdr; /* The ICMP header */
/* For readability, we'll make variables for the sizes of each of the structures */
#define DEBUG
#ifdef DEBUG
static const int mdebug=1;
#else
static const int mdebug=0;
#endif /* DEBUG */
#define dprintf if (mdebug) printf
void NSniff::packet_callback(u_char *args, const struct pcap_pkthdr *header,
const u_char *packet)
{
size_t pp_len = 0;
if (qlen >= qsize){
qsize *= 2;
queue = (struct npacket **)realloc(queue, sizeof(struct npacket *)*qsize);
size_t i;
for (i = qlen; i < qsize; i++){
queue[i] = (struct npacket *)malloc(sizeof(struct npacket));
memset(queue[i], 0, sizeof(struct npacket));
}
return;
}
struct npacket *np = queue[qlen];
qlen++;
if (header->len > np->data_size){
np->data_size = header->len;
np->data = (char *)realloc(np->data, np->data_size);
}
eth_hdr = (const struct ethhdr *)packet;
np->eth_proto = ntohs(eth_hdr->h_proto);
memcpy(np->eth_dest, eth_hdr->h_dest, ETH_ALEN);
memcpy(np->eth_source, eth_hdr->h_source, ETH_ALEN);
pp_len += sizeof(const struct ethhdr);
if (np->eth_proto == ETH_P_IP){
ip_hdr = (const struct iphdr *)(packet + pp_len);
pp_len += sizeof(struct iphdr);
np->ip_version = ip_hdr->version;
np->ip_tos = ip_hdr->tos;
np->ip_id = ntohs(ip_hdr->id);
np->ip_df = ntohs(ip_hdr->frag_off) & 0x1; /* do not fragment */
np->ip_mf = ntohs(ip_hdr->frag_off) & 0x2; /* more fragment */
np->ip_ttl = ip_hdr->ttl;
np->ip_protocol = ip_hdr->protocol;
np->ip_saddr = ip_hdr->saddr;
np->ip_daddr = ip_hdr->daddr;
if (np->ip_protocol == IPPROTO_ICMP){
icmp_hdr = (struct icmphdr *)(packet + pp_len);
pp_len += sizeof(struct icmphdr);
np->icmp_type = icmp_hdr->type;
np->icmp_code = icmp_hdr->code;
np->icmp_ident = ntohs(icmp_hdr->un.echo.id);
np->icmp_sequence = ntohs(icmp_hdr->un.echo.sequence);
}
else if (np->ip_protocol == IPPROTO_TCP){
tcp_hdr = (struct tcphdr *)(packet + pp_len);
pp_len += sizeof(struct tcphdr);
np->tcp_source = ntohs(tcp_hdr->source);
np->tcp_dest = ntohs(tcp_hdr->dest);
np->tcp_seq = ntohl(tcp_hdr->seq);
np->tcp_ack_seq = ntohl(tcp_hdr->ack_seq);
np->tcp_fin = tcp_hdr->fin;
np->tcp_syn = tcp_hdr->syn;
np->tcp_rst = tcp_hdr->rst;
np->tcp_psh = tcp_hdr->psh;
np->tcp_ack = tcp_hdr->ack;
np->tcp_urg = tcp_hdr->urg;
np->tcp_urg_ptr = ntohs(tcp_hdr->urg_ptr);
}
else if (np->ip_protocol == IPPROTO_UDP){
udp_hdr = (struct udphdr *)(packet + pp_len);
pp_len += sizeof(struct udphdr);
np->udp_source = ntohs(udp_hdr->source);
np->udp_dest = ntohs(udp_hdr->dest);
}
else{
}
}
else if (np->eth_proto == ETH_P_ARP){
qlen--;
}
else {
}
np->data_len = header->len-pp_len;
memmove(np->data, (char *)(packet + pp_len), np->data_len);
}
void NSniff::run()
{
err_code = 0;
err_str = "";
/* open pcap session */
pcap_t *handle = pcap_open_live(dev_name.ascii(), BUFSIZ, 1, 1, errbuf);
if (!handle){
err_code = 1;
err_str = "Pcap open failed!\n" + QString(errbuf);
return;
}
pcap_setnonblock(handle, 1, errbuf);
/* setting filter */
/*
pcap_lookupnet(sniff_dev, &net, &mask, errbuf);
pcap_compile(phandle, &pfilter, pfilter_app, 0, net);
pcap_setfilter([phandle, &pfilter);
*/
/* allocate memory for packet queue */
int datalink = pcap_datalink(handle);
if (datalink == DLT_EN10MB){
printf("Ok, datalink type - ethernet\n");
}
else{
fprintf(stderr,"Currently unsupported datalink type <%d>\n",
datalink); return;
}
stopped = 0;
while (1){
if ( c_stop && (qlen >= c_stop)){
stopped++;
}
if ( t_stop && (time(NULL) >= t_stop)){
stopped++;
}
if (stopped){
break;
}
struct pcap_pkthdr header;
const u_char *packet = pcap_next(handle, &header);
if (packet)
packet_callback(NULL, &header, packet);
//pcap_loop(phandle, queue_size, &packet_callback , NULL);
}
pcap_close(handle);
stopped++;
return;
}
NSniff::~NSniff( )
{
if (queue){
size_t i;
for (i = 0; i < qsize; i++){
if (queue[i]->data)
free(queue[i]->data);
free(queue[i]);
}
free(queue);
}
}
NSniff::NSniff( QWidget * pparent )
{
queue = NULL;
qsize = 0;
qlen = 0;
dev_name = "";
stopped = true;
t_stop = 0;
c_stop = 0;
parent = pparent;
err_code = 0;
err_str = "";
}
int NSniff::setParams(QString pdev_name, time_t ptime, size_t pcount)
{
if (running()){
return -1;
}
if (pdev_name == ""){
return -1;
}
dev_name = pdev_name;
t_stop = (ptime == 0) ? (0) : (time(NULL)+ptime*60);
c_stop = pcount;
if (pcount == 0)
pcount = 10000;
if (qsize < pcount){
queue = (struct npacket **)realloc(queue,
sizeof(struct npacket *)*pcount);
size_t i;
for (i = qsize; i < pcount; i++){
queue[i] = (struct npacket *)malloc(sizeof(struct npacket));
memset(queue[i], 0, sizeof(struct npacket));
}
qsize = pcount;
}
qlen = 0;
stopped = true;
dprintf("dev=%s; size=%d; t_stop=%d; c_stop=%d\n",dev_name.ascii(),
qsize, (int)t_stop, c_stop);
return 0;
}
void NSniff::stop()
{
stopped++;
}
int NSniff::getResults(struct npacket ***r_queue, size_t *r_len)
{
if (running()){
return -1;
}
*r_queue = queue;
*r_len = qlen;
return 0;
}
QString NSniff::print_packet(size_t index)
{
if (index >= qlen)
return QString("No such packet");
struct npacket *p = queue[index];
QString str = "<br><br><br><hr><br>";
str += "<font face=mono><table>\n";
str += QString("<tr><td width=140 align=center>Property<td align=center>Data");
/* get HW addr */
int g;
char s_addr[128];
QString s_hw_addr = "";
QString d_hw_addr = "";
sprintf(s_addr, "%.2hhx",p->eth_source[1]);
s_hw_addr += s_addr;
for (g=1; g < ETH_ALEN; g++){
sprintf(s_addr, ":%.2hhx",p->eth_source[g]);
s_hw_addr += s_addr;
}
sprintf(s_addr, "%.2hhx",p->eth_dest[1]);
d_hw_addr += s_addr;
for (g=1; g < ETH_ALEN; g++){
sprintf(s_addr, ":%.2hhx", p->eth_dest[g]);
d_hw_addr += s_addr;
}
str += QString("<tr><td>HW from address <td>%1\n").arg(s_hw_addr);
str += QString("<tr><td>HW to address <td>%1\n").arg(d_hw_addr);
if (p->eth_proto == ETH_P_IP){
/* ip packet*/
if (p->ip_protocol == IPPROTO_ICMP){
str += QString("<tr><td>Type <td>ICMP\n");
}
else if(p->ip_protocol == IPPROTO_TCP){
str += QString("<tr><td>Type <td>TCP\n");
}
else if(p->ip_protocol == IPPROTO_UDP){
str += QString("<tr><td>Type <td>UDP\n");
}
else{
str += QString("<tr><td>Type <td>IP #%1\n").arg(p->ip_protocol);
}
/* from ip */
inet_ntop(AF_INET, &p->ip_saddr, s_addr, sizeof(s_addr));
str += QString("<tr><td>IP from address <td>%1\n").arg(s_addr);
/* to ip */
inet_ntop(AF_INET, &p->ip_daddr, s_addr, sizeof(s_addr));
str += QString("<tr><td>IP to address <td>%1\n").arg(s_addr);
if (p->ip_protocol == IPPROTO_ICMP){
str += QString("<tr><td>ICMP type <td>%1\n").arg(p->icmp_type);
str += QString("<tr><td>ICMP code <td>%1\n").arg(p->icmp_code);
str += QString("<tr><td>ICMP ident <td>%1\n").arg(p->icmp_ident);
str += QString("<tr><td>ICMP sequence <td>%1\n").arg(p->icmp_sequence);
}
else if(p->ip_protocol == IPPROTO_TCP){
str += QString("<tr><td>Port from <td>%1\n").arg(p->tcp_source);
str += QString("<tr><td>Port to <td>%1\n").arg(p->tcp_dest);
str += QString("<tr><td>Seq num <td>%1\n").arg(p->tcp_seq);
str += QString("<tr><td>Ack num <td>%1\n").arg(p->tcp_ack_seq);
str += QString("<tr><td>Flags <td>\n");
if (p->tcp_ack){
str += QString("ACK\n");
}
if (p->tcp_fin){
str += QString("FIN\n");
}
if (p->tcp_syn){
str += QString("SYN\n");
}
if (p->tcp_rst){
str += QString("RST\n");
}
if (p->tcp_psh){
str += QString("PSH\n");
}
if (p->tcp_urg){
str += QString("URG\n");
}
/*
u_int16_t tcp_urg_ptr;*/
}
else if(p->ip_protocol == IPPROTO_UDP){
str += QString("<tr><td>Port from <td>%1\n").arg(p->udp_source);
str += QString("<tr><td>Port to <td>%1\n").arg(p->udp_dest);
}
else{
str += QString("<tr><td>Type <td>IP #%1\n").arg(p->ip_protocol);
}
}
else if (p->eth_proto == ETH_P_ARP){
/* arp packet */
str += QString("<tr><td>Type <td>ARP\n");
}
else{
str += QString("<tr><td>Type <td>ether #%1\n").arg(p->eth_proto);
}
str += QString("<tr><td>Data (%1 bytes) <td>\n").arg(p->data_len);
size_t i;
for (i=0; i < p->data_len; i++){
if (i % 20 == 0) str += QString("<br>");
sprintf(s_addr, "&#%hhd;",p->data[i]);
str += s_addr;
}
str += QString("<tr><td>HEX data <td>\n");
for (i=0; i < p->data_len; i++){
if (i % 10 == 0) str += QString("<br>");
sprintf(s_addr, "%.2hhX ",p->data[i]);
str += s_addr;
}
str += QString("</table></font>");
return str;
}
Соседние файлы в папке net_sniff