📄 speedtest.c
字号:
/***************************************************************************************************************** * Filr Name : speedtest.c * Description : modify from ping.c * related file : qosutils.h qosutils.c * Auther : Wendel Huang * History : 2006.05.22 post to WL500gP 2006.07.18 Post to WL700g, and remove execution message form release version 2006.08.01 Debug the error in MER mode *****************************************************************************************************************/#include <stdio.h>#include <sys/param.h>#include <sys/socket.h>#include <sys/file.h>#include <sys/time.h>#include <sys/times.h>#include <sys/signal.h>#include <string.h>#include <netinet/in.h>#include <netinet/ip.h>#include <netinet/ip_icmp.h>#include <arpa/inet.h>#include <netdb.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <unistd.h>#include <string.h>#include <stdlib.h>#include "qosutils.h"#ifdef WL600g#include "asusbcmnvram.h"#include "dbapi.h"#include "ifcwanapi.h"#include "syscall.h"#include "bcmadsl.h" //for ADSL_CONNECTION_INFO#else //WL500gP, WL550gE#include "bcmnvram.h"#endif#ifdef WL600gextern ADSL_CONNECTION_INFO glbAdslInfo;// global ADSL info variable is declared in syscall.c#endif#define STRUCT_LEN(name) sizeof(name)/sizeof(name[0])#define MAX_BANDWIDTH 15359 // S = (1500-64)*8/1024 (kbits) // S *1000 / (thelta t) * 1.369 (weight) = B#define DETECT_FILE "/tmp/detect_ip"static const int DEFDATALEN = 56;static const int MAXIPLEN = 60;static const int MAXICMPLEN = 76;static const int MAXWAIT = 10;static const int ADSLMXLEN = 1458;static const int HEADOVERHEAD = 42; //14(frame header)+20(ip header)+8(icmp header)#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */#define SET(bit) (A(bit) |= B(bit))#define CLR(bit) (A(bit) &= (~B(bit)))#define TST(bit) (A(bit) & B(bit))enum { WAN_RATE_SUCCESS, WAN_LINK_FAIL };struct icmp_map_t{ unsigned difference; unsigned rate;} icmp_map[] = { {3000, MAX_BANDWIDTH}, {1638, 2048}, {819, 1024}, {600, 640}, {410, 512}, {204, 256}, {102, 128}, {51, 64}, {27, 33},};//difference = rate * 0.8struct wan_link_rate { unsigned ds; unsigned us;};/* common routines */static int in_cksum(unsigned short *buf, int sz){ int nleft = sz; int sum = 0; unsigned short *w = buf; unsigned short ans = 0; while (nleft > 1) { sum += *w++; nleft -= 2; } if (nleft == 1) { *(unsigned char *) (&ans) = *(unsigned char *) w; sum += ans; } sum = (sum >> 16) + (sum & 0xFFFF); sum += (sum >> 16); ans = ~sum; return (ans);}static struct sockaddr_in pingaddr;static int pingsock = -1;int datalen; /* intentionally uninitialized to work around gcc bug */// brcm: changed default value of pingcount from 0 to 4.static long ntransmitted=0, nreceived=0;int pingcount=10;static int myid;static struct timeval tstart, tend;struct hostent *hostent;static char gateway_ip[16][30];static void sendping(int);static void unpack(char *, int, struct sockaddr_in *);static int detect();/**************************************************************************/static void sendping(int junk){#ifdef QOS_DEBUG printf(" Start of sendping()\n");#endif struct icmp *pkt; int i; char packet[datalen + 8]; pkt = (struct icmp *) packet; int repeat = 0; ntransmitted=0; nreceived=0; for ( ; repeat<pingcount ; repeat++ ) { pkt->icmp_type = ICMP_ECHO; pkt->icmp_code = 0; pkt->icmp_cksum = 0; pkt->icmp_seq = ntransmitted++; pkt->icmp_id = myid; gettimeofday((struct timeval *) &packet[8], NULL); pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(packet)); struct timeval tmshow; memcpy(&tmshow, &packet[8], sizeof(struct timeval));#ifdef QOS_DEBUG printf(" sendping() ** sequence = %d sendtime= %ld\n", pkt->icmp_seq, tmshow.tv_usec);#endif i = sendto(pingsock, packet, sizeof(packet), 0, (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in)); //2006.08.01 This is for sending echo-request error in MER mode //printf(" sendping() ** ntransmitted=%ld : sendto = %d\n", ntransmitted, i); //printf("QOS Detecting#%ld : sendto = %d\n", ntransmitted, i); //printf("QOS \n");#ifdef QOS_DEBUG if(i<0) switch(errno) { case EBADF: printf("EBADF\n"); case EFAULT: printf("EFAULT\n"); case ENOTSOCK: printf("ENOTSOCK\n"); case EINTR: printf("EINTR\n"); case EAGAIN: printf("EAGAIN\n"); case ENOBUFS: printf("ENOBUFS\n"); //case ENOMEN: //printf("ENOMEN\n"); case EINVAL: printf("EINVAL\n"); default: printf("sendto DNS error\n"); }#endif if ( i<0 || (size_t)i != sizeof(packet) ) printf(" sendping() ** sendto Error !!\n"); }}static void unpack(char *buf, int sz, struct sockaddr_in *from){ struct icmp *icmppkt; struct iphdr *iphdr; struct timeval tv, *tp; int hlen; unsigned long int triptime; gettimeofday(&tv, NULL); /* check IP header */ iphdr = (struct iphdr *) buf; hlen = iphdr->ihl << 2; /* discard if too short */ if (sz < (datalen + ICMP_MINLEN)) return; sz -= hlen; icmppkt = (struct icmp *) (buf + hlen); if (icmppkt->icmp_type == ICMP_ECHOREPLY) { if (icmppkt->icmp_id != myid) {#ifdef QOS_DEBUG printf(" unpack() ** not my ping !! icmp->icmpid = %d : myid =%d \n", icmppkt->icmp_id, myid); #endif return; /* not our ping */ } ++nreceived; tp = (struct timeval *) icmppkt->icmp_data; if( icmppkt->icmp_seq==0 ) { memcpy(&tstart, &tv, sizeof(struct timeval)); } if ( icmppkt->icmp_seq==(pingcount-1) ) { memcpy(&tend, &tv, sizeof(struct timeval)); } //printf("Icecream start tv_sec:%s,tv_usec:%s",tstart.tv_sec,tstart.tv_usec); //printf("Icecream start tv_sec:%s,tv_usec:%s",tend.tv_sec,tend.tv_usec); if ((tv.tv_usec -= tp->tv_usec) < 0) { --tv.tv_sec; tv.tv_usec += 1000000; } tv.tv_sec -= tp->tv_sec; triptime = tv.tv_sec * 1000000 + tv.tv_usec; //nvram_set("qos_ubw_status", "initialing"); /*brcm: changed display message to show actually receive data bytes length rather than ICMP packet length which is ICMP_MINLEN+dataLen */#ifdef QOS_DEBUG printf(" unpack() ** new sec = %ld new usec = %ld\n", tv.tv_sec, tv.tv_usec);#endif } else if (icmppkt->icmp_type == ICMP_UNREACH) { //if (icmppkt->icmp_code == ICMP_UNREACH_HOST) { nvram_set("qos_ubw_reason", "Host Unreachable"); #ifdef QOS_DEBUG printf(" unpack() ** DNS Host Unreachable !!\n");#endif nvram_set("qos_ubw_status", "fail"); } else { nvram_set("qos_ubw_status", "fail");#ifdef QOS_DEBUG printf(" unpack() ** icmp->type : %d\n", icmppkt->icmp_type);#endif }}extern void deltatime(const char *host, struct timeval *deltaval){#ifdef QOS_DEBUG printf(" Start of deltatime()\n");#endif datalen = ADSLMXLEN; char packet[datalen + MAXIPLEN + MAXICMPLEN]; unsigned long int ul_hostip; struct timeval socktv; myid = getpid() & 0xFFFF; if( (pingsock=socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0 ) { #ifdef QOS_DEBUG printf(" deltatime() ** socket() Error!!\n");#endif exit(2); } socktv.tv_sec = 5; socktv.tv_usec = 0; setsockopt(pingsock, SOL_SOCKET, SO_RCVTIMEO, &socktv, sizeof(socktv)); memset(&pingaddr, 0, sizeof(struct sockaddr_in)); pingaddr.sin_family = AF_INET; if( (ul_hostip=inet_addr(host)) !=INADDR_NONE ) { pingaddr.sin_addr.s_addr = ul_hostip; //printf("%s\n\n",inet_ntoa(pingaddr.sin_addr)); } else if((hostent=gethostbyname(host)) ) { memcpy(&pingaddr.sin_addr, hostent->h_addr, sizeof(pingaddr.sin_addr)); //printf("%s\n\n",inet_ntoa(pingaddr.sin_addr)); }#ifdef QOS_DEBUG else { printf(" deltatime() ** bad host ip or name!!\n"); return ; }#endif#ifdef QOS_DEBUG printf(" deltatime() ** host = %s\n", inet_ntoa(pingaddr.sin_addr));#endif /* start the ping's going ... */ signal(SIGALRM, sendping); alarm(1); /* listen for replies */ int runtimes = 1; int errotime = 0; while (1) {#ifdef QOS_DEBUG printf("\n receive exec times = %d\n", runtimes);#endif runtimes++; struct sockaddr_in from; socklen_t fromlen = (socklen_t) sizeof(from); int c = 0; c = recvfrom(pingsock, packet, sizeof(packet), 0, (struct sockaddr *) &from, &fromlen); //printf("C%d\n\n",c); if (c < 0) { errotime++; if (errno == EINTR) continue; if( errotime > 3 ) { nvram_set("qos_ubw_status", "fail"); //printf("time error!\n\n"); nvram_set("qos_ubw_reason", "DNS server fail"); }#ifdef QOS_DEBUG printf(" deltatime() ** recvfrom small than sendto !!\n");#endif if (pingcount > 0 && runtimes>=pingcount) break; else continue; } else if(c == 0) { nvram_set("qos_ubw_status", "fail"); } unpack(packet, c, &from); if (pingcount > 0 && nreceived >= pingcount) break; if ( strcmp(nvram_safe_get("qos_ubw_status"), "fail") == 0 ) exit(0); } close(pingsock); printf("gary start deltatime() ** tv_sec=%ld : tv_usec=%ld\n", tstart.tv_sec, tstart.tv_usec); printf("end deltatime() ** tv_sec=%ld : tv_usec=%ld\n", tend.tv_sec, tend.tv_usec); if ((tend.tv_usec -= tstart.tv_usec) < 0) { --tend.tv_sec; tend.tv_usec += 1000000; } printf("gary start deltatime() ** tv_sec=%ld : tv_usec=%ld\n", tstart.tv_sec, tstart.tv_usec); printf("end deltatime() ** tv_sec=%ld : tv_usec=%ld\n", tend.tv_sec, tend.tv_usec); tend.tv_sec -= tstart.tv_sec;#ifdef QOS_DEBUG printf(" deltatime() ** tv_sec=%ld : tv_usec=%ld\n", tend.tv_sec, tend.tv_usec);#endif //printf("start deltatime() ** tv_sec=%ld : tv_usec=%ld\n", tstart.tv_sec, tstart.tv_usec); //printf("end deltatime() ** tv_sec=%ld : tv_usec=%ld\n", tend.tv_sec, tend.tv_usec); memcpy(deltaval, &tend, sizeof(struct timeval));}//by icecream //function detect wan_ipstatic int detect(){ FILE *fp=NULL; char cmd[80]; char detect_ip[20]="18.52.86.150"; char line[254]; char get_ip[16][30]; snprintf(cmd,sizeof(cmd),"traceroute -m 16 %s >%s",detect_ip,DETECT_FILE); //printf("%s\n\n",cmd);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -