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