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