PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/MicroFrameworkPK_v4_2/DeviceCode/pal/lwip/SocketsDriver/lwIP__Sockets.cpp

https://bitbucket.org/pmfsampaio/netmf-lpc
C++ | 1124 lines | 850 code | 227 blank | 47 comment | 106 complexity | 260652a68cc2cc61a57640baf981b721 MD5 | raw file
  1. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4. #include "LWIP_sockets.h"
  5. #include "loopback_lwip_driver.h"
  6. extern "C"
  7. {
  8. #include "lwip\init.h"
  9. #include "lwip\tcpip.h"
  10. #include "lwip\dns.h"
  11. #include "lwip\netifapi.h"
  12. #include "lwip\tcp.h"
  13. #include <errno.h>
  14. }
  15. extern const HAL_CONFIG_BLOCK g_NetworkConfigHeader;
  16. extern LOOPBACK_LWIP_Driver g_LOOPBACK_LWIP_Driver;
  17. extern NETWORK_CONFIG g_NetworkConfig;
  18. //--//
  19. #if defined(DEBUG)
  20. #define DEBUG_HANDLE_SOCKET_ERROR(t,a)
  21. // assume there is something to add in later??
  22. #else
  23. #define DEBUG_HANDLE_SOCKET_ERROR(t,a)
  24. #endif
  25. struct netif *netif_find_interface(int num);
  26. //--//
  27. #if defined(ADS_LINKER_BUG__NOT_ALL_UNUSED_VARIABLES_ARE_REMOVED)
  28. #pragma arm section zidata = "g_LWIP_SOCKETS_Driver"
  29. #endif
  30. LWIP_SOCKETS_Driver g_LWIP_SOCKETS_Driver;
  31. #if defined(ADS_LINKER_BUG__NOT_ALL_UNUSED_VARIABLES_ARE_REMOVED)
  32. #pragma arm section zidata
  33. #endif
  34. //--//
  35. BOOL LWIP_SOCKETS_Driver::Initialize()
  36. {
  37. NATIVE_PROFILE_PAL_NETWORK();
  38. struct netif *pNetIf;
  39. int i;
  40. /* Initialize the raw lwIP stack and the tcp_tmr completion */
  41. lwip_init();
  42. #if defined(NETWORK_USE_LOOPBACK)
  43. /* Bind and Open the loopback driver */
  44. g_LOOPBACK_LWIP_Driver.Bind();
  45. g_LOOPBACK_LWIP_Driver.Open();
  46. #endif
  47. for(i=0; i<g_NetworkConfig.NetworkInterfaceCount; i++)
  48. {
  49. int interfaceNumber;
  50. SOCK_NetworkConfiguration *pNetCfg = &g_NetworkConfig.NetworkInterfaces[i];
  51. /* Bind and Open the Ethernet driver */
  52. Network_Interface_Bind( i );
  53. interfaceNumber = Network_Interface_Open( i );
  54. if (interfaceNumber == SOCK_SOCKET_ERROR)
  55. {
  56. DEBUG_HANDLE_SOCKET_ERROR("Network init", FALSE);
  57. debug_printf("SocketError: %d\n", errno);
  58. continue;
  59. }
  60. g_LWIP_SOCKETS_Driver.m_interfaces[i].m_interfaceNumber = interfaceNumber;
  61. UpdateAdapterConfiguration(i, SOCK_NETWORKCONFIGURATION_UPDATE_DHCP | SOCK_NETWORKCONFIGURATION_UPDATE_DNS, pNetCfg);
  62. // default debugger interface
  63. if(0 == i)
  64. {
  65. pNetIf = netif_find_interface(interfaceNumber);
  66. if (pNetIf)
  67. {
  68. UINT8* addr = (UINT8*)&pNetIf->ip_addr.addr;
  69. lcd_printf( "\f\n\n\n\n\n\n\nip address: %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3] );
  70. debug_printf( "ip address from interface info: %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3] );
  71. }
  72. }
  73. }
  74. return TRUE;
  75. }
  76. BOOL LWIP_SOCKETS_Driver::Uninitialize()
  77. {
  78. NATIVE_PROFILE_PAL_NETWORK();
  79. #if defined(NETWORK_USE_LOOPBACK)
  80. // close the loopback driver
  81. g_LOOPBACK_LWIP_Driver.Close();
  82. #endif
  83. for(int i=0; i<g_NetworkConfig.NetworkInterfaceCount; i++)
  84. {
  85. Network_Interface_Close(i);
  86. }
  87. lwip_uninit();
  88. return TRUE;
  89. }
  90. SOCK_SOCKET LWIP_SOCKETS_Driver::Socket(int family, int type, int protocol)
  91. {
  92. NATIVE_PROFILE_PAL_NETWORK();
  93. switch(protocol)
  94. {
  95. case SOCK_IPPROTO_TCP:
  96. protocol = IPPROTO_TCP;
  97. break;
  98. case SOCK_IPPROTO_UDP:
  99. protocol = IPPROTO_UDP;
  100. break;
  101. case SOCK_IPPROTO_ICMP:
  102. protocol = IP_PROTO_ICMP;
  103. break;
  104. case SOCK_IPPROTO_IGMP:
  105. protocol = IP_PROTO_IGMP;
  106. break;
  107. }
  108. return lwip_socket(family, type, protocol);
  109. }
  110. int LWIP_SOCKETS_Driver::Bind(SOCK_SOCKET socket, const SOCK_sockaddr* address, int addressLen)
  111. {
  112. NATIVE_PROFILE_PAL_NETWORK();
  113. sockaddr_in addr;
  114. SOCK_SOCKADDR_TO_SOCKADDR(address, addr, &addressLen);
  115. return lwip_bind(socket, (sockaddr*)&addr, addressLen);
  116. }
  117. int LWIP_SOCKETS_Driver::Connect(SOCK_SOCKET socket, const SOCK_sockaddr* address, int addressLen)
  118. {
  119. NATIVE_PROFILE_PAL_NETWORK();
  120. sockaddr_in addr;
  121. SOCK_SOCKADDR_TO_SOCKADDR(address, addr, &addressLen);
  122. return lwip_connect(socket, (sockaddr*)&addr, addressLen);
  123. }
  124. int LWIP_SOCKETS_Driver::Send(SOCK_SOCKET socket, const char* buf, int len, int flags)
  125. {
  126. NATIVE_PROFILE_PAL_NETWORK();
  127. return lwip_send(socket, (const void*)buf, len, flags);
  128. }
  129. int LWIP_SOCKETS_Driver::Recv(SOCK_SOCKET socket, char* buf, int len, int flags)
  130. {
  131. NATIVE_PROFILE_PAL_NETWORK();
  132. int nativeFlag;
  133. switch (flags)
  134. {
  135. case SOCKET_READ_PEEK_OPTION:
  136. nativeFlag = MSG_PEEK;
  137. break;
  138. default:
  139. nativeFlag = flags;
  140. break;
  141. }
  142. return lwip_recv(socket,(void*)buf, len, nativeFlag);
  143. }
  144. int LWIP_SOCKETS_Driver::Close(SOCK_SOCKET socket)
  145. {
  146. NATIVE_PROFILE_PAL_NETWORK();
  147. return lwip_close(socket);
  148. }
  149. int LWIP_SOCKETS_Driver::Listen(SOCK_SOCKET socket, int backlog)
  150. {
  151. NATIVE_PROFILE_PAL_NETWORK();
  152. return lwip_listen(socket, backlog);
  153. }
  154. SOCK_SOCKET LWIP_SOCKETS_Driver::Accept(SOCK_SOCKET socket, SOCK_sockaddr* address, int* addressLen)
  155. {
  156. NATIVE_PROFILE_PAL_NETWORK();
  157. SOCK_SOCKET ret;
  158. sockaddr_in addr;
  159. if (address)
  160. {
  161. SOCK_SOCKADDR_TO_SOCKADDR(address, addr, addressLen);
  162. }
  163. ret = lwip_accept(socket, address?(sockaddr*)&addr:NULL, (u32_t*)addressLen);
  164. if(address)
  165. {
  166. SOCKADDR_TO_SOCK_SOCKADDR(address, addr, addressLen);
  167. }
  168. return ret;
  169. }
  170. int LWIP_SOCKETS_Driver::Shutdown( SOCK_SOCKET socket, int how )
  171. {
  172. NATIVE_PROFILE_PAL_NETWORK();
  173. return lwip_shutdown (socket, how);
  174. }
  175. int LWIP_SOCKETS_Driver::GetAddrInfo(const char* nodename, char* servname, const SOCK_addrinfo* hints, SOCK_addrinfo** res)
  176. {
  177. #if LWIP_DNS
  178. NATIVE_PROFILE_PAL_NETWORK();
  179. SOCK_addrinfo *ai;
  180. SOCK_sockaddr_in *sa = NULL;
  181. int total_size = sizeof(SOCK_addrinfo) + sizeof(SOCK_sockaddr_in);
  182. struct addrinfo *lwipAddrinfo = NULL;
  183. if(res == NULL) return -1;
  184. *res = NULL;
  185. // if the nodename == "" then return the IP address of this device
  186. if(nodename[0] == 0 && servname == NULL)
  187. {
  188. struct netif *pNetIf = netif_find_interface(g_LWIP_SOCKETS_Driver.m_interfaces[0].m_interfaceNumber);
  189. if(pNetIf == NULL) return -1;
  190. ai = (SOCK_addrinfo*)mem_malloc(total_size);
  191. if (ai == NULL)
  192. {
  193. return -1;
  194. }
  195. memset(ai, 0, total_size);
  196. sa = (SOCK_sockaddr_in*)((u8_t*)ai + sizeof(SOCK_addrinfo));
  197. /* set up sockaddr */
  198. sa->sin_addr.S_un.S_addr = pNetIf->ip_addr.addr;
  199. sa->sin_family = AF_INET;
  200. sa->sin_port = 0;
  201. /* set up addrinfo */
  202. ai->ai_family = AF_INET;
  203. if (hints != NULL)
  204. {
  205. /* copy socktype & protocol from hints if specified */
  206. ai->ai_socktype = hints->ai_socktype;
  207. ai->ai_protocol = hints->ai_protocol;
  208. }
  209. ai->ai_addrlen = sizeof(SOCK_sockaddr_in);
  210. ai->ai_addr = (SOCK_sockaddr*)sa;
  211. *res = ai;
  212. return 0;
  213. }
  214. int err = lwip_getaddrinfo(nodename, servname, (addrinfo*)hints, &lwipAddrinfo);
  215. if(err == 0)
  216. {
  217. ///
  218. /// Marshal addrinfo data
  219. ///
  220. struct sockaddr_in* lwip_sockaddr_in;
  221. ai = (SOCK_addrinfo*)mem_malloc(total_size);
  222. if (ai == NULL)
  223. {
  224. lwip_freeaddrinfo(lwipAddrinfo);
  225. return -1;
  226. }
  227. memset(ai, 0, total_size);
  228. lwip_sockaddr_in = ((struct sockaddr_in*)lwipAddrinfo->ai_addr);
  229. sa = (SOCK_sockaddr_in*)((u8_t*)ai + sizeof(SOCK_addrinfo));
  230. /* set up sockaddr */
  231. sa->sin_addr.S_un.S_addr = lwip_sockaddr_in->sin_addr.s_addr;
  232. sa->sin_family = lwip_sockaddr_in->sin_family;
  233. sa->sin_port = lwip_sockaddr_in->sin_port;
  234. /* set up addrinfo */
  235. ai->ai_family = lwipAddrinfo->ai_family;
  236. if (hints != NULL)
  237. {
  238. /* copy socktype & protocol from hints if specified */
  239. ai->ai_socktype = hints->ai_socktype;
  240. ai->ai_protocol = hints->ai_protocol;
  241. }
  242. ai->ai_addrlen = sizeof(SOCK_sockaddr_in);
  243. ai->ai_addr = (SOCK_sockaddr*)sa;
  244. *res = ai;
  245. // free marshalled addrinfo
  246. lwip_freeaddrinfo(lwipAddrinfo);
  247. }
  248. else
  249. {
  250. err = -1;
  251. }
  252. return err;
  253. #else
  254. return -1;
  255. #endif
  256. }
  257. void LWIP_SOCKETS_Driver::FreeAddrInfo( SOCK_addrinfo* ai )
  258. {
  259. NATIVE_PROFILE_PAL_NETWORK();
  260. SOCK_addrinfo *next;
  261. while (ai != NULL) {
  262. next = ai->ai_next;
  263. mem_free(ai);
  264. ai = next;
  265. }
  266. }
  267. int LWIP_SOCKETS_Driver::Ioctl( SOCK_SOCKET socket, int cmd, int* data )
  268. {
  269. NATIVE_PROFILE_PAL_NETWORK();
  270. return lwip_ioctl(socket,cmd,data);
  271. }
  272. int LWIP_SOCKETS_Driver::GetLastError()
  273. {
  274. NATIVE_PROFILE_PAL_NETWORK();
  275. return GetNativeError(errno);
  276. }
  277. static int MARSHAL_SOCK_FDSET_TO_FDSET(SOCK_fd_set *sf, fd_set *f)
  278. {
  279. if(f != NULL && sf != NULL)
  280. {
  281. FD_ZERO(f);
  282. for(int i=0; i<sf->fd_count; i++)
  283. {
  284. FD_SET(sf->fd_array[i], f);
  285. }
  286. return sf->fd_count;
  287. }
  288. return 0;
  289. }
  290. static void MARSHAL_FDSET_TO_SOCK_FDSET(SOCK_fd_set *sf, fd_set *f)
  291. {
  292. if(sf != NULL && f != NULL)
  293. {
  294. sf->fd_count = 0;
  295. for(int i=0; i<sf->fd_count; i++)
  296. {
  297. if(FD_ISSET(sf->fd_array[i],f))
  298. {
  299. sf->fd_array[sf->fd_count] = sf->fd_array[i];
  300. sf->fd_count++;
  301. }
  302. }
  303. }
  304. }
  305. int LWIP_SOCKETS_Driver::Select( int nfds, SOCK_fd_set* readfds, SOCK_fd_set* writefds, SOCK_fd_set* exceptfds, const SOCK_timeval* timeout )
  306. {
  307. NATIVE_PROFILE_PAL_NETWORK();
  308. int ret = 0;
  309. fd_set read;
  310. fd_set write;
  311. fd_set excpt;
  312. fd_set* pR = (readfds != NULL) ? &read : NULL;
  313. fd_set* pW = (writefds != NULL) ? &write : NULL;
  314. fd_set* pE = (exceptfds != NULL) ? &excpt : NULL;
  315. // If the network goes down then we should alert any pending socket actions
  316. if(exceptfds != NULL && exceptfds->fd_count > 0)
  317. {
  318. struct netif *pNetIf = netif_find_interface(g_LWIP_SOCKETS_Driver.m_interfaces[0].m_interfaceNumber);
  319. if(pNetIf != NULL)
  320. {
  321. if(!netif_is_up(pNetIf))
  322. {
  323. if(readfds != NULL) readfds->fd_count = 0;
  324. if(writefds != NULL) writefds->fd_count = 0;
  325. errno = ENETDOWN;
  326. return exceptfds->fd_count;
  327. }
  328. }
  329. }
  330. MARSHAL_SOCK_FDSET_TO_FDSET(readfds , pR);
  331. MARSHAL_SOCK_FDSET_TO_FDSET(writefds , pW);
  332. MARSHAL_SOCK_FDSET_TO_FDSET(exceptfds, pE);
  333. ret = lwip_select(MEMP_NUM_NETCONN, pR, pW, pE, (struct timeval *)timeout);
  334. MARSHAL_FDSET_TO_SOCK_FDSET(readfds , pR);
  335. MARSHAL_FDSET_TO_SOCK_FDSET(writefds , pW);
  336. MARSHAL_FDSET_TO_SOCK_FDSET(exceptfds, pE);
  337. return ret;
  338. }
  339. int LWIP_SOCKETS_Driver::SetSockOpt( SOCK_SOCKET socket, int level, int optname, const char* optval, int optlen )
  340. {
  341. NATIVE_PROFILE_PAL_NETWORK();
  342. int nativeLevel;
  343. int nativeOptionName;
  344. int nativeIntValue;
  345. char *pNativeOptionValue = (char*)optval;
  346. switch(level)
  347. {
  348. case SOCK_IPPROTO_IP:
  349. nativeLevel = IPPROTO_IP;
  350. nativeOptionName = GetNativeIPOption(optname);
  351. break;
  352. case SOCK_IPPROTO_TCP:
  353. nativeLevel = IPPROTO_TCP;
  354. nativeOptionName = GetNativeTcpOption(optname);
  355. break;
  356. case SOCK_IPPROTO_UDP:
  357. case SOCK_IPPROTO_ICMP:
  358. case SOCK_IPPROTO_IGMP:
  359. case SOCK_IPPROTO_IPV4:
  360. case SOCK_SOL_SOCKET:
  361. nativeLevel = SOL_SOCKET;
  362. nativeOptionName = GetNativeSockOption(optname);
  363. switch(optname)
  364. {
  365. case SOCK_SOCKO_EXCLUSIVEADDRESSUSE:
  366. case SOCK_SOCKO_DONTLINGER:
  367. nativeIntValue = !*(int*)optval;
  368. pNativeOptionValue = (char*)&nativeIntValue;
  369. break;
  370. default:
  371. break;
  372. }
  373. break;
  374. default:
  375. nativeLevel = 0;
  376. nativeOptionName = 0;
  377. break;
  378. }
  379. return lwip_setsockopt(socket, nativeLevel, nativeOptionName, pNativeOptionValue, optlen);
  380. }
  381. int LWIP_SOCKETS_Driver::GetSockOpt( SOCK_SOCKET socket, int level, int optname, char* optval, int* optlen )
  382. {
  383. NATIVE_PROFILE_PAL_NETWORK();
  384. int nativeLevel;
  385. int nativeOptionName;
  386. char* pNativeOptval = optval;
  387. int ret;
  388. switch(level)
  389. {
  390. case SOCK_IPPROTO_IP:
  391. nativeLevel = IPPROTO_IP;
  392. nativeOptionName = GetNativeIPOption(optname);
  393. break;
  394. case SOCK_IPPROTO_TCP:
  395. nativeLevel = IPPROTO_TCP;
  396. nativeOptionName = GetNativeTcpOption(optname);
  397. break;
  398. case SOCK_IPPROTO_UDP:
  399. case SOCK_IPPROTO_ICMP:
  400. case SOCK_IPPROTO_IGMP:
  401. case SOCK_IPPROTO_IPV4:
  402. case SOCK_SOL_SOCKET:
  403. nativeLevel = SOL_SOCKET;
  404. nativeOptionName = GetNativeSockOption(optname);
  405. break;
  406. default:
  407. nativeLevel = level;
  408. nativeOptionName = optname;
  409. break;
  410. }
  411. ret = lwip_getsockopt(socket, nativeLevel, nativeOptionName, pNativeOptval, (u32_t*)optlen);
  412. if(ret == 0)
  413. {
  414. switch(level)
  415. {
  416. case SOCK_SOL_SOCKET:
  417. switch(optname)
  418. {
  419. case SOCK_SOCKO_EXCLUSIVEADDRESSUSE:
  420. case SOCK_SOCKO_DONTLINGER:
  421. *optval = !(*(int*)optval != 0);
  422. break;
  423. case SOCK_SOCKO_ACCEPTCONNECTION:
  424. case SOCK_SOCKO_BROADCAST:
  425. case SOCK_SOCKO_KEEPALIVE:
  426. *optval = (*(int*)optval != 0);
  427. break;
  428. }
  429. break;
  430. }
  431. }
  432. return ret;
  433. }
  434. int LWIP_SOCKETS_Driver::GetPeerName( SOCK_SOCKET socket, SOCK_sockaddr* name, int* namelen )
  435. {
  436. NATIVE_PROFILE_PAL_NETWORK();
  437. int ret;
  438. sockaddr_in addr;
  439. SOCK_SOCKADDR_TO_SOCKADDR(name, addr, namelen);
  440. ret = lwip_getpeername(socket, (sockaddr*)&addr, (u32_t*)namelen);
  441. SOCKADDR_TO_SOCK_SOCKADDR(name, addr, namelen);
  442. return ret;
  443. }
  444. int LWIP_SOCKETS_Driver::GetSockName( SOCK_SOCKET socket, SOCK_sockaddr* name, int* namelen )
  445. {
  446. NATIVE_PROFILE_PAL_NETWORK();
  447. int ret;
  448. sockaddr_in addr;
  449. SOCK_SOCKADDR_TO_SOCKADDR(name, addr, namelen);
  450. ret = lwip_getsockname(socket, (sockaddr*)&addr, (u32_t*)namelen);
  451. SOCKADDR_TO_SOCK_SOCKADDR(name, addr, namelen);
  452. return ret;
  453. }
  454. int LWIP_SOCKETS_Driver::RecvFrom( SOCK_SOCKET socket, char* buf, int len, int flags, SOCK_sockaddr* from, int* fromlen )
  455. {
  456. NATIVE_PROFILE_PAL_NETWORK();
  457. sockaddr_in addr;
  458. sockaddr *pFrom = NULL;
  459. int ret;
  460. if(from)
  461. {
  462. SOCK_SOCKADDR_TO_SOCKADDR(from, addr, fromlen);
  463. pFrom = (sockaddr*)&addr;
  464. }
  465. ret = lwip_recvfrom(socket, buf, len, flags, pFrom, (u32_t*)fromlen);
  466. if(from && ret != SOCK_SOCKET_ERROR)
  467. {
  468. SOCKADDR_TO_SOCK_SOCKADDR(from, addr, fromlen);
  469. }
  470. return ret;
  471. }
  472. int LWIP_SOCKETS_Driver::SendTo( SOCK_SOCKET socket, const char* buf, int len, int flags, const SOCK_sockaddr* to, int tolen )
  473. {
  474. NATIVE_PROFILE_PAL_NETWORK();
  475. sockaddr_in addr;
  476. SOCK_SOCKADDR_TO_SOCKADDR(to, addr, &tolen);
  477. return lwip_sendto(socket, buf, len, flags, (sockaddr*)&addr, (u32_t)tolen);
  478. }
  479. UINT32 LWIP_SOCKETS_Driver::GetAdapterCount()
  480. {
  481. NATIVE_PROFILE_PAL_NETWORK();
  482. return NETWORK_INTERFACE_COUNT;
  483. }
  484. HRESULT LWIP_SOCKETS_Driver::LoadAdapterConfiguration( UINT32 interfaceIndex, SOCK_NetworkConfiguration* config )
  485. {
  486. NATIVE_PROFILE_PAL_NETWORK();
  487. if(interfaceIndex >= NETWORK_INTERFACE_COUNT)
  488. {
  489. return CLR_E_INVALID_PARAMETER;
  490. }
  491. memcpy(config, &g_NetworkConfig.NetworkInterfaces[interfaceIndex], sizeof(g_NetworkConfig.NetworkInterfaces[interfaceIndex]));
  492. if(config->flags & SOCK_NETWORKCONFIGURATION_FLAGS_DHCP)
  493. {
  494. struct netif *pNetIf;
  495. if (pNetIf = netif_find_interface(g_LWIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_interfaceNumber))
  496. {
  497. config->ipaddr = pNetIf->ip_addr.addr;
  498. config->subnetmask = pNetIf->netmask.addr;
  499. config->gateway = pNetIf->gw.addr;
  500. #if LWIP_DNS
  501. config->dnsServer1 = dns_getserver(0).addr;
  502. config->dnsServer2 = dns_getserver(1).addr;
  503. #endif
  504. }
  505. else
  506. {
  507. config->ipaddr = 0;
  508. config->subnetmask = 0;
  509. config->gateway = 0;
  510. }
  511. }
  512. return S_OK;
  513. }
  514. HRESULT LWIP_SOCKETS_Driver::LoadWirelessConfiguration( UINT32 interfaceIndex, SOCK_WirelessConfiguration* wirelessConfig )
  515. {
  516. /// Load wireless specific settings if any. You must return S_OK, otherwise default values will be
  517. /// loaded by PAL.
  518. return CLR_E_FAIL;
  519. }
  520. struct dhcp_client_id
  521. {
  522. UINT8 code;
  523. UINT8 length;
  524. UINT8 type;
  525. UINT8 clientId[6];
  526. };
  527. HRESULT LWIP_SOCKETS_Driver::UpdateAdapterConfiguration( UINT32 interfaceIndex, UINT32 updateFlags, SOCK_NetworkConfiguration* config )
  528. {
  529. NATIVE_PROFILE_PAL_NETWORK();
  530. if(interfaceIndex >= NETWORK_INTERFACE_COUNT)
  531. {
  532. return CLR_E_INVALID_PARAMETER;
  533. }
  534. BOOL fEnableDhcp = (0 != (config->flags & SOCK_NETWORKCONFIGURATION_FLAGS_DHCP));
  535. BOOL fDynamicDns = (0 != (config->flags & SOCK_NETWORKCONFIGURATION_FLAGS_DYNAMIC_DNS));
  536. BOOL fDhcpStarted;
  537. struct netif *pNetIf = netif_find_interface(g_LWIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_interfaceNumber);
  538. if (NULL == pNetIf)
  539. {
  540. return CLR_E_FAIL;
  541. }
  542. fDhcpStarted = (0 != (pNetIf->flags & NETIF_FLAG_DHCP));
  543. #if LWIP_DNS
  544. // when using DHCP do not use the static settings
  545. if(0 != (updateFlags & SOCK_NETWORKCONFIGURATION_UPDATE_DNS))
  546. {
  547. // if dynamic dns is on, then we will set the corresonding NetIF flag
  548. // resetting dhcp if necessary.
  549. if(fDynamicDns || (config->dnsServer1 == 0 && config->dnsServer2 == 0))
  550. {
  551. if(0 == (pNetIf->flags & NETIF_FLAG_DYNAMIC_DNS))
  552. {
  553. pNetIf->flags |= NETIF_FLAG_DYNAMIC_DNS;
  554. // if dhcp is active, we need to reset in order to get the dynamic
  555. // dns
  556. if(fEnableDhcp && fDhcpStarted)
  557. {
  558. dhcp_stop(pNetIf);
  559. dhcp_start(pNetIf);
  560. }
  561. }
  562. }
  563. else
  564. {
  565. // user defined DNS addresses
  566. if(config->dnsServer1 != 0)
  567. {
  568. u8_t idx = 0;
  569. dns_setserver(idx, (struct ip_addr *)&config->dnsServer1);
  570. }
  571. if(config->dnsServer2 != 0)
  572. {
  573. u8_t idx = 1;
  574. dns_setserver(idx, (struct ip_addr *)&config->dnsServer2);
  575. }
  576. pNetIf->flags &= ~NETIF_FLAG_DYNAMIC_DNS;
  577. }
  578. }
  579. #endif
  580. #if LWIP_DHCP
  581. if(0 != (updateFlags & SOCK_NETWORKCONFIGURATION_UPDATE_DHCP))
  582. {
  583. if(fEnableDhcp)
  584. {
  585. if(!fDhcpStarted)
  586. {
  587. if(ERR_OK != dhcp_start(pNetIf))
  588. {
  589. return CLR_E_FAIL;
  590. }
  591. }
  592. }
  593. else if(fDhcpStarted)
  594. {
  595. dhcp_stop(pNetIf);
  596. netif_set_addr(pNetIf, (struct ip_addr *) &config->ipaddr, (struct ip_addr *)&config->subnetmask, (struct ip_addr *)&config->gateway);
  597. Network_PostEvent( NETWORK_EVENT_TYPE_ADDRESS_CHANGED, 0 );
  598. }
  599. }
  600. if(fEnableDhcp && fDhcpStarted)
  601. {
  602. if(0 != (updateFlags & SOCK_NETWORKCONFIGURATION_UPDATE_DHCP_RELEASE))
  603. {
  604. //netifapi_netif_common(pNetIf, NULL, dhcp_release);
  605. dhcp_release(pNetIf);
  606. }
  607. if(0 != (updateFlags & SOCK_NETWORKCONFIGURATION_UPDATE_DHCP_RENEW))
  608. {
  609. //netifapi_netif_common(pNetIf, NULL, dhcp_renew);
  610. dhcp_renew(pNetIf);
  611. }
  612. }
  613. #endif
  614. if(0 != (updateFlags & SOCK_NETWORKCONFIGURATION_UPDATE_MAC))
  615. {
  616. int len = __min(config->macAddressLen, sizeof(pNetIf->hwaddr));
  617. memcpy(pNetIf->hwaddr, config->macAddressBuffer, len);
  618. pNetIf->hwaddr_len = len;
  619. // mac address requires stack re-init
  620. Network_Interface_Close(interfaceIndex);
  621. g_LWIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_interfaceNumber = Network_Interface_Open(interfaceIndex);
  622. }
  623. return S_OK;
  624. }
  625. int LWIP_SOCKETS_Driver::GetNativeTcpOption (int optname)
  626. {
  627. NATIVE_PROFILE_PAL_NETWORK();
  628. int nativeOptionName = 0;
  629. switch(optname)
  630. {
  631. case SOCK_TCP_NODELAY:
  632. nativeOptionName = TCP_NODELAY;
  633. break;
  634. case SOCK_SOCKO_KEEPALIVE:
  635. nativeOptionName = TCP_KEEPALIVE;
  636. break;
  637. // allow the C# user to specify LWIP options that our managed enum
  638. // doesn't support
  639. default:
  640. nativeOptionName = optname;
  641. break;
  642. }
  643. return nativeOptionName;
  644. }
  645. int LWIP_SOCKETS_Driver::GetNativeSockOption (int optname)
  646. {
  647. NATIVE_PROFILE_PAL_NETWORK();
  648. int nativeOptionName = 0;
  649. switch(optname)
  650. {
  651. case SOCK_SOCKO_DONTLINGER:
  652. case SOCK_SOCKO_LINGER:
  653. nativeOptionName = SO_LINGER;
  654. break;
  655. case SOCK_SOCKO_SENDTIMEOUT:
  656. nativeOptionName = SO_SNDTIMEO;
  657. break;
  658. case SOCK_SOCKO_RECEIVETIMEOUT:
  659. nativeOptionName = SO_RCVTIMEO;
  660. break;
  661. case SOCK_SOCKO_EXCLUSIVEADDRESSUSE:
  662. case SOCK_SOCKO_REUSEADDRESS:
  663. nativeOptionName = SO_REUSEADDR;
  664. break;
  665. case SOCK_SOCKO_KEEPALIVE:
  666. nativeOptionName = SO_KEEPALIVE;
  667. break;
  668. case SOCK_SOCKO_ERROR:
  669. nativeOptionName = SO_ERROR;
  670. break;
  671. case SOCK_SOCKO_BROADCAST:
  672. nativeOptionName = SO_BROADCAST;
  673. break;
  674. case SOCK_SOCKO_RECEIVEBUFFER:
  675. nativeOptionName = SO_RCVBUF;
  676. break;
  677. case SOCK_SOCKO_SENDBUFFER:
  678. nativeOptionName = SO_SNDBUF;
  679. break;
  680. case SOCK_SOCKO_ACCEPTCONNECTION:
  681. nativeOptionName = SO_ACCEPTCONN;
  682. break;
  683. case SOCK_SOCKO_TYPE:
  684. nativeOptionName = SO_TYPE;
  685. break;
  686. case SOCK_SOCKO_USELOOPBACK:
  687. nativeOptionName = SO_USELOOPBACK;
  688. break;
  689. case SOCK_SOCKO_DONTROUTE:
  690. nativeOptionName = SO_DONTROUTE;
  691. break;
  692. case SOCK_SOCKO_OUTOFBANDINLINE:
  693. nativeOptionName = SO_OOBINLINE;
  694. break;
  695. case SOCK_SOCKO_DEBUG:
  696. nativeOptionName = SO_DEBUG;
  697. break;
  698. case SOCK_SOCKO_SENDLOWWATER:
  699. nativeOptionName = SO_SNDLOWAT;
  700. break;
  701. case SOCK_SOCKO_RECEIVELOWWATER:
  702. nativeOptionName = SO_RCVLOWAT;
  703. break;
  704. // case SOCK_SOCKO_MAXCONNECTIONS: //don't support
  705. case SOCK_SOCKO_UPDATE_ACCEPT_CTX:
  706. case SOCK_SOCKO_UPDATE_CONNECT_CTX:
  707. nativeOptionName = 0;
  708. break;
  709. // allow the C# user to specify LWIP options that our managed enum
  710. // doesn't support
  711. default:
  712. nativeOptionName = optname;
  713. break;
  714. }
  715. return nativeOptionName;
  716. }
  717. int LWIP_SOCKETS_Driver::GetNativeIPOption (int optname)
  718. {
  719. NATIVE_PROFILE_PAL_NETWORK();
  720. int nativeOptionName = 0;
  721. switch(optname)
  722. {
  723. case SOCK_IPO_TTL:
  724. nativeOptionName = IP_TTL;
  725. break;
  726. case SOCK_IPO_TOS:
  727. nativeOptionName = IP_TOS;
  728. break;
  729. #if LWIP_IGMP
  730. case SOCK_IPO_MULTICAST_IF:
  731. nativeOptionName = IP_MULTICAST_IF;
  732. break;
  733. case SOCK_IPO_MULTICAST_TTL:
  734. nativeOptionName = IP_MULTICAST_TTL;
  735. break;
  736. case SOCK_IPO_MULTICAST_LOOP:
  737. nativeOptionName = IP_MULTICAST_LOOP;
  738. break;
  739. case SOCK_IPO_ADD_MEMBERSHIP:
  740. nativeOptionName = IP_ADD_MEMBERSHIP;
  741. break;
  742. case SOCK_IPO_DROP_MEMBERSHIP:
  743. nativeOptionName = IP_DROP_MEMBERSHIP;
  744. break;
  745. #else
  746. case SOCK_IPO_MULTICAST_IF:
  747. case SOCK_IPO_MULTICAST_TTL:
  748. case SOCK_IPO_MULTICAST_LOOP:
  749. case SOCK_IPO_ADD_MEMBERSHIP:
  750. case SOCK_IPO_DROP_MEMBERSHIP:
  751. #endif
  752. case SOCK_IPO_ADD_SOURCE_MEMBERSHIP:
  753. case SOCK_IPO_DROP_SOURCE_MEMBERSHIP:
  754. case SOCK_IPO_OPTIONS:
  755. case SOCK_IPO_HDRINCL:
  756. case SOCK_IPO_IP_DONTFRAGMENT:
  757. case SOCK_IPO_BLOCK_SOURCE:
  758. case SOCK_IPO_UBLOCK_SOURCE:
  759. case SOCK_IPO_PACKET_INFO:
  760. nativeOptionName = 0;
  761. break;
  762. // allow the C# user to specify LWIP options that our managed enum
  763. // doesn't support
  764. default:
  765. nativeOptionName = optname;
  766. break;
  767. }
  768. return nativeOptionName;
  769. }
  770. int LWIP_SOCKETS_Driver::GetNativeError ( int error )
  771. {
  772. NATIVE_PROFILE_PAL_NETWORK();
  773. int ret;
  774. switch(error)
  775. {
  776. case EINTR:
  777. ret = SOCK_EINTR;
  778. break;
  779. case EACCES:
  780. ret = SOCK_EACCES;
  781. break;
  782. case EFAULT:
  783. ret = SOCK_EFAULT;
  784. break;
  785. case EINVAL:
  786. ret = SOCK_EINVAL;
  787. break;
  788. case EMFILE:
  789. ret = SOCK_EMFILE;
  790. break;
  791. case EAGAIN:
  792. case EBUSY:
  793. /* case EWOULDBLOCK: same as EINPROGRESS */
  794. case EINPROGRESS:
  795. ret = SOCK_EWOULDBLOCK;
  796. break;
  797. case EALREADY:
  798. ret = SOCK_EALREADY;
  799. break;
  800. case ENOTSOCK:
  801. ret = SOCK_ENOTSOCK;
  802. break;
  803. case EDESTADDRREQ:
  804. ret = SOCK_EDESTADDRREQ;
  805. break;
  806. case EMSGSIZE:
  807. ret = SOCK_EMSGSIZE;
  808. break;
  809. case EPROTOTYPE:
  810. ret = SOCK_EPROTOTYPE;
  811. break;
  812. case ENOPROTOOPT:
  813. ret = SOCK_ENOPROTOOPT;
  814. break;
  815. case EPROTONOSUPPORT:
  816. ret = SOCK_EPROTONOSUPPORT;
  817. break;
  818. case ESOCKTNOSUPPORT:
  819. ret = SOCK_ESOCKTNOSUPPORT;
  820. break;
  821. case EPFNOSUPPORT:
  822. ret = SOCK_EPFNOSUPPORT;
  823. break;
  824. case EAFNOSUPPORT:
  825. ret = SOCK_EAFNOSUPPORT;
  826. break;
  827. case EADDRINUSE:
  828. ret = SOCK_EADDRINUSE;
  829. break;
  830. case EADDRNOTAVAIL:
  831. ret = SOCK_EADDRNOTAVAIL;
  832. break;
  833. case ENETDOWN:
  834. ret = SOCK_ENETDOWN;
  835. break;
  836. case ENETUNREACH:
  837. ret = SOCK_ENETUNREACH;
  838. break;
  839. case ENETRESET:
  840. ret = SOCK_ENETRESET;
  841. break;
  842. case ECONNABORTED:
  843. ret = SOCK_ECONNABORTED;
  844. break;
  845. case ECONNRESET:
  846. ret = SOCK_ECONNRESET;
  847. break;
  848. case ENOBUFS:
  849. case ENOMEM:
  850. ret = SOCK_ENOBUFS;
  851. break;
  852. case EISCONN:
  853. ret = SOCK_EISCONN;
  854. break;
  855. case ENOTCONN:
  856. ret = SOCK_EISCONN;
  857. break;
  858. case ESHUTDOWN:
  859. ret = SOCK_ESHUTDOWN;
  860. break;
  861. case ETIMEDOUT:
  862. ret = SOCK_ETIMEDOUT;
  863. break;
  864. case ECONNREFUSED:
  865. ret = SOCK_ECONNREFUSED;
  866. break;
  867. case EHOSTDOWN:
  868. ret = SOCK_EHOSTDOWN;
  869. break;
  870. case EHOSTUNREACH:
  871. ret = SOCK_EHOSTUNREACH;
  872. break;
  873. case ENODATA:
  874. ret = SOCK_NO_DATA;
  875. break;
  876. default:
  877. ret = error;
  878. break;
  879. }
  880. return (ret);
  881. }
  882. /**
  883. * Find a network interface by searching for its number
  884. * Similar to LWIP's netif_find(char *name)
  885. */
  886. struct netif *netif_find_interface(int num)
  887. {
  888. struct netif *pNetIf;
  889. for (pNetIf = netif_list; pNetIf != NULL; pNetIf = pNetIf->next)
  890. {
  891. if (num == pNetIf->num)
  892. {
  893. return pNetIf;
  894. }
  895. }
  896. return NULL;
  897. }