1/***************************************************************************************************************** 2 * Filr Name : speedtest.c 3 * Description : modify from ping.c 4 * related file : qosutils.h qosutils.c 5 * Auther : Wendel Huang 6 * History : 2006.05.22 post to WL500gP 7 2006.07.18 Post to WL700g, and remove execution message form release version 8 2006.08.01 Debug the error in MER mode 9 *****************************************************************************************************************/ 10#ifdef QOS 11 12#include <stdio.h> 13#include <sys/param.h> 14#include <sys/socket.h> 15#include <sys/file.h> 16#include <sys/time.h> 17#include <sys/times.h> 18#include <sys/signal.h> 19#include <string.h> 20#include <netinet/in.h> 21#include <netinet/ip.h> 22#include <netinet/ip_icmp.h> 23#include <arpa/inet.h> 24#include <netdb.h> 25#include <stdio.h> 26#include <stdlib.h> 27#include <errno.h> 28#include <unistd.h> 29#include <string.h> 30#include <stdlib.h> 31#include <shutils.h> 32 33#include "qosutils.h" 34 35#ifdef WL600g 36#include "asusbcmnvram.h" 37#include "dbapi.h" 38#include "ifcwanapi.h" 39#include "syscall.h" 40#include "bcmadsl.h" //for ADSL_CONNECTION_INFO 41#else //WL500gP, WL550gE 42#include "bcmnvram.h" 43#endif 44 45#ifdef WL600g 46extern ADSL_CONNECTION_INFO glbAdslInfo;// global ADSL info variable is declared in syscall.c 47#endif 48 49#define STRUCT_LEN(name) sizeof(name)/sizeof(name[0]) 50#define MAX_BANDWIDTH 15359 // S = (1500-64)*8/1024 (kbits) 51 // S *1000 / (thelta t) * 1.369 (weight) = B 52#define DETECT_FILE "/tmp/detect_ip" 53 54static const int DEFDATALEN = 56; 55static const int MAXIPLEN = 60; 56static const int MAXICMPLEN = 76; 57static const int MAXWAIT = 10; 58static const int ADSLMXLEN =1400; 59static const int HEADOVERHEAD = 42; 60unsigned long int triptime[36]; //14(frame header)+20(ip header)+8(icmp header) 61static int request_time=1; 62 63#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */ 64#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */ 65#define SET(bit) (A(bit) |= B(bit)) 66#define CLR(bit) (A(bit) &= (~B(bit))) 67#define TST(bit) (A(bit) & B(bit)) 68 69enum { WAN_RATE_SUCCESS, WAN_LINK_FAIL }; 70 71struct icmp_map_t{ 72 unsigned difference; 73 unsigned rate; 74} icmp_map[] = { 75 {3000, MAX_BANDWIDTH}, 76 {1638, 2048}, 77 {819, 1024}, 78 {600, 640}, 79 {410, 512}, 80 {204, 256}, 81 {102, 128}, 82 {51, 64}, 83 {27, 33}, 84};//difference = rate * 0.8 85 86struct wan_link_rate { 87 unsigned ds; 88 unsigned us; 89}; 90 91/* common routines */ 92static int in_cksum(unsigned short *buf, int sz) 93{ 94 int nleft = sz; 95 int sum = 0; 96 unsigned short *w = buf; 97 unsigned short ans = 0; 98 99 while (nleft > 1) { 100 sum += *w++; 101 nleft -= 2; 102 } 103 104 if (nleft == 1) { 105 *(unsigned char *) (&ans) = *(unsigned char *) w; 106 sum += ans; 107 } 108 109 sum = (sum >> 16) + (sum & 0xFFFF); 110 sum += (sum >> 16); 111 ans = ~sum; 112 return (ans); 113} 114 115static struct sockaddr_in pingaddr; 116static int pingsock = -1; 117int datalen; /* intentionally uninitialized to work around gcc bug */ 118 119// brcm: changed default value of pingcount from 0 to 4. 120static long ntransmitted=0, nreceived=0; 121int pingcount=10; 122static int myid; 123static struct timeval tstart, tend; 124 125struct hostent *hostent; 126 127static char gateway_ip[10][30]; 128static void sendping(); 129static void unpack(char *, int, struct sockaddr_in *); 130static int detect(); 131static int pre_ping(const char *host); 132 133/**************************************************************************/ 134 135//static void sendping(int junk) 136static void sendping() 137{ 138#ifdef QOS_DEBUG 139 printf(" Start of sendping()\n"); 140#endif 141 struct icmp *pkt; 142 int i; 143 char packet[datalen + 8]; 144 145 pkt = (struct icmp *) packet; 146 147 int repeat = 0; 148 ntransmitted=0; 149 nreceived=0; 150 switch(request_time) 151 { 152 case 1: 153 case 2: 154 case 3: 155 pingcount=9; 156 printf("pingcount:%d\n",pingcount); 157 break; 158 case 4: 159 case 5: 160 case 6: 161 pingcount=15; 162 printf("pingcount:%d\n",pingcount); 163 break; 164 case 7: 165 case 8: 166 case 9: 167 pingcount=29; 168 printf("pingcount:%d\n",pingcount); 169 break; 170 case 10: 171 case 11: 172 case 12: 173 pingcount=54; 174 printf("pingcount:%d\n",pingcount); 175 break; 176 case 13: 177 case 14: 178 case 15: 179 pingcount=70; 180 printf("pingcount:%d\n",pingcount); 181 break; 182 case 16: 183 case 17: 184 case 18: 185 pingcount=72; 186 printf("pingcount:%d\n",pingcount); 187 break; 188 case 19: 189 case 20: 190 case 21: 191 pingcount=74; 192 printf("pingcount:%d\n",pingcount); 193 break; 194 case 22: 195 case 23: 196 case 24: 197 pingcount=76; 198 printf("pingcount:%d\n",pingcount); 199 break; 200 case 25: 201 case 26: 202 case 27: 203 pingcount=78; 204 printf("pingcount:%d\n",pingcount); 205 break; 206 case 28: 207 case 29: 208 case 30: 209 pingcount=80; 210 printf("pingcount:%d\n",pingcount); 211 break; 212 case 31: 213 case 32: 214 case 33: 215 pingcount=82; 216 printf("pingcount:%d\n",pingcount); 217 break; 218 case 34: 219 case 35: 220 case 36: 221 pingcount=84; 222 printf("pingcount:%d\n",pingcount); 223 break; 224 default: 225 printf("pingcount error!\n"); 226 } 227 for ( ; repeat<pingcount ; repeat++ ) { 228 int pingsock1; 229 if( (pingsock1=socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0 ) { 230#ifdef QOS_DEBUG 231 printf(" deltatime() ** socket() Error!!\n"); 232#endif 233 exit(2); 234 } 235 pkt->icmp_type = ICMP_ECHO; 236 pkt->icmp_code = 0; 237 if(repeat==pingcount-1) 238 { 239 pkt->icmp_cksum = 0; 240 } 241 else 242 { 243 pkt->icmp_cksum = 1; 244 } 245 pkt->icmp_seq = pingcount; 246 pkt->icmp_id = myid; 247 gettimeofday((struct timeval *)pkt->icmp_data, NULL); 248 if(repeat==0) 249 { 250 gettimeofday(&tstart, NULL); 251 } 252 pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(packet)); 253 254 struct timeval tmshow; 255 memcpy(&tmshow, pkt->icmp_data, sizeof(struct timeval)); 256 257#ifdef QOS_DEBUG 258 printf(" sendping() ** sequence = %d sendtime= %ld\n", pkt->icmp_seq, tmshow.tv_usec); 259#endif 260 261 i = sendto(pingsock1, packet, sizeof(packet), 0, (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in)); 262 //2006.08.01 This is for sending echo-request error in MER mode 263 //printf(" sendping() ** ntransmitted=%ld : sendto = %d\n", ntransmitted, i); 264 //printf("QOS Detecting#%ld : sendto = %d\n", ntransmitted, i); 265 //printf("QOS \n"); 266 267#ifdef QOS_DEBUG 268 if(i<0) 269 switch(errno) { 270 case EBADF: 271 printf("EBADF\n"); 272 case EFAULT: 273 printf("EFAULT\n"); 274 case ENOTSOCK: 275 printf("ENOTSOCK\n"); 276 case EINTR: 277 printf("EINTR\n"); 278 case EAGAIN: 279 printf("EAGAIN\n"); 280 case ENOBUFS: 281 printf("ENOBUFS\n"); 282 //case ENOMEN: 283 //printf("ENOMEN\n"); 284 case EINVAL: 285 printf("EINVAL\n"); 286 default: 287 printf("sendto DNS error\n"); 288 } 289#endif 290 291 if ( i<0 || (size_t)i != sizeof(packet) ) 292 printf(" sendping() ** sendto Error !!\n"); 293 close(pingsock1); 294 } 295} 296 297static void unpack(char *buf, int sz, struct sockaddr_in *from) 298{ 299 struct icmp *icmppkt; 300 struct iphdr *iphdr; 301 //struct timeval tv, *tp; 302 struct timeval tv; 303 int hlen; 304 //unsigned long int triptime; 305 306 gettimeofday(&tv, NULL); 307 308 /* check IP header */ 309 iphdr = (struct iphdr *) buf; 310 hlen = iphdr->ihl << 2; 311 /* discard if too short */ 312 if (sz < ICMP_MINLEN) 313 return; 314 315 sz -= hlen; 316 icmppkt = (struct icmp *) (buf + hlen); 317 318 if (icmppkt->icmp_type == ICMP_ECHOREPLY) { 319 320 if (icmppkt->icmp_id != myid) { 321#ifdef QOS_DEBUG 322 printf(" unpack() ** not my ping !! icmp->icmpid = %d : myid =%d \n", icmppkt->icmp_id, myid); 323#endif 324 return; /* not our ping */ 325 } 326 327 ++nreceived; 328 if ((tv.tv_usec -= tstart.tv_usec) < 0) { 329 --tv.tv_sec; 330 tv.tv_usec += 1000000; 331 } 332 tv.tv_sec -= tstart.tv_sec; 333 334 triptime[request_time-1] = tv.tv_sec * 1000000 + tv.tv_usec; 335 //nvram_set("qos_ubw_status", "initialing"); 336 /*brcm: changed display message to show actually receive data bytes length 337 rather than ICMP packet length which is ICMP_MINLEN+dataLen */ 338#ifdef QOS_DEBUG 339 printf(" unpack() ** new sec = %ld new usec = %ld\n", tv.tv_sec, tv.tv_usec); 340#endif 341 } 342 else if (icmppkt->icmp_type == ICMP_UNREACH) { 343 nvram_set("qos_ubw_reason", "Host Unreachable"); 344 345#ifdef QOS_DEBUG 346 printf(" unpack() ** DNS Host Unreachable !!\n"); 347#endif 348 349 nvram_set("qos_ubw_status", "fail"); 350 } 351 else { 352 nvram_set("qos_ubw_status", "fail"); 353 354#ifdef QOS_DEBUG 355 printf(" unpack() ** icmp->type : %d\n", icmppkt->icmp_type); 356#endif 357 } 358} 359 360static int pre_ping(const char *host) 361{ 362 int package=60; 363 char packet[package+MAXIPLEN+MAXICMPLEN]; 364 unsigned long int ul_hostip; 365 struct timeval socktv; 366 myid = getpid() & 0xFFFF; 367 368 if( (pingsock=socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0 ) 369 { 370 return 0; 371 } 372 373 socktv.tv_sec = 5; 374 socktv.tv_usec = 0; 375 setsockopt(pingsock, SOL_SOCKET, SO_RCVTIMEO, &socktv, sizeof(socktv)); 376 377 memset(&pingaddr, 0, sizeof(struct sockaddr_in)); 378 379 pingaddr.sin_family = AF_INET; 380 381 if( (ul_hostip=inet_addr(host)) !=INADDR_NONE ) 382 { 383 pingaddr.sin_addr.s_addr = ul_hostip; 384 } 385 else if((hostent=gethostbyname(host)) ) 386 { 387 memcpy(&pingaddr.sin_addr, hostent->h_addr, sizeof(pingaddr.sin_addr)); 388 } 389 struct icmp *pkt; 390 int i; 391 char packet1[package + 8]; 392 393 pkt = (struct icmp *) packet1; 394 395 int repeat = 0; 396 ntransmitted=0; 397 nreceived=0; 398 for ( ; repeat<pingcount ; repeat++ ) { 399 pkt->icmp_type = ICMP_ECHO; 400 pkt->icmp_code = 0; 401 pkt->icmp_cksum = 0; 402 pkt->icmp_seq = ntransmitted++; 403 pkt->icmp_id = myid; 404 gettimeofday((struct timeval *)pkt->icmp_data, NULL); 405 gettimeofday(&tstart, NULL); 406 pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(packet1)); 407 struct timeval tmshow; 408 memcpy(&tmshow, pkt->icmp_data, sizeof(struct timeval)); 409 i = sendto(pingsock, packet1, sizeof(packet1), 0, 410 (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in)); 411 if ( i<0 || (size_t)i != sizeof(packet1) ) 412 { 413 printf(" sendping() ** sendto Error !!\n"); 414 return 0; 415 } 416 } 417 int runtimes = 1; 418 int errotime = 0; 419 while (1) { 420 runtimes++; 421 422 struct sockaddr_in from; 423 socklen_t fromlen = (socklen_t) sizeof(from); 424 int c = 0; 425 426 c = recvfrom(pingsock, packet1, sizeof(packet1), 0, 427 (struct sockaddr *) &from, &fromlen); 428 if (c < 0) { 429 errotime++; 430 431 if (errno == EINTR) continue; 432 433 if( errotime > 3 ) { 434 nvram_set("qos_ubw_status", "fail"); 435 nvram_set("qos_ubw_reason", "DNS server fail"); 436 return 0; 437 } 438 if (pingcount > 0 && runtimes>=pingcount) 439 { 440 return 0; 441 break; 442 } 443 else 444 continue; 445 } 446 else if(c == 0) { 447 return 0; 448 nvram_set("qos_ubw_status", "fail"); 449 } 450 if (pingcount > 0) 451 { 452 break; 453 } 454 455 } 456 return 1; 457 458} 459 460extern void deltatime(const char *host, struct timeval *deltaval) 461{ 462#ifdef QOS_DEBUG 463 printf(" Start of deltatime()\n"); 464#endif 465 466 datalen =ADSLMXLEN; 467 char packet[datalen + MAXIPLEN + MAXICMPLEN]; 468 unsigned long int ul_hostip; 469 struct timeval socktv; 470 471 myid = getpid() & 0xFFFF; 472 473 if( (pingsock=socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0 ) { 474#ifdef QOS_DEBUG 475 printf(" deltatime() ** socket() Error!!\n"); 476#endif 477 exit(2); 478 } 479int pingsock2=-1; 480if( (pingsock2=socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0 ) { 481#ifdef QOS_DEBUG 482 printf(" deltatime() ** socket() Error!!\n"); 483#endif 484 exit(2); 485 } 486 487 socktv.tv_sec = 5; 488 socktv.tv_usec = 0; 489 setsockopt(pingsock2, SOL_SOCKET, SO_RCVTIMEO, &socktv, sizeof(socktv)); 490 memset(&pingaddr, 0, sizeof(struct sockaddr_in)); 491 492 pingaddr.sin_family = AF_INET; 493 494 if( (ul_hostip=inet_addr(host)) !=INADDR_NONE ) 495 { 496 pingaddr.sin_addr.s_addr = ul_hostip; 497 } 498 else if((hostent=gethostbyname(host)) ) 499 { 500 memcpy(&pingaddr.sin_addr, hostent->h_addr, sizeof(pingaddr.sin_addr)); 501 } 502#ifdef QOS_DEBUG 503 else 504 { 505 printf(" deltatime() ** bad host ip or name!!\n"); 506 return ; 507 } 508#endif 509 510#ifdef QOS_DEBUG 511 printf(" deltatime() ** host = %s\n", inet_ntoa(pingaddr.sin_addr)); 512#endif 513 514 /* start the ping's going ... */ 515 //signal(SIGALRM, sendping); 516 //alarm(1); 517 sendping(); 518 519 /* listen for replies */ 520 int runtimes = 1; 521 int errotime = 0; 522 while (1) { 523#ifdef QOS_DEBUG 524 printf("\n receive exec times = %d\n", runtimes); 525#endif 526 runtimes++; 527 struct sockaddr_in from; 528 socklen_t fromlen = (socklen_t) sizeof(from); 529 int c = 0; 530 531 c = recvfrom(pingsock2, packet, sizeof(packet), 0, 532 (struct sockaddr *) &from, &fromlen); 533 if (c < 0 && request_time==1) { 534 errotime++; 535 536 if (errno == EINTR) continue; 537 538 if( errotime > 3 ) { 539 nvram_set("qos_ubw_status", "fail"); 540 nvram_set("qos_ubw_reason", "DNS server fail"); 541 } 542 543#ifdef QOS_DEBUG 544 printf(" deltatime() ** recvfrom small than sendto !!\n"); 545#endif 546 547 if (pingcount > 0 && runtimes>=pingcount) 548 break; 549 else 550 continue; 551 } 552 else if(c<0 && request_time!=1) 553 { 554 request_time=100; 555 break; 556 } 557 558 else if(c == 0) { 559 nvram_set("qos_ubw_status", "fail"); 560 } 561 unpack(packet, c, &from); 562 if (pingcount > 0) 563 { 564 break; 565 } 566 if ( strcmp(nvram_safe_get("qos_ubw_status"), "fail") == 0 ) 567 { 568 exit(0); 569 } 570 } 571 572 close(pingsock); 573 close(pingsock2); 574#ifdef QOS_DEBUG 575 printf(" deltatime() ** tv_sec=%ld : tv_usec=%ld\n", tend.tv_sec, tend.tv_usec); 576#endif 577 578} 579 580 581//by icecream 582//function detect wan_ip 583static int detect() 584{ 585 FILE *fp=NULL; 586 char cmd[80]; 587 char detect_ip[20]="18.52.86.150"; 588 char line[254]; 589 char get_ip[10][30]; 590 int j=0; 591 while(j<=9) 592 { 593 memset(&get_ip[j], 0, sizeof(get_ip[j])); 594 memset(&gateway_ip[j], 0, sizeof(gateway_ip[j])); 595 j++; 596 } 597 snprintf(cmd,sizeof(cmd),"traceroute -m 10 %s >%s",detect_ip,DETECT_FILE); 598 remove(DETECT_FILE); 599 int i=0; 600 int ping=0; 601 system(cmd); 602 if ((fp = fopen(DETECT_FILE, "r")) != NULL) 603 { 604 while(i<10) 605 { 606 if( fgets(line, sizeof(line), fp) != NULL ) 607 { 608 char *p=NULL; 609 p=index(line,'('); 610 if(!p) 611 { 612 //printf("has no address!\n\n"); 613 ping++; 614 if(ping>=3) 615 { 616 return 0; 617 } 618 continue; 619 } 620 int j=1; 621 while((*p)!=')') 622 { 623 p++; 624 get_ip[i][j-1]=*p; 625 j++; 626 } 627 get_ip[i][j-2]='\0'; 628 629 } 630 i++; 631 632 } 633 i=0; 634 while(i<10) 635 { 636 sprintf(gateway_ip[i],"%s",get_ip[i]); 637 i++; 638 } 639 } 640 fclose(fp); 641 return 1; 642} 643 644/************************************************************************** 645 * Function Name: qos_get_wan_rate 646 * Description : get the ADSL line rate 647 * Parameters : None 648 * Returns : Is successful when get the ADSL data rate? 649 0 : Success 650 1 : Link fail 651 **************************************************************************/ 652extern int qos_get_wan_rate(void) 653{ 654 static struct wan_link_rate wanrate; 655 char us[256], ds[256] ; 656 char * gw_ip=NULL; 657 struct timeval deltaval; 658 double delta_us = 0; 659 wanrate.us = wanrate.ds = 0; 660 int step=3; 661 char *ip = nvram_safe_get("wan_dns_t"); 662 int need_package=80; 663 if( !check_wan_link(0) ) 664 return WAN_LINK_FAIL; 665 666 gw_ip = get_gw_ip(); 667 668 if((strchr(ip, ' ')) ||(!strcmp(ip, ""))) 669 { 670 struct dns_lists *dns_list = get_dns_list(1); 671 int i; 672 673 for(i=0 ; i<dns_list->num_servers ; i++){ 674 ip = dns_list->dns_server[i]; 675 if( (!strchr(ip, ' ')) 676 && (strcmp(ip, "")) 677 && (strcmp(ip, gw_ip))) //WL600g auto assign LAN IP as DNS Server 678 break; 679 } 680 free(dns_list); 681 } 682 if( (strchr(ip, ' ')) || (!strcmp(ip, "")) || (!strcmp(ip, gw_ip)) ) { 683#ifdef QOS_DEBUG 684 printf(" qos_get_wan_rate() ** GET DNS IP Error\n"); 685#endif 686 nvram_set("qos_ubw_status", "fail"); 687 nvram_set("qos_ubw_reason", "DNS server fail"); 688 } 689 else 690 { 691 int choose=1; 692 choose=detect(); 693 if(choose==0) 694 { 695 return WAN_LINK_FAIL; 696 } 697 if(strlen(gateway_ip[step])!=0) 698 { 699 while(pre_ping(gateway_ip[step])==0) 700 { 701 if(step==9) 702 { 703 return WAN_LINK_FAIL; 704 } 705 step++; 706 while(strlen(gateway_ip[step])==0) 707 { 708 if(step==9) 709 { 710 return WAN_LINK_FAIL; 711 } 712 step++; 713 } 714 715 } 716 sleep(1); 717 loop:request_time=1; 718 int i=0; 719 while(i<=35) 720 { 721 triptime[i]=0; 722 i++; 723 } 724 //printf("gateway_ip[step]=%s\n",gateway_ip[step]); 725 while(request_time<36) 726 { 727 deltatime(gateway_ip[step], &deltaval); 728 usleep(10); 729 request_time++; 730 } 731 i=0; 732 while(triptime[i]!=0) 733 { 734 i++; 735 } 736 i=i-(i%3); 737 if(i>12) 738 { 739 switch(i) 740 { 741 case 15: 742 triptime[0]=(triptime[3]+triptime[4]+triptime[5])/3; 743 triptime[1]=(triptime[i-1]+triptime[i-2]+triptime[i-3])/3; 744 break; 745 case 18: 746 triptime[0]=(triptime[3]+triptime[4]+triptime[5])/3; 747 triptime[1]=(triptime[i-1]+triptime[i-2]+triptime[i-3])/3; 748 triptime[2]=(triptime[i-4]+triptime[i-5]+triptime[i-6])/3; 749 break; 750 case 21: 751 triptime[0]=(triptime[3]+triptime[4]+triptime[5])/3; 752 triptime[1]=(triptime[i-1]+triptime[i-2]+triptime[i-3])/3; 753 triptime[2]=(triptime[i-4]+triptime[i-5]+triptime[i-6])/3; 754 triptime[3]=(triptime[i-7]+triptime[i-8]+triptime[i-9])/3; 755 break; 756 case 24: 757 triptime[0]=(triptime[3]+triptime[4]+triptime[5])/3; 758 triptime[1]=(triptime[i-1]+triptime[i-2]+triptime[i-3])/3; 759 triptime[2]=(triptime[i-4]+triptime[i-5]+triptime[i-6])/3; 760 triptime[3]=(triptime[i-7]+triptime[i-8]+triptime[i-9])/3; 761 triptime[4]=(triptime[i-10]+triptime[i-11]+triptime[i-12])/3; 762 break; 763 case 27: 764 triptime[0]=(triptime[3]+triptime[4]+triptime[5])/3; 765 triptime[1]=(triptime[i-1]+triptime[i-2]+triptime[i-3])/3; 766 triptime[2]=(triptime[i-4]+triptime[i-5]+triptime[i-6])/3; 767 triptime[3]=(triptime[i-7]+triptime[i-8]+triptime[i-9])/3; 768 triptime[4]=(triptime[i-10]+triptime[i-11]+triptime[i-12])/3; 769 triptime[5]=(triptime[i-13]+triptime[i-14]+triptime[i-15])/3; 770 break; 771 default: 772 triptime[0]=(triptime[3]+triptime[4]+triptime[5])/3; 773 triptime[1]=(triptime[i-1]+triptime[i-2]+triptime[i-3])/3; 774 triptime[2]=(triptime[i-4]+triptime[i-5]+triptime[i-6])/3; 775 triptime[3]=(triptime[i-7]+triptime[i-8]+triptime[i-9])/3; 776 triptime[4]=(triptime[i-10]+triptime[i-11]+triptime[i-12])/3; 777 triptime[5]=(triptime[i-13]+triptime[i-14]+triptime[i-15])/3; 778 triptime[6]=(triptime[i-16]+triptime[i-17]+triptime[i-18])/3; 779 break; 780 781 } 782 if(i>=33) 783 { 784 int h=0; 785 for(h=0;h<=2;h++) 786 { 787 if(h==0) 788 { 789 need_package=80-15; 790 } 791 else 792 { 793 need_package=80-(h*2)-15; 794 } 795 wanrate.us=wanrate.us+((double)need_package*(datalen+46)*8/(triptime[h+2]-triptime[0])/1024*1000000); 796 int a=0; 797 a=(double)need_package*(datalen+46)*8/(triptime[h+2]-triptime[0])/1024*1000000; 798 printf("this package wanrateus=%d\n",a); 799 printf("finally wanrateus=%d\n",wanrate.us); 800 } 801 wanrate.us=wanrate.us/3; 802 printf("wanrate.us1=%d\n",wanrate.us); 803 if(wanrate.us>10500) 804 { 805 wanrate.us=10080; 806 } 807 808 } 809 else 810 { 811 int y=i; 812 y=(30-y)/3; 813 int h=1; 814 //i=30 need_package=80-15 815 //i=27 need_package=78-15 816 //i=24 need_package=76-15 817 //i=21 need_package=74-15 818 //i=18 need_package=72-15 819 //i=15 need_package=70-15 820 while(need_package>55) 821 { 822 need_package=80-(y*2)-15; 823 y=y+1; 824 h++; 825 wanrate.us=wanrate.us+((double)need_package*(datalen+46)*8/(triptime[h-1]-triptime[0])/1024*1000000); 826 //int a=0; 827 //a=(double)need_package*(datalen+46)*8/(triptime[h-1]-triptime[0])/1024*1000000; 828 //printf("a=%d\n",a); 829 //printf("wanrate.us%d\n",wanrate.us); 830 } 831 wanrate.us=wanrate.us/(h-1); 832 printf("wanrate.us2=%d\n",wanrate.us); 833 if(wanrate.us>10500) 834 { 835 wanrate.us=10080; 836 } 837 } 838 839 840 } 841 else 842 { 843 triptime[0]=(triptime[3]+triptime[4]+triptime[5])/3; 844 triptime[1]=(triptime[9]+triptime[10]+triptime[11])/3; 845 need_package=54-15; 846 wanrate.us = (double)need_package*(datalen+46)*8/(triptime[1]-triptime[0])/1024*1000000 ; 847 if(wanrate.us>10500) 848 { 849 wanrate.us=10080; 850 } 851 if(wanrate.us==0 && i==9) 852 { 853 triptime[0]=(triptime[3]+triptime[4]+triptime[5])/3; 854 triptime[1]=(triptime[6]+triptime[7]+triptime[8])/3; 855 need_package=29-15; 856 wanrate.us = (double)need_package*(datalen+46)*8/(triptime[1]-triptime[0])/1024*1000000*1.1 ; 857 if(wanrate.us>10500) 858 { 859 wanrate.us=10080; 860 } 861 } 862 if(wanrate.us==0 && i==6) 863 { 864 triptime[0]=(triptime[0]+triptime[1]+triptime[2])/3; 865 triptime[1]=(triptime[3]+triptime[4]+triptime[5])/3; 866 need_package=15-9; 867 wanrate.us = (double)need_package*(datalen+46)*8/(triptime[1]-triptime[0])/1024*1000000*1.1 ; 868 if(wanrate.us>10500) 869 { 870 wanrate.us=10080; 871 } 872 } 873 printf("wanrate.us3=%d\n",wanrate.us); 874 875 } 876 } 877 else 878 { 879 step--; 880 while(strlen(gateway_ip[step])==0) 881 { 882 if(step==0) 883 { 884 return WAN_LINK_FAIL; 885 } 886 step--; 887 } 888 while(pre_ping(gateway_ip[step])==0) 889 { 890 if(step==0) 891 { 892 return WAN_LINK_FAIL; 893 } 894 step--; 895 } 896 sleep(1); 897 goto loop; 898 } 899 } 900 free(gw_ip); 901 902 if( strcmp(nvram_safe_get("qos_ubw_status"), "fail") == 0 ) { 903#ifdef WL600g 904 if( !strcmp(nvram_safe_get("qos_ubw_reason"), "DNS server fail") ) 905 { 906 //DownStream 907 if ( glbAdslInfo.ulInterleavedDnStreamRate != 0 ) 908 wanrate.ds = glbAdslInfo.ulInterleavedDnStreamRate / 1000; 909 else 910 wanrate.ds = glbAdslInfo.ulFastDnStreamRate / 1000; 911 912 //UpStream 913 if ( glbAdslInfo.ulInterleavedUpStreamRate != 0 ) 914 wanrate.us = glbAdslInfo.ulInterleavedUpStreamRate / 1000; 915 else 916 wanrate.us = glbAdslInfo.ulFastUpStreamRate / 1000; 917 918 //sprintf(ds, "%u", wanrate.ds); 919 //nvram_set("wan_ds", ds); 920 sprintf(us, "%u", wanrate.us); 921 nvram_set("qos_ubw", us); 922 923 nvram_set("qos_ubw_status", "success"); 924 925 return WAN_RATE_SUCCESS; 926 } 927 else 928 return WAN_LINK_FAIL; 929#else 930 return WAN_LINK_FAIL; 931#endif 932 } 933 934#ifdef QOS_DEBUG 935 printf("\n start time ** tv_sec=%ld: tv_usec=%ld\n",tstart.tv_sec, tstart.tv_usec); 936 printf(" end time ** tv_sec=%ld : tv_usec=%ld\n", tend.tv_sec, tend.tv_usec); 937 printf(" delta_sec=%ld : delta_usec=%ld\n", deltaval.tv_sec*1000000, deltaval.tv_usec); 938#endif 939 printf("wanrate.us=%u\n\n",wanrate.us); 940 941 942 if( wanrate.us!=0 ) 943 nvram_set("qos_ubw_status", "success"); 944 945#ifdef QOS_DEBUG 946 printf("\nUpload Bandwidth = %.0u kbps\n", wanrate.us); 947#endif 948 949 wanrate.ds = 0; 950 sprintf(us, "%u", wanrate.us); 951 nvram_set("qos_ubw", us); 952 953 954 return WAN_RATE_SUCCESS; 955 956} 957 958#ifdef WL600g 959//************************************************************************** 960// Function Name: Speedtest_init 961// Description : init function, called by BcmNtwk_init() in ifcntwkapi.cpp 962// Returns : 0 963//************************************************************************** 964int Speedtest_init(void) { 965 FILE *fp; 966 967 /* Run it under background */ 968 switch (fork()) { 969 case -1: 970 exit(0); 971 break; 972 case 0: 973 // start in a new session 974 (void) setsid(); 975 break; 976 default: 977 // parent process should just die 978 return 0; 979 } 980 981 /* write pid */ 982 if ((fp=fopen("/var/run/speedtest.pid", "w"))!=NULL) 983 { 984 fprintf(fp, "%d", getpid()); 985 fclose(fp); 986 } 987 988 nvram_set("qos_ubw_status", "initialing"); 989 990 sleep(60); 991 if( nvram_match("qos_enable", "1") ) { 992 993 qos_get_wan_rate(); 994 if(nvram_match("qos_ubw_status", "success") ) 995 start_qos(); 996 } 997 998 while(1){ 999 pause(); 1000 } 1001 1002 return 0; 1003} 1004#else 1005//extern void start_qos(void); 1006 1007int Speedtest_Init(void) { 1008 char net_name[32]; 1009 FILE *fp=NULL; 1010 1011 printf("*** run Speedtest_Init(). ***\n"); 1012 1013// 2009.03 James. Mark these and put them into network.c. { 1014/* nvram_set("qos_userspec_app", "0"); 1015 nvram_set("qos_global_enable", "0"); 1016 nvram_set("qos_userdef_enable", "0"); 1017 //nvram_set("qos_enable", "0"); 1018 1019 if(nvram_invmatch("qos_rulenum_x", "0")) 1020 nvram_set("qos_userspec_app", "1"); 1021 1022 //add by Angela 2008.05 1023 if(nvram_match("qos_tos_prio", "1")||nvram_match("qos_pshack_prio", "1") 1024 || nvram_match("qos_service_enable", "1")|| nvram_match("qos_shortpkt_prio", "1")) 1025 nvram_set("qos_global_enable", "1"); 1026 1027 if(nvram_match("qos_userspec_app", "1") || nvram_match("qos_dfragment_enable", "1")) 1028 nvram_set("qos_userdef_enable", "1");//*/ 1029// 2009.03 James. } 1030 1031 /* Get interface name */ 1032 if (nvram_match("wan0_proto", "pppoe") || nvram_match("wan0_proto", "pptp") || nvram_match("wan0_proto", "l2tp")) 1033 strcpy (net_name, nvram_safe_get("wan0_pppoe_ifname")); 1034 else 1035 strcpy (net_name, nvram_safe_get("wan0_ifname")); 1036 1037 /* Reset all qdisc first */ 1038 eval ("tc","qdisc","del", "dev", net_name, "root", "htb"); 1039 1040 /* Clean iptables*/ 1041 /*eval("iptables", "-F", "-t", "mangle");*/ 1042 if ((fp=fopen("/tmp/mangle_rules", "w"))==NULL) return 0; 1043 fprintf(fp, "*mangle\n"); 1044 fprintf(fp, "-F\n"); 1045 fprintf(fp, "COMMIT\n\n"); 1046 fclose(fp); 1047 eval("iptables-restore", "/tmp/mangle_rules"); 1048 1049// 2009.03 James. Mark these and put them into network.c. { 1050 /*if(nvram_invmatch("qos_manual_ubw","0") && nvram_invmatch("qos_manual_ubw","")) 1051 { 1052 nvram_set("qos_ubw",nvram_get("qos_manual_ubw")); 1053 } 1054 else if(nvram_invmatch("qos_ubw", "0")) 1055 nvram_set("qos_ubw",nvram_get("qos_ubw_tmp")); 1056 1057#if 0 1058 if(nvram_invmatch("qos_manual_ubw","0") && nvram_invmatch("qos_manual_ubw","")) 1059 { 1060 nvram_set("qos_ubw",nvram_get("qos_manual_ubw")); 1061 } 1062 else if(nvram_match("qos_ubw_tmp", "0")) 1063 { 1064 qos_get_wan_rate(); 1065 nvram_set("qos_ubw",nvram_get("qos_ubw_tmp")); 1066 } 1067 else 1068 nvram_set("qos_ubw", nvram_get("qos_ubw_tmp")); 1069#endif//*/ 1070// 2009.03 James. Mark these and put them into network.c. } 1071 1072// 2009.03 James. { 1073 /*if(nvram_match("qos_global_enable", "1") || nvram_match("qos_userdef_enable", "1")) 1074 { 1075 nvram_set("qos_enable", "1"); 1076 nvram_commit(); 1077 1078 if(nvram_invmatch("qos_ubw", "0")) 1079 { 1080 start_qos(); 1081 } 1082 } 1083 else{ 1084 nvram_set("qos_enable", "0"); 1085 nvram_commit(); 1086 }//*/ 1087 if(nvram_match("qos_enable", "1")) 1088 start_qos(); 1089// 2009.03 James. } 1090 1091 return 0; 1092} 1093#endif 1094 1095#ifdef MYGCC 1096int main(int argc, char** argv) 1097{ 1098 int i = 0; 1099 char *thisarg; 1100 1101 printf(" %-20s %-20s\n", "index", "value"); 1102 1103 while( i<argc ) { 1104 printf(" %-20d %-20s\n", i, argv[i]); 1105 i++; 1106 } 1107 1108 argc--; 1109 argv++; 1110 while( argc>0 && **argv=='-' ) { 1111 thisarg = *argv; 1112 thisarg++; 1113 switch (*thisarg) { 1114 case 'c': 1115 if (--argc <= 0) 1116 exit(1); 1117 argv++; 1118 pingcount = atoi(*argv); 1119 break; 1120 case 's': 1121 if (--argc <= 0) 1122 exit(1); 1123 argv++; 1124 datalen = atoi(*argv); 1125 break; 1126 default: 1127 exit(1); 1128 } 1129 argc--; 1130 argv++; 1131 } 1132 1133 if( argc<0 ) exit(1); 1134 1135 struct timeval deltaval; 1136 1137 deltatime(*argv, &deltaval); 1138 1139 printf("\n start time ** tv_sec=%u : tv_usec=%u\n",tstart.tv_sec, tstart.tv_usec); 1140 printf(" end time ** tv_sec=%u : tv_usec=%u\n", tend.tv_sec, tend.tv_usec); 1141 printf(" delta_sec=%u : delta_usec=%u\n", deltaval.tv_sec*1000000, deltaval.tv_usec); 1142 1143 double delta_us = 0; 1144 delta_us = (int)deltaval.tv_sec * 1000000 + deltaval.tv_usec; 1145 printf(" delta interval = %f us\n", delta_us); 1146 1147 double bw = ( (( (datalen+42)*pingcount*8 )/delta_us) )*1000000/1024; 1148 printf("\n bandwidth = %.0f kbps\n", bw); 1149 1150 return 0; 1151} 1152#endif 1153 1154#endif 1155