PageRenderTime 59ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

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

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