X-Git-Url: http://sjero.net/git/?p=dccpping;a=blobdiff_plain;f=dccpping.c;h=b71a7e3bb08998aaa0b0be4e00d482e1ae4011a4;hp=dd3fdf9855921f01471bbfc8e211c3a3ab2a5f26;hb=HEAD;hpb=55b10e3267f54298b22f0aa37fbc713e34459c94 diff --git a/dccpping.c b/dccpping.c index dd3fdf9..b71a7e3 100644 --- a/dccpping.c +++ b/dccpping.c @@ -45,16 +45,19 @@ Date: 11/2012 #include "checksums.h" -/*Use the DCCP source port to multiplex DCCP Ping streams by PID*/ -#define DCCP_SERVICE_CODE 0x50455246 +#define DEFAULT_SERVICE_CODE 1885957735 #define DEFAULT_PORT 33434 -#define DCCPPING_VERSION 1.0 + +#define DCCPPING_VERSION 1.1 #define MAX(x,y) (x>y ? x : y) extern int errno; #ifndef NI_IDN #define NI_IDN 32 #endif +#ifndef SOL_DCCP +#define SOL_DCCP 269 +#endif /*Structure for simpler IPv4/IPv6 Address handling*/ @@ -173,10 +176,12 @@ struct request_queue{ struct stats{ int requests_sent; int replies_received; + int duplicates; int errors; - double rtt_min; - double rtt_avg; - double rtt_max; + long long rtt_min; + long long rtt_sum; + long long rtt_sum2; + long rtt_max; struct timeval start; struct timeval stop; }; @@ -193,6 +198,7 @@ struct params{ ipaddr_ptr_t src_addr; /*Source Address*/ int dccp_socket; /*DCCP Socket used to grab src addr/port*/ char* hostname; /*Originally requested hostname*/ + unsigned int service_code;/*DCCP Service Code*/ }; @@ -217,12 +223,13 @@ int logResponse(ipaddr_ptr_t *src, int seq, int type, int v1, int v2); const char *get_error_string(int type, int v1, int v2); void clearQueue(); void sigHandler(); +void printStats(); char* addr2str(ipaddr_ptr_t *res, int nores); void usage(); void version(); void sanitize_environment(); void dbgprintf(int level, const char *fmt, ...); - +static long llsqrt(long long a); /*Parse commandline options*/ int main(int argc, char *argv[]) @@ -230,13 +237,16 @@ int main(int argc, char *argv[]) char c; char *src=NULL; char *dst=NULL; + char *tmp; /*Set Defaults*/ queue.head=NULL; queue.tail=NULL; ping_stats.replies_received=0; ping_stats.requests_sent=0; - ping_stats.rtt_avg=0; + ping_stats.rtt_sum=0; + ping_stats.rtt_sum2=0; + ping_stats.duplicates=0; ping_stats.rtt_max=0; ping_stats.rtt_min=0; ping_stats.errors=0; @@ -250,10 +260,11 @@ int main(int argc, char *argv[]) parms.dccp_socket=-1; parms.no_resolve=0; parms.hostname=NULL; + parms.service_code=DEFAULT_SERVICE_CODE; sanitize_environment(); - while ((c = getopt(argc, argv, "64vhnc:p:i:dt:S:")) != -1) { + while ((c = getopt(argc, argv, "64vVhnc:p:i:t:S:s:")) != -1) { switch (c) { case '6': parms.ip_type=AF_INET6; @@ -288,6 +299,18 @@ int main(int argc, char *argv[]) parms.ttl = atoi(optarg); if (parms.ttl < 1 || parms.ttl > 255) { dbgprintf(0,"Error: Invalid TTL\n"); + exit(1); + } + break; + case 's': + parms.service_code=strtol(optarg,&tmp,0); + if(*tmp!='\0'){ + dbgprintf(0,"Error: Invalid Service Code\n"); + exit(1); + } + if(parms.service_code<=0){ + dbgprintf(0, "Error: Service Code MUST be positive"); + exit(1); } break; case 'S': @@ -340,6 +363,7 @@ void getAddresses(char *src, char* dst){ struct sockaddr_in* iv42; int addrlen; int err; + int opt; /*Lookup destination Address*/ memset(&hint,0,sizeof(struct addrinfo)); @@ -452,6 +476,11 @@ void getAddresses(char *src, char* dst){ exit(1); } } + opt=htonl(parms.service_code); + if(setsockopt(parms.dccp_socket,SOL_DCCP, DCCP_SOCKOPT_SERVICE,&opt,sizeof(opt))<0){ + dbgprintf(0, "Error: Failed setsockopt() on DCCP socket (%s)\n",strerror(errno)); + exit(1); + } /*Connect socket to get source address/port*/ if(parms.ip_type==AF_INET){ @@ -590,6 +619,8 @@ void doping(){ updateRequestPacket(sbuffer,&slen, packet_seq); } + printStats(); + close(rs); close(is4); close(is6); @@ -967,7 +998,7 @@ void buildRequestPacket(unsigned char* buffer, int *len, int seq){ dhdr->dccph_seq2=htonl(0); //Reserved if using 48 bit sequence numbers dhdr->dccph_seq=htonl(0); //High 16bits of sequence number. Always make 0 for simplicity. dhdre->dccph_seq_low=htonl(seq); - dhdrr->dccph_req_service=htonl(DCCP_SERVICE_CODE); + dhdrr->dccph_req_service=htonl(parms.service_code); /*Checksums*/ if(parms.ip_type==AF_INET){ @@ -1060,7 +1091,7 @@ int logPacket(int req_seq, int packet_seq){ int logResponse(ipaddr_ptr_t *src, int seq, int type, int v1, int v2){ struct request *cur; - double diff; + long long diff; if(queue.tail==NULL){ dbgprintf(2,"Response received but no requests sent!\n"); @@ -1072,9 +1103,6 @@ int logResponse(ipaddr_ptr_t *src, int seq, int type, int v1, int v2){ while(cur!=NULL){ if(cur->packet_seq==seq){ gettimeofday(&cur->reply,NULL); - if(cur->num_replies>0){ - printf("Duplicate packet detected! (%i)\n",cur->request_seq); - } if((type==DCCP_RESET && v1==3) || type==DCCP_RESPONSE || type==DCCP_SYNC){ cur->num_replies++; }else{ @@ -1099,15 +1127,14 @@ int logResponse(ipaddr_ptr_t *src, int seq, int type, int v1, int v2){ } diff=(cur->reply.tv_usec + 1000000*cur->reply.tv_sec) - (cur->sent.tv_usec + 1000000*cur->sent.tv_sec); - diff=diff/1000.0; /*Print Message*/ if((type==DCCP_RESET && v1==3) || type==DCCP_RESPONSE || type==DCCP_SYNC){ if(debug==0){ - printf( "Response from %s : seq=%i time=%.1fms\n",addr2str(src,0),cur->request_seq, diff); + printf( "Response from %s : seq=%i time=%.1fms\n",addr2str(src,0),cur->request_seq, diff/1000.0); }else{ printf( "Response from %s : seq=%i time=%.1fms status=%s\n", - addr2str(src,0),cur->request_seq, diff,response_good[type]); + addr2str(src,0),cur->request_seq, diff/1000.0,response_good[type]); } }else{ @@ -1118,10 +1145,12 @@ int logResponse(ipaddr_ptr_t *src, int seq, int type, int v1, int v2){ if((type==DCCP_RESET && v1==3) || type==DCCP_RESPONSE || type==DCCP_SYNC){ /*Good Response*/ if(cur->num_replies==1){ - ping_stats.rtt_avg=((ping_stats.replies_received*ping_stats.rtt_avg)+(diff))/(ping_stats.replies_received+1); + ping_stats.rtt_sum+=diff; + ping_stats.rtt_sum2+=(diff*diff); ping_stats.replies_received++; }else{ - ping_stats.errors++; + printf("Duplicate packet detected! (%i)\n",cur->request_seq); + ping_stats.duplicates++; } if(diff < ping_stats.rtt_min || ping_stats.rtt_min==0){ ping_stats.rtt_min=diff; @@ -1202,26 +1231,46 @@ void clearQueue(){ } void sigHandler(){ - int diff; - double ploss; + /*Exit Quickly*/ + parms.count=0; +} - /*Print Stats*/ - gettimeofday(&ping_stats.stop,NULL); - printf("-----------%s PING STATISTICS-----------\n",parms.hostname); +void printStats(){ + int diff; + double ploss, rtt_avg, rtt_avg2, rtt_mdev; + /*Compute Stats*/ + if(ping_stats.replies_received>0){ + rtt_avg=ping_stats.rtt_sum/(ping_stats.replies_received*1.0); + rtt_avg2=ping_stats.rtt_sum2/(ping_stats.replies_received*1.0); + rtt_mdev=llsqrt(rtt_avg2 - (rtt_avg*rtt_avg)); + }else{ + rtt_avg=0; + rtt_avg2=0; + rtt_mdev=0; + } diff=(ping_stats.stop.tv_usec + 1000000*ping_stats.stop.tv_sec) - (ping_stats.start.tv_usec + 1000000*ping_stats.start.tv_sec); diff=diff/1000.0; - ploss=(1.0*(ping_stats.requests_sent-ping_stats.replies_received)/ping_stats.requests_sent*1.0)*100; - printf("%i packets transmitted, %i received, %i errors, %.2f%% loss, time %ims\n", - ping_stats.requests_sent,ping_stats.replies_received,ping_stats.errors, - ploss,diff); - printf("rtt min/avg/max = %.1f/%.1f/%.1f ms\n", - ping_stats.rtt_min,ping_stats.rtt_avg,ping_stats.rtt_max); + /*Print Stats*/ + gettimeofday(&ping_stats.stop,NULL); + printf("-----------%s PING STATISTICS-----------\n",parms.hostname); + ploss=(1.0*(ping_stats.requests_sent-ping_stats.replies_received)/ping_stats.requests_sent*1.0)*100; + printf("%i packets transmitted, %i received, ",ping_stats.requests_sent,ping_stats.replies_received); + if(ping_stats.duplicates>0){ + printf("%i duplicates, ",ping_stats.duplicates); + } + if(ping_stats.errors>0){ + printf("%i errors, ",ping_stats.errors); + } + printf("%.2f%% loss, time %ims\n",ploss,diff); + if(ping_stats.replies_received>ping_stats.requests_sent){ + printf("+Somebody is creating packets out of thing air!\n"); + } + printf("rtt min/avg/max/mdev = %.1f/%.1f/%.1f/%.1f ms\n", + ping_stats.rtt_min/1000.0,rtt_avg/1000.0,ping_stats.rtt_max/1000.0,rtt_mdev/1000.0); - /*Exit Quickly*/ - parms.count=0; } char* addr2str(ipaddr_ptr_t *res, int nores){ @@ -1258,7 +1307,7 @@ char* addr2str(ipaddr_ptr_t *res, int nores){ void usage() { dbgprintf(0, "dccpping: [-v] [-V] [-h] [-n] [-6|-4] [-c count] [-p port] [-i interval]\n"); - dbgprintf(0, " [-t ttl] [-S srcaddress] remote_host\n"); + dbgprintf(0, " [-t ttl] [-s service_code] [-S srcaddress] remote_host\n"); dbgprintf(0, "\n"); dbgprintf(0, " -v Verbose. May be repeated for aditional verbosity.\n"); dbgprintf(0, " -V Version information\n"); @@ -1297,3 +1346,21 @@ void dbgprintf(int level, const char *fmt, ...) va_end(args); } } + +/*Square Root function for longs*/ +/*Borrowed from iputils/ping_common.c*/ +/* http://www.skbuff.net/iputils/ */ +static long llsqrt(long long a) +{ + long long prev = ~((long long)1 << 63); + long long x = a; + + if (x > 0) { + while (x < prev) { + prev = x; + x = (x+(a/x))/2; + } + } + + return (long)x; +}