📄 ip.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 <errno.h>#include <time.h>#include <pthread.h>#include <netinet/in.h>#include "log.h"#include "stat.h"#include "in_ntoa.h"#include "lookup.h"#include "ip.h"#include "tcp.h"#include "udp.h"#include "icmp.h"struct gen_stat ip_stat;int ip_handle(struct sniff_pkt *pkt, struct pkt_ip *ip) { void *pointer; unsigned short len; char *ip_source = NULL, *ip_dest = NULL;#ifdef IP_UNSUPPORTED char *extra = NULL;#endif#ifdef IP_CHECKSUM unsigned short oldcheck; /* used to store the ckeck sum when we check it */#endif pkt->func = "ip_handle"; ip_stat.packets++; ip_stat.bytes += pkt->dataleft; /* sanity checks */ if (ip->version != 4) { log_error("Bad IP Version\n"); ip_stat.dropped++; return ERR_MISC; } if (ip->ihl < 5) { log_error("IP header length to short for valid packet\n"); ip_stat.dropped++; return ERR_MISC; } len = ip->ihl * 4; pointer = (void *) ip + len; if (pkt->dataleft < len) { ip_stat.dropped++; return ERR_DATA; }#ifdef IP_CHECKSUM /* do the checksum calcuation */ oldcheck = ip->check; ip->check = 0; ip->check = ip_cksum( (unsigned short *) ip, len); if ( oldcheck != ip->check) { ip_source = lookup(ip->saddr, 0); ip_dest = lookup(ip->daddr, 0); log_error("FAILED IP CHECKSUM: ?%s -> ?%s\n", ip_source, ip_dest, oldcheck, ip->check); ip_stat.dropped++; return ERR_CSUM; }#endif lookup_stats(ip->daddr, pkt->dataleft, ip->saddr, pkt->dataleft); if ( ntohs(ip->frag_off) & (IP_MF|IP_OFFSET) ) { ip_stat.dropped++; return ERR_SUPP; } switch ( ip->protocol ) { case IP_TCP: return tcp_handle(pkt, ip, pointer); break; case IP_UDP: return udp_handle(ip, (void *) pointer); break; case IP_ICMP: return icmp_handle(pkt, ip, (void *) pointer); break; #ifdef IP_UNSUPPORTED case IP_IGMP: extra = "IP Cannot Handle IGMP"; ip_stat.dropped++; goto bad_proto; break; case IP_GRE: extra = "IP Cannot Handle GRE"; ip_stat.dropped++; goto bad_proto; break; case IP_IPIP: extra = "IP Cannot Handle IPIP"; ip_stat.dropped++; goto bad_proto; break; case IP_IPV6: extra = "IP Cannot Handle IPV6"; ip_stat.dropped++; goto bad_proto; break; case IP_EGP: extra = "IP Cannot Handle EGP"; ip_stat.dropped++; goto bad_proto; break; case IP_PUP: extra = "IP Cannot Handle PUP"; ip_stat.dropped++; goto bad_proto; break; case IP_IDP: extra = "IP Cannot Handle IDP"; ip_stat.dropped++; goto bad_proto; break; case IP_RSVP: extra = "IP Cannot Handle RSVP"; ip_stat.dropped++; goto bad_proto; break; case IP_ESP: extra = "IP Cannot Handle ESP"; ip_stat.dropped++; goto bad_proto; break; case IP_AH: extra = "IP Cannot Handle COMP"; ip_stat.dropped++; goto bad_proto; break; #endif default: /* a different protocol */ ip_stat.dropped++; goto bad_proto; break; } log_unreach(); return ERR_MISC;#ifdef IP_UNSUPPORTEDbad_proto: /* jump to here when we have a unknowen/unsupported protocol */ ip_source = lookup(ip->saddr, 0); ip_dest = lookup(ip->daddr, 0); if (extra) log_error("%s %s -> %s IPPROTO: %u\n", extra, ip_source, ip_dest, ip->protocol); else log_error("%s -> %s IPPROTO: %u\n", ip_source, ip_dest, ip->protocol);#endif return ERR_SUPP;} /* end of ip_handle *//* ip header checksum */inline unsigned short ip_cksum(unsigned short *buff, int len) { unsigned long sum = 0; while(len > 1) { sum += *buff++; len -= 2; } if (len == 1) sum += (*buff & 0xff); sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); sum = ~sum; return (sum & 0xffff);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -