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]; // 2009.12 James. Directly use gateway_ip. 590 int j=0; 591 while(j<=9) 592 { 593 //memset(&get_ip[j], 0, sizeof(get_ip[j])); // 2009.12 James. 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 gateway_ip[i][j-1]=*p; // 2009.12 James. 626 j++; 627 } 628 //get_ip[i][j-2]='\0'; 629 gateway_ip[i][j-2]='\0'; // 2009.12 James. 630 } 631 i++; 632 633 } 634 /*i=0; // 2009.12 James. 635 while(i<10) 636 { 637 sprintf(gateway_ip[i],"%s",get_ip[i]); 638 i++; 639 }//*/ 640 } 641 fclose(fp); 642 return 1; 643} 644 645/************************************************************************** 646 * Function Name: qos_get_wan_rate 647 * Description : get the ADSL line rate 648 * Parameters : None 649 * Returns : Is successful when get the ADSL data rate? 650 0 : Success 651 1 : Link fail 652 **************************************************************************/ 653extern int qos_get_wan_rate(void) 654{ 655 static struct wan_link_rate wanrate; 656 char us[256], ds[256] ; 657 char * gw_ip=NULL; 658 struct timeval deltaval; 659 double delta_us = 0; 660 wanrate.us = wanrate.ds = 0; 661 int step=3; 662 char *ip = nvram_safe_get("wan_dns_t"); 663 int need_package=80; 664 if( !check_wan_link(0) ) 665 return WAN_LINK_FAIL; 666 667 gw_ip = get_gw_ip(); 668 669 if((strchr(ip, ' ')) ||(!strcmp(ip, ""))) 670 { 671 struct dns_lists *dns_list = get_dns_list(1); 672 int i; 673 674 for(i=0 ; i<dns_list->num_servers ; i++){ 675 ip = dns_list->dns_server[i]; 676 if( (!strchr(ip, ' ')) 677 && (strcmp(ip, "")) 678 && (strcmp(ip, gw_ip))) //WL600g auto assign LAN IP as DNS Server 679 break; 680 } 681 free(dns_list); 682 } 683 if( (strchr(ip, ' ')) || (!strcmp(ip, "")) || (!strcmp(ip, gw_ip)) ) { 684#ifdef QOS_DEBUG 685 printf(" qos_get_wan_rate() ** GET DNS IP Error\n"); 686#endif 687 nvram_set("qos_ubw_status", "fail"); 688 nvram_set("qos_ubw_reason", "DNS server fail"); 689 } 690 else 691 { 692 int choose=1; 693 choose=detect(); 694 if(choose==0) 695 { 696 return WAN_LINK_FAIL; 697 } 698 if(strlen(gateway_ip[step])!=0) 699 { 700 while(pre_ping(gateway_ip[step])==0) 701 { 702 if(step==9) 703 { 704 return WAN_LINK_FAIL; 705 } 706 step++; 707 while(strlen(gateway_ip[step])==0) 708 { 709 if(step==9) 710 { 711 return WAN_LINK_FAIL; 712 } 713 step++; 714 } 715 716 } 717 sleep(1); 718 loop:request_time=1; 719 int i=0; 720 while(i<=35) 721 { 722 triptime[i]=0; 723 i++; 724 } 725 //printf("gateway_ip[step]=%s\n",gateway_ip[step]); 726 while(request_time<36) 727 { 728 deltatime(gateway_ip[step], &deltaval); 729 usleep(10); 730 request_time++; 731 } 732 i=0; 733 while(triptime[i]!=0) 734 { 735 i++; 736 } 737 i=i-(i%3); 738 if(i>12) 739 { 740 switch(i) 741 { 742 case 15: 743 triptime[0]=(triptime[3]+triptime[4]+triptime[5])/3; 744 triptime[1]=(triptime[i-1]+triptime[i-2]+triptime[i-3])/3; 745 break; 746 case 18: 747 triptime[0]=(triptime[3]+triptime[4]+triptime[5])/3; 748 triptime[1]=(triptime[i-1]+triptime[i-2]+triptime[i-3])/3; 749 triptime[2]=(triptime[i-4]+triptime[i-5]+triptime[i-6])/3; 750 break; 751 case 21: 752 triptime[0]=(triptime[3]+triptime[4]+triptime[5])/3; 753 triptime[1]=(triptime[i-1]+triptime[i-2]+triptime[i-3])/3; 754 triptime[2]=(triptime[i-4]+triptime[i-5]+triptime[i-6])/3; 755 triptime[3]=(triptime[i-7]+triptime[i-8]+triptime[i-9])/3; 756 break; 757 case 24: 758 triptime[0]=(triptime[3]+triptime[4]+triptime[5])/3; 759 triptime[1]=(triptime[i-1]+triptime[i-2]+triptime[i-3])/3; 760 triptime[2]=(triptime[i-4]+triptime[i-5]+triptime[i-6])/3; 761 triptime[3]=(triptime[i-7]+triptime[i-8]+triptime[i-9])/3; 762 triptime[4]=(triptime[i-10]+triptime[i-11]+triptime[i-12])/3; 763 break; 764 case 27: 765 triptime[0]=(triptime[3]+triptime[4]+triptime[5])/3; 766 triptime[1]=(triptime[i-1]+triptime[i-2]+triptime[i-3])/3; 767 triptime[2]=(triptime[i-4]+triptime[i-5]+triptime[i-6])/3; 768 triptime[3]=(triptime[i-7]+triptime[i-8]+triptime[i-9])/3; 769 triptime[4]=(triptime[i-10]+triptime[i-11]+triptime[i-12])/3; 770 triptime[5]=(triptime[i-13]+triptime[i-14]+triptime[i-15])/3; 771 break; 772 default: 773 triptime[0]=(triptime[3]+triptime[4]+triptime[5])/3; 774 triptime[1]=(triptime[i-1]+triptime[i-2]+triptime[i-3])/3; 775 triptime[2]=(triptime[i-4]+triptime[i-5]+triptime[i-6])/3; 776 triptime[3]=(triptime[i-7]+triptime[i-8]+triptime[i-9])/3; 777 triptime[4]=(triptime[i-10]+triptime[i-11]+triptime[i-12])/3; 778 triptime[5]=(triptime[i-13]+triptime[i-14]+triptime[i-15])/3; 779 triptime[6]=(triptime[i-16]+triptime[i-17]+triptime[i-18])/3; 780 break; 781 782 } 783 if(i>=33) 784 { 785 int h=0; 786 for(h=0;h<=2;h++) 787 { 788 if(h==0) 789 { 790 need_package=80-15; 791 } 792 else 793 { 794 need_package=80-(h*2)-15; 795 } 796 wanrate.us=wanrate.us+((double)need_package*(datalen+46)*8/(triptime[h+2]-triptime[0])/1024*1000000); 797 int a=0; 798 a=(double)need_package*(datalen+46)*8/(triptime[h+2]-triptime[0])/1024*1000000; 799 printf("this package wanrateus=%d\n",a); 800 printf("finally wanrateus=%d\n",wanrate.us); 801 } 802 wanrate.us=wanrate.us/3; 803 printf("wanrate.us1=%d\n",wanrate.us); 804 if(wanrate.us>10500) 805 { 806 wanrate.us=10080; 807 } 808 809 } 810 else 811 { 812 int y=i; 813 y=(30-y)/3; 814 int h=1; 815 //i=30 need_package=80-15 816 //i=27 need_package=78-15 817 //i=24 need_package=76-15 818 //i=21 need_package=74-15 819 //i=18 need_package=72-15 820 //i=15 need_package=70-15 821 while(need_package>55) 822 { 823 need_package=80-(y*2)-15; 824 y=y+1; 825 h++; 826 wanrate.us=wanrate.us+((double)need_package*(datalen+46)*8/(triptime[h-1]-triptime[0])/1024*1000000); 827 //int a=0; 828 //a=(double)need_package*(datalen+46)*8/(triptime[h-1]-triptime[0])/1024*1000000; 829 //printf("a=%d\n",a); 830 //printf("wanrate.us%d\n",wanrate.us); 831 } 832 wanrate.us=wanrate.us/(h-1); 833 printf("wanrate.us2=%d\n",wanrate.us); 834 if(wanrate.us>10500) 835 { 836 wanrate.us=10080; 837 } 838 } 839 840 841 } 842 else 843 { 844 triptime[0]=(triptime[3]+triptime[4]+triptime[5])/3; 845 triptime[1]=(triptime[9]+triptime[10]+triptime[11])/3; 846 need_package=54-15; 847 wanrate.us = (double)need_package*(datalen+46)*8/(triptime[1]-triptime[0])/1024*1000000 ; 848 if(wanrate.us>10500) 849 { 850 wanrate.us=10080; 851 } 852 if(wanrate.us==0 && i==9) 853 { 854 triptime[0]=(triptime[3]+triptime[4]+triptime[5])/3; 855 triptime[1]=(triptime[6]+triptime[7]+triptime[8])/3; 856 need_package=29-15; 857 wanrate.us = (double)need_package*(datalen+46)*8/(triptime[1]-triptime[0])/1024*1000000*1.1 ; 858 if(wanrate.us>10500) 859 { 860 wanrate.us=10080; 861 } 862 } 863 if(wanrate.us==0 && i==6) 864 { 865 triptime[0]=(triptime[0]+triptime[1]+triptime[2])/3; 866 triptime[1]=(triptime[3]+triptime[4]+triptime[5])/3; 867 need_package=15-9; 868 wanrate.us = (double)need_package*(datalen+46)*8/(triptime[1]-triptime[0])/1024*1000000*1.1 ; 869 if(wanrate.us>10500) 870 { 871 wanrate.us=10080; 872 } 873 } 874 printf("wanrate.us3=%d\n",wanrate.us); 875 876 } 877 } 878 else 879 { 880 step--; 881 while(strlen(gateway_ip[step])==0) 882 { 883 if(step==0) 884 { 885 return WAN_LINK_FAIL; 886 } 887 step--; 888 } 889 while(pre_ping(gateway_ip[step])==0) 890 { 891 if(step==0) 892 { 893 return WAN_LINK_FAIL; 894 } 895 step--; 896 } 897 sleep(1); 898 goto loop; 899 } 900 } 901 free(gw_ip); 902 903 if( strcmp(nvram_safe_get("qos_ubw_status"), "fail") == 0 ) { 904#ifdef WL600g 905 if( !strcmp(nvram_safe_get("qos_ubw_reason"), "DNS server fail") ) 906 { 907 //DownStream 908 if ( glbAdslInfo.ulInterleavedDnStreamRate != 0 ) 909 wanrate.ds = glbAdslInfo.ulInterleavedDnStreamRate / 1000; 910 else 911 wanrate.ds = glbAdslInfo.ulFastDnStreamRate / 1000; 912 913 //UpStream 914 if ( glbAdslInfo.ulInterleavedUpStreamRate != 0 ) 915 wanrate.us = glbAdslInfo.ulInterleavedUpStreamRate / 1000; 916 else 917 wanrate.us = glbAdslInfo.ulFastUpStreamRate / 1000; 918 919 //sprintf(ds, "%u", wanrate.ds); 920 //nvram_set("wan_ds", ds); 921 sprintf(us, "%u", wanrate.us); 922 nvram_set("qos_ubw", us); 923 924 nvram_set("qos_ubw_status", "success"); 925 926 return WAN_RATE_SUCCESS; 927 } 928 else 929 return WAN_LINK_FAIL; 930#else 931 return WAN_LINK_FAIL; 932#endif 933 } 934 935#ifdef QOS_DEBUG 936 printf("\n start time ** tv_sec=%ld: tv_usec=%ld\n",tstart.tv_sec, tstart.tv_usec); 937 printf(" end time ** tv_sec=%ld : tv_usec=%ld\n", tend.tv_sec, tend.tv_usec); 938 printf(" delta_sec=%ld : delta_usec=%ld\n", deltaval.tv_sec*1000000, deltaval.tv_usec); 939#endif 940 printf("wanrate.us=%u\n\n",wanrate.us); 941 942 943 if( wanrate.us!=0 ) 944 nvram_set("qos_ubw_status", "success"); 945 946#ifdef QOS_DEBUG 947 printf("\nUpload Bandwidth = %.0u kbps\n", wanrate.us); 948#endif 949 950 wanrate.ds = 0; 951 sprintf(us, "%u", wanrate.us); 952 nvram_set("qos_ubw", us); 953 954 955 return WAN_RATE_SUCCESS; 956 957} 958 959#ifdef WL600g 960//************************************************************************** 961// Function Name: Speedtest_init 962// Description : init function, called by BcmNtwk_init() in ifcntwkapi.cpp 963// Returns : 0 964//************************************************************************** 965int Speedtest_init(void) { 966 FILE *fp; 967 968 /* Run it under background */ 969 switch (fork()) { 970 case -1: 971 exit(0); 972 break; 973 case 0: 974 // start in a new session 975 (void) setsid(); 976 break; 977 default: 978 // parent process should just die 979 return 0; 980 } 981 982 /* write pid */ 983 if ((fp=fopen("/var/run/speedtest.pid", "w"))!=NULL) 984 { 985 fprintf(fp, "%d", getpid()); 986 fclose(fp); 987 } 988 989 nvram_set("qos_ubw_status", "initialing"); 990 991 sleep(60); 992 if( nvram_match("qos_enable", "1") ) { 993 994 qos_get_wan_rate(); 995 if(nvram_match("qos_ubw_status", "success") ) 996 start_qos(); 997 } 998 999 while(1){ 1000 pause(); 1001 } 1002 1003 return 0; 1004} 1005#else 1006//extern void start_qos(void); 1007 1008int Speedtest_Init(void) { 1009 char net_name[32]; 1010 FILE *fp=NULL; 1011 1012 printf("*** run Speedtest_Init(). ***\n"); 1013 1014// 2009.03 James. Mark these and put them into network.c. { 1015/* nvram_set("qos_userspec_app", "0"); 1016 nvram_set("qos_global_enable", "0"); 1017 nvram_set("qos_userdef_enable", "0"); 1018 //nvram_set("qos_enable", "0"); 1019 1020 if(nvram_invmatch("qos_rulenum_x", "0")) 1021 nvram_set("qos_userspec_app", "1"); 1022 1023 //add by Angela 2008.05 1024 if(nvram_match("qos_tos_prio", "1")||nvram_match("qos_pshack_prio", "1") 1025 || nvram_match("qos_service_enable", "1")|| nvram_match("qos_shortpkt_prio", "1")) 1026 nvram_set("qos_global_enable", "1"); 1027 1028 if(nvram_match("qos_userspec_app", "1") || nvram_match("qos_dfragment_enable", "1")) 1029 nvram_set("qos_userdef_enable", "1");//*/ 1030// 2009.03 James. } 1031 1032 /* Get interface name */ 1033 if (nvram_match("wan0_proto", "pppoe") || nvram_match("wan0_proto", "pptp") || nvram_match("wan0_proto", "l2tp")) 1034 strcpy (net_name, nvram_safe_get("wan0_pppoe_ifname")); 1035 else 1036 strcpy (net_name, nvram_safe_get("wan0_ifname")); 1037 1038 /* Reset all qdisc first */ 1039 eval ("tc","qdisc","del", "dev", net_name, "root", "htb"); 1040 1041 /* Clean iptables*/ 1042 /*eval("iptables", "-F", "-t", "mangle");*/ 1043 if ((fp=fopen("/tmp/mangle_rules", "w"))==NULL) return 0; 1044 fprintf(fp, "*mangle\n"); 1045 fprintf(fp, "-F\n"); 1046 fprintf(fp, "COMMIT\n\n"); 1047 fclose(fp); 1048 eval("iptables-restore", "/tmp/mangle_rules"); 1049 1050// 2009.03 James. Mark these and put them into network.c. { 1051 /*if(nvram_invmatch("qos_manual_ubw","0") && nvram_invmatch("qos_manual_ubw","")) 1052 { 1053 nvram_set("qos_ubw",nvram_get("qos_manual_ubw")); 1054 } 1055 else if(nvram_invmatch("qos_ubw", "0")) 1056 nvram_set("qos_ubw",nvram_get("qos_ubw_tmp")); 1057 1058#if 0 1059 if(nvram_invmatch("qos_manual_ubw","0") && nvram_invmatch("qos_manual_ubw","")) 1060 { 1061 nvram_set("qos_ubw",nvram_get("qos_manual_ubw")); 1062 } 1063 else if(nvram_match("qos_ubw_tmp", "0")) 1064 { 1065 qos_get_wan_rate(); 1066 nvram_set("qos_ubw",nvram_get("qos_ubw_tmp")); 1067 } 1068 else 1069 nvram_set("qos_ubw", nvram_get("qos_ubw_tmp")); 1070#endif//*/ 1071// 2009.03 James. Mark these and put them into network.c. } 1072 1073// 2009.03 James. { 1074 /*if(nvram_match("qos_global_enable", "1") || nvram_match("qos_userdef_enable", "1")) 1075 { 1076 nvram_set("qos_enable", "1"); 1077 nvram_commit(); 1078 1079 if(nvram_invmatch("qos_ubw", "0")) 1080 { 1081 start_qos(); 1082 } 1083 } 1084 else{ 1085 nvram_set("qos_enable", "0"); 1086 nvram_commit(); 1087 }//*/ 1088 if(nvram_match("qos_enable", "1")) 1089 start_qos(); 1090// 2009.03 James. } 1091 1092 return 0; 1093} 1094#endif 1095 1096#ifdef MYGCC 1097int main(int argc, char** argv) 1098{ 1099 int i = 0; 1100 char *thisarg; 1101 1102 printf(" %-20s %-20s\n", "index", "value"); 1103 1104 while( i<argc ) { 1105 printf(" %-20d %-20s\n", i, argv[i]); 1106 i++; 1107 } 1108 1109 argc--; 1110 argv++; 1111 while( argc>0 && **argv=='-' ) { 1112 thisarg = *argv; 1113 thisarg++; 1114 switch (*thisarg) { 1115 case 'c': 1116 if (--argc <= 0) 1117 exit(1); 1118 argv++; 1119 pingcount = atoi(*argv); 1120 break; 1121 case 's': 1122 if (--argc <= 0) 1123 exit(1); 1124 argv++; 1125 datalen = atoi(*argv); 1126 break; 1127 default: 1128 exit(1); 1129 } 1130 argc--; 1131 argv++; 1132 } 1133 1134 if( argc<0 ) exit(1); 1135 1136 struct timeval deltaval; 1137 1138 deltatime(*argv, &deltaval); 1139 1140 printf("\n start time ** tv_sec=%u : tv_usec=%u\n",tstart.tv_sec, tstart.tv_usec); 1141 printf(" end time ** tv_sec=%u : tv_usec=%u\n", tend.tv_sec, tend.tv_usec); 1142 printf(" delta_sec=%u : delta_usec=%u\n", deltaval.tv_sec*1000000, deltaval.tv_usec); 1143 1144 double delta_us = 0; 1145 delta_us = (int)deltaval.tv_sec * 1000000 + deltaval.tv_usec; 1146 printf(" delta interval = %f us\n", delta_us); 1147 1148 double bw = ( (( (datalen+42)*pingcount*8 )/delta_us) )*1000000/1024; 1149 printf("\n bandwidth = %.0f kbps\n", bw); 1150 1151 return 0; 1152} 1153#endif 1154 1155#endif 1156