1#include <sys/socket.h> 2#include <sys/ioctl.h> 3#include <linux/if_packet.h> 4#include <stdio.h> 5//#include <linux/in.h> 6#include <linux/if_ether.h> 7#include <net/if.h> 8#include <string.h> 9#include <fcntl.h> 10#include <errno.h> 11#include <sys/time.h> 12#include <bcmnvram.h> 13#include "networkmap.h" 14 15#include <netinet/in.h> 16#include <arpa/inet.h> 17#include <stdlib.h> 18#include <unistd.h> 19#include <stdarg.h> 20#include <signal.h> 21#include <asm/byteorder.h> 22#include "iboxcom.h" 23#include "../shared/shutils.h" 24#ifdef RTCONFIG_NOTIFICATION_CENTER 25#include <libnt.h> 26#endif 27 28 29extern int scan_count;//from networkmap; 30extern FILE *fp_upnp; 31extern FILE *fp_smb; 32 33static char *strip_chars(char *str, char *reject); 34void interrupt(); 35int create_ssdp_socket_ctrlpt(char *ifname, ushort port); 36int create_http_socket_ctrlpt(char *host, ushort destport); 37int create_msearch_ctrlpt(int Mx); 38int process_device_response(char *msg); 39void store_description(char *msg); 40 41int ssdp_fd; 42int global_exit = FALSE; 43ushort return_value = FALSE; 44struct device_info description; 45 46UCHAR emptyname[2] = {0x00, 0x00}; 47char NetBIOS_name[16]={0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, 48 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20}; //for SMB NBSS request 49char SMB_OS[10]; 50char SMB_PriDomain[16]; 51 52void fixstr(const char *buf) 53{ 54 char *p; 55 int i; 56 57 p = (char *) buf; 58 59 for (i = 0; i < 16; i++) 60 { 61 if (*p < 0x21) 62 *p = 0x0; 63 if (i == 15) 64 *p = '\0'; 65 p++; 66 } 67 68 return; 69} 70 71/***** Http Server detect function *****/ 72int SendHttpReq(unsigned char *des_ip) 73{ 74 int getlen, sock_http; 75 struct sockaddr_in dest; 76 char buffer[512]; 77 char *dest_ip_ptr; 78 struct timeval tv1, tv2, timeout={1, 0}; 79 80 /* create socket */ 81 sock_http = socket(AF_INET, SOCK_STREAM, 0); 82 83 /* initialize value in dest */ 84 bzero(&dest, sizeof(dest)); 85 dest.sin_family = AF_INET; 86 dest.sin_port = htons(HTTP_PORT); 87 memcpy(&dest.sin_addr, des_ip, 4); 88 dest_ip_ptr = inet_ntoa(dest.sin_addr); 89 90 setsockopt(sock_http, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));//set connect timeout 91 setsockopt(sock_http, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));//set receive timeout 92 93 /* Connecting to server */ 94 if( connect(sock_http, (struct sockaddr*)&dest, sizeof(dest))== -1 ) 95 { 96 #ifdef DEBUG 97 perror("Http: connect"); 98 #endif 99 close(sock_http); 100 return 0 ; 101 } 102 103 sprintf(buffer, "GET / HTTP/1.1\r\nHost: %s\r\n\r\n", dest_ip_ptr); 104 105 if (send(sock_http, buffer, strlen(buffer), 0) == -1) 106 { 107 perror("send:"); 108 close(sock_http); 109 return 0 ; 110 } 111 112 gettimeofday(&tv1, NULL); 113 114 while(1) 115 { 116 bzero(buffer, 512); 117 getlen = recv(sock_http, buffer, sizeof(buffer), 0); 118 if (getlen > 0) 119 { 120 NMP_DEBUG_F("Check http response: %s\n", buffer); 121 if(!memcmp(buffer, "HTTP/1.", 7) && 122 (!memcmp(buffer+9, "2", 1)||!memcmp(buffer+9, "3", 1)||!memcmp(buffer+9, "401", 3)) ) 123 { 124 close(sock_http); 125 return 1; 126 } 127 } 128 129 gettimeofday(&tv2, NULL); 130 if( (((tv2.tv_sec)*1000000 + tv2.tv_usec)-((tv1.tv_sec)*1000000 + tv1.tv_usec)) > RCV_TIMEOUT*1000000 ) 131 { 132 NMP_DEBUG_F("Http receive timeout\n"); 133 break; 134 } 135 } 136 137 close(sock_http); 138 return 0; 139} 140 141/***** NBNS Name Query function *****/ 142int Nbns_query(unsigned char *src_ip, unsigned char *dest_ip, P_CLIENT_DETAIL_INFO_TABLE p_client_detail_info_tab, int i) 143{ 144 struct sockaddr_in my_addr, other_addr1, other_addr2; 145 int sock_nbns, status, sendlen, recvlen, retry=1, exit=0; 146 socklen_t other_addr_len1, other_addr_len2; 147 char sendbuf[50] = {0x87, 0x96, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 148 0x00, 0x00, 0x00, 0x00, 0x20, 0x43, 0x4b, 0x41, 149 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 150 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 151 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 152 0x41, 0x41, 0x41, 0x41, 0x41, 0x00, 0x00, 0x21, 153 0x00, 0x01}; 154 char recvbuf[512] = {0}; 155 char *other_ptr; 156 NBNS_RESPONSE *nbns_response; 157 struct timeval timeout={1, 500}; 158 int lock; 159 160 memset(NetBIOS_name, 0x20, 16); 161 162 sock_nbns = socket(AF_INET, SOCK_DGRAM, 0); 163 if (-1 == sock_nbns) 164 { 165 NMP_DEBUG_F("NBNS: socket error.\n"); 166 return -1; 167 } 168 memset(&my_addr, 0, sizeof(my_addr)); 169 my_addr.sin_family = AF_INET; 170 my_addr.sin_port = htons(NBNS_PORT); // my port 171 memcpy(&my_addr.sin_addr, src_ip, 4); 172 173 //2011.02 Yau add to fix bind error 174 int flag=1; 175 setsockopt(sock_nbns, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag)); 176 status = bind(sock_nbns, (struct sockaddr *)&my_addr, sizeof(my_addr)); 177 if (-1 == status) 178 { 179 NMP_DEBUG_F("NBNS: bind error.\n"); 180 return -1; 181 } 182 183 setsockopt(sock_nbns, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));//set timeout 184 memset(&other_addr1, 0, sizeof(other_addr1)); 185 other_addr1.sin_family = AF_INET; 186 other_addr1.sin_port = htons(NBNS_PORT); // other port 187 memcpy(&other_addr1.sin_addr, dest_ip, 4); // other ip 188 other_ptr = inet_ntoa(other_addr1.sin_addr); 189 other_addr_len1 = sizeof(other_addr1); 190 191 while(1) 192 { 193 sendlen = sendto(sock_nbns, sendbuf, sizeof(sendbuf), 0, (struct sockaddr*)&other_addr1, other_addr_len1); 194 195 bzero(recvbuf, 512); 196 memset(&other_addr2, 0, sizeof(other_addr2)); 197 other_addr_len2 = sizeof(other_addr2); 198 199 recvlen = recvfrom(sock_nbns, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&other_addr2, &other_addr_len2); 200 if( recvlen > 0 ) { 201 NMP_DEBUG_F("NBNS Response:\n"); 202 #if 0 //def DEBUG_MORE 203 int x; 204 for(x=0; x<recvlen; x++) 205 NMP_DEBUG_F("%02x ",recvbuf[x]); 206 NMP_DEBUG_F("\n"); 207 #endif 208 209 nbns_response =(NBNS_RESPONSE *)recvbuf; 210 NMP_DEBUG_F("flags: %02x %02x, number of names= %d\n", 211 nbns_response->flags[0],nbns_response->flags[1],nbns_response->number_of_names); 212 if( nbns_response->number_of_names ==0 ) { 213 exit++; //Not support NBNS name query 214 if( exit==6 ) 215 break; 216 } 217 else 218 if(((nbns_response->flags[0]>>4) == 8) && (nbns_response->number_of_names > 0) 219 && (other_addr2.sin_addr.s_addr = other_addr1.sin_addr.s_addr)) 220 { 221 lock = file_lock("networkmap"); 222 memcpy(p_client_detail_info_tab->device_name[i], nbns_response->device_name1, 16); 223 fixstr(p_client_detail_info_tab->device_name[i]); 224 file_unlock(lock); 225 memcpy(NetBIOS_name, nbns_response->device_name1, 15); 226 NMP_DEBUG_F("Device name:%s~%s~\n", nbns_response->device_name1, 227 p_client_detail_info_tab->device_name[i]); 228 break; 229 } 230 else 231 { 232 exit++; //Not support NBNS name query 233 if( exit==6 ){ 234 NMP_DEBUG_F("Unknown error!\n"); 235 break; 236 } 237 } 238 } 239 else 240 { 241 retry++; 242 if( retry==3 ) 243 { 244 NMP_DEBUG_F("NBNS timeout...\n"); 245 break; 246 } 247 } 248 sleep(2); //2008.09.16 Yau add 249 } 250 close(sock_nbns); 251 NMP_DEBUG_F("NBNS close socket\n"); 252 return 0; 253} 254 255/***** Printer server detect function *****/ 256int lpd515(unsigned char *dest_ip) 257{ 258 struct sockaddr_in other_addr1; 259 int sockfd1, sendlen1, recvlen1; 260 char sendbuf1[34] = {0}; 261 char recvbuf1[MAXDATASIZE]; 262 struct timeval tv1, timeout={1, 0}; 263 struct LPDProtocol lpd; 264 265 if ((sockfd1 = socket(AF_INET, SOCK_STREAM, 0)) == -1) 266 { 267 NMP_DEBUG_F("LPD515: socket create error.\n"); 268 return -1; 269 } 270 271 memset(&other_addr1, 0, sizeof(other_addr1)); 272 other_addr1.sin_family = AF_INET; 273 other_addr1.sin_port = htons(LPD_PORT); 274 memcpy(&other_addr1.sin_addr, dest_ip, 4); 275 276 setsockopt(sockfd1, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); 277 setsockopt(sockfd1, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); 278 279 if (connect(sockfd1, (struct sockaddr*)&other_addr1, sizeof(other_addr1)) == -1) 280 { 281 NMP_DEBUG_F("LPD515: socket connect failed!\n"); 282 return -1; 283 } 284 285 /* Send data... */ 286 lpd.cmd_code = LPR; 287 strlcpy(lpd.options, MODEL_NAME, sizeof(lpd.options)); // Set the queue name as you wish 288 lpd.lf = 0x0a; 289 sprintf(sendbuf1, "%c%s%c", lpd.cmd_code, lpd.options, lpd.lf); 290 if ((sendlen1 = send(sockfd1, sendbuf1, strlen(sendbuf1), 0)) == -1) 291 { 292 NMP_DEBUG_F("LPD515: Send packet failed!\n"); 293 return -1; 294 } 295 gettimeofday(&tv1, NULL); 296 297 /* Receive data */ 298 recvlen1 = recv(sockfd1, recvbuf1, MAXDATASIZE, 0); 299 memcpy(&lpd, recvbuf1, 1); 300 if (lpd.cmd_code == LPR_RESPONSE) 301 { 302 close(sockfd1); 303 return 0; 304 } 305 306 close(sockfd1); 307 return -1; 308} 309 310int raw9100(unsigned char *dest_ip) 311{ 312 struct sockaddr_in other_addr2; 313 int sockfd2; 314 struct timeval timeout={0, 500000}; 315 if ((sockfd2 = socket(AF_INET, SOCK_STREAM, 0)) == -1) 316 { 317 NMP_DEBUG_F("RAW9100: socket create error.\n"); 318 return -1; 319 } 320 321 322 memset(&other_addr2, 0, sizeof(other_addr2)); 323 other_addr2.sin_family = AF_INET; 324 other_addr2.sin_port = htons(RAW_PORT); 325 memcpy(&other_addr2.sin_addr, dest_ip, 4); 326 327 setsockopt(sockfd2, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); 328 329 if (connect(sockfd2, (struct sockaddr*)&other_addr2, sizeof(other_addr2)) == -1) 330 { 331 NMP_DEBUG_F("RAW9100: socket connect failed!\n"); 332 close(sockfd2); 333 return -1; 334 } 335 336 close(sockfd2); 337 return 0; 338} 339 340/***** iTune Server detect function *****/ 341static int waitsock(int sockfd, int sec, int usec) 342{ 343 struct timeval tv; 344 fd_set fdvar; 345 int res; 346 347 FD_ZERO(&fdvar); 348 FD_SET(sockfd, &fdvar); 349 tv.tv_sec = sec; 350 tv.tv_usec = usec; 351 res = select(sockfd + 1, &fdvar, NULL, NULL, &tv); 352 353 return res; 354} 355 356int open_socket_ipv4( unsigned char *src_ip ) 357{ 358 struct sockaddr_in local; 359 int fd = -1, ittl; 360 unsigned char ttl; 361 362 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 363 { 364 //printf("socket() failed: %s\n", strerror(errno)); 365 goto fail; 366 } 367 ttl = 255; 368 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) 369 { 370 //printf("IP_MULTICAST_TTL failed: %s\n", strerror(errno)); 371 goto fail; 372 } 373 ittl = 255; 374 if (setsockopt(fd, IPPROTO_IP, IP_TTL, &ittl, sizeof(ittl)) < 0) 375 { 376 //printf("IP_TTL failed: %s\n", strerror(errno)); 377 goto fail; 378 } 379 //select local ip address used to send the multicast packet, 380 //for router its the lan interface's ip. 381 struct in_addr any; 382 memcpy(&any, src_ip, 4); 383 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &any, sizeof(struct in_addr)) < 0) 384 { 385 //printf("IP_MULTICAST_IF failed: %s\n", strerror(errno)); 386 return -1; 387 } 388 /* Set timeout. Cherry Cho added in 2009/2/20. */ 389 struct timeval timeout={1, 0}; 390 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) 391 { 392 NMP_DEBUG_F("SO_RCVTIMEO failed: %s\n", strerror(errno)); 393 return -1; 394 } 395 396 memset(&local, 0, sizeof(local)); 397 local.sin_family = AF_INET; 398 local.sin_port = 0; 399 400 //2011.02 Yau add to fix bind error 401 int flag=1; 402 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag)) < 0) 403 { 404 NMP_DEBUG_F("SO_REUSEADDR failed: %s\n", strerror(errno)); 405 return -1; 406 } 407 if(bind(fd, (struct sockaddr*) &local, sizeof(local)) < 0) 408 { 409 //printf("Bind failed: %s\n", strerror(errno)); 410 goto fail; 411 } 412 return fd; 413 414fail: 415 if (fd >= 0) 416 close(fd); 417 418 return -1; 419} 420 421void dns_decode_servername(char *name, char **buf) 422{ 423 int k, len, j; 424 425 k = 0; 426 len = *(*buf)++; 427 for( j = 0; j<len ; j++) 428 name[k++] = *(*buf)++; 429 name[k++] = 0; 430} 431 432int dns_construct_name(char *name, char *encoded_name) 433{ 434 int i,j,k,n; 435 436 k = 0; /* k is the index to temp */ 437 i = 0; /* i is the index to name */ 438 while( name[i] ) 439 { 440 /* find the dist to the next '.' or the end of the string and add it*/ 441 for( j = 0; name[i+j] && name[i+j] != '.'; j++); 442 encoded_name[k++] = j; 443 /* now copy the text till the next dot */ 444 for( n = 0; n < j; n++) 445 encoded_name[k++] = name[i+n]; 446 /* now move to the next dot */ 447 i += j + 1; 448 /* check to see if last dot was not the end of the string */ 449 if(!name[i-1]) 450 break; 451 } 452 encoded_name[k++] = 0; 453 454 return k; 455} 456 457static int dns_decode_respond(dns_header_s header,char * buf,int numread) 458{ 459 char *buf_ip; 460 buf_ip=buf; 461 SET_UINT16( header.id, buf ); 462 if(header.id == 0x0086) 463 { 464 return 1; 465 } 466 else 467 { 468 return -1; 469 } 470} 471 472int send_mdns_packet_ipv4 (unsigned char *src_ip, unsigned char *dest_ip) 473{ 474 struct sockaddr_in dst_addr,from; 475 char dnsbuf[MAXDATASIZE]; 476 int dnsbuflen; 477 int sockfd; 478 479 if((sockfd=open_socket_ipv4(src_ip))<0) 480 { 481 //printf("creat socket fail\n"); 482 return -1; 483 } 484 485 memset(&dst_addr, 0, sizeof(struct sockaddr_in)); 486 dst_addr.sin_family = AF_INET; 487 dst_addr.sin_port = htons(MDNS_PORT); 488 //inet_pton(AF_INET, IPV4_MCAST_GROUP, &dst_addr.sin_addr); 489 memcpy(&dst_addr.sin_addr, dest_ip, 4); 490 491 dnsbuflen = 0; 492 493 dnsbuf[dnsbuflen++] = 0x00; //Transaction ID 494 dnsbuf[dnsbuflen++] = 0x86; 495 dnsbuf[dnsbuflen++] = 0x01; //Flag: Standard query 496 dnsbuf[dnsbuflen++] = 0x00; 497 dnsbuf[dnsbuflen++] = 0x00; //Question 498 dnsbuf[dnsbuflen++] = 0x01; 499 memset(&dnsbuf[dnsbuflen], 0x00, 6);//Answer RRs, Authority RRs, Additional RRs 500 dnsbuflen+=6; 501 dnsbuflen+=dns_construct_name(PROTOCOL_NAME, &dnsbuf[dnsbuflen]); 502 dnsbuf[dnsbuflen++] = 0x00; // Type: PTR 503 dnsbuf[dnsbuflen++] = 0x0c; 504 dnsbuf[dnsbuflen++] = 0x00; // Class : inet 505 dnsbuf[dnsbuflen++] = 0x01; 506 507 if(sendto(sockfd , dnsbuf, dnsbuflen , 0 ,(struct sockaddr *) &dst_addr, sizeof(dst_addr)) == -1) 508 { 509 //perror("sendto\n"); 510 goto finish; 511 } 512 513 while(1) 514 { 515 if (waitsock(sockfd, RCV_TIMEOUT, 0) == 0) 516 { 517 //perror("timeout\n"); 518 goto finish; 519 } 520 int numread,fromlen; 521 fromlen = sizeof(from); 522 char recv_buf[MAXDATASIZE]; 523 524 if ((numread=recvfrom(sockfd, recv_buf, sizeof(recv_buf), 0, NULL, &fromlen)) == -1) 525 { 526 //perror("recvfrom\n"); 527 continue; 528 } 529 dns_header_s header; 530 531 if (numread<sizeof(header)) 532 { 533 //perror("invalid packet\n"); 534 continue; 535 } 536 537 if(dns_decode_respond(header,recv_buf,numread)==-1) 538 { 539 continue; 540 } 541 else //Found iTune Server 542 { 543 return 1; 544 } 545 } 546finish: 547 close(sockfd); 548 return 0; 549} 550/***** End of iTune Server detection function *****/ 551 552/************** UPNP Detect Function ****************/ 553int ctrlpt(unsigned char *dest_ip) 554{ 555 fd_set rfds; 556 char ifname[] = INTERFACE; 557 ushort port = 1008; 558 struct sockaddr_in destaddr; 559 int nbytes, addrlen; 560 char buf[UPNP_BUFSIZE]; 561 int n; 562 563 if((ssdp_fd = create_ssdp_socket_ctrlpt(ifname, port)) == -1) 564 return 0; 565 566 create_msearch_ctrlpt(3); 567 signal(SIGALRM, interrupt); 568 alarm(4); 569 570 global_exit = FALSE; //reset timeout flag 571 memset(&description, 0, sizeof(struct device_info)); //reset description 572 573 //enter the top of the loop. 574 while(global_exit == FALSE) 575 { 576 addrlen = sizeof(destaddr); 577 memset(&destaddr, 0, addrlen); 578 579 FD_ZERO(&rfds); 580 FD_SET(ssdp_fd, &rfds); 581 582 n = select(ssdp_fd+1, &rfds, NULL, NULL, NULL); 583 if(n > 0) 584 { 585 if(FD_ISSET(ssdp_fd, &rfds)) 586 { 587 nbytes = recvfrom(ssdp_fd, buf, sizeof(buf), 0, (struct sockaddr*)&destaddr, &addrlen); 588 buf[nbytes] = '\0'; 589 590 //NMP_DEBUG_F("recv: %d from: %s\n", nbytes, inet_ntoa(destaddr.sin_addr)); 591 if( !memcmp(&destaddr.sin_addr, dest_ip, 4) ) 592 { 593 if(MATCH_PREFIX(buf, "HTTP/1.1 200 OK")) 594 { 595 global_exit = TRUE; 596 process_device_response(buf); 597 return_value = TRUE; 598 } 599 } 600 } 601 } 602 } 603 close(ssdp_fd); 604 if(return_value == FALSE) 605 return 0; 606 607 return 1; 608} 609 610 611/*******************************************************************************************/ 612static char *strip_chars(char *str, char *reject) 613{ 614 char *end; 615 616 str += strspn(str, reject); 617 end = &str[strlen(str)-1]; 618 while (end > str && strpbrk(end, reject)) 619 *end-- = '\0'; 620 621 return str; 622} 623 624void interrupt() 625{ 626 global_exit = TRUE; 627 NMP_DEBUG_F("no upnp device of this ip\n"); 628 return_value = FALSE; 629} 630 631/*****************************************************************************************/ 632// create socket of ssdp 633// socket, bind, join multicast group. 634int create_ssdp_socket_ctrlpt(char *ifname, ushort port) 635{ 636 int fd; 637 int sockfd; 638 struct sockaddr_in srcaddr; 639 struct in_addr inaddr; 640 struct ifreq ifreq; 641 struct ip_mreqn mcreqn; 642 int flag; 643 u_char ttl; 644 645 // create socket 646 if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 647 goto error; 648 649 // get the src ip 650 if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 651 goto error; 652 strlcpy(ifreq.ifr_name, ifname, sizeof(ifreq.ifr_name)); 653 if(ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0) 654 { 655 close(sockfd); 656 goto error; 657 } 658 memcpy(&inaddr, &(((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr),sizeof(struct in_addr)); 659 close(sockfd); 660 661 // make sure this interface is capable of MULTICAST ... 662 memset(&ifreq, 0, sizeof(ifreq)); 663 strlcpy(ifreq.ifr_name, ifname, sizeof(ifreq.ifr_name)); 664 if(ioctl(fd, SIOCGIFFLAGS, (int) &ifreq)) 665 goto error; 666 if((ifreq.ifr_flags & IFF_MULTICAST) == 0) 667 goto error; 668 669 // bind the socket to an address and port. 670 flag = 1; 671 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag)); 672 memset(&srcaddr, 0, sizeof(srcaddr)); 673 srcaddr.sin_addr = inaddr; 674 srcaddr.sin_family = AF_INET; 675 srcaddr.sin_port = htons(port); 676 if ( bind(fd, (struct sockaddr *) &srcaddr, sizeof(srcaddr)) ) 677 goto error; 678 679 // join the multicast group 680 memset(&ifreq, 0, sizeof(ifreq)); 681 strlcpy(ifreq.ifr_name, ifname, sizeof(ifreq.ifr_name)); 682 if(ioctl(fd, SIOCGIFINDEX, &ifreq)) 683 goto error; 684 685 memset(&mcreqn, 0, sizeof(mcreqn)); 686 mcreqn.imr_multiaddr.s_addr = inet_addr(SSDP_IP); 687 mcreqn.imr_address.s_addr = srcaddr.sin_addr.s_addr; 688 mcreqn.imr_ifindex = ifreq.ifr_ifindex; 689 if(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcreqn, sizeof(mcreqn))) 690 goto error; 691 692 // restrict multicast messages sent on this socket 693 // to only go out this interface and no other 694 if(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (char *)&srcaddr.sin_addr, sizeof(struct in_addr))) 695 goto error; 696 697 // set the multicast TTL 698 ttl = 4; 699 if(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl))) 700 goto error; 701 702 return fd; 703error: 704 close(fd); 705 return -1; 706} 707 708/****************************************************************************************/ 709//construct the multicast address and send out the M-SEARCH advertisement packets. 710int create_msearch_ctrlpt(int Mx) 711{ 712 struct sockaddr_in addr; 713 char *data; 714 char tmp[50]; 715 716 addr.sin_family = AF_INET; 717 addr.sin_addr.s_addr = inet_addr(SSDP_IP); 718 addr.sin_port = htons(SSDP_PORT); 719 720 if(Mx < MIN_SEARCH_TIME) 721 Mx = MIN_SEARCH_TIME; 722 if(Mx >MAX_SEARCH_TIME) 723 Mx = MAX_SEARCH_TIME; 724 725 data = (char *)malloc(300 * sizeof(char)); 726 *data = '\0'; 727 sprintf(tmp, "M-SEARCH * HTTP/1.1\r\n"); 728 strcat(data, tmp); 729 sprintf(tmp, "HOST:%s:%d\r\n", SSDP_IP, SSDP_PORT); 730 strcat(data, tmp); 731 sprintf(tmp, "ST:upnp:rootdevice\r\n"); 732 strcat(data, tmp); 733 sprintf(tmp, "MAN:\"ssdp:discover\"\r\n"); 734 strcat(data, tmp); 735 sprintf(tmp, "MX:%d\r\n\r\n", Mx); 736 strcat(data, tmp); 737 738 if(sendto(ssdp_fd, data, strlen(data), 0, (struct sockaddr *)&addr, sizeof(addr)) <0) 739 return 0; 740 741 return 1; 742 743} 744 745/************************************************************************************************/ 746// process the device response "HTTP/1.1 200 OK" 747int process_device_response(char *msg) 748{ 749 char *line, *body, *p; // temporary variables 750 char *location = NULL; // the LOCATION: header 751 char host[16], port[6]; // the ip and port of the device 752 ushort destport; // the integer type of device port 753 char *data = NULL; // the data in packet 754 int http_fd; // the http socket fd 755 int nbytes; // recv number 756 int i; 757 char *descri = NULL; 758 int len; 759 struct timeval timeout={10, 0}; 760 761 //search "\r\n\r\n" or "\r\n" first appear place and judge whether msg have blank. 762 if( (body = strstr(msg, "\r\n\r\n")) != NULL) 763 body +=4; 764 else if ( (body = strstr(msg, "\r\n")) != NULL) 765 body +=2; 766 else 767 return 0; 768 769 p = msg; 770 // find the LOCATION information. 771 while( p!= NULL && p < body) 772 { 773 line = strsep(&p, "\r\n"); //divide up string 774 if((strncmp(line, "LOCATION:", 9) == 0) || (strncmp(line, "Location:", 9) == 0)) 775 { 776 location = strip_chars(&line[9], "\t"); 777 location = strip_chars(&line[9], " "); 778 break; 779 } 780 } 781 NMP_DEBUG_F("UPnP location=%s\n", location); 782 //fprintf(fp_upnp, "UPnP location=%s\n", location);//Yau 783 // get the destination ip 784 location += 7; 785 i = 0; 786 while( (*location != ':') && (*location != '/')) { 787 host[i] = *location++; 788 i++; 789 } 790 host[i] = '\0'; 791 //get the destination port 792 if(*location == ':') { 793 for(location++, i =0; *location != '/'; i++) 794 port[i] = *location++; 795 port[i] = '\0'; 796 destport = (ushort)atoi(port); 797 } 798 else 799 destport = 80; 800 801 //create a socket of http 802 if ( (http_fd = create_http_socket_ctrlpt(host, destport)) == -1) 803 goto error; 804 805 //set the send data information. 806 data = (char *)malloc(1500 * sizeof(char)); 807 memset(data, 0, 1500); 808 *data = '\0'; 809 sprintf(data, "GET %s HTTP/1.1\r\nHOST: %s:%s\r\nACCEPT-LANGUAGE: zh-cn\r\n\r\n",\ 810 location, host, port); 811 //printf("%s\n",data); 812 813 //send the request to get the device description 814 if((nbytes = send(http_fd, data, strlen(data), 0)) == -1) 815 goto error; 816 free(data); 817 data = (char *)malloc(1501 * sizeof(char)); 818 memset(data, 0, 1501); 819 *data = '\0'; 820 descri = (char *) malloc(6001*sizeof(char)); 821 memset(descri, 0, 6001); 822 *descri ='\0'; 823 824 //receive data of http socket 825 len = 0; 826 setsockopt(http_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)); 827 while((nbytes = recv(http_fd, data,1500, 0)) > 0) 828 { 829 len += nbytes; 830 if(len > 6000) 831 break; 832 data[nbytes] ='\0'; 833 strcat(descri, data); 834 } 835 //printf("%s\n", descri); 836 //printf("len = %d", len); 837 //if(fp_upnp!=NULL) 838 // fprintf(fp_upnp, "%s\n\n", descri);//Yau 839 840 //store the useful information. 841 store_description(descri); 842 843 free(descri); 844 free(data); 845 return 1; 846error: 847 http_fd = -1; 848 free(data); 849 free(descri); 850 return 0; 851} 852 853/*******************************************************************************************/ 854//create a socket of http 855int create_http_socket_ctrlpt(char *host, ushort destport) 856{ 857 struct sockaddr_in destaddr; // the device address information 858 int fd; 859 860 NMP_DEBUG_F("UPnP create http socket to: %s:%d\n", host,destport); 861 // create out http socket 862 if((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) 863 return -1; 864 865 //set the tcp connect destination information 866 destaddr.sin_addr.s_addr = inet_addr(host); 867 destaddr.sin_family = AF_INET; 868 destaddr.sin_port = htons(destport); 869 870 //connect to the device. 871 if(connect(fd, (struct sockaddr *)&destaddr, sizeof(destaddr)) == -1) 872 return -1; 873 874 return fd; 875 876} 877 878/***************************************************************/ 879// store the descirption information to sturct device_info. 880void store_description(char *msg) 881{ 882 char line[200], *body, *p, *mxend; 883 char tmp[200]; 884 int i, j; 885 int s_num = 0; 886 int type = 0; 887 char *opts[] = {"<friendlyName>","<manufacturer>", "<presentationURL>", 888 "<modelDescription>", "<modelName>", "<modelNumber>", 889 "<serviceType>", "<SCPDURL>", 890 }; 891 // pointer to the end of msg 892 p = strstr(msg, "<?xml"); 893 //printf("%s", p); 894 body = strstr(msg, "</root>"); 895 896 while( p!= NULL && p < body) 897 { 898 // get rid of 'TAB' or 'Space' in the start of a line. 899 while((*p == '\r' || *p == '\n' || *p == '\t' || *p == ' ') && p < body) 900 p ++; 901 902 // get a line. 903 i = 0; 904 while(*p != '>' && p < body) 905 { 906 if(i<199) 907 line[i++] = *p++; 908 else 909 *p++; 910 } 911 if(p == body) 912 { 913 //printf("end of the data\n"); 914 break; 915 } 916 917 line[i++] = *p++; 918 line[i] ='\0'; 919 920 if(p == body) 921 { 922 //printf("end of the data 2\n"); 923 break; 924 } 925 926 // judge whether this line is useful. 927 for(type = 0; type< sizeof(opts)/sizeof(*opts); type++) 928 if(strncmp(line, opts[type], strlen(opts[type])) == 0) 929 break; 930 if(type == sizeof(opts)/sizeof(*opts)) 931 continue; 932 933 // get the information. 934 // eg. <manufacturer> information </manufacturer> 935 i = 0; 936 while(*p != '>' && p < body) 937 { 938 if(i<199) 939 line[i++] = *p++; 940 else 941 *p++; 942 } 943 line[i++] = *p++; 944 line[i] ='\0'; 945 946 for(j =0; line[j] != '<'; j++) 947 tmp[j] = line[j]; 948 tmp[j] = '\0'; 949 //printf("tmp = %s\n", tmp); 950 951 switch(type) 952 { 953 case 0: 954 strlcpy(description.friendlyname, tmp, sizeof(description.friendlyname)); 955 NMP_DEBUG_F("friendlyname = %s\n", tmp); 956#ifdef NMP_DEBUG_F 957 if(strstr(tmp, "WDTVLive")) { 958 FILE *fp = fopen("/var/networkmap.upnp", "w"); 959 if(fp != NULL) { 960 fprintf(fp, "%s", msg); 961 fclose(fp); 962 } 963 } 964#endif 965 break; 966 case 1: 967 strlcpy(description.manufacturer, tmp, sizeof(description.manufacturer)); 968 NMP_DEBUG_F("manufacturer = %s\n", tmp); 969 break; 970 case 2: 971 strlcpy(description.presentation, tmp, sizeof(description.presentation)); 972 NMP_DEBUG_F("presentation = %s\n", tmp); 973 break; 974 case 3: 975 strlcpy(description.description, tmp, sizeof(description.description)); 976 NMP_DEBUG_F("description = %s\n", tmp); 977 break; 978 case 4: 979 strlcpy(description.modelname, tmp, sizeof(description.modelname)); 980 NMP_DEBUG_F("modelname = %s\n", tmp); 981 break; 982 case 5: 983 strlcpy(description.modelnumber, tmp, sizeof(description.modelnumber)); 984 NMP_DEBUG_F("modelnumber = %s\n", tmp); 985 break; 986 case 6: // tmp="urn:schemas-upnp-org:service:serviceType:v" 987 mxend = tmp; 988 i = 0; j = 0; 989 while(i != 4) 990 { 991 if(i == 3) 992 tmp[j++] = *mxend; 993 if(*mxend == ':') 994 i++; 995 mxend++; 996 } 997 tmp[j-1] = '\0'; 998 strlcpy(description.service[s_num].name, tmp, sizeof(description.service)); 999 NMP_DEBUG_F("service %d name = %s\n", s_num, tmp); 1000 break; 1001 case 7: 1002 strlcpy(description.service[s_num].url, tmp, sizeof(description.service[s_num].url)); 1003 NMP_DEBUG_F("service %d url = %s\n", s_num, tmp); 1004 s_num++; 1005 break; 1006 } 1007 } 1008 description.service_num = s_num; 1009} 1010/***** End of UPNP Detect Function *****/ 1011 1012/************* SMB Function ************/ 1013// 0xAB, 0xA+41,0xB+41 1014int EncodeName(unsigned char *name, unsigned char *buffer, unsigned short length) 1015{ 1016 int i; 1017 buffer[0] = 0x20; 1018 buffer[length*2+1] = 0x00; 1019 for (i = 0; i < length; i++) 1020 { 1021 buffer[i*2+1] = ((name[i] & 0xF0)>>4) +65; 1022 buffer[i*2+2] = (name[i] & 0x0F) + 65; 1023 } 1024 return length*2+2; 1025} 1026 1027int TranUnicode(UCHAR *uni, UCHAR *asc, USHORT length) 1028{ 1029 int i; 1030 for (i=0; i<length; i++) 1031 { 1032 uni[i*2] = asc[i]; 1033 uni[i*2+1] = 0x00; 1034 } 1035 return length*2; 1036} 1037 1038int SendSMBReq(UCHAR *des_ip, MY_DEVICE_INFO *my_info) 1039{ 1040 int sockfd, numbytes; 1041 int i, j, operate; 1042 unsigned char buf[MAXDATASIZE] ; 1043 char ptr[32]; 1044 struct sockaddr_in des_addr; 1045 struct hostent *hptr; 1046 struct in_addr *hipaddr; 1047 fd_set rfds; 1048 int ret; 1049 struct timeval tv1, tv2, tm; 1050 int error=-1, len; 1051 len = sizeof(int); 1052 UCHAR securitymode; 1053 UCHAR WordCount; // Count of parameter words 1054 USHORT ParameterWords[1024]; // The parameter words 1055 USHORT ByteCount; // Count of bytes 1056 UCHAR Buffer[1024]; // The bytes 1057 int offsetlen = 0; 1058 USHORT tmplen = 0, tmplen2, tmplen3; 1059 int pos1, pos2, pos3, slip; 1060 int smbretry_flag = 0; 1061 1062 unsigned char nbss_buf[4]; 1063 unsigned char nbss_header[4] = {0x81, 0x00, 0x00, 0x44}; 1064 1065 UCHAR des_nbss_name[34]; 1066 UCHAR my_nbss_name[34]; 1067 UCHAR smb_buf[98] = { 1068 0x02, 0x50, 0x43, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x20, 0x50, 0x52, 0x4f, 0x47, 1069 0x52, 0x41, 0x4d, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02, 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x31, 1070 0x2e, 0x30, 0x00, 0x02, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 1071 0x57, 0x6f, 0x72, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x20, 0x33, 0x2e, 0x31, 0x61, 0x00, 1072 0x02, 0x4c, 0x4d, 0x31, 0x2e, 0x32, 0x58, 0x30, 0x30, 0x32, 0x00, 0x02, 0x4c, 0x41, 0x4e, 0x4d, 1073 0x41, 0x4e, 0x32, 0x2e, 0x31, 0x00, 0x02, 0x4e, 0x54, 0x20, 0x4c, 0x4d, 0x20, 0x30, 0x2e, 0x31, 1074 0x32, 0x00}; 1075 UCHAR sessionX_buf[204] = { 1076 0x0c, 0xff, 0x00, 0xec, 0x00, 0x04, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 1077 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0xa0, 0xb1, 0x00, 0x60, 0x48, 0x06, 0x06, 0x2b, 1078 0x06, 0x01, 0x05, 0x05, 0x02, 0xa0, 0x3e, 0x30, 0x3c, 0xa0, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 1079 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa2, 0x2a, 0x04, 0x28, 0x4e, 0x54, 0x4c, 1080 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x97, 0x82, 0x08, 0xe2, 0x00, 0x00, 0x00, 1081 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0x28, 1082 0x0a, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x57, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x6f, 0x00, 1083 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x32, 0x00, 0x20, 0x00, 1084 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 1085 0x50, 0x00, 0x61, 0x00, 0x63, 0x00, 0x6b, 0x00, 0x20, 0x00, 0x32, 0x00, 0x20, 0x00, 0x32, 0x00, 1086 0x36, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 1087 0x6f, 0x00, 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x32, 0x00, 1088 0x20, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00 1089 }; 1090 UCHAR securityblob[74] = { 1091 0x60, 0x48, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02, 0xa0, 0x3e, 0x30, 0x3c, 0xa0, 0x0e, 1092 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa2, 0x2a, 1093 0x04, 0x28, 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x97, 0x82, 1094 0x08, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1095 0x00, 0x00, 0x05, 0x01, 0x28, 0x0a, 0x00, 0x00, 0x00, 0x0f}; 1096 1097 if((int)*(des_ip+3)==255) 1098 return 0; 1099 1100SMBretry: 1101 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) 1102 { 1103 perror("SAMBA: create socket err"); 1104 return -1 ; 1105 } 1106 des_addr.sin_family = AF_INET; /* host byte order */ 1107 des_addr.sin_port = htons(NBSS_PORT); /* short, network byte order */ 1108 memcpy(&des_addr.sin_addr, des_ip, 4); 1109 inet_ntop(AF_INET, &des_addr.sin_addr, ptr, 32); 1110 bzero(&(des_addr.sin_zero), 8); /* zero the rest of the struct */ 1111 1112 unsigned long ul = 1; 1113 ioctl(sockfd, FIONBIO, &ul); 1114 if (connect(sockfd, (struct sockaddr *)&des_addr, sizeof(struct sockaddr)) == -1) 1115 { 1116 tm.tv_sec = TIME_OUT_TIME; 1117 tm.tv_usec = 0; 1118 FD_ZERO(&rfds); 1119 FD_SET(sockfd, &rfds); 1120 if( select(sockfd+1, NULL, &rfds, NULL, &tm) > 0) 1121 { 1122 getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len); 1123 if(error != 0) 1124 { 1125 perror("SAMBA: get socket opt err"); 1126 return -1 ; 1127 } 1128 } 1129 else 1130 { 1131 perror("SAMBA: select err"); 1132 return -1 ; 1133 } 1134 } 1135 ul = 0; 1136 ioctl(sockfd, FIONBIO, &ul); 1137 NMP_DEBUG_F("NetBIOS(NBSS) connected\n"); 1138 1139 operate = NBSS_REQ; 1140 while(operate != 0) 1141 { 1142 NMP_DEBUG_F("Operate= %d\n", operate); 1143 if(fp_smb!=NULL) 1144 fprintf(fp_smb, "Operate= %d\n", operate); 1145 switch(operate) 1146 { 1147 case NBSS_REQ: // first send nbss request 1148 offsetlen = 0; 1149 bzero(buf, MAXDATASIZE); 1150 EncodeName(my_info->des_hostname, des_nbss_name, my_info->des_hostname_len); 1151 EncodeName(my_info->my_hostname, my_nbss_name, my_info->my_hostname_len); 1152 1153 memcpy(buf, nbss_header, sizeof(nbss_header)); // nbss base header 1154 offsetlen += sizeof(nbss_header); // 4 1155 1156 memcpy(buf+offsetlen, des_nbss_name, sizeof(des_nbss_name)); // destination device host name, 34 bytes 1157 offsetlen += sizeof(des_nbss_name); 1158 1159 memcpy(buf+offsetlen, my_nbss_name, sizeof(my_nbss_name)); // client host name, 34 bytes 1160 offsetlen += sizeof(my_nbss_name); 1161 1162 if (send(sockfd, buf, offsetlen, 0) == -1) 1163 { 1164 perror("connect") ; 1165 return -1 ; 1166 } 1167 gettimeofday(&tv1, NULL); // set nbss statrt time 1168 operate = NBSS_RSP; 1169 break; 1170 case NBSS_RSP: // second receive nbss response 1171 FD_ZERO(&rfds); 1172 FD_SET(sockfd, &rfds); 1173 struct timeval timeout={1,0}; 1174 ret = select( sockfd + 1, &rfds, NULL, NULL, &timeout); 1175 if(ret) 1176 { 1177 if(FD_ISSET(sockfd,&rfds))//Using TCP client socket 1178 { 1179 bzero(nbss_buf, sizeof(nbss_buf)); 1180 if ((numbytes=recv(sockfd, nbss_buf, sizeof(nbss_buf), 0)) == -1) 1181 { 1182 perror("recv"); 1183 return -1 ; 1184 } 1185 if(numbytes > 0) 1186 { 1187 if(nbss_buf[0] == 0x83) 1188 { 1189 NMP_DEBUG_F("Called Name Error!\n"); 1190 smbretry_flag++; 1191 close(sockfd); 1192 sleep(2); 1193 if(smbretry_flag == 5) 1194 { 1195 operate = 0; 1196 break; 1197 } 1198 else 1199 goto SMBretry; 1200 } 1201 else if(nbss_buf[0] == 0x82) 1202 { 1203 operate = SMB_NEGOTIATE_REQ; 1204 break; 1205 } 1206 } 1207 } 1208 } 1209 gettimeofday(&tv2, NULL); 1210 if((tv2.tv_sec - tv1.tv_sec) > RCV_TIMEOUT) 1211 { 1212 NMP_DEBUG_F("NBSS receive timeout\n"); 1213 operate = 0; 1214 break; 1215 } 1216 break; 1217 case SMB_NEGOTIATE_REQ: 1218 { 1219 NBSS_HEADER nbss_hdr; 1220 SMB_HEADER smb_hdr; 1221 bzero(buf, sizeof(buf)); 1222 1223 nbss_hdr.msg_type = 0x00; 1224 nbss_hdr.flags = 0x00; 1225 nbss_hdr.length = htons(133); 1226 memcpy(buf, &nbss_hdr, 4); // add nbss header 1227 1228 smb_hdr.Protocol[0] = 0xFF; 1229 smb_hdr.Protocol[1] = 0x53; 1230 smb_hdr.Protocol[2] = 0x4d; 1231 smb_hdr.Protocol[3] = 0x42; 1232 smb_hdr.Command = 0x72; 1233 bzero(smb_hdr.Status, 4); 1234 smb_hdr.Flags = 0x18; 1235 smb_hdr.Flags2 = __cpu_to_le16(0xc853); 1236 bzero(&smb_hdr.Pad, 12); 1237 smb_hdr.Tid = 0x0000; 1238 smb_hdr.Pid = __cpu_to_le16(0xFEFF); 1239 smb_hdr.Uid = 0x0000; 1240 smb_hdr.Mid = 0x0000; 1241 memcpy(buf+4, &smb_hdr, 32); 1242 WordCount = 0x00; 1243 memcpy(buf+36, &WordCount, 1); 1244 ByteCount = __cpu_to_le16(0x0062); 1245 memcpy(buf+37, &ByteCount, 2); 1246 memcpy(buf+39, smb_buf, 98); 1247 1248 if (send(sockfd, buf, 137, 0) == -1) 1249 { 1250 perror("connect") ; 1251 return -1 ; 1252 } 1253 gettimeofday(&tv1, NULL); // set nbss statrt time 1254 1255 operate = SMB_NEGOTIATE_RSP; 1256 } 1257 break; 1258 case SMB_NEGOTIATE_RSP: 1259 { 1260 FD_ZERO(&rfds); 1261 FD_SET(sockfd, &rfds); 1262 struct timeval timeout={1,0}; 1263 ret = select( sockfd + 1, &rfds, NULL, NULL, &timeout); 1264 securitymode = 0x00; 1265 if(ret) 1266 { 1267 if(FD_ISSET(sockfd,&rfds))//Using TCP client socket 1268 { 1269 bzero(buf, sizeof(buf)); 1270 if ((numbytes=recv(sockfd, buf, sizeof(buf), 0)) == -1) 1271 { 1272 perror("recv"); 1273 return -1 ; 1274 } 1275 if(numbytes > 0) 1276 { 1277 if(fp_smb!=NULL) 1278 fprintf(fp_smb, "SMB_NEGOTIATE_RSP: %s\n", buf);//Yau 1279 if(buf[4] == 0xFF && buf[5] == 0x53 && buf[6]==0x4d 1280 && buf[7]==0x42 && buf[8]==0x72) 1281 { 1282 NMP_DEBUG_F("SMS rev%02x\n", buf[0]); 1283 securitymode = buf[39]; 1284 operate = SMB_SESSON_ANDX_REQ; 1285 } 1286 break; 1287 } 1288 } 1289 } 1290 gettimeofday(&tv2, NULL); 1291 if((tv2.tv_sec - tv1.tv_sec) > RCV_TIMEOUT) 1292 { 1293 operate = 0; 1294 break; 1295 } 1296 1297 } 1298 break; 1299 case SMB_SESSON_ANDX_REQ: 1300 { 1301 NBSS_HEADER nbss_hdr; 1302 SMB_HEADER smb_hdr; 1303 SMB_SESSION_SETUPX_REQ seX_req; 1304 SMB_CLIENT_INFO smb_info; 1305 bzero(buf, sizeof(buf)); 1306 offsetlen = 0; 1307 //-------------------------------------------------- 1308 nbss_hdr.msg_type = 0x00; 1309 nbss_hdr.flags = 0x00; 1310 if(securitymode == 0x02) // Samba 1311 { 1312 nbss_hdr.length = htons(130); 1313 } 1314 else // Windows 1315 { 1316 nbss_hdr.length = htons(236); 1317 } 1318 memcpy(buf, &nbss_hdr, 4); 1319 offsetlen += 4; 1320 pos1 = offsetlen-2; // first length position 1321 //-------------------------------------------------- nbss header 1322 smb_hdr.Protocol[0] = 0xFF; 1323 smb_hdr.Protocol[1] = 0x53; 1324 smb_hdr.Protocol[2] = 0x4d; 1325 smb_hdr.Protocol[3] = 0x42; 1326 smb_hdr.Command = 0x73; 1327 bzero(smb_hdr.Status, 4); 1328 smb_hdr.Flags = 0x18; 1329 smb_hdr.Flags2 = __cpu_to_le16(0xc807); 1330 bzero(&smb_hdr.Pad, 12); 1331 smb_hdr.Tid = 0x0000; 1332 smb_hdr.Pid = __cpu_to_le16(0xFEFF); 1333 smb_hdr.Uid = 0x0000; 1334 smb_hdr.Mid = __cpu_to_le16(0x0010); 1335 memcpy(buf+offsetlen, &smb_hdr, 32); 1336 offsetlen += 32; // 36 1337 //-------------------------------------------------- SMB base header 1338 if(securitymode == 0x02) 1339 { 1340 seX_req.WordCount = 0x0d; // 13 Samba 1341 memcpy(buf+offsetlen, &seX_req.WordCount, 1); 1342 offsetlen += 1; // 37 1343 seX_req.AndXCommand = 0xff; // no further commands 1344 memcpy(buf+offsetlen, &seX_req.AndXCommand, 1); 1345 offsetlen += 1; // 38 1346 seX_req.AndXReserved = 0x00; 1347 memcpy(buf+offsetlen, &seX_req.AndXReserved, 1); 1348 offsetlen += 1; // 39 1349 seX_req.AndXOffset = 0x0000; //0x0082; 1350 memcpy(buf+offsetlen, &seX_req.AndXOffset, 2); 1351 pos2 = offsetlen; 1352 offsetlen += 2; // 41 1353 seX_req.MaxBufferSize = 4356; 1354 memcpy(buf+offsetlen, &seX_req.MaxBufferSize, 2); 1355 offsetlen += 2; // 43 1356 seX_req.MaxMpxCount = __cpu_to_le16(0x000a); 1357 memcpy(buf+offsetlen, &seX_req.MaxMpxCount, 2); 1358 offsetlen += 2; // 45 1359 seX_req.VcNumber = 0x0000; 1360 memcpy(buf+offsetlen, &seX_req.VcNumber, 2); 1361 offsetlen += 2; // 47 1362 seX_req.SessionKey = 0x00000000; 1363 memcpy(buf+offsetlen, &seX_req.SessionKey, 4); 1364 offsetlen += 4; // 51 1365 seX_req.CaseInsensitivePasswordLength = __cpu_to_le16(0x0001); 1366 memcpy(buf+offsetlen, &seX_req.CaseInsensitivePasswordLength, 2); 1367 offsetlen += 2; // 53 1368 seX_req.CaseSensitivePasswordLength = __cpu_to_le16(0x0001); 1369 memcpy(buf+offsetlen, &seX_req.CaseSensitivePasswordLength, 2); 1370 offsetlen += 2; // 55 1371 seX_req.Reserved = 0x00000000; 1372 memcpy(buf+offsetlen, &seX_req.Reserved, 4); 1373 offsetlen += 4; // 59 1374 seX_req.Capabilities = __cpu_to_le32(0x000000d4); 1375 memcpy(buf+offsetlen, &seX_req.Capabilities, 4); 1376 offsetlen += 4; // 63 1377 //---------------------------------------------------------------SMB Session and X header 1378 smb_info.ByteCount = 0x0000; //0x0045; 1379 memcpy(buf+offsetlen, &smb_info.ByteCount, 2); 1380 pos3 = offsetlen; 1381 offsetlen += 2; // 65 1382 slip = offsetlen; 1383 bzero(smb_info.CaseInsensitivePassword, 32); 1384 memcpy(buf+offsetlen, smb_info.CaseInsensitivePassword, 1); 1385 offsetlen += 1; // 66 1386 bzero(smb_info.CaseSensitivePassword, 32); 1387 memcpy(buf+offsetlen, smb_info.CaseInsensitivePassword, 1); 1388 offsetlen += 1; // 67 1389 memcpy(buf+offsetlen, smb_info.CaseInsensitivePassword, 1); 1390 offsetlen += 1; // 68 1391 bzero(smb_info.AccountName, 32); 1392 tmplen = TranUnicode(smb_info.AccountName, my_info->account, my_info->account_len); 1393 memcpy(buf+offsetlen, smb_info.AccountName, tmplen+2); 1394 offsetlen += tmplen+2; // 78 1395 bzero(smb_info.PrimaryDomain, 32); 1396 tmplen = TranUnicode(smb_info.PrimaryDomain, my_info->primarydomain, my_info->primarydomain_len); 1397 memcpy(buf+offsetlen, smb_info.PrimaryDomain, tmplen+2); 1398 offsetlen += tmplen+2; // 98 1399 bzero(smb_info.NativeOS, 128); 1400 tmplen = TranUnicode(smb_info.NativeOS, my_info->nativeOS, my_info->nativeOS_len); 1401 memcpy(buf+offsetlen, smb_info.NativeOS, tmplen+2); 1402 offsetlen += tmplen+2; // 110 1403 bzero(smb_info.NativeLanMan, 128); 1404 tmplen = TranUnicode(smb_info.NativeLanMan, my_info->nativeLanMan, my_info->nativeLanMan_len); 1405 memcpy(buf+offsetlen, smb_info.NativeLanMan, tmplen+2); 1406 offsetlen += tmplen+2; // 1407 tmplen = htons(offsetlen-4); 1408 memcpy(buf+pos1, &tmplen, 2); 1409 tmplen = offsetlen-4; 1410 memcpy(buf+pos2, &tmplen, 2); 1411 tmplen = offsetlen-slip; 1412 memcpy(buf+pos3, &tmplen, 2); 1413 } 1414 else 1415 { 1416 memcpy(buf+offsetlen, sessionX_buf, 204); 1417 offsetlen += 204; // 36 1418 } 1419 //---------------------------------------------------------------SMB Client infomation 1420 if (send(sockfd, buf, offsetlen, 0) == -1) 1421 { 1422 perror("connect") ; 1423 return -1 ; 1424 } 1425 gettimeofday(&tv1, NULL); // set SMB SESSON ANDX REQ statrt time 1426 operate = SMB_SESSON_ANDX_RSP; 1427 } 1428 break; 1429 case SMB_SESSON_ANDX_RSP: 1430 { 1431 FD_ZERO(&rfds); 1432 FD_SET(sockfd, &rfds); 1433 struct timeval timeout={3,0}; 1434 ret = select( sockfd + 1, &rfds, NULL, NULL, &timeout); 1435 if(ret) 1436 { 1437 if(FD_ISSET(sockfd,&rfds))//Using TCP client socket 1438 { 1439 bzero(buf, sizeof(buf)); 1440 if ((numbytes=recv(sockfd, buf, sizeof(buf), 0)) == -1) 1441 { 1442 perror("recv"); 1443 return -1 ; 1444 } 1445 if(numbytes > 0) 1446 { 1447 if(fp_smb!=NULL) 1448 fprintf(fp_smb, "SMB_SESSON_ANDX_RSP:\n%s\n", buf);//Yau 1449 if(buf[4] == 0xFF && buf[5] == 0x53 && buf[6]==0x4d 1450 && buf[7]==0x42 && buf[8]==0x73) 1451 { 1452 if(securitymode == 0x02) // Samba 1453 { 1454 tmplen = buf[36]; 1455 UCHAR tmpch[2] = {0x00, 0x00}; 1456 i=36+1+tmplen*2+2; 1457 1458 while(memcmp(buf+i, tmpch, 2) != 0) 1459 { 1460 snprintf(SMB_OS, sizeof(SMB_OS), "%s%c", SMB_OS, buf[i]); 1461 i++; 1462 } 1463 i += 2; 1464 NMP_DEBUG_F("\nNativeOS: %s\n", SMB_OS); 1465 1466 while(memcmp(buf+i, tmpch, 2) != 0) 1467 { 1468 i++; 1469 } 1470 i += 2; 1471 1472 while(memcmp(buf+i, tmpch, 2) != 0) 1473 { 1474 snprintf(SMB_PriDomain, sizeof(SMB_PriDomain), "%s%c", SMB_PriDomain, buf[i]); 1475 i++; 1476 } 1477 NMP_DEBUG_F("Primary Domain: %s\n", SMB_PriDomain); 1478 } 1479 else //Windows 1480 { 1481 tmplen2 = (USHORT)buf[43]; 1482 tmplen3 = (USHORT)buf[44]; 1483 tmplen = tmplen3*256+tmplen2; 1484 UCHAR tmpch[2] = {0x00, 0x00}; 1485 i=47+tmplen; 1486 1487 while(memcmp(buf+i, tmpch, 2) != 0) 1488 { 1489 snprintf(SMB_OS, sizeof(SMB_OS), "%s%c", SMB_OS, buf[i]); 1490 i++; 1491 } 1492 i += 2; 1493 NMP_DEBUG_F("\nNativeOS: %s\n", SMB_OS); 1494 1495 while(memcmp(buf+i, tmpch, 2) != 0) 1496 { 1497 i++; 1498 } 1499 i += 2; 1500 while(memcmp(buf+i, tmpch, 2) != 0) 1501 { 1502 snprintf(SMB_PriDomain, sizeof(SMB_PriDomain), "%s%c", SMB_PriDomain, buf[i]); 1503 i++; 1504 } 1505 NMP_DEBUG_F("Primary Domain: %s\n", SMB_PriDomain); 1506 } 1507 operate = 0; 1508 } 1509 break; 1510 } 1511 } 1512 } 1513 gettimeofday(&tv2, NULL); 1514 1515 if((tv2.tv_sec - tv1.tv_sec) > RCV_TIMEOUT) 1516 { 1517 NMP_DEBUG_F("SMB receive timeout\n"); 1518 operate = 0; 1519 break; 1520 } 1521 } 1522 break; 1523 } 1524 } 1525 close(sockfd); 1526 return 0; 1527} 1528 1529/******** End of SMB function **********/ 1530 1531/* ASUS Device Discovery */ 1532int PackGetInfo(char *pdubuf) 1533{ 1534 IBOX_COMM_PKT_HDR_EX *hdr; 1535 1536 hdr=(IBOX_COMM_PKT_HDR_EX *)pdubuf; 1537 hdr->ServiceID = NET_SERVICE_ID_IBOX_INFO; 1538 hdr->PacketType = NET_PACKET_TYPE_CMD; 1539 hdr->OpCode = NET_CMD_ID_GETINFO; 1540 hdr->Info = 0; 1541 1542 return (0); 1543} 1544 1545int UnpackGetInfo(char *pdubuf, PKT_GET_INFO *Info) 1546{ 1547 IBOX_COMM_PKT_RES_EX *hdr; 1548 1549 hdr = (IBOX_COMM_PKT_RES_EX *)pdubuf; 1550 1551 if (hdr->ServiceID!=NET_SERVICE_ID_IBOX_INFO || 1552 hdr->PacketType!=NET_PACKET_TYPE_RES || 1553 hdr->OpCode!=NET_CMD_ID_GETINFO) 1554 return 0; 1555 1556 1557 memcpy(Info, pdubuf+sizeof(IBOX_COMM_PKT_RES), sizeof(PKT_GET_INFO)); 1558 return 1; 1559} 1560 1561int 1562Asus_Device_Discovery(unsigned char *src_ip, unsigned char *dest_ip, P_CLIENT_DETAIL_INFO_TABLE p_client_detail_info_tab, int i) 1563{ 1564 struct sockaddr_in my_addr, other_addr1, other_addr2; 1565 int sock_dd, status, other_addr_len1, other_addr_len2, sendlen, recvlen, retry=3; 1566 char txPdubuf[512] = {0}; 1567 char *other_ptr; 1568 struct timeval timeout={1, 500}; 1569 PKT_GET_INFO get_info; 1570 fd_set fdvar; 1571 int res; 1572 1573 sock_dd = socket(AF_INET, SOCK_DGRAM, 0); 1574 if (-1 == sock_dd) 1575 { 1576 NMP_DEBUG_F("DD: socket error.\n"); 1577 return -1; 1578 } 1579 1580 memset(&my_addr, 0, sizeof(my_addr)); 1581 my_addr.sin_family = AF_INET; 1582 my_addr.sin_port = htons(9999); //infosvr port 1583 my_addr.sin_addr.s_addr = htonl(INADDR_ANY); 1584 1585 int flag=1; 1586 if (setsockopt(sock_dd, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag)) < 0) 1587 { 1588 NMP_DEBUG_F("DD: SO_REUSEADDR failed: %s\n", strerror(errno)); 1589 return -1; 1590 } 1591 1592 status = bind(sock_dd, (struct sockaddr *)&my_addr, sizeof(my_addr)); 1593 if (-1 == status) 1594 { 1595 NMP_DEBUG_F("DD: bind error.\n"); 1596 return -1; 1597 } 1598 1599 setsockopt(sock_dd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));//set timeout 1600 memset(&other_addr1, 0, sizeof(other_addr1)); 1601 other_addr1.sin_family = AF_INET; 1602 other_addr1.sin_port = htons(9999); // infosvr port 1603 memcpy(&other_addr1.sin_addr, dest_ip, 4); // dist ip 1604 other_ptr = inet_ntoa(other_addr1.sin_addr); 1605 other_addr_len1 = sizeof(other_addr1); 1606 1607 while (retry > 0 /*&& ED*/) 1608 { 1609 PackGetInfo(txPdubuf); 1610 sendlen = sendto(sock_dd, txPdubuf, sizeof(txPdubuf), 0, (struct sockaddr*)&other_addr1, other_addr_len1); 1611 1612 bzero(txPdubuf, 512); 1613 other_addr_len2 = sizeof(other_addr2); 1614 recvlen = recv(sock_dd, txPdubuf, sizeof(txPdubuf), 0); 1615 1616 if( recvlen > 0 ) { 1617 if(UnpackGetInfo(txPdubuf, &get_info)) { 1618 NMP_DEBUG_F("DD: productID= %s~\n", get_info.ProductID); 1619 memcpy(p_client_detail_info_tab->device_name[i], get_info.ProductID, 16); 1620 p_client_detail_info_tab->type[i] = 3; 1621 break; 1622 } 1623 else 1624 retry--; 1625 } 1626 else 1627 retry--; 1628 } 1629 close(sock_dd); 1630 return 1; 1631} 1632/* End of discovery */ 1633 1634void 1635get_name_from_dhcp_lease(unsigned char *mac, char *dev_name) 1636{ 1637 FILE *fp; 1638 char line[256], dev_mac[18]; 1639 char *hwaddr, *ipaddr, *name, *next, *ret; 1640 unsigned int expires; 1641 1642 if (!nvram_get_int("dhcp_enable_x")) 1643 return; 1644 1645 sprintf(dev_mac, "%02x:%02x:%02x:%02x:%02x:%02x", 1646 *mac,*(mac+1),*(mac+2),*(mac+3),*(mac+4),*(mac+5)); 1647 1648 NMP_DEBUG_F("Check dhcp lease table\n"); 1649 /* Read leases file */ 1650 if (!(fp = fopen("/var/lib/misc/dnsmasq.leases", "r"))) 1651 return; 1652 1653 while ((next = fgets(line, sizeof(line), fp)) != NULL) { 1654 /* line should start from numeric value */ 1655 if (sscanf(next, "%u ", &expires) != 1) 1656 continue; 1657 1658 strsep(&next, " "); 1659 hwaddr = strsep(&next, " ") ? : ""; 1660 ipaddr = strsep(&next, " ") ? : ""; 1661 name = strsep(&next, " ") ? : ""; 1662 1663 if(!strcmp(dev_mac, hwaddr)) { 1664 NMP_DEBUG_F("Find the same MAC(%s)! copy device name\n", dev_mac); 1665 strlcpy(dev_name, name, 16); 1666 #ifdef RTCONFIG_NOTIFICATION_CENTER 1667 extern int TRIGGER_FLAG; 1668 if(!(TRIGGER_FLAG>>FLAG_UPNP_RENDERER & 1) && (strstr(dev_name, "Chromecast"))){ 1669 NOTIFY_EVENT_T *event_t = initial_nt_event(); 1670 event_t->event = HINT_UPNP_RENDERER_EVENT; 1671 snprintf(event_t->msg, sizeof(event_t->msg), "%s", "HINT_UPNP_RENDERER_EVENT"); 1672 NMP_DEBUG("NT_CENTER: Send event UPnP renderer ID:%08x msg:%s!\n", event_t->event, event_t->msg); 1673 send_trigger_event(event_t); 1674 nt_event_free(event_t); 1675 TRIGGER_FLAG |= (1<<FLAG_UPNP_RENDERER); 1676 NMP_DEBUG("========check TRIGGER_FLAG %d\n", TRIGGER_FLAG); 1677 } 1678 #endif 1679 break; 1680 } 1681 } 1682 fclose(fp); 1683 1684 return; 1685} 1686void toLowerCase(char *str) { 1687 char *p; 1688 1689 for(p=str;*p!='\0';p++) 1690 if('A'<=*p&&*p<='Z')*p+=32; 1691 1692} 1693 1694int FindAllApp(unsigned char *src_ip, P_CLIENT_DETAIL_INFO_TABLE p_client_detail_info_tab, int i) 1695{ 1696 unsigned char *dest_ip = p_client_detail_info_tab->ip_addr[i]; 1697 int found_type = 0, ret = 0; 1698 UCHAR account[32]; 1699 UCHAR primarydomain[32]; 1700 UCHAR nativeOS[32]; 1701 UCHAR nativeLanMan[32]; 1702 int lock; 1703 1704 NMP_DEBUG_F("*FindAllApp: %d -> %d.%d.%d.%d-%02X:%02X:%02X:%02X:%02X:%02X\n",i, 1705 p_client_detail_info_tab->ip_addr[i][0], 1706 p_client_detail_info_tab->ip_addr[i][1], 1707 p_client_detail_info_tab->ip_addr[i][2], 1708 p_client_detail_info_tab->ip_addr[i][3], 1709 p_client_detail_info_tab->mac_addr[i][0], 1710 p_client_detail_info_tab->mac_addr[i][1], 1711 p_client_detail_info_tab->mac_addr[i][2], 1712 p_client_detail_info_tab->mac_addr[i][3], 1713 p_client_detail_info_tab->mac_addr[i][4], 1714 p_client_detail_info_tab->mac_addr[i][5] 1715 ); 1716 1717 //NBSS Called and Calling Name 1718 UCHAR des_hostname[16] = { 1719 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 1720 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; 1721 UCHAR my_hostname[16] = { 1722 0x43, 0x48, 0x49, 0x4E, 0x45, 0x53, 0x45, 0x2d, 1723 0x43, 0x45, 0x52, 0x45, 0x52, 0x45, 0x52, 0x00}; 1724 MY_DEVICE_INFO my_dvinfo; 1725 1726 memcpy(account, "root", 4); 1727 memcpy(primarydomain, "WORKGROUP", 9); 1728 memcpy(nativeOS, "Linux", 5); 1729 memcpy(nativeLanMan, "Samba", 5); 1730 1731 //ASUS Device Discovery 1732 //Asus_Device_Discovery(src_ip, dest_ip, p_client_detail_info_tab); 1733 1734 //http service detect 1735 ret = SendHttpReq(dest_ip); 1736 lock = file_lock("networkmap"); 1737 if(ret) { 1738 NMP_DEBUG_F("Found HTTP\n"); 1739 p_client_detail_info_tab->http[i] = 1; 1740 } 1741 else { 1742 NMP_DEBUG_F("HTTP Not Found\n"); 1743 p_client_detail_info_tab->http[i] = 0; 1744 } 1745 file_unlock(lock); 1746 if(scan_count==0) //leave when click refresh 1747 return 0; 1748 1749 //printer server detect 1750 ret = lpd515(dest_ip); 1751 if(!ret) { 1752 lock = file_lock("networkmap"); 1753 NMP_DEBUG_F("LPR Printer Server found!\n"); 1754 p_client_detail_info_tab->printer[i] = 1; 1755 file_unlock(lock); 1756 } 1757 else { 1758 ret = raw9100(dest_ip); 1759 lock = file_lock("networkmap"); 1760 if(!ret) { 1761 NMP_DEBUG_F("RAW Printer Server found!\n"); 1762 p_client_detail_info_tab->printer[i] = 2; 1763 } 1764 else { 1765 NMP_DEBUG_F("Printer Server not found!\n"); 1766 p_client_detail_info_tab->printer[i] = 0; 1767 } 1768 file_unlock(lock); 1769 } 1770 if(scan_count==0) //leave when click refresh 1771 return 0; 1772 1773 //iTune Server detect 1774 ret = send_mdns_packet_ipv4(src_ip, dest_ip); 1775 lock = file_lock("networkmap"); 1776 if(ret) { 1777 NMP_DEBUG_F("Found iTune Server!\n"); 1778 p_client_detail_info_tab->itune[i] = 1; 1779 } 1780 else { 1781 NMP_DEBUG_F("No iTune Server!\n"); 1782 p_client_detail_info_tab->itune[i] = 0; 1783 } 1784 file_unlock(lock); 1785 if(scan_count==0) //leave when click refresh 1786 return 0; 1787 1788 if(p_client_detail_info_tab->type[i]==0) { 1789 if( ctrlpt(dest_ip) )//UPNP detect 1790 { 1791 lock = file_lock("networkmap"); 1792 NMP_DEBUG_F("Find UPnP device: description= %s, modelname= %s\n",description.description, description.modelname); 1793 //parse description 1794 toLowerCase(description.description); 1795 if( strstr(description.description, "router")!=NULL ) 1796 { 1797 p_client_detail_info_tab->type[i] = 2; 1798 } 1799 else if( (strstr(description.description, "ap")!=NULL) || 1800 (strstr(description.description, "access pointer")!=NULL) || 1801 (strstr(description.description, "wireless device")!=NULL) ) 1802 { 1803 p_client_detail_info_tab->type[i] = 3; 1804 } 1805 else if( strstr(description.description, "nas") ) 1806 { 1807 p_client_detail_info_tab->type[i] = 4; 1808 } 1809 else if( strstr(description.description, "cam") ) 1810 { 1811 p_client_detail_info_tab->type[i] = 5; 1812 } 1813 else if( strstr(description.modelname, "Xbox") ) 1814 { 1815 p_client_detail_info_tab->type[i] = 8; 1816 #ifdef RTCONFIG_NOTIFICATION_CENTER 1817 extern int TRIGGER_FLAG; 1818 if(!(TRIGGER_FLAG>>FLAG_XBOX_PS & 1)){ 1819 NOTIFY_EVENT_T *event_t = initial_nt_event(); 1820 event_t->event = HINT_XBOX_PS_EVENT; 1821 snprintf(event_t->msg, sizeof(event_t->msg), "%s", "HINT_XBOX_PS_EVENT"); 1822 NMP_DEBUG("NT_CENTER: Send event xbox ID:%08x msg:%s!\n", event_t->event, event_t->msg); 1823 send_trigger_event(event_t); 1824 nt_event_free(event_t); 1825 TRIGGER_FLAG |= (1<<FLAG_XBOX_PS); 1826 NMP_DEBUG("========check TRIGGER_FLAG %d\n", TRIGGER_FLAG); 1827 } 1828 #endif 1829 } 1830 1831 //Copy modelname to device name if exist. 1832 if(strcmp("",description.modelname) && 1833 !strcmp("",p_client_detail_info_tab->device_name[i])) { 1834 strlcpy(p_client_detail_info_tab->device_name[i], description.modelname, 32); 1835 } 1836 file_unlock(lock); 1837 } 1838 else 1839 NMP_DEBUG_F("UPnP no response!\n"); 1840 } 1841 if(scan_count==0) //leave when click refresh 1842 return 0; 1843 1844 //nbns name query 1845 NMP_DEBUG_F("NBNS Name Query...\n"); 1846 Nbns_query(src_ip, dest_ip, p_client_detail_info_tab, i); 1847 if(scan_count==0) //leave when click refresh 1848 return 0; 1849 1850 if(p_client_detail_info_tab->type[i]==0) 1851 { 1852 //Check SMB data 1853 NMP_DEBUG_F("Check Samba... \n"); 1854 memcpy(des_hostname, NetBIOS_name, 16); 1855 strcpy(my_hostname, MODEL_NAME); 1856 my_dvinfo.des_hostname= des_hostname; 1857 my_dvinfo.des_hostname_len = 16; 1858 my_dvinfo.my_hostname = my_hostname; 1859 my_dvinfo.my_hostname_len = 16; 1860 my_dvinfo.account= account; 1861 my_dvinfo.account_len = 4; 1862 my_dvinfo.primarydomain= primarydomain; 1863 my_dvinfo.primarydomain_len = 9; 1864 my_dvinfo.nativeOS= nativeOS; 1865 my_dvinfo.nativeOS_len = 5; 1866 my_dvinfo.nativeLanMan= nativeLanMan; 1867 my_dvinfo.nativeLanMan_len = 5; 1868 bzero(SMB_OS, sizeof(SMB_OS)); 1869 bzero(SMB_PriDomain, sizeof(SMB_PriDomain)); 1870 sleep(2); 1871 1872 lock = file_lock("networkmap"); 1873 if(!SendSMBReq(dest_ip, &my_dvinfo)) 1874 { 1875 if( strstr(SMB_OS, "Windows")!=NULL ) 1876 { 1877 p_client_detail_info_tab->type[i] = 1; 1878 NMP_DEBUG_F("Find: PC!\n"); 1879 } 1880 else if( strstr(SMB_PriDomain, "NAS")!=NULL ) 1881 { 1882 p_client_detail_info_tab->type[i] = 4; 1883 NMP_DEBUG_F("Find: NAS Server!\n"); 1884 } 1885 #ifdef RTCONFIG_NOTIFICATION_CENTER 1886 extern int TRIGGER_FLAG; 1887 if(!(TRIGGER_FLAG>>FLAG_SAMBA_INLAN & 1)){ 1888 if( p_client_detail_info_tab->type[i] == 1 || p_client_detail_info_tab->type[i] == 4 ){ 1889 NOTIFY_EVENT_T *event_t = initial_nt_event(); 1890 event_t->event = HINT_SAMBA_INLAN_EVENT; 1891 snprintf(event_t->msg, sizeof(event_t->msg), "%s", "HINT_SAMBA_INLAN_EVENT"); 1892 NMP_DEBUG("NT_CENTER: Send event lan with SAMBA ID:%08x msg:%s!\n", event_t->event, event_t->msg); 1893 send_trigger_event(event_t); 1894 nt_event_free(event_t); 1895 TRIGGER_FLAG |= (1<<FLAG_SAMBA_INLAN); 1896 NMP_DEBUG("========check TRIGGER_FLAG %d\n", TRIGGER_FLAG); 1897 } 1898 } 1899 #endif 1900 } 1901 file_unlock(lock); 1902 } 1903 1904 if(!strcmp("", p_client_detail_info_tab->device_name[i])) { 1905 get_name_from_dhcp_lease(p_client_detail_info_tab->mac_addr[i], 1906 p_client_detail_info_tab->device_name[i]); 1907 fixstr(p_client_detail_info_tab->device_name[i]); 1908 NMP_DEBUG_F("Get device name from dhcp lease: %s\n", 1909 p_client_detail_info_tab->device_name[i]); 1910 } 1911 1912 return 1; 1913} 1914 1915 1916int FindHostname(P_CLIENT_DETAIL_INFO_TABLE p_client_detail_info_tab) 1917{ 1918 unsigned char *dest_ip = p_client_detail_info_tab->ip_addr[p_client_detail_info_tab->detail_info_num]; 1919 char ipaddr[16]; 1920 sprintf(ipaddr, "%d.%d.%d.%d",(int)*(dest_ip),(int)*(dest_ip+1),(int)*(dest_ip+2),(int)*(dest_ip+3)); 1921 1922 char *nv, *nvp, *b; 1923 char *mac, *ip, *name, *expire; 1924 FILE *fp; 1925 char line[256]; 1926 char *next; 1927 1928// Get current hostname from DHCP leases 1929 if (!nvram_get_int("dhcp_enable_x") || !nvram_match("sw_mode", "1")) 1930 return 0; 1931 1932 if ((fp = fopen("/var/lib/misc/dnsmasq.leases", "r"))) { 1933 fcntl(fileno(fp), F_SETFL, fcntl(fileno(fp), F_GETFL) | O_NONBLOCK); 1934 while ((next = fgets(line, sizeof(line), fp)) != NULL) { 1935 if (vstrsep(next, " ", &expire, &mac, &ip, &name) == 4) { 1936 if ((!strcmp(ipaddr, ip)) && 1937 (strlen(name) > 0) && 1938 (!strchr(name, '*')) && // Ensure it's not a clientid in 1939 (!strchr(name, ':'))) // case device didn't have a hostname 1940 strlcpy(p_client_detail_info_tab->device_name[p_client_detail_info_tab->detail_info_num], name, 32); 1941 } 1942 } 1943 fclose(fp); 1944 } 1945 1946// Get names from static lease list, overruling anything else 1947 nv = nvp = strdup(nvram_safe_get("dhcp_staticlist")); 1948 1949 if (nv) { 1950 while ((b = strsep(&nvp, "<")) != NULL) { 1951 if ((vstrsep(b, ">", &mac, &ip, &name) == 3) && (strlen(ip) > 0) && (strlen(name) > 0)) { 1952 if (!strcmp(ipaddr, ip)) 1953 strlcpy(p_client_detail_info_tab->device_name[p_client_detail_info_tab->detail_info_num], name, 32); 1954 } 1955 } 1956 free(nv); 1957 } 1958 1959 return 1; 1960} 1961