?? if.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 <string.h>#include <unistd.h>#include <errno.h>#include <pthread.h>#include <time.h>#include <fcntl.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/socket.h>#include "config.h"#include "locks.h"#include "list.h"#include "arp.h"#include "sniff.h"#include "stat.h"#include "log.h"#include "ip.h"#include "if.h"struct list_t *if_list;pthread_mutex_t if_mutex = PTHREAD_MUTEX_INITIALIZER;/* The new way to read from the socket *//* this should be able to tell that interface the packet came from *//* and then send it to the correct handler */int inline if_handle(struct sniff_pkt *pkt, struct sockaddr_ll *fromaddr, void *data) { struct if_stat cmp; /* used for the searches */ struct if_stat *tmp; /* used for stats */ int i; SLOCK(&if_mutex); /* we need to lock the list */ cmp.if_index = fromaddr->sll_ifindex; i = list_search(if_list, &cmp); if (i < 0) { tmp = if_add(fromaddr); if (!tmp) return -1; /* something bad happened */ } else { tmp = list_get(if_list, i); } SLOCK(&tmp->mutex); /* lock the single record */ SUNLOCK(&if_mutex); /* unlock the whole list */ pkt->if_index = tmp->if_index; pkt->if_name = &tmp->if_name[0]; /* work out which packet type it is */ switch(fromaddr->sll_hatype) { case LINK_ETHERNET: /* ethernet packet */ return if_eth(pkt, tmp, fromaddr, data); break; case LINK_PPP: return if_raw(pkt, tmp, fromaddr, data); break; case ARPHRD_LOOPBACK: return if_lo(pkt, tmp, fromaddr, data); break; case ARPHRD_PPP: return if_raw(pkt, tmp, fromaddr, data); break; default: stat_global.dropped++; tmp->all_stat.dropped++; SUNLOCK(&tmp->mutex); /* nobody else got it !! */ log_error("if_handle: Packet Type %d Not Known\n", fromaddr->sll_hatype); break; } /* end of hardware types */ return -2;}struct if_stat *if_add(struct sockaddr_ll *fromaddr) { struct ifreq ifr; struct if_stat *tmp; int i, total; total = list_length(if_list); for(i=0;i<total;i++) { tmp = list_get(if_list, i); SLOCK(&tmp->mutex); bzero(&ifr, sizeof(ifr)); ifr.ifr_ifru.ifru_ivalue = fromaddr->sll_ifindex; if (ioctl(sockfd, SIOCGIFNAME, &ifr) < 0) { log_errno("ioctl"); } else { /* do a string compare for if name */ if (strcmp(&ifr.ifr_ifrn.ifrn_name[0], &tmp->if_name[0]) == 0) { tmp->if_index = fromaddr->sll_ifindex; /* FIXME we need to call stuff to change if_index on other data eg ARP */ SUNLOCK(&tmp->mutex); return tmp; } } SUNLOCK(&tmp->mutex); } /* if we get down here create a new record */ tmp = malloc( sizeof(struct if_stat)); if (!tmp) { log_errno("malloc"); return NULL; } init_stat(&tmp->all_stat, "ALL"); init_stat(&tmp->in_stat, "IN"); init_stat(&tmp->out_stat, "OUT"); init_stat(&tmp->other_stat, "OTHER"); tmp->if_index = fromaddr->sll_ifindex; pthread_mutex_init(&tmp->mutex, NULL); bzero(&ifr, sizeof(ifr)); ifr.ifr_ifru.ifru_ivalue = fromaddr->sll_ifindex; if (ioctl(sockfd, SIOCGIFNAME, &ifr) < 0) { log_errno("ioctl"); sprintf(&tmp->if_name[0], "IF%d\n", fromaddr->sll_ifindex); } strcpy(&tmp->if_name[0], &ifr.ifr_ifrn.ifrn_name[0]); list_add_sort(if_list, tmp); return tmp;}int if_cmp_index(struct if_stat *c1, struct if_stat *c2) { if (c1->if_index > c2->if_index) return -1; if (c1->if_index < c2->if_index) return 1; if (c1->if_index == c2->if_index) return 0; return 0;}int if_init() { SLOCK(&if_mutex); if_list = list_init(); list_setcmp(if_list, (void *) if_cmp_index); SUNLOCK(&if_mutex); return 0;}/* Functions for different interfaces */int inline if_eth(struct sniff_pkt *pkt, struct if_stat *interface, struct sockaddr_ll *fromaddr, char *data) { struct ethhdr *eth_packet; /* ethernet packet */ char *pointer = data; if (pkt->dataleft < sizeof(struct ethhdr)) return -10; /* move forward */ eth_packet = (struct ethhdr *) data; pointer += sizeof(struct ethhdr); pkt->dataleft -= sizeof(struct ethhdr); interface->all_stat.packets++; interface->all_stat.bytes += pkt->readlen; /* time to find out what ethernet packet it is */ switch(fromaddr->sll_pkttype) { case PACKET_HOST: interface->in_stat.packets++; interface->in_stat.bytes += pkt->readlen; break; case PACKET_OUTGOING: interface->out_stat.packets++; interface->out_stat.bytes += pkt->readlen; break; default: interface->other_stat.packets++; interface->other_stat.bytes += pkt->readlen; break; } SUNLOCK(&interface->mutex); /* it arrives locked */ switch( ntohs(eth_packet->h_proto)) { case ETH_P_ARP: /* arp packets */ return arp_handle(pkt, pointer); break; case ETH_P_IP: /* ip - tcp/udp/icmp */ return ip_handle(pkt, (void *) pointer); break; default: stat_global.dropped++; log_error("sniff_eth Unsupported Packet Type: %x\n", ntohs(eth_packet->h_proto)); break; } /* end switch ethetnet packet type */ return -2;} int inline if_lo(struct sniff_pkt *pkt, struct if_stat *interface, struct sockaddr_ll *fromaddr, char *data) { struct ethhdr *eth_packet; /* ethernet packet */ char *pointer = data; if (pkt->dataleft < sizeof(struct ethhdr)) return -10; eth_packet = (struct ethhdr *) data; pointer += sizeof(struct ethhdr); pkt->dataleft -= sizeof(struct ethhdr); /* NOTE on a loop back interface we will see all data twice we dont want this so jump out ASAP */ switch(fromaddr->sll_pkttype) { case PACKET_HOST: interface->all_stat.packets++; interface->all_stat.bytes += pkt->readlen; break; default: /* on the local if we get both in / out which are the same packet */ SUNLOCK(&interface->mutex); return 0; break; } SUNLOCK(&interface->mutex); /* time to find out what ethernet packet it is */ switch( ntohs(eth_packet->h_proto)) { case ETH_P_ARP: /* arp packets */ return arp_handle(pkt, pointer); break; case ETH_P_IP: /* ip - tcp/udp/icmp */ return ip_handle(pkt, (void *) pointer); break; default: stat_global.dropped++; log_error("sniff_eth Unsupported Packet Type: %x\n", ntohs(eth_packet->h_proto)); break; } /* end switch ethetnet packet type */ return -2;} int inline if_raw(struct sniff_pkt *pkt, struct if_stat *interface, struct sockaddr_ll *fromaddr, char *data) { switch(fromaddr->sll_pkttype) { case PACKET_HOST: interface->in_stat.packets++; interface->in_stat.bytes += pkt->readlen; break; case PACKET_OUTGOING: interface->out_stat.packets++; interface->out_stat.bytes += pkt->readlen; break; default: interface->other_stat.packets++; interface->other_stat.bytes += pkt->readlen; break; } interface->all_stat.packets++; interface->all_stat.bytes += pkt->readlen; SUNLOCK(&interface->mutex); switch(ntohs(fromaddr->sll_protocol)) { case ETH_P_IP: return ip_handle(pkt, (void *) data); break; default: log_error("sniff_raw Unsupported Packet: %x\n", ntohs(fromaddr->sll_protocol)); return -2; break; } /* end of different protocls */ return -3;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -