/* * Name: kerninetstat * Date: Sun Feb 13 13:16:33 2000 * Author: pIGpEN [pigpen@s0ftpj.org, deadhead@sikurezza.org] * * SoftProject Digital Security for Y2K (www.s0ftpj.org) * Sikurezza.org Italian Security MailingList (www.sikurezza.org) * * COFFEE-WARE LICENSE - This source code is like "THE BEER-WARE LICENSE" by * Poul-Henning Kamp but you can give me in return a coffee. * * Tested on: FreeBSD 4.0-19990705-CURRENT FreeBSD 4.0-19990705-CURRENT #6 i386 * * This simple source code uses sysctlbyname() to fetch statistics of a protocol * you can use them for security purposes or for kernel testing... see also * sources of systat or netstat -s... * * Note: some variables of stat structures can be not present in other kernel * versions */ /* * knstat is intended to be used as cron job example: * * knstat -icmp >> icmp_stat.log * * if you wanna use this tool like a command define WAIT * * #define WAIT * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define Error(s) err(EX_UNAVAILABLE, s); #define E(s) if(!strcmp(s, arg[1])) void usage __P((char *)); void ip_stat __P((void)); void udp_stat __P((void)); void tcp_stat __P((void)); void icmp_stat __P((void)); void igmp_stat __P((void)); struct prot { char *name; void (*funct) (void); }; struct prot protos[] = { { "-ip" , ip_stat }, { "-udp" , udp_stat }, { "-tcp" , tcp_stat }, { "-icmp", icmp_stat }, { "-igmp", igmp_stat }, }; int main(int narg, char **arg) { int i; int len = sizeof(protos) / sizeof(struct prot); if(narg != 2){ usage(arg[0]); exit(0); } /* Think different */ for(i=0; i < len; i++) E(protos[i].name) { (*protos[i].funct) (); return 1; } usage(arg[0]); return 0; } void usage(char *cmdname) { printf("Usage:\n" "\t%s -option\n\n" "Option: -ip\n" " -icmp\n" " -igmp\n" " -tcp\n" " -udp\n", cmdname); } /* * You can cover printf() with a macro... but I'm fucking about... so * I have time to spend... */ void ip_stat(void) { struct ipstat i_stat; int len = sizeof(i_stat); if(sysctlbyname("net.inet.ip.stats", &i_stat, &len, 0, 0) < 0 ) Error("[ip_stat] sysctlbyname"); printf("IP Statistics\n\n"); printf("\t\treceived [ %ld ]\n", i_stat.ips_total); printf("\t\tbad checksum [ %ld ]\n", i_stat.ips_badsum); printf("\t\tpkts too short [ %ld ]\n", i_stat.ips_tooshort); printf("\t\tno enough data [ %ld ]\n", i_stat.ips_toosmall); printf("\t\tiph len < data [ %ld ]\n", i_stat.ips_badhlen); printf("\t\tip len < iph len [ %ld ]\n", i_stat.ips_badlen); printf("\t\tfragments [ %ld ]\n", i_stat.ips_fragments); printf("\t\tfrags dropped [ %ld ]\n", i_stat.ips_fragdropped); printf("\t\tfrags timeout [ %ld ]\n", i_stat.ips_fragtimeout); printf("\t\tforwarded [ %ld ]\n", i_stat.ips_forward); printf("\t\tfast forward [ %ld ]\n", i_stat.ips_fastforward); printf("\t\tcant forward [ %ld ]\n", i_stat.ips_cantforward); printf("\t\tredirect sent [ %ld ]\n", i_stat.ips_redirectsent); printf("\t\tproto unknown [ %ld ]\n", i_stat.ips_noproto); printf("\t\tiplen > maxpksz [ %ld ]\n", i_stat.ips_toolong); printf("\t\tip version != 4 [ %ld ]\n", i_stat.ips_badvers); printf("\t\ttotal raw gen [ %ld ]\n", i_stat.ips_rawout); printf("\t\tmcast not memb [ %ld ]\n", i_stat.ips_notmember); } void udp_stat(void) { struct udpstat u_stat; int len = sizeof(u_stat); if(sysctlbyname("net.inet.udp.stats", &u_stat, &len, 0, 0) < 0) Error("[udp_stat] sysctlbyname"); printf("UDP Statistics\n\n"); printf("Total input packets: %ld\n", u_stat.udps_ipackets); printf("\t\t\t\tPacket shorter than header: %ld\n", u_stat.udps_hdrops); printf("\t\t\t\tChecksum error: %ld\n", u_stat.udps_badsum); printf("\t\t\t\tData len larger than pkt: %ld\n", u_stat.udps_badlen); printf("\t\t\t\tNo socket on port: %ld\n", u_stat.udps_noport); printf("\t\t\t\tArrived as broadcast: %ld\n", u_stat.udps_noportbcast); printf("\t\t\t\tNot delivered: %ld\n", u_stat.udps_fullsock); printf("\t\t\t\tMissing pcb cache: %ld\n", u_stat.udpps_pcbcachemiss); printf("\t\t\t\tNot for hashed pcb: %ld\n\n",u_stat.udpps_pcbhashmiss); printf("Total ouput packets: %ld\n", u_stat.udps_opackets); printf("\t\t\t\tFast path: %ld\n", u_stat.udps_fastout); } void tcp_stat(void) { struct tcpstat t_stat; int len = sizeof(t_stat); if(sysctlbyname("net.inet.tcp.stats", &t_stat, &len, 0, 0) < 0) Error("[tcp_stat] sysctlbyname"); printf("TCP Statistics\n\n"); printf("Connection:\n"); printf("\t\tinitiated: [ %ld ]\n", t_stat.tcps_connattempt); printf("\t\taccepted: [ %ld ]\n", t_stat.tcps_accepts); printf("\t\testabilished [ %ld ]\n", t_stat.tcps_connects); printf("\t\tdropped [ %ld ]\n", t_stat.tcps_drops); printf("\t\tembryonic dropped [ %ld ]\n", t_stat.tcps_conndrops); printf("\t\tkeepalive dropped [ %ld ]\n", t_stat.tcps_keepdrops); printf("\t\tclosed [ %ld ]\n", t_stat.tcps_closed); printf("\nTimers:\n"); printf("\t\tsegs timed [ %ld ]\n", t_stat.tcps_segstimed); printf("\t\trtt updated [ %ld ]\n", t_stat.tcps_rttupdated); printf("\t\tdelayed acks sent [ %ld ]\n", t_stat.tcps_delack); printf("\t\tdropped in rxmt timeouts [ %ld ]\n", t_stat.tcps_timeoutdrop); printf("\t\tretrasmit timeouts [ %ld ]\n", t_stat.tcps_rexmttimeo); printf("\t\tpersist timeouts [ %ld ]\n", t_stat.tcps_persisttimeo); printf("\t\tkeepalive timeouts [ %ld ]\n", t_stat.tcps_keeptimeo); printf("\t\tkeepalive probes sent [ %ld ]\n", t_stat.tcps_keepprobe); #ifdef WAIT getchar(); #endif printf("\nPackets\n"); printf("\t\tsent [ %ld ]\n", t_stat.tcps_sndtotal); printf("\t\tdata pkt [ %ld ]\n", t_stat.tcps_sndpack); printf("\t\tdata bytes [ %ld ]\n", t_stat.tcps_sndbyte); printf("\t\tdata pkt retrasmitted [ %ld ]\n", t_stat.tcps_sndrexmitpack); printf("\t\tdata bytes retrasmitted [ %ld ]\n", t_stat.tcps_sndrexmitbyte); printf("\t\tack only pkts [ %ld ]\n", t_stat.tcps_sndacks); printf("\t\turg only pkts [ %ld ]\n", t_stat.tcps_sndurg); printf("\t\twin update only pkt [ %ld ]\n", t_stat.tcps_sndwinup); printf("\t\tsyn|fin|rst pkt [ %ld ]\n", t_stat.tcps_sndctrl); printf("\t\twindow probes [ %ld ]\n", t_stat.tcps_sndprobe); printf("\n\n"); #ifdef WAIT getchar(); #endif printf("\t\treceived [ %ld ]\n", t_stat.tcps_rcvtotal); printf("\t\tpkt in sequence [ %ld ]\n", t_stat.tcps_rcvpack); printf("\t\tbyte in sequence [ %ld ]\n", t_stat.tcps_rcvbyte); printf("\t\tpkt with checksum errors [ %ld ]\n", t_stat.tcps_rcvbadsum); printf("\t\tpkt with bad offset [ %ld ]\n", t_stat.tcps_rcvbadoff); printf("\t\tpkt received too short [ %ld ]\n", t_stat.tcps_rcvshort); printf("\t\tduplicate only pkts [ %ld ]\n", t_stat.tcps_rcvduppack); printf("\t\tduplicate only bytes [ %ld ]\n", t_stat.tcps_rcvdupbyte); printf("\t\tpartial duplicate data [ %ld ]\n", t_stat.tcps_rcvpartduppack); printf("\t\tpartial duplicate bytes [ %ld ]\n", t_stat.tcps_rcvpartdupbyte); printf("\t\tout of order pkts [ %ld ]\n", t_stat.tcps_rcvoopack); printf("\t\tout of order bytes [ %ld ]\n", t_stat.tcps_rcvoobyte); printf("\t\tpkts with data after win [ %ld ]\n", t_stat.tcps_rcvpackafterwin); printf("\t\tbytes received after win [ %ld ]\n", t_stat.tcps_rcvbyteafterwin); printf("\t\tpkts rcvd after close [ %ld ]\n", t_stat.tcps_rcvafterclose); printf("\t\tpkts rcvd win probe [ %ld ]\n", t_stat.tcps_rcvwinprobe); printf("\t\tduplicate acks [ %ld ]\n", t_stat.tcps_rcvdupack); printf("\t\tacks for unsent data [ %ld ]\n", t_stat.tcps_rcvacktoomuch); printf("\t\tacks packets [ %ld ]\n", t_stat.tcps_rcvackpack); printf("\t\tbytes acked by rcvd acks [ %ld ]\n", t_stat.tcps_rcvwinupd); printf("\t\tseg dropped due to PAWS [ %ld ]\n", t_stat.tcps_pawsdrop); printf("\t\tbogus syn [ %ld ]\n", t_stat.tcps_badsyn); printf("\t\tresnd due to MTU discov. [ %ld ]\n", t_stat.tcps_mturesent); printf("\t\tlisten queue overflow [ %ld ]\n", t_stat.tcps_listendrop); } void icmp_stat(void) { struct icmpstat i_stat; int len = sizeof i_stat; if(sysctlbyname("net.inet.icmp.stats", &i_stat, &len, 0, 0) < 0) Error("[icmp_stat] sysctlbyname"); printf("ICMP Statistics\n\n"); printf("\t\tNumber of calls to icmp_error [ %ld ]\n", i_stat.icps_error); printf("\t\ticmp_code out of range [ %ld ]\n", i_stat.icps_badcode); printf("\t\tpkts < ICMP_MINLEN [ %ld ]\n", i_stat.icps_tooshort); printf("\t\tbad checksum [ %ld ]\n", i_stat.icps_checksum); printf("\t\tbad length [ %ld ]\n", i_stat.icps_badlen); printf("\t\tnumber of responses [ %ld ]\n", i_stat.icps_reflect); printf("\t\tm/bcast echo requests dropped [ %ld ]\n", i_stat.icps_bmcastecho); } void igmp_stat(void) { struct igmpstat i_stat; int len = sizeof i_stat; if(sysctlbyname("net.inet.igmp.stats", &i_stat, &len, 0, 0) < 0) Error("[igmp_stat] sysctlbyname"); printf("IGMP Statistics\n\n"); printf("\t\tmessages received [ %d ]\n", i_stat.igps_rcv_total); printf("\t\trcvd with too few bytes [ %d ]\n", i_stat.igps_rcv_tooshort); printf("\t\trcvd with bad checksum [ %d ]\n", i_stat.igps_rcv_badsum); printf("\t\trcvd membership queries [ %d ]\n", i_stat.igps_rcv_queries); printf("\t\trcvd invalid queries [ %d ]\n", i_stat.igps_rcv_badqueries); printf("\t\trcvd membership reports [ %d ]\n", i_stat.igps_rcv_reports); printf("\t\trcvd invalid reports [ %d ]\n", i_stat.igps_rcv_badreports); printf("\t\trcvd rep. for our grps [ %d ]\n", i_stat.igps_rcv_ourreports); printf("\t\tsent membership reports [ %d ]\n", i_stat.igps_snd_reports); }