PageRenderTime 28ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

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

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