📄 perroicmp.c
字号:
/* Perroicmp - ICMP logging routines -------------------------------------------------------------------- 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"void usage( void);int main( int argc, char *argv[]){ FILE *fperro; /* Simple log file pointer */ FILE *fpraw; /* Raw log file poinetr */ char buf[ 65535]; /* The buffer we use to read a packet */ char *type; /* ICMP type string */ struct perro_iphdr *iph; /* IP header pointer */ struct perro_icmphdr *ich; /* ICMP header pointer */ struct in_addr addrs; /* Mask to apply for IP addresses to ignore */ struct in_addr mask[ PER_IGN_HOST]; /* Mask to apply for ignored packets */ struct in_addr ignoremask[ PER_IGN_HOST]; struct tm *ltm; /* Used by localtime(3) */ time_t t; /* Used by time(2) */ char *ti; /* Used by ctime(3) */ int ch; /* For command line parsing */ int iphlen; /* IP header length (Used to skip */ /* options) */ int i; progname = perro_basename( strdup( argv[ 0])); if( argc < 2) usage(); perro_init(); /* Parse command line */ while(( ch = getopt( argc, argv, "qlwri:")) != EOF){ switch( ch) { case 'q': flag_quiet = 1; break; case 'l': flag_log = 1; break; case 'w': flag_raw = 1; break; case 'r': flag_dont_resolve = 0; break; case 'i': if( qty_ignore >= PER_IGN_HOST) { fprintf( stderr, "%s: Quantity of ignored host too long: %d\n", progname, qty_ignore); exit( -1); } process_host_and_mask( optarg, &mask[ qty_ignore], &ignoremask[ qty_ignore]); qty_ignore++; break; default : usage(); } } if( !flag_log && !flag_raw) usage(); open_socket( IPPROTO_ICMP); show_version( "perroicmp (ICMP logger)"); gobackground(); init_signals(); if( flag_log) { fperro = fopen( PER_ICMP_LOG, "a+"); t = time( NULL); ti = ctime( &t); /* Write log headings */ fprintf( fperro, "%s\n", perro_hyphen); fprintf( fperro, "Perro ICMP logger - Begins at %-24.24s\n", ti); fprintf( fperro, "%s\n", perro_hyphen); if( qty_ignore != 0) { fprintf( fperro, "Ignore hostname/mask enabled.\n"); for( i = 0; i < qty_ignore; i++) { fprintf( fperro, "%-5d: Mask : %s\n", i, inet_ntoa( mask[ i])); fprintf( fperro, "%-5d: Ignore host mask: %s\n", i, inet_ntoa( ignoremask[ i])); } fprintf( fperro, "%s\n", perro_hyphen); } fprintf( fperro, "- Date - Source IP - Domain Name - ICMP type / code -\n"); fprintf( fperro, "%s\n", perro_hyphen); fclose( fperro); } while( 1) {again: if( read( socket_fd, buf, sizeof( buf)) <= 0) continue; /* Cast the IP header */ iph = ( struct perro_iphdr *) buf; /* Do we ignore some IP addresses? */ if( qty_ignore != 0) { /* * Take the IP source address * 'and' it with the mask * and if it is equal to the ignore mask * ignore the packet */ addrs.s_addr = iph->saddr; for( i = 0; i < qty_ignore; i++) if( (addrs.s_addr & mask[ i].s_addr) == ignoremask[ i].s_addr) goto again; } /* Skip IP options */ iphlen = ( iph->hlv & 0x0F) << 2; iphlen -= 20; /* Cast the ICMP header */ ich = ( struct perro_icmphdr *) &buf[ sizeof( struct perro_iphdr) + iphlen]; t = time( NULL); /* Make a simple human readeable log */ if( flag_log) { fperro = fopen( PER_ICMP_LOG, "a+"); ltm = localtime( &t); fprintf( fperro, "%02d:%02d:%02d %02d/%02d/%02d " , ltm->tm_hour , ltm->tm_min , ltm->tm_sec , ltm->tm_mon + 1 , ltm->tm_mday /* I think this program will be obsolete in 2100 :) */ , ltm->tm_year >= 100 ? ltm->tm_year - 100 : ltm->tm_year); switch( ich->type) { case 1: /* Unassigned ICMP types */ case 2: case 7: type = "Unassigned" ; break; case 0: type = "Echo Reply" ; break; case 3: type = "Dest. Unreachable" ; break; case 4: type = "Source Quench" ; break; case 5: type = "Redirect ch. route" ; break; case 6: type = "Alt. Host Address" ; break; case 8: type = "Echo Request" ; break; case 9: type = "Router Advertisement"; break; case 10: type = "Router Solicitation" ; break; case 11: type = "Time Exceeded" ; break; case 12: type = "Parameter problem" ; break; case 13: type = "Timestamp Request" ; break; case 14: type = "Timestamp Reply" ; break; case 15: type = "Information Request" ; break; case 16: type = "Information Reply" ; break; case 17: type = "Address Mask Request"; break; case 18: type = "Address Mask Reply" ; break; case 30: type = "Traceroute" ; break; case 31: type = "Conversion Failed" ; break; case 32: type = "Mobile Host Redirect"; break; case 33: type = "IPv6 Where-Are-You" ; break; case 34: type = "IPv6 I-Am-Here" ; break; case 35: type = "Mobile Reg. Request" ; break; case 36: type = "Mobile Reg. Reply" ; break; case 37: type = "Domain Name Request" ; break; case 38: type = "Domain Name Reply" ; break; default: type = "Reserved" ; break; } /* end switch( ich->type) */ addrs.s_addr = iph->saddr; fprintf( fperro, "%-15.15s %-17.17s %-20.20s %d/%d\n" , inet_ntoa( addrs), resolve_host_name( iph->saddr) , type, ich->type , ich->code); fclose( fperro); } /* Dump time + raw data */ if( flag_raw) { fpraw = fopen( PER_ICMP_RAW, "a+"); fwrite( &t, sizeof( t), 1, fpraw); fwrite( buf, htons( iph->tot_len), 1, fpraw); fclose( fpraw); } } /* end while( 1) */ close( socket_fd); return 0;}void usage( void){ fprintf( stderr, "\nPerro Release %s - perroicmp (ICMP logger)\n\n" " by Diego J. Grigna (diego@grigna.com)\n\n" "Usage:\n%s [-q] [-lwr] [-i hostname[/mask]]\n" "\t-q\t Quiet mode, don't send output to stdout.\n" "\t-l\t Make a simple human readeable log\n" "\t-w\t Log time + raw data\n" "\t-r\t Resolve domain names\n" "\t-i\t Ignore packets from hostname/mask\n\n" , PER_VERSION, progname); exit( -1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -