1//
2//  ASUS_Discovery.c
3//  ASUS
4//
5//  Created by Junda Txia on 11/22/10.
6//  Copyright ASUSTek COMPUTER INC. 2011. All rights reserved.
7//
8
9#include <string.h>          //memset function
10#include <stdio.h>           //sprintf function
11#include <sys/socket.h>      //socket function
12//#include <sys/_endian.h>     //htons function
13#include <sys/errno.h>       //errorno function
14#include <sys/poll.h>        //struct pollfd
15#include <netinet/in.h>      //const IPPROTO_UDP
16#include <unistd.h>          //close function
17#include "../shared/rtstate.h"
18#include <bcmnvram.h>
19
20#include "ASUS_Discovery_Debug.h"    //myAsusDiscoveryDebugPrint function
21#include "iboxcom.h"         //const INFO_PDU_LENGTH
22#include "packet.h"          //const RESPONSE_HDR_OK
23#include "ASUS_Discovery.h"
24
25//char txMac[6] = {0};
26int a_bEndApp = 0;
27int a_socket = 0;
28int a_GetRouterCount = 0;
29
30//SearchRouterInfoStruct searchRouterInfo[MAX_SEARCH_ROUTER] = {0};
31SearchRouterInfoStruct searchRouterInfo[MAX_SEARCH_ROUTER];
32
33int ASUS_Discovery()
34{
35    myAsusDiscoveryDebugPrint("----------ASUS_Discovery Start----------");
36
37    int iRet = 0;
38
39    //initial search router count
40    a_GetRouterCount = 0;
41    // clean structure
42    memset(&searchRouterInfo[0], 0, MAX_SEARCH_ROUTER * sizeof(SearchRouterInfoStruct));
43
44    if (a_socket != 0)
45    {
46        close(a_socket);
47        a_socket = 0;
48    }
49
50    a_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
51    if (a_socket < 0)
52    {
53        myAsusDiscoveryDebugPrint("Create socket failed");
54        return 0;
55    }
56
57    // set reuseaddr option
58    int reuseaddr = 1;
59    if (setsockopt(a_socket, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)) < 0)
60    {
61        myAsusDiscoveryDebugPrint("setsockopt: SO_REUSEADDR failed\n");
62        return 0;
63    }
64
65    char *lan_ifname;
66    lan_ifname = nvram_safe_get("lan_ifname");
67    setsockopt(a_socket, SOL_SOCKET, SO_BINDTODEVICE, lan_ifname, strlen(lan_ifname));
68
69    // set broadcast flag
70    int broadcast = 1;
71    int iRes = setsockopt(a_socket, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast));
72    if (iRes != 0)
73    {
74        myAsusDiscoveryDebugPrint("setsockopt: SO_BROADCAST failed");
75        close(a_socket);
76        a_socket = 0;
77        return 0;
78    }
79
80    struct sockaddr_in clit;
81    memset(&clit, 0, sizeof(clit));
82    clit.sin_family = AF_INET;
83    clit.sin_port = htons(INFO_SERVER_PORT);
84    clit.sin_addr.s_addr = htonl(INADDR_ANY);
85
86    int bind_result = bind(a_socket, (struct sockaddr *)&clit, sizeof(clit));
87    if (bind_result < 0)
88    {
89        myAsusDiscoveryDebugPrint("could not bind to address");
90        close(a_socket);
91        a_socket = 0;
92        return 0;
93    }
94
95	struct sockaddr_in serv;
96	memset(&serv, 0, sizeof(serv));
97    	serv.sin_family = AF_INET;
98	serv.sin_port = htons(INFO_SERVER_PORT);
99	inet_aton("255.255.255.255", &serv.sin_addr);
100
101	char pdubuf[INFO_PDU_LENGTH] = {0};
102	pdubuf[0] = 0x0C; //12
103	pdubuf[1] = 0x15; //21
104	pdubuf[2] = 0x1f; //31
105	pdubuf[3] = 0x00;
106	pdubuf[4] = 0x00;
107	pdubuf[5] = 0x00;
108	pdubuf[6] = 0x00;
109	pdubuf[7] = 0x00;
110
111    	// POLLIN      any readable data available
112    	// POLLRDNORM  non-OOB/URG data available
113	struct pollfd pollfd[1];
114    	pollfd->fd = a_socket;
115	pollfd->events = POLLIN;
116    	pollfd->revents = 0;
117
118    	int result;
119
120	int retry = 3;
121	while (retry > 0)
122	{
123		ssize_t iRet2 = sendto(a_socket, pdubuf, INFO_PDU_LENGTH, 0, (struct sockaddr *) &serv, sizeof(serv));
124		if (iRet2 < 0)
125		{
126            		char error[128] = {0};
127            		sprintf(error, "sendto failed : %s", strerror(errno));
128			myAsusDiscoveryDebugPrint(error);
129
130            		close(a_socket);
131            		a_socket = 0;
132			return 0;
133		}
134
135        	//receive
136	        while (1)
137	        {
138	            result = poll(pollfd, 1, 500); // Wait for 1 seconds
139
140        	    // Error during poll()
141	            if (result < 0)
142        	    {
143	                myAsusDiscoveryDebugPrint("Error during poll()");
144        	        break;
145	            }
146	            // Timeout...
147	            else if (result == 0)
148        	    {
149	                myAsusDiscoveryDebugPrint("Timeout during poll()");
150        	        break;
151	            }
152        	    // Success
153	            else
154        	    {
155	                if (!(pollfd->revents & pollfd->events))
156        	            continue;
157
158	                if (!ParseASUSDiscoveryPackage(a_socket))
159        	        {
160	                    myAsusDiscoveryDebugPrint("Failed to ParseASUSDiscoveryPackage");
161        	        }
162                	else
163	                {
164        	            iRet = 1;
165                	    //break;
166	                }
167        	    }
168	        }
169
170        	sleep(1);
171
172	        retry --;
173	}
174
175    close(a_socket);
176    a_socket = 0;
177
178        unsigned int lan_netmask, lan_gateway, ip_addr_t;
179        lan_netmask = inet_addr(nvram_safe_get("lan_netmask"));
180        lan_gateway = inet_addr(nvram_safe_get("lan_gateway"));
181
182        char asus_device_buf[128] = {0};
183        char asus_device_list_buf[2048] = {0};
184        int getRouterIndex;
185
186        for (getRouterIndex = 0; getRouterIndex < a_GetRouterCount; getRouterIndex++)
187        {
188                ip_addr_t = inet_addr(searchRouterInfo[getRouterIndex].routerIPAddress);
189                sprintf(asus_device_buf, "<%d>%s>%s>%s>%d>%s>%s>%d",
190                3,
191                searchRouterInfo[getRouterIndex].routerProductID,
192                searchRouterInfo[getRouterIndex].routerIPAddress,
193                searchRouterInfo[getRouterIndex].routerRealMacAddress,
194                ((ip_addr_t&lan_netmask)==(lan_gateway&lan_netmask))?1:0,
195                searchRouterInfo[getRouterIndex].routerSSID,
196                searchRouterInfo[getRouterIndex].routerSubMask,
197                searchRouterInfo[getRouterIndex].routerOperationMode
198                );
199                strcat(asus_device_list_buf, asus_device_buf);
200        }
201   	nvram_set("asus_device_list", asus_device_list_buf);
202
203    return iRet;
204}
205
206int ParseASUSDiscoveryPackage(int socket)
207{
208	myAsusDiscoveryDebugPrint("----------ParseASUSDiscoveryPackage Start----------");
209
210	if (a_bEndApp)
211	{
212		myAsusDiscoveryDebugPrint("a_bEndApp = true");
213		return 0;
214	}
215
216	struct sockaddr_in from_addr;
217	socklen_t ifromlen = sizeof(from_addr);
218	char buf[INFO_PDU_LENGTH] = {0};
219	ssize_t iRet = recvfrom(socket , buf, INFO_PDU_LENGTH, 0, (struct sockaddr *)&from_addr, &ifromlen);
220	if (iRet <= 0)
221	{
222		myAsusDiscoveryDebugPrint("recvfrom function failed");
223		return 0;
224	}
225
226	PROCESS_UNPACK_GET_INFO(buf, from_addr);
227
228	return 1;
229}
230
231void PROCESS_UNPACK_GET_INFO(char *pbuf, struct sockaddr_in from_addr)
232{
233
234    PKT_GET_INFO get_discovery_info = {0};
235    STORAGE_INFO_T get_storage_info = {0};
236
237    int responseUnpackGetInfo = UnpackGetInfo_NEW(pbuf, &get_discovery_info, &get_storage_info);
238    if (responseUnpackGetInfo == RESPONSE_HDR_IGNORE ||
239        responseUnpackGetInfo == RESPONSE_HDR_ERR_UNSUPPORT)
240    {
241        return; // error data
242    }
243
244	// copy info to local buffer
245    // check whether buffer overflow!
246    if (a_GetRouterCount >= MAX_NO_OF_IBOX)
247        return;
248
249    //memcpy(txMac, get_discovery_info.MacAddress, 6);
250
251	//check MAC address for duplicate response
252    int getRouterIndex;
253    for (getRouterIndex = 0; getRouterIndex < a_GetRouterCount; getRouterIndex++)
254    {
255        if (memcmp(searchRouterInfo[getRouterIndex].routerMacAddress, get_discovery_info.MacAddress, 6) == 0)
256            return;
257    }
258
259	char cTemp1[128] = {0};
260    if ((get_discovery_info.PrinterInfo[0] == ' ' && get_discovery_info.PrinterInfo[1] == ' ' && get_discovery_info.PrinterInfo[2] == '\0') ||
261        (get_discovery_info.PrinterInfo[0] == '\0' && get_discovery_info.PrinterInfo[1] == '\0' && get_discovery_info.PrinterInfo[2] == '\0'))
262	{
263        //[sPrinterInfo stringWithFormat: @"%s", ""];
264	}
265    else
266    {
267	int i;
268        for (i=0; i<sizeof(get_discovery_info.PrinterInfo); i++)
269        {
270            cTemp1[i] = get_discovery_info.PrinterInfo[i];
271        }
272    }
273	memcpy(searchRouterInfo[a_GetRouterCount].routerPrinterInfo, cTemp1, 128);
274
275	char *pTemp = inet_ntoa(from_addr.sin_addr);
276	memcpy(searchRouterInfo[a_GetRouterCount].routerIPAddress, pTemp, 32);
277
278	char cTemp2[32] = {0};
279    sprintf(cTemp2, "%02X:%02X:%02X:%02X:%02X:%02X",(unsigned char)get_discovery_info.MacAddress[0], (unsigned char)get_discovery_info.MacAddress[1], (unsigned char)get_discovery_info.MacAddress[2], (unsigned char)get_discovery_info.MacAddress[3], (unsigned char)get_discovery_info.MacAddress[4], (unsigned char)get_discovery_info.MacAddress[5]);
280    memcpy(searchRouterInfo[a_GetRouterCount].routerRealMacAddress, cTemp2, 17);
281
282    memcpy(searchRouterInfo[a_GetRouterCount].routerSSID,            get_discovery_info.SSID,              32);
283    searchRouterInfo[a_GetRouterCount].routerSSID[32] = '\0';	/* get_discovery_info.SSID is not ASCIIZ string. */
284    memcpy(searchRouterInfo[a_GetRouterCount].routerSubMask,         get_discovery_info.NetMask,           32);
285    memcpy(searchRouterInfo[a_GetRouterCount].routerProductID,       get_discovery_info.ProductID,         32);
286    memcpy(searchRouterInfo[a_GetRouterCount].routerFirmwareVersion, get_discovery_info.FirmwareVersion,   16);
287	memcpy(searchRouterInfo[a_GetRouterCount].routerMacAddress,      get_discovery_info.MacAddress,        6);
288    searchRouterInfo[a_GetRouterCount].routerOperationMode =  get_discovery_info.OperationMode;
289    searchRouterInfo[a_GetRouterCount].routerRegulation =     get_discovery_info.Regulation;
290
291    char cTemp[512] = {0};
292    myAsusDiscoveryDebugPrint("********************* Search a Router ********************");
293    sprintf(cTemp, "Router ProductID : %s", searchRouterInfo[a_GetRouterCount].routerProductID);
294    myAsusDiscoveryDebugPrint(cTemp);
295    sprintf(cTemp, "Router SSID : %s", searchRouterInfo[a_GetRouterCount].routerSSID);
296    myAsusDiscoveryDebugPrint(cTemp);
297    sprintf(cTemp, "Router IPAddress : %s", searchRouterInfo[a_GetRouterCount].routerIPAddress);
298    myAsusDiscoveryDebugPrint(cTemp);
299    sprintf(cTemp, "Router MacAddress : %s", searchRouterInfo[a_GetRouterCount].routerRealMacAddress);
300    myAsusDiscoveryDebugPrint(cTemp);
301    sprintf(cTemp, "Router Firmware version : %s", searchRouterInfo[a_GetRouterCount].routerFirmwareVersion);
302    myAsusDiscoveryDebugPrint(cTemp);
303
304    if (searchRouterInfo[a_GetRouterCount].routerOperationMode == SW_MODE_ROUTER)
305    {
306        sprintf(cTemp, "Router Operation Mode : %d, ROUTER mode", searchRouterInfo[a_GetRouterCount].routerOperationMode);
307        myAsusDiscoveryDebugPrint(cTemp);
308    }
309    else if (searchRouterInfo[a_GetRouterCount].routerOperationMode == SW_MODE_REPEATER)
310    {
311        sprintf(cTemp, "Router Operation Mode : %d, REPEATER mode", searchRouterInfo[a_GetRouterCount].routerOperationMode);
312        myAsusDiscoveryDebugPrint(cTemp);
313    }
314    else if (searchRouterInfo[a_GetRouterCount].routerOperationMode == SW_MODE_AP)
315    {
316        sprintf(cTemp, "Router Operation Mode : %d, AP mode", searchRouterInfo[a_GetRouterCount].routerOperationMode);
317        myAsusDiscoveryDebugPrint(cTemp);
318    }
319    else if (searchRouterInfo[a_GetRouterCount].routerOperationMode == SW_MODE_HOTSPOT)
320    {
321        sprintf(cTemp, "Router Operation Mode : %d, HOTSPOT mode", searchRouterInfo[a_GetRouterCount].routerOperationMode);
322        myAsusDiscoveryDebugPrint(cTemp);
323    }
324    else
325    {
326        sprintf(cTemp, "Router Operation Mode : %d, Not support this flag!", searchRouterInfo[a_GetRouterCount].routerOperationMode);
327        myAsusDiscoveryDebugPrint(cTemp);
328	searchRouterInfo[a_GetRouterCount].routerOperationMode = 0;
329    }
330
331    if (responseUnpackGetInfo == RESPONSE_HDR_OK)
332    {
333        searchRouterInfo[a_GetRouterCount].webdavSupport = 0;
334
335        a_GetRouterCount++;
336
337        return;
338    }
339
340    // ap mode WAN IP address will be zero
341    unsigned int getWANIPAddr = get_storage_info.u.wt.WANIPAddr;
342    if (getWANIPAddr == 0)
343    {
344        searchRouterInfo[a_GetRouterCount].webdavSupport = 0;
345
346        a_GetRouterCount++;
347
348        return;
349    }
350
351    // save webdav info
352    searchRouterInfo[a_GetRouterCount].webdavSupport = 1;
353    searchRouterInfo[a_GetRouterCount].webdavEnableWebDav = get_storage_info.u.wt.EnableWebDav;
354    searchRouterInfo[a_GetRouterCount].webdavHttpType = get_storage_info.u.wt.HttpType;
355    searchRouterInfo[a_GetRouterCount].webdavHttpPort = htons(get_storage_info.u.wt.HttpPort);
356    searchRouterInfo[a_GetRouterCount].webdavHttpsPort = htons(get_storage_info.u.wt.HttpsPort);
357    searchRouterInfo[a_GetRouterCount].webdavEnableDDNS = get_storage_info.u.wt.EnableDDNS;
358    memcpy(searchRouterInfo[a_GetRouterCount].webdavHostName, get_storage_info.u.wt.HostName, 64);
359    searchRouterInfo[a_GetRouterCount].webdavWANIPAddr = getWANIPAddr;
360    searchRouterInfo[a_GetRouterCount].webdavWANState = htons(get_storage_info.u.wt.WANState);
361    searchRouterInfo[a_GetRouterCount].webdavIsNotDefault = htons(get_storage_info.u.wt.isNotDefault);
362
363    struct in_addr tempAddrWANIP = {0};
364    tempAddrWANIP.s_addr = searchRouterInfo[a_GetRouterCount].webdavWANIPAddr;
365    char *pTempWANIP = inet_ntoa(tempAddrWANIP);
366
367    // covert 1.1.168.192 to 192.168.1.1
368    char cTempWANIP[4][32];// = {0};
369    int indexCol = 0;
370    int indexRow = 0;
371    memset(cTempWANIP, 0, sizeof(char)*4*32);
372    while (*pTempWANIP != '\0')
373    {
374        if (indexCol == 4)
375            break;
376
377        if (*pTempWANIP != '.')
378        {
379            cTempWANIP[indexCol][indexRow] = *pTempWANIP;
380
381            pTempWANIP += 1;
382            indexRow += 1;
383        }
384        else
385        {
386            indexRow = 0;
387            indexCol += 1;
388            pTempWANIP += 1;
389        }
390    }
391
392    sprintf(searchRouterInfo[a_GetRouterCount].webdavWANIPAddress, "%s.%s.%s.%s", cTempWANIP[3], cTempWANIP[2], cTempWANIP[1], cTempWANIP[0]);
393
394    sprintf(cTemp, "Webdav Enable WebDav : %d", searchRouterInfo[a_GetRouterCount].webdavEnableWebDav);
395    myAsusDiscoveryDebugPrint(cTemp);
396    sprintf(cTemp, "Webdav Http Type : %d", searchRouterInfo[a_GetRouterCount].webdavHttpType);
397    myAsusDiscoveryDebugPrint(cTemp);
398    sprintf(cTemp, "Webdav Http Port : %d", searchRouterInfo[a_GetRouterCount].webdavHttpPort);
399    myAsusDiscoveryDebugPrint(cTemp);
400    sprintf(cTemp, "Webdav Https Port : %d", searchRouterInfo[a_GetRouterCount].webdavHttpsPort);
401    myAsusDiscoveryDebugPrint(cTemp);
402    sprintf(cTemp, "Webdav Enable DDNS : %d", searchRouterInfo[a_GetRouterCount].webdavEnableDDNS);
403    myAsusDiscoveryDebugPrint(cTemp);
404    sprintf(cTemp, "Webdav Host Name (DDNS Name) : %s", searchRouterInfo[a_GetRouterCount].webdavHostName);
405    myAsusDiscoveryDebugPrint(cTemp);
406    sprintf(cTemp, "Webdav WANIPAddr : %u", searchRouterInfo[a_GetRouterCount].webdavWANIPAddr);
407    myAsusDiscoveryDebugPrint(cTemp);
408    sprintf(cTemp, "Webdav WAN IP Address : %s", searchRouterInfo[a_GetRouterCount].webdavWANIPAddress);
409    myAsusDiscoveryDebugPrint(cTemp);
410
411    if (responseUnpackGetInfo == RESPONSE_HDR_OK_SUPPORT_WEBDAV)
412    {
413        searchRouterInfo[a_GetRouterCount].tunnelSupport = 0;
414
415        a_GetRouterCount++;
416
417        return;
418    }
419
420    // save tunnel info
421    searchRouterInfo[a_GetRouterCount].tunnelAppHttpPort =  get_storage_info.AppHttpPort;
422    searchRouterInfo[a_GetRouterCount].tunnelAppAPILevel = get_storage_info.AppAPILevel;
423    searchRouterInfo[a_GetRouterCount].tunnelEnableAAE = get_storage_info.EnableAAE;
424    memcpy(searchRouterInfo[a_GetRouterCount].tunnelAAEDeviceID, get_storage_info.AAEDeviceID, 64);
425
426    sprintf(cTemp, "Tunnel App Http Port : %d", searchRouterInfo[a_GetRouterCount].tunnelAppHttpPort);
427    myAsusDiscoveryDebugPrint(cTemp);
428    sprintf(cTemp, "Tunnel App API Level : %d", searchRouterInfo[a_GetRouterCount].tunnelAppAPILevel);
429    myAsusDiscoveryDebugPrint(cTemp);
430    sprintf(cTemp, "Tunnel Enable AAE : %d", searchRouterInfo[a_GetRouterCount].tunnelEnableAAE);
431    myAsusDiscoveryDebugPrint(cTemp);
432    sprintf(cTemp, "Tunnel AAE Device ID : %s", searchRouterInfo[a_GetRouterCount].tunnelAAEDeviceID);
433    myAsusDiscoveryDebugPrint(cTemp);
434
435    a_GetRouterCount++;
436}
437
438int main(void)
439{
440	return ASUS_Discovery();
441}
442