📄 arp_48bit.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"#ifdef ARP#ifdef ARP_48BIT#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <pthread.h>#include <fcntl.h>#include <sys/stat.h>#include "sniff.h"#include "list.h"#include "locks.h"#include "gui_main.h"#include "in_ntoa.h"#include "lookup.h"#include "arp.h"#include "arp_48bit.h"#include "stat.h"#include "log.h"unsigned long int inet_addr(const char *cp);pthread_mutex_t arp_48bit_mutex = PTHREAD_MUTEX_INITIALIZER;struct list_t *arp_48bit_ven; /* for a list of vendors to be stored */struct list_t *arp_48bit_data; /* list for 48 bit arp addresses on network */unsigned long long arp_48bit_stats_requests = 0;unsigned long long arp_48bit_stats_replies = 0;unsigned long long arp_48bit_stats_dropped = 0;unsigned long long arp_48bit_stats_errors = 0;int arp_handle_48bit(struct sniff_pkt *pkt, struct arphdr *in, void *data) { struct arp_48bit *packet; /* the contents of the packet */ /* get out data */ pkt->func = "arp_handle_48bit"; if (pkt->dataleft < sizeof(struct arp_48bit)) return ERR_DATA; packet = (struct arp_48bit *) data; pkt->dataleft -= sizeof(struct arp_48bit); switch(ntohs(in->ar_op)) { case ARPOP_REQUEST: /* look for the recivers */ arp_48bit_stats_requests++; return arp_48bit_request(pkt, packet); break; case ARPOP_REPLY: /* we look for the sender this time */ arp_48bit_stats_replies++; return arp_48bit_reply(pkt, packet); break;/* FIXME: need reverse arp done */ case ARPOP_RREQUEST: case ARPOP_RREPLY: default: arp_48bit_stats_dropped++; return ERR_SUPP; } log_unreach(); return ERR_MISC;}inline int arp_48bit_reply(struct sniff_pkt *pkt, struct arp_48bit *packet) { struct arp_48bit_data_t tmp; struct arp_48bit_data_t *record; char ipstr[16]; int index; pkt->func = "arp_48bit_reply"; sprintf(&ipstr[0], "%d.%d.%d.%d", packet->sip[0], packet->sip[1], packet->sip[2], packet->sip[3]); tmp.ip = inet_addr(ipstr); tmp.if_index = pkt->if_index; SLOCK(&arp_48bit_mutex); index = list_search(arp_48bit_data, &tmp); if (index < 0) { /* we do not have a struct lets set 1 up */ record = malloc( sizeof(struct arp_48bit_data_t) ); if (!record) { arp_48bit_stats_errors++; log_errno("malloc");/* unlock */ SUNLOCK(&arp_48bit_mutex); return ERR_OOM; } bzero(record, sizeof(struct arp_48bit_data_t)); record->if_index = pkt->if_index; record->if_name = pkt->if_name; record->ip = tmp.ip; record->str_addr = in_ntoa(record->ip); record->str_name = NULL; record->str_vendor = NULL; /* this gets set futher down */ record->last = time(NULL); record->first = 1; list_add_sort(arp_48bit_data, record); } else { record = list_get(arp_48bit_data, index); } /* modify record as we need to */ if (memcmp(&record->hw[0], &packet->shw[0], ETH_ALEN) != 0) { if (!record->first) { if (arp_log) fprintf(arp_log, "REPLY ADDREES (%.2X:%.2X:%.2X:%.2X:%.2X:%.2X) changed to (%.2X:%.2X:%.2X:%.2X:%.2X:%.2X) on %s for %s\n" ,record->hw[0], record->hw[1], record->hw[2] ,record->hw[3], record->hw[4], record->hw[5] ,packet->shw[0], packet->shw[1], packet->shw[2] ,packet->shw[3], packet->shw[4], packet->shw[5] ,record->if_name, lookup(record->ip, 0)); } else { if (arp_log) fprintf(arp_log, "REPLY NEW (%.2X:%.2X:%.2X:%.2X:%.2X:%.2X) on %s for %s\n" ,packet->shw[0], packet->shw[1], packet->shw[2] ,packet->shw[3], packet->shw[4], packet->shw[5] ,record->if_name, lookup(record->ip, 0)); } memcpy(&record->hw[0], &packet->shw[0], ETH_ALEN); record->first = 0; /* set the vendor name */ arp_48bit_set_vendor(record); } record->last = time(NULL); SUNLOCK(&arp_48bit_mutex); return 0;}inline int arp_48bit_request(struct sniff_pkt *pkt, struct arp_48bit *packet) { struct arp_48bit_data_t tmp; struct arp_48bit_data_t *record; char ipstr[16]; int index; pkt->func = "arp_48bit_request"; sprintf(&ipstr[0], "%d.%d.%d.%d", packet->rip[0], packet->rip[1], packet->rip[2], packet->rip[3]); tmp.ip = inet_addr(ipstr); tmp.if_index = pkt->if_index; SLOCK(&arp_48bit_mutex); index = list_search(arp_48bit_data, &tmp); if (index < 0) { /* we do not have a struct lets set 1 up */ record = malloc( sizeof(struct arp_48bit_data_t) ); if (!record) { arp_48bit_stats_errors++; log_errno("malloc");/* unlock */ SUNLOCK(&arp_48bit_mutex); return ERR_OOM; } bzero(record, sizeof(struct arp_48bit_data_t)); record->if_index = pkt->if_index; record->if_name = pkt->if_name; record->ip = tmp.ip; record->str_addr = in_ntoa(record->ip); record->str_name = NULL; record->str_vendor = NULL; /* this cannot be set because we do not have the info */ record->last = time(NULL); record->first = 1; list_add_sort(arp_48bit_data, record); } else { record = list_get(arp_48bit_data, index); } /* modify record */ record->last = time(NULL); SUNLOCK(&arp_48bit_mutex); return 0;}int arp_48bit_cmp_ip(struct arp_48bit_data_t *c1, struct arp_48bit_data_t *c2) { unsigned long ip1, ip2; ip1 = ntohl(c1->ip); ip2 = ntohl(c2->ip); if (ip1 > ip2) return -1; if (ip1 < ip2) return 1; if (c1->if_index > c2->if_index) return -1; if (c2->if_index < c2->if_index) return 1; return 0;}/*************************************** set the vendor string in the struct* to a the vendor or NULL**************************************/void arp_48bit_set_vendor(struct arp_48bit_data_t *data) { struct arp_48bit_vendor tmp; struct arp_48bit_vendor *res; int index; /* set up the first 3 bytes of the fake struct tmp */ memcpy(&tmp.hw, &data->hw, ETH_ALEN); tmp.hw[3] = 0; tmp.hw[4] = 0; tmp.hw[5] = 0; /* get a value in out list of data */ index = list_search(arp_48bit_ven, &tmp); if (index < 0) { /* we dont have the data */ data->str_vendor = NULL; return; } else { /* we have the data so just make it point to it */ res = list_get(arp_48bit_ven, index); data->str_vendor = res->string; return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -