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