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