📄 ipretperro.c
字号:
/* Ipretperro - Perro RAW packet format interpreter -------------------------------------------------------------------- Perro - The Internet Protocols logger Copyright (C) 1998, 1999, 2000 Diego Javier Grigna <diego@grigna.com> 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include "common.h"/* Global variables */static int flag_verbose; /* Verbose mode, explain all. */static int flag_printiph; /* Interpret ICMP data as an IP header + 64 bits of data. Used when ICMP Destination unreachable, ICMP time exceeded, etc, packets are found. */ /* Function prototypes */void mainloop( FILE *fp);void print_header_ip( struct perro_iphdr iph);void print_header_ipoptions( char *buf, int size);void print_ipoptions_route( char *buf, unsigned char opt_len, unsigned char routing_ptr);void print_header_tcp( struct perro_tcphdr tcph);void print_header_tcp_options( char *buf, int tcpol);void print_header_udp( struct perro_udphdr udph);void print_header_icmp( struct perro_icmphdr ich);void print_data( char *buf, char *pkttype, int size);void print_ala_hexdump( char *buf, int size);void print_hex( char *buf, int size);void print_ascii( char *buf, int size);void print_ipret_icmp_printiph_again( char *buf);int main( int argc, char *argv[]){ FILE *fp; struct stat stbuf; int ch; perro_init(); flag_verbose = 0; flag_printiph = 0; if( argc < 2) { mainloop( stdin); return 0; } while(( ch = getopt( argc, argv, "rv")) != EOF){ switch( ch) { case 'r': flag_dont_resolve = 0; break; case 'v': flag_verbose = 1; break; } } if( optind >= argc) fp = stdin; else { fp = fopen( argv[ optind], "r"); if( fp == NULL) { fprintf( stderr, "%s: %s : %s\n", argv[ 0], argv[ optind], strerror( errno)); return -1; } fstat( fileno( fp), &stbuf); if( ( stbuf.st_mode & S_IFMT) == S_IFDIR){ fprintf( stderr, "\"%s\" is a directory\n", argv[ optind]); return -1; } if( ( stbuf.st_mode & S_IFMT) != S_IFREG){ fprintf( stderr, "\"%s\" is not a regular file\n", argv[ optind]); return -1; } } mainloop( fp); return 0;}void mainloop( FILE *fp){ struct perro_iphdr iph; /* IP header */ struct perro_tcphdr tcph; /* TCP header */ struct perro_udphdr udph; /* UDP header */ struct perro_icmphdr ich; /* ICMP header */ char buf[ 65535]; /* Buffer to read packets */ time_t t; /* Time when the packet was logged */ int iphlen; /* IP header length */ int hsize; /* Header size (TCP, UDP or ICMP */ int totlen; /* Total length size */ int datas; /* Data size */ int packet; /* Number of packets */ int tcphl; /* TCP header length */ int tcpol; /* TCP options length */ char *pkttype; iphlen = hsize = totlen = datas = packet = 0; while( !feof( fp)) { flag_printiph = 0; if( fread( &t, sizeof( t), 1, fp) <= 0) break; packet++; printf( "%-22.22s Begin of packet number: %10d %-22.22s\n" , perro_hyphen , packet , perro_hyphen); printf( "%-20.20s arrival date: %-24.24s %-20.20s\n" , perro_hyphen , ctime( &t) , perro_hyphen); if( fread( &iph, sizeof( iph), 1, fp) <= 0) break; print_header_ip( iph); /* Get IP options size */ iphlen = ( iph.hlv & 0x0F) << 2; iphlen -= 20; if( iphlen > 0) { if( fread( buf, iphlen, 1, fp) <= 0) break; print_header_ipoptions( buf, iphlen); } if( iph.protocol == IPPROTO_TCP) { if( fread( &tcph, sizeof( tcph), 1, fp) <= 0) break; hsize = sizeof( tcph); pkttype = "TCP"; print_header_tcp( tcph); tcphl = ( tcph.th_do & 0xF0) >> 4; tcphl *= 4; if( tcphl > sizeof( tcph)) { tcpol = tcphl - sizeof( tcph); hsize += tcpol; if( fread( &buf, tcpol, 1, fp) <= 0) break; print_header_tcp_options( buf, tcpol); } } else if( iph.protocol == IPPROTO_UDP) { if( fread( &udph, sizeof( udph), 1, fp) <= 0) break; hsize = sizeof( udph); pkttype = "UDP"; print_header_udp( udph); } else if( iph.protocol == IPPROTO_ICMP) { if( fread( &ich, sizeof( ich), 1, fp) <= 0) break; hsize = sizeof( ich); pkttype = "ICMP"; print_header_icmp( ich); } else { printf( "Protocol not supported by Perro.\n"); continue; } totlen = sizeof( iph) + hsize + iphlen; if( totlen < htons( iph.tot_len )) { datas = htons( iph.tot_len) - totlen; if( fread( buf, datas, 1, fp) <= 0) break; print_data( buf, pkttype, datas); } printf( "%-22.22s End of packet number: %10d %-22.22s\n\n" , perro_hyphen , packet , perro_hyphen); }}void print_header_ip( struct perro_iphdr iph){ struct protoent *proto; struct in_addr addrs; int ip_version; int ip_hl; int tos_precedence; int flags; int tos; /* Type of service bits */ flags = 0; ip_hl = ( iph.hlv & 0x0F) << 2; ip_version = ( iph.hlv & 0xF0) >> 4; printf( "******* IP Header *******\n"); printf( "IP Version : %-5d (IPv%d)\n", ip_version, ip_version); printf( "Header Length : %-5d (%d)\n" , ip_hl , ip_hl ); printf( "Type Of Service : %-5d (0x%x)\n" , iph.tos , iph.tos ); /* Show even more details */ if( flag_verbose) { /* * Explain Type of Service * RFC 791 & RFC 1349 */ printf( "%-30.30sBits 0-2: Precedence\n", " "); printf( "%-40.40s", " "); tos_precedence = ( iph.tos & 0xe0) >> 5; switch( tos_precedence) { case 0: printf( "Routine" ); break; /* 000 */ case 1: printf( "Priority" ); break; /* 001 */ case 2: printf( "Immediate" ); break; /* 010 */ case 3: printf( "Flash" ); break; /* 011 */ case 4: printf( "Flash Override" ); break; /* 100 */ case 5: printf( "CRITIC/ECP" ); break; /* 101 */ case 6: printf( "Internetwork Control"); break; /* 110 */ case 7: printf( "Network Control" ); break; /* 111*/ } printf( " (0x%x)\n", tos_precedence); tos = ( iph.tos & 0x1E) >> 1; printf( "%-30.30sBits 3-6: ", " "); switch( tos) { case 15: /* 1111 */ printf( "Maximize security" ); break; case 8: /* 1000 */ printf( "Minimize delay" ); break; case 4: /* 0100 */ printf( "Maximize throughput" ); break; case 2: /* 0010 */ printf( "Maximize reliability" ); break; case 1: /* 0001 */ printf( "Minimize monetary cost"); break; case 0: /* 0000 */ printf( "Normal service" ); break; } printf( " (%d)\n", tos); printf( "%-30.30sBit 7: MBZ (Must Be Zero) (0x%x)\n", " ", iph.tos & 0x01); } printf( "Total lenght of packet : %-5d (0x%x) bytes\n", htons( iph.tot_len), htons( iph.tot_len)); printf( "Identification : %-5d (0x%x)\n" , htons( iph.id) , htons( iph.id) ); flags = ( iph.frag_off & 0xe000) >> 13; printf( "3 bit flags : %-5d (0x%x)\n" , flags , flags ); if( flag_verbose) { printf( "%-30.30sBit 0: Reserved (%d)\n", " ", flags & 4); printf( "%-30.30sBit 1: %s (%d)\n" , " ", flags & 5 ? "Don't Fragment" : "May Fragment ", flags & 5); printf( "%-30.30sBit 2: %s (%d)\n" , " ", flags & 6 ? "More Fragments" : "Last Fragment", flags & 6); } flags = iph.frag_off & 0x1fff; printf( "13 bit Fragmentation offset : %-5d (0x%x)\n" , flags , flags ); printf( "Time To Live : %-5d (0x%x)\n" , iph.ttl , iph.ttl ); proto = NULL; proto = getprotobynumber( iph.protocol); if( proto == NULL) printf( "Protocol : Protocol unknown! %-5d (0x%x)\n", iph.protocol, iph.protocol); else printf( "Protocol : %s (0x%x)\n", proto->p_name, iph.protocol); printf( "CheckSum : %-5d (0x%x)\n" , htons( iph.check), htons( iph.check)); addrs.s_addr = iph.saddr; printf( "IP Source address (From) : %s (%s)\n", inet_ntoa( addrs), resolve_host_name( iph.saddr)); addrs.s_addr = iph.daddr; printf( "IP Destination address : %s (%s)\n", inet_ntoa( addrs), resolve_host_name( iph.daddr));}void print_header_ipoptions( char *buf, int size){ printf( "IP Options :\n"); /* * See RFC 791 ( Internet protocol specification) * Also see RFC 1700 ( Assigned numbers) and search for "IP OPTIONS" */ if( flag_verbose) { unsigned char opt_type; unsigned char opt_len; unsigned char routing_ptr; int opt_copied; int opt_class; int opt_number; unsigned short stream_id; int timestamp_overflow; int timestamp_flag; unsigned short router_alert; struct in_addr ts_ipaddr; unsigned long ts_date; unsigned short tmp; int i, k; opt_type = ( unsigned char) buf[ 0]; opt_len = ( unsigned char) buf[ 1]; opt_copied = opt_type >> 7; /* Bit 0 */ opt_class = ( opt_type & 0x60) >> 5; /* Bits 1-2 */ opt_number = opt_type & 0x1F; /* Bits 3-7 */ routing_ptr = ( unsigned char) buf[ 2]; printf( "%-30.30sOption-type octet : %-5d (0x%x)\n", " ", opt_type, opt_type); printf( "%-30.30sBit 0: Copied flag : %s\n", " ", opt_copied ? "Not copied (1)" : "Copied (0)"); printf( "%-30.30sBits 1-2: Option class : ", " "); switch( opt_class) { case 0: printf( "Control" ); break; case 1: /* The same that 3 */ case 3: printf( "Reserved for future use" ); break; case 2: printf( "Debugging and measurement"); break; } printf( "\n%-55.55s(0x%x)\n", " ", opt_class); printf( "%-30.30sBits 3-7: Option number: %-5d (0x%x)\n", " ", opt_number, opt_number); printf( "%-30.30sClass | Number | length | Description\n", " "); printf( "%-30.30s------+--------+--------+-------------\n", " "); switch( opt_type) { /* See RFC 791 */ /* End of Option */ case 0: /* opt_copied == 0 && opt_class == 0 && opt_number == 0 */ printf( "%-30.30s %4d | %6d | - | End of Option list.\n", " ", opt_class, opt_number); break; /* No operation IP option */ case 1: /* opt_copied == 0 && opt_class == 0 && opt_number == 1 */ printf( "%-30.30s %4d | %6d | - | No Operation.\n" , " ", opt_class, opt_number); break; /* Security option DoD Basic Security See RFC 791 (IP) and RFC 1108 (DoD Security IP option...) I think that it is historic, obsolete, delete, deprecated, or something like this, so I won't make much detail here.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -