PageRenderTime 63ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/MicroFrameworkPK_v4_1/DeviceCode/pal/rtip/SocketsDriver/RTIP__Sockets.cpp

https://bitbucket.org/pmfsampaio/netmf-lpc
C++ | 1173 lines | 940 code | 199 blank | 34 comment | 122 complexity | 3cc24146db95ce9787836cddf0e2dbf6 MD5 | raw file
  1. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4. #include "RTIP_sockets.h"
  5. #include "net_decl.h"
  6. #include "xnconf.h"
  7. #include "rtipconf.h"
  8. #include "rtipapi.h"
  9. #include "socket.h"
  10. #include "pollos.h"
  11. #include "bget.h"
  12. #include "rtpnet.h"
  13. #include "dhcpcapi.h"
  14. #include "loopback_driver.h"
  15. #include "rtipext.h"
  16. #include "rtpnet.h"
  17. /* JRT */
  18. #include "rtpprint.h"
  19. //--//
  20. /* JRT */
  21. extern int default_mcast_iface;
  22. extern const HAL_CONFIG_BLOCK g_NetworkConfigHeader;
  23. extern LOOPBACK_Driver g_LOOPBACK_Driver;
  24. extern NETWORK_CONFIG g_NetworkConfig;
  25. //--//
  26. #if defined(DEBUG)
  27. #define DEBUG_HANDLE_SOCKET_ERROR(t,a) \
  28. int iErr = xn_getlasterror(); \
  29. const char* textErr = xn_geterror_string(iErr); \
  30. debug_printf( "%s failed! %d: %s\r\n", t, iErr, textErr ); \
  31. ASSERT(!(a))
  32. #else
  33. #define DEBUG_HANDLE_SOCKET_ERROR(t,a)
  34. #endif
  35. //--//
  36. #if defined(ADS_LINKER_BUG__NOT_ALL_UNUSED_VARIABLES_ARE_REMOVED)
  37. #pragma arm section zidata = "g_RTIP_SOCKETS_Driver"
  38. #endif
  39. RTIP_SOCKETS_Driver g_RTIP_SOCKETS_Driver;
  40. #if defined(ADS_LINKER_BUG__NOT_ALL_UNUSED_VARIABLES_ARE_REMOVED)
  41. #pragma arm section zidata
  42. #endif
  43. //--//
  44. BOOL RTIP_SOCKETS_Driver::Initialize()
  45. {
  46. NATIVE_PROFILE_PAL_NETWORK();
  47. IFACE_INFO info;
  48. memset(g_RTIP_SOCKETS_Driver.m_interfaces, 0, sizeof(g_RTIP_SOCKETS_Driver.m_interfaces));
  49. /* Initialize the network stack */
  50. if (rtp_net_init() != 0)
  51. {
  52. DEBUG_HANDLE_SOCKET_ERROR("rtp_net_init", TRUE);
  53. return FALSE;
  54. }
  55. #if defined(NETWORK_USE_LOOPBACK)
  56. // Bind and Open the loopback driver
  57. g_LOOPBACK_Driver.Bind();
  58. if (g_LOOPBACK_Driver.Open() == SOCK_SOCKET_ERROR)
  59. {
  60. DEBUG_HANDLE_SOCKET_ERROR("loopback init", FALSE);
  61. }
  62. #endif
  63. for(int i=0; i<g_NetworkConfig.NetworkInterfaceCount; i++)
  64. {
  65. int interfaceNumber;
  66. SOCK_NetworkConfiguration *pNetCfg = &g_NetworkConfig.NetworkInterfaces[i];
  67. Network_Interface_Bind(i);
  68. interfaceNumber = Network_Interface_Open(i);
  69. if (interfaceNumber == SOCK_SOCKET_ERROR)
  70. {
  71. DEBUG_HANDLE_SOCKET_ERROR("Network init", FALSE);
  72. debug_printf("SocketError: %d\n", xn_getlasterror());
  73. continue;
  74. }
  75. g_RTIP_SOCKETS_Driver.m_interfaces[i].m_interfaceNumber = interfaceNumber;
  76. UpdateAdapterConfiguration(i, SOCK_NETWORKCONFIGURATION_UPDATE_DHCP | SOCK_NETWORKCONFIGURATION_UPDATE_DNS, pNetCfg);
  77. // default debugger interface
  78. if(0 == i)
  79. {
  80. // add multicast addresses to the routing table
  81. UINT32 mcast1 = SOCK_htonl(SOCK_DISCOVERY_MULTICAST_IPADDR);
  82. UINT32 mcast2 = SOCK_htonl(SOCK_DISCOVERY_MULTICAST_IPADDR_SND);
  83. UINT32 mask = SOCK_htonl(SOCK_MAKE_IP_ADDR(255,255,255,255));
  84. if(SOCK_SOCKET_ERROR == xn_rt_add((RTP_PFCUINT8)&mcast1, (RTP_PFUINT8)&mask, (RTP_PFUINT8)0, RT_USEIFACEMETRIC, interfaceNumber, RT_INF))
  85. {
  86. DEBUG_HANDLE_SOCKET_ERROR("Multicast xn_rt_add (recv)", FALSE);
  87. }
  88. if(SOCK_SOCKET_ERROR == xn_rt_add((RTP_PFCUINT8)&mcast2, (RTP_PFUINT8)&mask, (RTP_PFUINT8)0, RT_USEIFACEMETRIC, interfaceNumber, RT_INF))
  89. {
  90. DEBUG_HANDLE_SOCKET_ERROR("Multicast xn_rt_add (send)", FALSE);
  91. }
  92. /* JRT - TBD call xn_ip_set_option */
  93. default_mcast_iface = interfaceNumber;
  94. xn_interface_info(interfaceNumber, &info );
  95. debug_printf( "ip address from interface info: %d.%d.%d.%d\r\n", (UINT32)info.my_ip_address[0],
  96. (UINT32)info.my_ip_address[1],
  97. (UINT32)info.my_ip_address[2],
  98. (UINT32)info.my_ip_address[3] );
  99. debug_printf( "mac addrress from interface info: %x.%x.%x.%x.%x.%x\r\n", (UINT32)info.my_ethernet_address[0],
  100. (UINT32)info.my_ethernet_address[1],
  101. (UINT32)info.my_ethernet_address[2],
  102. (UINT32)info.my_ethernet_address[3],
  103. (UINT32)info.my_ethernet_address[4],
  104. (UINT32)info.my_ethernet_address[5] );
  105. }
  106. }
  107. return TRUE;
  108. }
  109. BOOL RTIP_SOCKETS_Driver::Uninitialize()
  110. {
  111. NATIVE_PROFILE_PAL_NETWORK();
  112. const int c_exitTimeout = 1; // secs
  113. int exitRetries = 3;
  114. bool fEnabled = INTERRUPTS_ENABLED_STATE();
  115. if(!fEnabled) ENABLE_INTERRUPTS();
  116. while(exitRetries--)
  117. {
  118. if(!xn_wait_pkts_output( RTP_TRUE, c_exitTimeout * rtp_get_ticks_p_sec() )) break;
  119. while(HAL_CONTINUATION::Dequeue_And_Execute());
  120. }
  121. if(!fEnabled) DISABLE_INTERRUPTS();
  122. #if defined(NETWORK_USE_LOOPBACK)
  123. // close the loopback driver
  124. g_LOOPBACK_Driver.Close();
  125. #endif
  126. for(int i=0; i<g_NetworkConfig.NetworkInterfaceCount; i++)
  127. {
  128. UpdateAdapterConfiguration(i, SOCK_NETWORKCONFIGURATION_UPDATE_DHCP_RELEASE, &g_NetworkConfig.NetworkInterfaces[i]);
  129. Network_Interface_Close(i);
  130. }
  131. rtp_net_exit();
  132. return TRUE;
  133. }
  134. SOCK_SOCKET RTIP_SOCKETS_Driver::Socket( int family, int type, int protocol )
  135. {
  136. NATIVE_PROFILE_PAL_NETWORK();
  137. SOCK_SOCKET socketHandle;
  138. int nativeType;
  139. int nativeFamily;
  140. switch(type)
  141. {
  142. case SOCK_SOCK_STREAM:
  143. nativeType = RTP_NET_SOCK_STREAM;
  144. break;
  145. case SOCK_SOCK_DGRAM:
  146. nativeType = RTP_NET_SOCK_DGRAM;
  147. break;
  148. case SOCK_SOCK_RAW:
  149. nativeType = RTP_NET_SOCK_RAW;
  150. break;
  151. default:
  152. nativeType = 0;
  153. break;
  154. }
  155. switch (family)
  156. {
  157. case SOCK_AF_INET:
  158. nativeFamily = RTP_NET_AF_INET;
  159. break;
  160. default:
  161. nativeFamily = 0;
  162. break;
  163. }
  164. rtp_net_socket((RTP_SOCKET *)&socketHandle, nativeFamily, nativeType, protocol);
  165. return socketHandle;
  166. }
  167. int RTIP_SOCKETS_Driver::Bind( SOCK_SOCKET socket, const SOCK_sockaddr* address, int addressLen )
  168. {
  169. NATIVE_PROFILE_PAL_NETWORK();
  170. int ret;
  171. unsigned char *ipAddr;
  172. int port;
  173. port = ((SOCK_sockaddr_in *) address)->sin_port;
  174. ipAddr = (unsigned char *) &(((SOCK_sockaddr_in *) address)->sin_addr);
  175. ret = rtp_net_bind ((RTP_HANDLE) socket,
  176. ipAddr,
  177. port,
  178. RTP_NET_TYPE_IPV4);
  179. return ret;
  180. }
  181. int RTIP_SOCKETS_Driver::Connect(SOCK_SOCKET socket, const SOCK_sockaddr* address, int addressLen)
  182. {
  183. NATIVE_PROFILE_PAL_NETWORK();
  184. int ret;
  185. unsigned char * ipAddr;
  186. int port;
  187. ipAddr = (unsigned char *) &(((SOCK_sockaddr_in *) address)->sin_addr);
  188. port = ((SOCK_sockaddr_in *) address)->sin_port;
  189. ret = rtp_net_connect ((RTP_HANDLE) socket,
  190. ipAddr,
  191. port,
  192. RTP_NET_TYPE_IPV4);
  193. return ret;
  194. }
  195. int RTIP_SOCKETS_Driver::Send(SOCK_SOCKET socket, const char* buf, int len, int flags)
  196. {
  197. NATIVE_PROFILE_PAL_NETWORK();
  198. int ret;
  199. ret = (int) rtp_net_send ((RTP_HANDLE) socket,
  200. (const unsigned char *) buf,
  201. len, flags);
  202. return ret;
  203. }
  204. int RTIP_SOCKETS_Driver::Recv(SOCK_SOCKET socket, char* buf, int len, int flags)
  205. {
  206. NATIVE_PROFILE_PAL_NETWORK();
  207. int ret;
  208. int nativeFlag;
  209. switch (flags)
  210. {
  211. case SOCKET_READ_PEEK_OPTION:
  212. nativeFlag = RTP_NET_MSG_PEEK;
  213. break;
  214. default:
  215. nativeFlag = flags;
  216. break;
  217. }
  218. ret = (int) rtp_net_recv ((RTP_HANDLE) socket,
  219. (unsigned char *) buf,
  220. len, nativeFlag);
  221. return ret;
  222. }
  223. int RTIP_SOCKETS_Driver::Close(SOCK_SOCKET socket)
  224. {
  225. NATIVE_PROFILE_PAL_NETWORK();
  226. int ret;
  227. ret = rtp_net_closesocket((RTP_HANDLE) socket);
  228. return ret;
  229. }
  230. int RTIP_SOCKETS_Driver::Listen( SOCK_SOCKET socket,
  231. int backlog )
  232. {
  233. int ret;
  234. ret = rtp_net_listen ((RTP_HANDLE) socket,
  235. backlog);
  236. return ret;
  237. }
  238. SOCK_SOCKET RTIP_SOCKETS_Driver::Accept( SOCK_SOCKET socket,
  239. SOCK_sockaddr* address,
  240. int* addressLen )
  241. {
  242. SOCK_SOCKET ret = SOCK_SOCKET_ERROR;
  243. int type = RTP_NET_TYPE_IPV4;
  244. unsigned long addr = address == NULL? 0: ((SOCK_sockaddr_in *) address)->sin_addr.S_un.S_addr;
  245. int port = address == NULL? 0: ((SOCK_sockaddr_in *) address)->sin_port;
  246. rtp_net_accept ((RTP_SOCKET *) &ret,
  247. (RTP_SOCKET) socket,
  248. (unsigned char*)&addr,
  249. &port,
  250. &type);
  251. if(address)
  252. {
  253. ((SOCK_sockaddr_in *) address)->sin_addr.S_un.S_addr = addr;
  254. ((SOCK_sockaddr_in *) address)->sin_port = port;
  255. ((SOCK_sockaddr_in *) address)->sin_family = RTP_NET_AF_INET;
  256. }
  257. return ret;
  258. }
  259. int RTIP_SOCKETS_Driver::Shutdown( SOCK_SOCKET socket,
  260. int how )
  261. {
  262. int ret;
  263. ret = rtp_net_shutdown ((RTP_HANDLE) socket, how);
  264. return ret;
  265. }
  266. int RTIP_SOCKETS_Driver::GetAddrInfo( const char* nodename,
  267. char* servname,
  268. const SOCK_addrinfo* hints,
  269. SOCK_addrinfo** res )
  270. {
  271. if(res == NULL || nodename == NULL)
  272. {
  273. set_errno(EINVAL);
  274. return SOCK_SOCKET_ERROR;
  275. }
  276. *res = NULL;
  277. PFHOSTENT pHost = NULL;
  278. struct hostentext localHost;
  279. if(nodename[0] == '\0')
  280. {
  281. IFACE_INFO info;
  282. if(SOCK_SOCKET_ERROR != xn_interface_info(g_RTIP_SOCKETS_Driver.m_interfaces[0].m_interfaceNumber, &info ))
  283. {
  284. memset(&localHost, 0, sizeof(localHost));
  285. localHost.ip_addr.s_un.S_addr = *(UINT32*)info.my_ip_address;
  286. pHost = &localHost;
  287. }
  288. }
  289. else
  290. {
  291. // this method will be called to get both IP address from name and name from IP address, so nodename
  292. // can either be "www.xxx.com" or "xxx.xxx.xxx.xxx". Therefore we will need to first get the IP bytes
  293. // gethostbyname will do this for either name or IP format, then we will need to get the name
  294. // by calling gethostbyaddr to get the host name.
  295. // first call is to get the IP bytes from string version (name or IP)
  296. pHost = gethostbyname((RTP_PFCHAR)nodename);
  297. // second call to get the host name
  298. if(pHost != NULL)
  299. {
  300. pHost = gethostbyaddr((RTP_PFCHAR)&pHost->ip_addr.s_un.S_addr, sizeof(UINT32), PF_INET);
  301. if(!pHost)
  302. {
  303. DEBUG_HANDLE_SOCKET_ERROR( "gethostbyaddr", FALSE );
  304. }
  305. }
  306. else
  307. {
  308. DEBUG_HANDLE_SOCKET_ERROR( "gethostbyname", FALSE );
  309. }
  310. }
  311. if(pHost)
  312. {
  313. SOCK_addrinfo* pAddrInfo = (SOCK_addrinfo*) private_malloc(sizeof(SOCK_addrinfo));
  314. if(pAddrInfo)
  315. {
  316. memset(pAddrInfo, 0, sizeof(SOCK_addrinfo));
  317. pAddrInfo->ai_family = RTP_NET_AF_INET;
  318. SOCK_sockaddr_in *pSockaddr = (SOCK_sockaddr_in*) private_malloc(sizeof(SOCK_sockaddr_in));
  319. if(pSockaddr)
  320. {
  321. memset(pSockaddr, 0, sizeof(SOCK_sockaddr_in));
  322. pSockaddr->sin_addr.S_un.S_addr = pHost->ip_addr.s_un.S_addr;
  323. pSockaddr->sin_family = RTP_NET_AF_INET;
  324. pAddrInfo->ai_addr = (SOCK_sockaddr*)pSockaddr;
  325. pAddrInfo->ai_addrlen = sizeof(SOCK_sockaddr_in);
  326. }
  327. if(pHost->sz_name != NULL)
  328. {
  329. int len = hal_strlen_s(pHost->sz_name);
  330. if(len > 0)
  331. {
  332. int buffer_size = sizeof(char) * len + 1;
  333. pAddrInfo->ai_canonname = (char*) private_malloc(buffer_size);
  334. if(pAddrInfo->ai_canonname)
  335. {
  336. hal_strcpy_s(pAddrInfo->ai_canonname, buffer_size, pHost->sz_name);
  337. }
  338. }
  339. }
  340. *res = pAddrInfo;
  341. }
  342. }
  343. return (*res == NULL? SOCK_SOCKET_ERROR: 0);
  344. }
  345. void RTIP_SOCKETS_Driver::FreeAddrInfo( SOCK_addrinfo* ai )
  346. {
  347. NATIVE_PROFILE_PAL_NETWORK();
  348. if(ai == NULL) return;
  349. if(ai->ai_canonname)
  350. {
  351. private_free(ai->ai_canonname);
  352. ai->ai_canonname = NULL;
  353. }
  354. if(ai->ai_addr)
  355. {
  356. private_free(ai->ai_addr);
  357. ai->ai_addr = NULL;
  358. }
  359. private_free(ai);
  360. }
  361. int RTIP_SOCKETS_Driver::Ioctl( SOCK_SOCKET socket, int cmd, int* data )
  362. {
  363. NATIVE_PROFILE_PAL_NETWORK();
  364. int ret = SOCK_SOCKET_ERROR;
  365. int blocking = !(*data);
  366. int nToRead;
  367. switch( cmd )
  368. {
  369. case SOCK_FIONBIO:
  370. ret = rtp_net_setblocking((RTP_SOCKET) socket,
  371. (unsigned int) blocking);
  372. break;
  373. case SOCK_FIONREAD:
  374. ret = rtp_net_getntoread ((RTP_SOCKET) socket,
  375. (unsigned long *) &nToRead);
  376. *data = nToRead;
  377. if (ret != -1)
  378. {
  379. return nToRead;
  380. }
  381. break;
  382. default:
  383. ret = 0;
  384. break;
  385. }
  386. return ret;
  387. }
  388. int RTIP_SOCKETS_Driver::GetLastError()
  389. {
  390. NATIVE_PROFILE_PAL_NETWORK();
  391. int err = 0;
  392. err = rtp_net_getlasterror();
  393. return GetNativeError(err);
  394. }
  395. int RTIP_SOCKETS_Driver::Select( int nfds, SOCK_fd_set* readfds, SOCK_fd_set* writefds, SOCK_fd_set* exceptfds, const SOCK_timeval* timeout )
  396. {
  397. NATIVE_PROFILE_PAL_NETWORK();
  398. int ret;
  399. ret = rtp_net_select (( RTP_FD_SET *) readfds,
  400. (RTP_FD_SET *) writefds,
  401. (RTP_FD_SET *) exceptfds,
  402. (struct timeval*) timeout);
  403. if(ret == SOCK_SOCKET_ERROR)
  404. {
  405. DEBUG_HANDLE_SOCKET_ERROR("Select failed", FALSE);
  406. }
  407. return ret;
  408. }
  409. int RTIP_SOCKETS_Driver::SetSockOpt( SOCK_SOCKET socket, int level, int optname, const char* optval, int optlen )
  410. {
  411. NATIVE_PROFILE_PAL_NETWORK();
  412. int ret;
  413. int nativeLevel;
  414. int nativeOptionName;
  415. int nativeIntValue;
  416. char *pNativeOptionValue = (char*)optval;
  417. switch(level)
  418. {
  419. case SOCK_IPPROTO_IP:
  420. nativeLevel = RTP_NET_IPROTO_IP;
  421. nativeOptionName = GetNativeIPOption(optname);
  422. break;
  423. case SOCK_IPPROTO_TCP:
  424. case SOCK_IPPROTO_UDP:
  425. case SOCK_IPPROTO_ICMP:
  426. case SOCK_IPPROTO_IGMP:
  427. case SOCK_IPPROTO_IPV4:
  428. case SOCK_SOL_SOCKET:
  429. nativeLevel = RTP_NET_SOL_SOCKET;
  430. nativeOptionName = GetNativeSockOption(level, optname);
  431. switch(optname)
  432. {
  433. case SOCK_SOCKO_EXCLUSIVEADDRESSUSE:
  434. case SOCK_SOCKO_NOCHECKSUM:
  435. case SOCK_SOCKO_DONTLINGER:
  436. nativeIntValue = !*(int*)optval;
  437. pNativeOptionValue = (char*)&nativeIntValue;
  438. break;
  439. default:
  440. break;
  441. }
  442. break;
  443. default:
  444. nativeLevel = 0;
  445. nativeOptionName = 0;
  446. break;
  447. }
  448. ret = rtp_net_setsockoopt((RTP_HANDLE) socket,
  449. nativeLevel,
  450. nativeOptionName,
  451. pNativeOptionValue,
  452. optlen);
  453. return ret;
  454. }
  455. int RTIP_SOCKETS_Driver::GetSockOpt( SOCK_SOCKET socket, int level, int optname, char* optval, int* optlen )
  456. {
  457. NATIVE_PROFILE_PAL_NETWORK();
  458. int ret;
  459. int nativeLevel;
  460. int nativeOptionName;
  461. switch(level)
  462. {
  463. case SOCK_IPPROTO_IP:
  464. nativeLevel = RTP_NET_IPROTO_IP;
  465. nativeOptionName = GetNativeIPOption(optname);
  466. break;
  467. case SOCK_IPPROTO_TCP:
  468. case SOCK_IPPROTO_UDP:
  469. case SOCK_IPPROTO_ICMP:
  470. case SOCK_IPPROTO_IGMP:
  471. case SOCK_IPPROTO_IPV4:
  472. case SOCK_SOL_SOCKET:
  473. nativeLevel = RTP_NET_SOL_SOCKET;
  474. nativeOptionName = GetNativeSockOption(level, optname);
  475. break;
  476. default:
  477. nativeLevel = 0;
  478. nativeOptionName = 0;
  479. break;
  480. }
  481. ret = rtp_net_getsockopt((RTP_HANDLE)socket,
  482. nativeLevel,
  483. nativeOptionName,
  484. optval,
  485. optlen);
  486. if(SOCK_SOCKET_ERROR != ret)
  487. {
  488. switch(optname)
  489. {
  490. case SOCK_SOCKO_NOCHECKSUM:
  491. case SOCK_SOCKO_EXCLUSIVEADDRESSUSE:
  492. *((int *) optval) = !*(int*)optval;
  493. break;
  494. default:
  495. break;
  496. }
  497. }
  498. return ret;
  499. }
  500. int RTIP_SOCKETS_Driver::GetPeerName( SOCK_SOCKET socket, SOCK_sockaddr* name, int* namelen )
  501. {
  502. NATIVE_PROFILE_PAL_NETWORK();
  503. int ret;
  504. unsigned char * ipAddr;
  505. int port;
  506. int type = RTP_NET_TYPE_IPV4;
  507. ipAddr = (unsigned char *)&(((SOCK_sockaddr_in *) name)->sin_addr);
  508. ret = rtp_net_getpeername ((RTP_HANDLE) socket,
  509. ipAddr ,
  510. &port,
  511. &type);
  512. ((SOCK_sockaddr_in *) name)->sin_family = RTP_NET_AF_INET;
  513. ((SOCK_sockaddr_in *) name)->sin_port = port;
  514. return ret;
  515. }
  516. int RTIP_SOCKETS_Driver::GetSockName( SOCK_SOCKET socket, SOCK_sockaddr* name, int* namelen )
  517. {
  518. NATIVE_PROFILE_PAL_NETWORK();
  519. int ret;
  520. int port;
  521. int type = RTP_NET_TYPE_IPV4;
  522. ret = rtp_net_getsockname ((RTP_HANDLE) socket,
  523. (unsigned char *) &((SOCK_sockaddr_in *) name)->sin_addr,
  524. &port,
  525. &type);
  526. ((SOCK_sockaddr_in *) name)->sin_family = RTP_NET_AF_INET;
  527. ((SOCK_sockaddr_in *) name)->sin_port = port;
  528. return ret;
  529. }
  530. int RTIP_SOCKETS_Driver::RecvFrom( SOCK_SOCKET s, char* buf, int len, int flags, SOCK_sockaddr* from, int* fromlen )
  531. {
  532. NATIVE_PROFILE_PAL_NETWORK();
  533. int ret;
  534. int type;
  535. int port;
  536. UINT32 ipAddr;
  537. int nativeFlag;
  538. type = RTP_NET_TYPE_IPV4;
  539. switch (flags)
  540. {
  541. case SOCKET_READ_PEEK_OPTION:
  542. nativeFlag = RTP_NET_MSG_PEEK;
  543. break;
  544. default:
  545. nativeFlag = flags;
  546. break;
  547. }
  548. if(from == NULL)
  549. {
  550. ret = (int ) rtp_net_recvfrom ((RTP_HANDLE) s,
  551. (unsigned char *)buf,
  552. len,
  553. NULL,
  554. NULL,
  555. &type,
  556. nativeFlag);
  557. }
  558. else
  559. {
  560. port = ((SOCK_sockaddr_in *) from)->sin_port;
  561. ipAddr = ((SOCK_sockaddr_in *) from)->sin_addr.S_un.S_addr;
  562. ret = (int) rtp_net_recvfrom ((RTP_HANDLE) s,
  563. (unsigned char *)buf,
  564. len,
  565. (unsigned char*)&ipAddr,
  566. &port,
  567. &type,
  568. nativeFlag);
  569. if (SOCK_SOCKET_ERROR != ret)
  570. {
  571. ((SOCK_sockaddr_in *) from)->sin_port = port;
  572. ((SOCK_sockaddr_in *) from)->sin_family = RTP_NET_AF_INET;
  573. ((SOCK_sockaddr_in *) from)->sin_addr.S_un.S_addr = ipAddr;
  574. }
  575. }
  576. return ret;
  577. }
  578. int RTIP_SOCKETS_Driver::SendTo( SOCK_SOCKET s, const char* buf, int len, int flags, const SOCK_sockaddr* to, int tolen )
  579. {
  580. NATIVE_PROFILE_PAL_NETWORK();
  581. int ret;
  582. UINT32 ipAddr;
  583. int port;
  584. if(to == NULL)
  585. {
  586. set_errno(EINVAL);
  587. return SOCK_SOCKET_ERROR;
  588. }
  589. ipAddr = ((SOCK_sockaddr_in *) to)->sin_addr.S_un.S_addr;
  590. port = ((SOCK_sockaddr_in *) to)->sin_port;
  591. ret = rtp_net_sendto ((RTP_HANDLE) s,
  592. (const unsigned char *) buf,
  593. len,
  594. (unsigned char *)&ipAddr,
  595. port,
  596. RTP_NET_TYPE_IPV4,
  597. flags);
  598. return ret;
  599. }
  600. UINT32 RTIP_SOCKETS_Driver::GetAdapterCount()
  601. {
  602. NATIVE_PROFILE_PAL_NETWORK();
  603. return NETWORK_INTERFACE_COUNT;
  604. }
  605. HRESULT RTIP_SOCKETS_Driver::LoadAdapterConfiguration( UINT32 interfaceIndex, SOCK_NetworkConfiguration* config )
  606. {
  607. NATIVE_PROFILE_PAL_NETWORK();
  608. if(interfaceIndex >= NETWORK_INTERFACE_COUNT)
  609. {
  610. return CLR_E_INVALID_PARAMETER;
  611. }
  612. memcpy(config, &g_NetworkConfig.NetworkInterfaces[interfaceIndex], sizeof(g_NetworkConfig.NetworkInterfaces[interfaceIndex]));
  613. if(config->flags & SOCK_NETWORKCONFIGURATION_FLAGS_DHCP)
  614. {
  615. IFACE_INFO info;
  616. if(SOCK_SOCKET_ERROR != xn_interface_info(g_RTIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_interfaceNumber, &info ))
  617. {
  618. config->ipaddr = *(UINT32*)info.my_ip_address;
  619. config->subnetmask = *(UINT32*)info.ip_mask;
  620. config->gateway = *(UINT32*)info.gateways[0];
  621. config->dnsServer1 = *(UINT32*)info.dns_servers[0];
  622. config->dnsServer2 = *(UINT32*)info.dns_servers[1];
  623. }
  624. else
  625. {
  626. config->ipaddr = 0;
  627. config->subnetmask = 0;
  628. config->gateway = 0;
  629. }
  630. }
  631. return S_OK;
  632. }
  633. HRESULT RTIP_SOCKETS_Driver::LoadWirelessConfiguration( UINT32 interfaceIndex, SOCK_WirelessConfiguration* wirelessConfig )
  634. {
  635. /// Load wireless specific settings if any. You must return S_OK, otherwise default values will be
  636. /// loaded by PAL.
  637. return CLR_E_FAIL;
  638. }
  639. HRESULT RTIP_SOCKETS_Driver::UpdateAdapterConfiguration( UINT32 interfaceIndex, UINT32 updateFlags, SOCK_NetworkConfiguration* config )
  640. {
  641. NATIVE_PROFILE_PAL_NETWORK();
  642. if(interfaceIndex >= NETWORK_INTERFACE_COUNT)
  643. {
  644. return CLR_E_INVALID_PARAMETER;
  645. }
  646. BOOL fEnableDhcp = (0 != (config->flags & SOCK_NETWORKCONFIGURATION_FLAGS_DHCP));
  647. if(0 != (updateFlags & SOCK_NETWORKCONFIGURATION_UPDATE_DHCP))
  648. {
  649. if(fEnableDhcp)
  650. {
  651. DHCP_conf reg_conf;
  652. memset(&reg_conf, 0, sizeof(reg_conf));
  653. memset(&g_RTIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_currentDhcpSession, 0, sizeof(DHCP_session));
  654. xn_dhcp_init_conf(&reg_conf);
  655. g_RTIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_currentDhcpSession.packet_style = DHCP_MICROSOFT;
  656. if (SOCK_SOCKET_ERROR == xn_dhcp(g_RTIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_interfaceNumber, &g_RTIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_currentDhcpSession, &reg_conf))
  657. {
  658. DEBUG_HANDLE_SOCKET_ERROR("update cfg: xn_dhcp", FALSE);
  659. return CLR_E_FAIL;
  660. }
  661. }
  662. else
  663. {
  664. if(SOCK_SOCKET_ERROR == rtp_net_set_ip(g_RTIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_interfaceNumber, (RTP_PFUINT8)&config->ipaddr, (RTP_PFUINT8)&config->subnetmask))
  665. {
  666. DEBUG_HANDLE_SOCKET_ERROR("update cfg: rtp_net_set_ip", FALSE);
  667. return CLR_E_FAIL;
  668. }
  669. UINT32 destMask = SOCK_MAKE_IP_ADDR_LITTLEEND(0,0,0,0);
  670. if(SOCK_SOCKET_ERROR == xn_rt_add((RTP_PFUINT8)RT_DEFAULT, (RTP_PFUINT8)&destMask, (RTP_PFUINT8)&config->gateway, RT_USEIFACEMETRIC, g_RTIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_interfaceNumber, RT_INF))
  671. {
  672. DEBUG_HANDLE_SOCKET_ERROR("update cfg: xn_rt_add", FALSE);
  673. return FALSE;
  674. }
  675. }
  676. }
  677. if(fEnableDhcp)
  678. {
  679. if(0 != (updateFlags & SOCK_NETWORKCONFIGURATION_UPDATE_DHCP_RELEASE))
  680. {
  681. if(g_RTIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_currentDhcpSession.client_ip != 0)
  682. {
  683. if(SOCK_SOCKET_ERROR == xn_dhcp_release(&g_RTIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_currentDhcpSession))
  684. {
  685. DEBUG_HANDLE_SOCKET_ERROR("update cfg: xn_dhcp_release", FALSE);
  686. /*return CLR_E_FAIL;*/
  687. }
  688. }
  689. memset(&g_RTIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_currentDhcpSession, 0, sizeof(DHCP_session));
  690. }
  691. if(0 != (updateFlags & SOCK_NETWORKCONFIGURATION_UPDATE_DHCP_RENEW))
  692. {
  693. DHCP_conf reg_conf;
  694. xn_dhcp_init_conf(&reg_conf);
  695. g_RTIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_currentDhcpSession.packet_style = DHCP_MICROSOFT;
  696. if (SOCK_SOCKET_ERROR == xn_dhcp(g_RTIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_interfaceNumber, &g_RTIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_currentDhcpSession, &reg_conf))
  697. {
  698. DEBUG_HANDLE_SOCKET_ERROR("update cfg: xn_dhcp", FALSE);
  699. return CLR_E_FAIL;
  700. }
  701. }
  702. }
  703. // when using DHCP do not use the static settings
  704. else if(0 != (updateFlags & SOCK_NETWORKCONFIGURATION_UPDATE_DNS))
  705. {
  706. if(config->dnsServer1 != 0 || config->dnsServer2 != 0)
  707. {
  708. xn_set_server_list( NULL, 0);
  709. // add the DNS servers of the config
  710. if( config->dnsServer1 != 0)
  711. {
  712. RTP_PFCUINT8 dns1 = (RTP_PFCUINT8)&(config->dnsServer1);
  713. if (SOCK_SOCKET_ERROR == xn_add_dns_server( dns1 ))
  714. {
  715. DEBUG_HANDLE_SOCKET_ERROR("update cfg: xn_add_dns_server(1)", FALSE);
  716. }
  717. }
  718. if( config->dnsServer2 != 0)
  719. {
  720. RTP_PFCUINT8 dns2 = (RTP_PFCUINT8)&(config->dnsServer2);
  721. if (SOCK_SOCKET_ERROR == xn_add_dns_server( dns2 ))
  722. {
  723. DEBUG_HANDLE_SOCKET_ERROR("update cfg: xn_add_dns_server(2)", FALSE);
  724. }
  725. }
  726. }
  727. }
  728. if(0 != (updateFlags & SOCK_NETWORKCONFIGURATION_UPDATE_MAC))
  729. {
  730. // mac address requires stack re-init
  731. Network_Uninitialize();
  732. Network_Initialize();
  733. }
  734. if(0 != (config->flags & SOCK_NETWORKCONFIGURATION_FLAGS_DYNAMIC_DNS))
  735. {
  736. // the rtip stack doesn't support dynamic dns
  737. return CLR_E_NOT_SUPPORTED;
  738. }
  739. return S_OK;
  740. }
  741. int RTIP_SOCKETS_Driver::GetNativeSockOption (int level, int optname)
  742. {
  743. NATIVE_PROFILE_PAL_NETWORK();
  744. int nativeOptionName;
  745. switch(optname)
  746. {
  747. case SOCK_SOCKO_LINGER:
  748. case SOCK_SOCKO_DONTLINGER:
  749. nativeOptionName = RTP_NET_SO_LINGER;
  750. break;
  751. case SOCK_SOCKO_SENDTIMEOUT:
  752. nativeOptionName = RTP_NET_SO_SEND_TIMEO;
  753. break;
  754. case SOCK_SOCKO_RECEIVETIMEOUT:
  755. nativeOptionName = RTP_NET_SO_RCV_TIMEO;
  756. break;
  757. case SOCK_SOCKO_EXCLUSIVEADDRESSUSE:
  758. case SOCK_SOCKO_REUSEADDRESS:
  759. nativeOptionName = RTP_NET_SO_REUSEADDR;
  760. break;
  761. case SOCK_SOCKO_KEEPALIVE:
  762. nativeOptionName = RTP_NET_SO_KEEPALIVE;
  763. break;
  764. case SOCK_SOCKO_ERROR:
  765. nativeOptionName = RTP_NET_SO_ERROR;
  766. break;
  767. case SOCK_SOCKO_BROADCAST:
  768. nativeOptionName = RTP_NET_IP_OPTS_BROADCAST;
  769. break;
  770. case SOCK_SOCKO_RECEIVEBUFFER:
  771. // for UDP level we use the UDP buffer size
  772. if(level == SOCK_IPPROTO_UDP || level == SOCK_SOL_SOCKET)
  773. {
  774. nativeOptionName = RTP_NET_SO_RECEIVE_BUFFER;
  775. }
  776. // for tcp we use the TCP window size
  777. // for socket level we use the tcp window size as well, assuming arbitrarily the socket is a tcp socket
  778. else if(level == SOCK_IPPROTO_TCP)
  779. {
  780. nativeOptionName = RTP_NET_SO_RCVBUF;
  781. }
  782. else
  783. {
  784. nativeOptionName = 0;
  785. }
  786. break;
  787. case SOCK_SOCKO_SENDBUFFER:
  788. // for UDP level we use the UDP buffer size
  789. if(level == SOCK_IPPROTO_UDP || level == SOCK_SOL_SOCKET)
  790. {
  791. nativeOptionName = RTP_NET_SO_SEND_BUFFER;
  792. }
  793. // for tcp we use the TCP window size
  794. // for socket level we use the tcp window size as well, assuming arbitrarily the socket is a tcp socket
  795. else if(level == SOCK_IPPROTO_TCP)
  796. {
  797. nativeOptionName = RTP_NET_SO_SNDBUF;
  798. }
  799. else
  800. {
  801. nativeOptionName = 0;
  802. }
  803. break;
  804. case SOCK_SOCKO_NOCHECKSUM:
  805. if (level == SOCK_IPPROTO_UDP)
  806. {
  807. nativeOptionName = RTP_NET_SO_UDPCKSUM_IN;
  808. }
  809. else if (level == SOCK_IPPROTO_TCP)
  810. {
  811. nativeOptionName = RTP_NET_SO_NAGLE;
  812. }
  813. else
  814. {
  815. nativeOptionName = 0;
  816. }
  817. break;
  818. case SOCK_SOCKO_ACCEPTCONNECTION:
  819. nativeOptionName = RTP_NET_SO_ACCEPTCON;
  820. break;
  821. case SOCK_SOCKO_TYPE:
  822. nativeOptionName = RTP_NET_SO_TYPE;
  823. break;
  824. case SOCK_SOCKO_USELOOPBACK: //don't support
  825. case SOCK_SOCKO_DONTROUTE: //don't support
  826. case SOCK_SOCKO_OUTOFBANDINLINE: //don't support
  827. case SOCK_SOCKO_SENDLOWWATER: //don't support
  828. case SOCK_SOCKO_RECEIVELOWWATER: //don't dupport
  829. case SOCK_SOCKO_MAXCONNECTIONS: //don't support
  830. nativeOptionName = 0;
  831. break;
  832. default:
  833. nativeOptionName = 0;
  834. break;
  835. }
  836. return nativeOptionName;
  837. }
  838. int RTIP_SOCKETS_Driver::GetNativeIPOption (int optname)
  839. {
  840. NATIVE_PROFILE_PAL_NETWORK();
  841. int nativeOptionName;
  842. switch(optname)
  843. {
  844. case SOCK_IPO_MULTICAST_IF:
  845. nativeOptionName = RTP_NET_IP_OPTS_MULTICAST_IF;
  846. break;
  847. case SOCK_IPO_MULTICAST_TTL:
  848. nativeOptionName = RTP_NET_IP_OPTS_MULTICAST_TTL;
  849. break;
  850. case SOCK_IPO_MULTICAST_LOOP:
  851. nativeOptionName = RTP_NET_IP_OPTS_MULTICAST_LOOP;
  852. break;
  853. case SOCK_IPO_ADD_MEMBERSHIP:
  854. nativeOptionName = RTP_NET_IP_OPTS_ADD_MEMBERSHIP;
  855. break;
  856. case SOCK_IPO_DROP_MEMBERSHIP:
  857. nativeOptionName = RTP_NET_IP_OPTS_DROP_MEMBERSHIP;
  858. break;
  859. case SOCK_IPO_IP_DONTFRAGMENT:
  860. nativeOptionName = RTP_NET_IP_OPTS_DONTFRAG;
  861. break;
  862. case SOCK_IPO_TTL:
  863. nativeOptionName = RTP_NET_SO_IP_TTL;
  864. break;
  865. default:
  866. nativeOptionName = 0;
  867. break;
  868. }
  869. return nativeOptionName;
  870. }
  871. int RTIP_SOCKETS_Driver::GetNativeError ( int error )
  872. {
  873. NATIVE_PROFILE_PAL_NETWORK();
  874. int ret;
  875. switch(error)
  876. {
  877. case RTP_NET_EADDRNOTAVAIL:
  878. ret = SOCK_EADDRNOTAVAIL;
  879. break;
  880. case RTP_NET_EADDRINUSE:
  881. ret = SOCK_EADDRINUSE;
  882. break;
  883. case RTP_NET_EAFNOSUPPORT:
  884. ret = SOCK_EAFNOSUPPORT;
  885. break;
  886. case RTP_NET_ECONNREFUSED:
  887. ret = SOCK_ECONNREFUSED;
  888. break;
  889. case RTP_NET_EDESTADDREQ:
  890. ret = SOCK_EDESTADDRREQ;
  891. break;
  892. case RTP_NET_EDESTUNREACH:
  893. ret = SOCK_EHOSTUNREACH;
  894. break;
  895. case RTP_NET_EFAULT:
  896. ret = SOCK_EFAULT;
  897. break;
  898. case RTP_NET_EINVAL:
  899. ret = SOCK_EINVAL;
  900. break;
  901. case RTP_NET_EISCONN:
  902. ret = SOCK_EISCONN;
  903. break;
  904. case RTP_NET_EMFILE:
  905. ret = SOCK_EMFILE;
  906. break;
  907. case RTP_NET_ENETDOWN:
  908. ret = SOCK_ENETDOWN;
  909. break;
  910. case RTP_NET_ENETUNREACH:
  911. ret = SOCK_ENETUNREACH;
  912. break;
  913. case RTP_NET_ENOPROTOOPT:
  914. ret = SOCK_ENOPROTOOPT;
  915. break;
  916. case RTP_NET_ENOTCONN:
  917. ret = SOCK_ENOTCONN;
  918. break;
  919. case RTP_NET_ENOTINITIALIZED:
  920. ret = SOCK_NOTINITIALISED;
  921. break;
  922. case RTP_NET_ENOTSOCK:
  923. ret = SOCK_ENOTSOCK;
  924. break;
  925. case RTP_NET_EOPNOTSUPPORT:
  926. ret = SOCK_EOPNOTSUPP;
  927. break;
  928. case RTP_NET_ESHUTDOWN:
  929. ret = SOCK_ESHUTDOWN;
  930. break;
  931. case RTP_NET_ETIMEDOUT:
  932. ret = SOCK_ETIMEDOUT;
  933. break;
  934. case RTP_NET_EWOULDBLOCK:
  935. case RTP_NET_EOUTPUTFULL:
  936. case RTP_NET_ENOPKTS:
  937. ret = SOCK_EWOULDBLOCK;
  938. break;
  939. case RTP_NET_EMSGSIZE:
  940. ret = SOCK_EMSGSIZE;
  941. break;
  942. case RTP_NET_ENAME_TOO_LONG:
  943. ret = SOCK_ENAMETOOLONG;
  944. break;
  945. case RTP_NET_ETRYAGAIN:
  946. ret = SOCK_TRY_AGAIN;
  947. break;
  948. case RTP_NET_ENODATA:
  949. ret = SOCK_NO_DATA;
  950. break;
  951. case RTP_NET_EPROTONOSUPPORT:
  952. ret = SOCK_EPROTONOSUPPORT;
  953. break;
  954. case RTP_NET_EPFNOSUPPORT:
  955. ret = SOCK_EPFNOSUPPORT;
  956. break;
  957. case RTP_NET_ENORESPONSE:
  958. ret = SOCK_HOST_NOT_FOUND;
  959. break;
  960. case RTP_NET_EACCES:
  961. ret = SOCK_EACCES;
  962. break;
  963. case RTP_NET_EBADRESP:
  964. ret = SOCK_TRY_AGAIN;
  965. break;
  966. case RTP_NET_ETNOSUPPORT:
  967. ret = SOCK_EPROTONOSUPPORT;
  968. break;
  969. default:
  970. ret = error;
  971. break;
  972. }
  973. return (ret);
  974. }