PageRenderTime 58ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/Patch_4.1/DeviceCode/Targets/OS/EddyLinux/DeviceCode/socketsdriver/EddyLinux__Sockets.cpp

#
C++ | 1044 lines | 856 code | 166 blank | 22 comment | 73 complexity | 3c1181797927798a5d2b9b77940b8217 MD5 | raw file
  1. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. // Modified for Linux from lwip__Sockets.cpp on NETMF 4.1 by Device Drivers Limited.
  4. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5. #include "EddyLinux_sockets.h"
  6. #include <errno.h>
  7. #include <fcntl.h>
  8. #include <sys/ioctl.h>
  9. #include <sys/types.h>
  10. #include <sys/socket.h>
  11. #include <netinet/in.h>
  12. #include <netinet/tcp.h>
  13. #include <arpa/inet.h>
  14. #include <asm/ioctls.h>
  15. #include <netdb.h>
  16. extern const HAL_CONFIG_BLOCK g_NetworkConfigHeader;
  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. #if !defined(BUILD_RTM)
  26. void printfd(char *s, fd_set* fds);
  27. void printfd(char *s, fd_set* fds)
  28. {
  29. unsigned int *p;
  30. p = (unsigned int *) fds;
  31. if (LINUXDBG <= 3) return;
  32. if (p != NULL) {
  33. printf("%s%08x %08x %08x %08x\r\n", s, *p, *(p+1), *(p+2), *(p+3));
  34. }
  35. else
  36. printf("%sNULL\r\n", s);
  37. }
  38. void printsockfd(char *s, SOCK_fd_set *fds);
  39. void printsockfd(char *s, SOCK_fd_set *fds)
  40. {
  41. int i;
  42. unsigned int *p = (unsigned int *) &fds->fd_array[0];
  43. int maxcnt = 0;
  44. if (LINUXDBG > 3)
  45. maxcnt = 1;
  46. else
  47. return;
  48. if (p != NULL) {
  49. printf("%s count=%d\n", s, fds->fd_count);
  50. for(i = 0; i < maxcnt; i++) {
  51. printf("%08x %08x %08x %08x %08x %08x %08x %08x\r\n",
  52. *p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5), *(p+6), *(p+7));
  53. p += 8;
  54. }
  55. }
  56. else
  57. printf("%sNULL\r\n", s);
  58. }
  59. #define PRINTFD(a, b) printfd(a, b)
  60. #define PRINTSOCKFD(a, b) printsockfd(a, b)
  61. #else
  62. #define PRINTFD(a, b)
  63. #define PRINTSOCKFD(a, b)
  64. #endif
  65. int sockfdset_to_fdset(SOCK_fd_set *sockfds, fd_set *fds);
  66. int sockfdset_to_fdset(SOCK_fd_set *sockfds, fd_set *fds)
  67. {
  68. int i;
  69. for(i = 0; i < sockfds->fd_count; i++)
  70. {
  71. FD_SET(sockfds->fd_array[i], fds);
  72. }
  73. return(sockfds->fd_count);
  74. }
  75. int fdset_to_sockfdset(fd_set *fds, SOCK_fd_set *sockfds);
  76. int fdset_to_sockfdset(fd_set *fds, SOCK_fd_set *sockfds)
  77. {
  78. int i;
  79. for(i = 0; i < 128; i++)
  80. {
  81. if (FD_ISSET(i, fds))
  82. {
  83. SOCK_FD_SET(i, sockfds);
  84. }
  85. }
  86. return(sockfds->fd_count);
  87. }
  88. //--//
  89. BOOL LINUX_SOCKETS_Driver::Initialize()
  90. {
  91. return TRUE;
  92. }
  93. BOOL LINUX_SOCKETS_Driver::Uninitialize()
  94. {
  95. return TRUE;
  96. }
  97. SOCK_SOCKET LINUX_SOCKETS_Driver::Socket(int family, int type, int protocol)
  98. {
  99. NATIVE_PROFILE_PAL_NETWORK();
  100. int ret = socket(family, type, protocol);
  101. DBGP("family=%d, type=%d, protocol=%d, ret = %d", family, type, protocol, ret);
  102. if (ret >= 0) return (SOCK_SOCKET) ret;
  103. debug_printf("socket() error: %s (%d)\r\n",
  104. strerror(errno), errno);
  105. return SOCK_SOCKET_ERROR;
  106. }
  107. int LINUX_SOCKETS_Driver::Bind(SOCK_SOCKET socket, const SOCK_sockaddr* address, int addressLen)
  108. {
  109. NATIVE_PROFILE_PAL_NETWORK();
  110. int ret = bind(socket, (const sockaddr*) address, addressLen);
  111. DBGP("socket=%d, address=%p, addressLen=%d, ret=%d", socket, address, addressLen, ret);
  112. if (ret >= 0) return ret;
  113. debug_printf("bind() error: %s (%d)\r\n",
  114. strerror(errno), errno);
  115. return SOCK_SOCKET_ERROR;
  116. }
  117. int LINUX_SOCKETS_Driver::Connect(SOCK_SOCKET socket, const SOCK_sockaddr* address, int addressLen)
  118. {
  119. NATIVE_PROFILE_PAL_NETWORK();
  120. int ret = connect(socket, (const sockaddr*) address, addressLen);
  121. DBGP("socket=%d, address=%p, addressLen=%d, ret=%d, errno=%d", socket, address, addressLen, ret, errno);
  122. if (ret >= 0) return ret;
  123. //if (errno == EINPROGRESS || errno == EAGAIN)
  124. if (errno == EINPROGRESS)
  125. {
  126. DBGP("connect() return: %s(%d), connection process has started.\r\n",
  127. strerror(errno), errno);
  128. return SOCK_EWOULDBLOCK;
  129. }
  130. debug_printf("connect() error: %s (%d)\r\n",
  131. strerror(errno), errno);
  132. return SOCK_SOCKET_ERROR;
  133. }
  134. int LINUX_SOCKETS_Driver::Send(SOCK_SOCKET socket, const char* buf, int len, int flags)
  135. {
  136. NATIVE_PROFILE_PAL_NETWORK();
  137. int ret = send(socket, buf, len, flags);
  138. DBGP("socket=%d, buf=%p, len=%d, flags=%x, ret=%d", socket, buf, len, flags, ret);
  139. if (ret >= 0) return ret;
  140. debug_printf("send() error: %s (%d)\r\n",
  141. strerror(errno), errno);
  142. return SOCK_SOCKET_ERROR;
  143. }
  144. int LINUX_SOCKETS_Driver::Recv(SOCK_SOCKET socket, char* buf, int len, int flags)
  145. {
  146. NATIVE_PROFILE_PAL_NETWORK();
  147. int nativeFlag;
  148. switch (flags)
  149. {
  150. case SOCKET_READ_PEEK_OPTION:
  151. nativeFlag = MSG_PEEK;
  152. break;
  153. default:
  154. nativeFlag = flags;
  155. break;
  156. }
  157. int ret = recv(socket, buf, len, nativeFlag);
  158. DBGP("socket=%d, buf=%p, len=%d, nativeFlag=%d, ret=%d", socket, buf, len, nativeFlag, ret);
  159. if (ret >= 0) return ret;
  160. if (errno == EAGAIN)
  161. {
  162. if (LINUXDBG > 3)
  163. {
  164. DBGP("recv() returns: EAGAIN (%d)\r\n", errno);
  165. }
  166. }
  167. else
  168. {
  169. debug_printf("recv() error: %s (%d)\r\n",
  170. strerror(errno), errno);
  171. }
  172. return SOCK_SOCKET_ERROR;
  173. }
  174. int LINUX_SOCKETS_Driver::Close(SOCK_SOCKET socket)
  175. {
  176. NATIVE_PROFILE_PAL_NETWORK();
  177. int ret = close(socket);
  178. DBGP("socket=%d, ret=%d", socket, ret);
  179. if (ret >= 0)
  180. {
  181. return ret;
  182. }
  183. debug_printf("close() error: %s (%d)\r\n",
  184. strerror(errno), errno);
  185. return SOCK_SOCKET_ERROR;
  186. }
  187. int LINUX_SOCKETS_Driver::Listen(SOCK_SOCKET socket, int backlog)
  188. {
  189. NATIVE_PROFILE_PAL_NETWORK();
  190. int ret = listen(socket, backlog);
  191. DBGP("socket=%d, backlog=%x, ret=%d", socket, backlog, ret);
  192. if (ret >= 0) return ret;
  193. debug_printf("listen() error: %s (%d)\r\n",
  194. strerror(errno), errno);
  195. return SOCK_SOCKET_ERROR;
  196. }
  197. SOCK_SOCKET LINUX_SOCKETS_Driver::Accept(SOCK_SOCKET socket, SOCK_sockaddr* address, int* addressLen)
  198. {
  199. NATIVE_PROFILE_PAL_NETWORK();
  200. DBGP("Enter, socket=%d", socket);
  201. int ret = accept(socket, (struct sockaddr*) address, (socklen_t *) addressLen);
  202. DBGP("socket=%d, address=%p, addressLen=%p(%d), ret=%d", socket, address, addressLen,
  203. addressLen != NULL ? addressLen : 0, ret);
  204. if (ret >= 0) return (SOCK_SOCKET) ret;
  205. debug_printf("accept() error: %s (%d)\r\n",
  206. strerror(errno), errno);
  207. return SOCK_SOCKET_ERROR;
  208. }
  209. int LINUX_SOCKETS_Driver::Shutdown( SOCK_SOCKET socket, int how )
  210. {
  211. NATIVE_PROFILE_PAL_NETWORK();
  212. int ret = shutdown(socket, how);
  213. DBGP("socket=%d, how=%d, ret=%d", socket, how, ret);
  214. if (ret >= 0) return ret;
  215. debug_printf("shutdown() error: %s (%d)\r\n",
  216. strerror(errno), errno);
  217. return SOCK_SOCKET_ERROR;
  218. }
  219. //////////////////////////////////////
  220. typedef struct _SOCK_addrinfo
  221. {
  222. SOCK_addrinfo info;
  223. struct addrinfo *_addrinfo;
  224. } _SOCK_addrinfo;
  225. void SOCK_addrinfo_to_addrinfo(const SOCK_addrinfo* in, struct addrinfo *out)
  226. {
  227. out->ai_flags = in->ai_flags;
  228. out->ai_family = in->ai_family;
  229. out->ai_socktype = in->ai_socktype;
  230. out->ai_protocol = in->ai_protocol;
  231. out->ai_addrlen = in->ai_addrlen;
  232. out->ai_addr = (struct sockaddr*) in->ai_addr;
  233. out->ai_canonname = in->ai_canonname;
  234. out->ai_next = NULL; //in->ai_next;
  235. }
  236. void change_addrinfolist_to_SOCK_addrinfolist(struct addrinfo *a, SOCK_addrinfo **p);
  237. void change_addrinfolist_to_SOCK_addrinfolist(struct addrinfo *a, SOCK_addrinfo **p)
  238. {
  239. _SOCK_addrinfo *base_ps;
  240. SOCK_addrinfo *ps;
  241. SOCK_sockaddr *pa;
  242. SOCK_addrinfo *pfirst;
  243. SOCK_addrinfo **plast;
  244. #define error_check_mem(m) \
  245. if ((m) == NULL) { debug_printf("cannot malloc mem\r\n"); return; }
  246. plast = NULL;
  247. while(a != NULL)
  248. {
  249. base_ps = (_SOCK_addrinfo*) private_malloc(sizeof(_SOCK_addrinfo));
  250. error_check_mem(base_ps);//
  251. memset(base_ps, 0, sizeof(_SOCK_addrinfo));
  252. ps = &base_ps->info;
  253. ps->ai_addr = (SOCK_sockaddr*) private_malloc(sizeof(SOCK_sockaddr));
  254. error_check_mem(ps->ai_addr);
  255. memset(ps->ai_addr, 0, sizeof(SOCK_sockaddr));
  256. ps->ai_flags = a->ai_flags;
  257. ps->ai_family = a->ai_family;
  258. ps->ai_socktype = a->ai_socktype;
  259. ps->ai_protocol = a->ai_protocol;
  260. ps->ai_addrlen = a->ai_addrlen;
  261. if (a->ai_canonname != NULL)
  262. {
  263. int len = hal_strlen_s(a->ai_canonname) + 1;
  264. ps->ai_canonname = (char *) private_malloc(len);
  265. error_check_mem(ps->ai_canonname);
  266. hal_strcpy_s(ps->ai_canonname, len, a->ai_canonname);
  267. }
  268. memcpy(ps->ai_addr, a->ai_addr, sizeof(SOCK_sockaddr));
  269. if (plast == NULL) // first time ?
  270. {
  271. pfirst = ps; // keep return address
  272. base_ps->_addrinfo = a; // keep start addrinfo
  273. }
  274. else
  275. {
  276. *plast = ps;
  277. }
  278. a = a->ai_next;
  279. plast = &ps->ai_next;
  280. }
  281. if (plast != NULL && p != NULL)
  282. {
  283. *p = pfirst;
  284. }
  285. #undef error_check_mem
  286. }
  287. int LINUX_SOCKETS_Driver::GetAddrInfo(const char* nodename, char* servname, const SOCK_addrinfo* hints, SOCK_addrinfo** res)
  288. {
  289. NATIVE_PROFILE_PAL_NETWORK();
  290. struct addrinfo ainfo;
  291. struct addrinfo *ares;
  292. SOCK_addrinfo *sres;
  293. int ret;
  294. SOCK_addrinfo_to_addrinfo(hints, &ainfo);
  295. ret = getaddrinfo(nodename, servname, (const struct addrinfo*) &ainfo, &ares);
  296. change_addrinfolist_to_SOCK_addrinfolist(ares, &sres);
  297. if (res) *res = sres;
  298. DBGP("nodename = %s, servname=%s, hints=%p, res=%p(%p), ret=%d", nodename, servname, hints, res, res ? *res : 0, ret);
  299. if (ret == 0) return ret;
  300. debug_printf("getaddrinfo() error: %s (%d)\r\n",
  301. strerror(errno), errno);
  302. return SOCK_SOCKET_ERROR;
  303. }
  304. void LINUX_SOCKETS_Driver::FreeAddrInfo( SOCK_addrinfo* ai )
  305. {
  306. NATIVE_PROFILE_PAL_NETWORK();
  307. _SOCK_addrinfo *base_ps;
  308. SOCK_addrinfo *ps;
  309. SOCK_addrinfo *ps_next;
  310. DBGP("ai=%p", ai);
  311. if (ai == NULL) return;
  312. base_ps = (_SOCK_addrinfo *) ai;
  313. for(ps = ai; ps != NULL; ps = ps_next)
  314. {
  315. ps_next = ps->ai_next; // save next address before free
  316. if (ps->ai_canonname)
  317. {
  318. private_free(ps->ai_canonname);
  319. ps->ai_canonname = NULL;
  320. }
  321. if (ps->ai_addr)
  322. {
  323. private_free(ps->ai_addr);
  324. ps->ai_addr = NULL;
  325. }
  326. private_free(ps);
  327. ps = NULL;
  328. }
  329. if (base_ps->_addrinfo != NULL)
  330. {
  331. DBGP("base_ps=%p", base_ps);
  332. freeaddrinfo(base_ps->_addrinfo);
  333. }
  334. }
  335. int LINUX_SOCKETS_Driver::Ioctl( SOCK_SOCKET socket, int cmd, int* data )
  336. {
  337. NATIVE_PROFILE_PAL_NETWORK();
  338. int ret = 0;
  339. int val = 0;
  340. if (!socket)
  341. {
  342. debug_printf("HAL_SOCK_ioctl() error: socket is 0\r\n");
  343. return SOCK_SOCKET_ERROR;
  344. }
  345. DBGP("socket=%d, cmd=%x(%s), data=%p(%d)", socket,
  346. cmd, cmd == SOCK_FIONREAD ? "FIONREAD" :
  347. cmd == SOCK_FIONBIO ?
  348. data && *(unsigned int *)data ? "NONBLOCK" : "BLOCK" :
  349. "Unknown",
  350. data, data != NULL ? *data : 0);
  351. switch(cmd)
  352. {
  353. case SOCK_FIONREAD:
  354. if (data == NULL)
  355. {
  356. debug_printf("HAL_SOCK_ioctl() error: data is NULL\r\n");
  357. return SOCK_SOCKET_ERROR;
  358. }
  359. //
  360. // since asm/ioctls.h(34):#define FIONREAD 0x541B
  361. //
  362. *data = 0;
  363. ret = ioctl(socket, FIONREAD, data);
  364. if (ret >= 0)
  365. {
  366. DBGP("FIONREAD: socket=%d, data=%p(%d), ret=%d",
  367. socket, data, *data, ret);
  368. return ret;
  369. }
  370. break;
  371. case SOCK_FIONBIO:
  372. val = fcntl(socket, F_GETFL);
  373. if (data && *(unsigned int *)data)
  374. val |= O_NONBLOCK;
  375. else
  376. val &= ~O_NONBLOCK;
  377. ret = fcntl(socket, F_SETFL, val);
  378. if (ret >= 0)
  379. {
  380. return ret;
  381. }
  382. break;
  383. default:
  384. debug_printf("HAL_SOCK_ioctl(%d, UNIMPL: 0x%x, %p, 0x%d)\n",
  385. socket, cmd, data, data != NULL ? (int) *data : 0);
  386. break;
  387. } /* switch (cmd) */
  388. return SOCK_SOCKET_ERROR;
  389. }
  390. int LINUX_SOCKETS_Driver::GetLastError()
  391. {
  392. NATIVE_PROFILE_PAL_NETWORK();
  393. DBGP("errno = %d", errno);
  394. return GetNativeError(errno);
  395. }
  396. int LINUX_SOCKETS_Driver::Select( int nfds, SOCK_fd_set* readsockfds, SOCK_fd_set* writesockfds, SOCK_fd_set* exceptsockfds, const SOCK_timeval* timeout )
  397. {
  398. NATIVE_PROFILE_PAL_NETWORK();
  399. fd_set readfds;
  400. fd_set writefds;
  401. fd_set exceptfds;
  402. PRINTSOCKFD("*** before readfds:", readsockfds);
  403. PRINTSOCKFD("*** before writefd:", writesockfds);
  404. PRINTSOCKFD("*** before except :", exceptsockfds);
  405. FD_ZERO(&readfds);
  406. FD_ZERO(&writefds);
  407. FD_ZERO(&exceptfds);
  408. sockfdset_to_fdset(readsockfds, &readfds);
  409. sockfdset_to_fdset(writesockfds, &writefds);
  410. sockfdset_to_fdset(exceptsockfds, &exceptfds);
  411. if (LINUXDBG > 5)
  412. {
  413. PRINTFD("** before readfds:", &readfds);
  414. PRINTFD("** before writefd:", &writefds);
  415. PRINTFD("** before except :", &exceptfds);
  416. }
  417. int sec = timeout != NULL ? timeout->tv_sec : 0;
  418. int usec = timeout != NULL ? timeout->tv_usec : 0;
  419. int ret = select(nfds, &readfds, &writefds, &exceptfds, (struct timeval *) timeout);
  420. if (LINUXDBG > 5)
  421. {
  422. PRINTFD("** after readfds :", &readfds);
  423. PRINTFD("** after writefd :", &writefds);
  424. PRINTFD("** after except :", &exceptfds);
  425. }
  426. SOCK_FD_ZERO(readsockfds);
  427. SOCK_FD_ZERO(writesockfds);
  428. SOCK_FD_ZERO(exceptsockfds);
  429. fdset_to_sockfdset(&readfds, readsockfds);
  430. fdset_to_sockfdset(&writefds, writesockfds);
  431. fdset_to_sockfdset(&exceptfds, exceptsockfds);
  432. PRINTSOCKFD("*** after readfds :", readsockfds);
  433. PRINTSOCKFD("*** after writefd :", writesockfds);
  434. PRINTSOCKFD("*** after except :", exceptsockfds);
  435. DBGP("nfds=%d, readfds=%p, writefds=%p, except=%p, timeout=%p(%d.%06d), ret=%d",
  436. nfds, readsockfds, writesockfds, exceptsockfds,
  437. timeout, (int) sec, (int) usec, ret);
  438. if (ret >= 0) return ret;
  439. debug_printf("select() error: %s (%d)\r\n",
  440. strerror(errno), errno);
  441. return SOCK_SOCKET_ERROR;
  442. }
  443. int LINUX_SOCKETS_Driver::SetSockOpt( SOCK_SOCKET socket, int level, int optname, const char* optval, int optlen )
  444. {
  445. NATIVE_PROFILE_PAL_NETWORK();
  446. int ret;
  447. int nativeLevel;
  448. int nativeOptionName;
  449. int nativeIntValue;
  450. char *pNativeOptionValue = (char*)optval;
  451. switch(level)
  452. {
  453. case SOCK_IPPROTO_IP:
  454. nativeLevel = IPPROTO_IP;
  455. nativeOptionName = GetNativeIPOption(optname);
  456. break;
  457. case SOCK_IPPROTO_TCP:
  458. nativeLevel = IPPROTO_TCP;
  459. nativeOptionName = GetNativeTcpOption(optname);
  460. break;
  461. case SOCK_IPPROTO_UDP:
  462. case SOCK_IPPROTO_ICMP:
  463. case SOCK_IPPROTO_IGMP:
  464. case SOCK_IPPROTO_IPV4:
  465. case SOCK_SOL_SOCKET:
  466. nativeLevel = SOL_SOCKET;
  467. nativeOptionName = GetNativeSockOption(optname);
  468. switch(optname)
  469. {
  470. case SOCK_SOCKO_EXCLUSIVEADDRESSUSE:
  471. case SOCK_SOCKO_NOCHECKSUM:
  472. case SOCK_SOCKO_DONTLINGER:
  473. nativeIntValue = !*(int*)optval;
  474. pNativeOptionValue = (char*)&nativeIntValue;
  475. break;
  476. default:
  477. break;
  478. }
  479. break;
  480. default:
  481. nativeLevel = 0;
  482. nativeOptionName = 0;
  483. break;
  484. }
  485. ret = setsockopt(socket, nativeLevel, nativeOptionName,
  486. pNativeOptionValue, (socklen_t) optlen);
  487. DBGP("socket=%d, level=%d, optname=%d, optval=%s, optlen=%d, ret=%d",
  488. socket, nativeLevel, nativeOptionName, pNativeOptionValue, optlen, ret);
  489. if (ret >= 0) return ret;
  490. debug_printf("setsockopt() error: %s (%d)\r\n",
  491. strerror(errno), errno);
  492. return SOCK_SOCKET_ERROR;
  493. }
  494. int LINUX_SOCKETS_Driver::GetSockOpt( SOCK_SOCKET socket, int level, int optname, char* optval, int* optlen )
  495. {
  496. NATIVE_PROFILE_PAL_NETWORK();
  497. int nativeLevel;
  498. int nativeOptionName;
  499. char* pNativeOptval = optval;
  500. int ret;
  501. switch(level)
  502. {
  503. case SOCK_IPPROTO_IP:
  504. nativeLevel = IPPROTO_IP;
  505. nativeOptionName = GetNativeIPOption(optname);
  506. break;
  507. case SOCK_IPPROTO_TCP:
  508. nativeLevel = IPPROTO_TCP;
  509. nativeOptionName = GetNativeTcpOption(optname);
  510. break;
  511. case SOCK_IPPROTO_UDP:
  512. case SOCK_IPPROTO_ICMP:
  513. case SOCK_IPPROTO_IGMP:
  514. case SOCK_IPPROTO_IPV4:
  515. case SOCK_SOL_SOCKET:
  516. nativeLevel = SOL_SOCKET;
  517. nativeOptionName = GetNativeSockOption(optname);
  518. break;
  519. default:
  520. nativeLevel = level;
  521. nativeOptionName = optname;
  522. break;
  523. }
  524. ret = getsockopt(socket, nativeLevel, nativeOptionName, optval, (socklen_t *) optlen);
  525. DBGP("socket=%d, level=%d, optname=%d, optval=%s, optlen=%p, ret=%d",
  526. socket, level, optname, optval, optlen, ret);
  527. if(ret >= 0)
  528. {
  529. switch(level)
  530. {
  531. case SOCK_SOL_SOCKET:
  532. switch(optname)
  533. {
  534. case SOCK_SOCKO_EXCLUSIVEADDRESSUSE:
  535. case SOCK_SOCKO_DONTLINGER:
  536. *optval = !(*(int*)optval != 0);
  537. break;
  538. case SOCK_SOCKO_ACCEPTCONNECTION:
  539. case SOCK_SOCKO_BROADCAST:
  540. case SOCK_SOCKO_KEEPALIVE:
  541. *optval = (*(int*)optval != 0);
  542. break;
  543. }
  544. break;
  545. }
  546. return ret;
  547. }
  548. debug_printf("getsockopt() error: %s (%d)\r\n",
  549. strerror(errno), errno);
  550. return SOCK_SOCKET_ERROR;
  551. }
  552. int LINUX_SOCKETS_Driver::GetPeerName( SOCK_SOCKET socket, SOCK_sockaddr* name, int* namelen )
  553. {
  554. NATIVE_PROFILE_PAL_NETWORK();
  555. int ret;
  556. ret = getsockname(socket, (sockaddr*) name, (socklen_t *) namelen);
  557. DBGP("socket=%d, name=%p, namelen=%p, ret=%d", socket, name, namelen, ret);
  558. if (ret >= 0) return ret;
  559. debug_printf("getsockname() error: %s (%d)\r\n",
  560. strerror(errno), errno);
  561. return SOCK_SOCKET_ERROR;
  562. }
  563. int LINUX_SOCKETS_Driver::GetSockName( SOCK_SOCKET socket, SOCK_sockaddr* name, int* namelen )
  564. {
  565. NATIVE_PROFILE_PAL_NETWORK();
  566. int ret;
  567. ret = getsockname(socket, (sockaddr*) name, (socklen_t *) namelen);
  568. DBGP("socket=%d, name=%p, namelen=%p, ret=%d", socket, name, namelen, ret);
  569. if (ret >= 0) return ret;
  570. debug_printf("getsockname() error: %s (%d)\r\n",
  571. strerror(errno), errno);
  572. return SOCK_SOCKET_ERROR;
  573. }
  574. int LINUX_SOCKETS_Driver::RecvFrom( SOCK_SOCKET socket, char* buf, int len, int flags, SOCK_sockaddr* from, int* fromlen )
  575. {
  576. NATIVE_PROFILE_PAL_NETWORK();
  577. sockaddr_in addr;
  578. sockaddr *pFrom = NULL;
  579. int ret = recvfrom(socket, buf, (size_t) len, flags, (struct sockaddr *) from, (socklen_t *) fromlen);
  580. DBGP("socket=%d, buf=%p, len=%d, flags=0x%x, from=%p, fromlen=%p, ret=%d", socket, buf, len, flags, from, fromlen, ret);
  581. if (ret >= 0) return ret;
  582. debug_printf("recvfrom() error: %s (%d)\r\n",
  583. strerror(errno), errno);
  584. return SOCK_SOCKET_ERROR;
  585. }
  586. int LINUX_SOCKETS_Driver::SendTo( SOCK_SOCKET socket, const char* buf, int len, int flags, const SOCK_sockaddr* to, int tolen )
  587. {
  588. NATIVE_PROFILE_PAL_NETWORK();
  589. int ret = sendto(socket, buf, (size_t) len, flags, (const struct sockaddr *) to, (socklen_t) tolen);
  590. DBGP("socket=%d, buf=%p, len=%d, flags=0x%x, to=%p, tolen=%d, ret=%d", socket, buf, len, flags, to, tolen, ret);
  591. if (ret >= 0) return ret;
  592. debug_printf("sendto() error: %s (%d)\r\n",
  593. strerror(errno), errno);
  594. return SOCK_SOCKET_ERROR;
  595. }
  596. UINT32 LINUX_SOCKETS_Driver::GetAdapterCount()
  597. {
  598. NATIVE_PROFILE_PAL_NETWORK();
  599. DBGP("ret=%d", NETWORK_INTERFACE_COUNT);
  600. return NETWORK_INTERFACE_COUNT;
  601. }
  602. HRESULT LINUX_SOCKETS_Driver::LoadAdapterConfiguration( UINT32 interfaceIndex, SOCK_NetworkConfiguration* config )
  603. {
  604. return S_OK;
  605. }
  606. HRESULT LINUX_SOCKETS_Driver::LoadWirelessConfiguration( UINT32 interfaceIndex, SOCK_WirelessConfiguration* wirelessConfig )
  607. {
  608. /// Load wireless specific settings if any. You must return S_OK, otherwise default values will be
  609. /// loaded by PAL.
  610. return CLR_E_FAIL;
  611. }
  612. struct dhcp_client_id
  613. {
  614. UINT8 code;
  615. UINT8 length;
  616. UINT8 type;
  617. UINT8 clientId[6];
  618. };
  619. HRESULT LINUX_SOCKETS_Driver::UpdateAdapterConfiguration( UINT32 interfaceIndex, UINT32 updateFlags, SOCK_NetworkConfiguration* config )
  620. {
  621. return S_OK;
  622. }
  623. int LINUX_SOCKETS_Driver::GetNativeTcpOption (int optname)
  624. {
  625. NATIVE_PROFILE_PAL_NETWORK();
  626. int nativeOptionName = 0;
  627. switch(optname)
  628. {
  629. case SOCK_TCP_NODELAY:
  630. nativeOptionName = TCP_NODELAY;
  631. break;
  632. // allow the C# user to specify LINUX options that our managed enum
  633. // doesn't support
  634. default:
  635. nativeOptionName = optname;
  636. break;
  637. }
  638. return nativeOptionName;
  639. }
  640. int LINUX_SOCKETS_Driver::GetNativeSockOption (int optname)
  641. {
  642. NATIVE_PROFILE_PAL_NETWORK();
  643. int nativeOptionName = 0;
  644. switch(optname)
  645. {
  646. case SOCK_SOCKO_DONTLINGER:
  647. case SOCK_SOCKO_LINGER:
  648. nativeOptionName = SO_LINGER;
  649. break;
  650. case SOCK_SOCKO_SENDTIMEOUT:
  651. nativeOptionName = SO_SNDTIMEO;
  652. break;
  653. case SOCK_SOCKO_RECEIVETIMEOUT:
  654. nativeOptionName = SO_RCVTIMEO;
  655. break;
  656. case SOCK_SOCKO_EXCLUSIVEADDRESSUSE:
  657. case SOCK_SOCKO_REUSEADDRESS:
  658. nativeOptionName = SO_REUSEADDR;
  659. break;
  660. case SOCK_SOCKO_KEEPALIVE:
  661. nativeOptionName = SO_KEEPALIVE;
  662. break;
  663. case SOCK_SOCKO_ERROR:
  664. nativeOptionName = SO_ERROR;
  665. break;
  666. case SOCK_SOCKO_BROADCAST:
  667. nativeOptionName = SO_BROADCAST;
  668. break;
  669. case SOCK_SOCKO_RECEIVEBUFFER:
  670. nativeOptionName = SO_RCVBUF;
  671. break;
  672. case SOCK_SOCKO_SENDBUFFER:
  673. nativeOptionName = SO_SNDBUF;
  674. break;
  675. case SOCK_SOCKO_ACCEPTCONNECTION:
  676. nativeOptionName = SO_ACCEPTCONN;
  677. break;
  678. case SOCK_SOCKO_TYPE:
  679. nativeOptionName = SO_TYPE;
  680. break;
  681. case SOCK_SOCKO_DONTROUTE:
  682. nativeOptionName = SO_DONTROUTE;
  683. break;
  684. case SOCK_SOCKO_OUTOFBANDINLINE:
  685. nativeOptionName = SO_OOBINLINE;
  686. break;
  687. case SOCK_SOCKO_DEBUG:
  688. nativeOptionName = SO_DEBUG;
  689. break;
  690. case SOCK_SOCKO_SENDLOWWATER:
  691. nativeOptionName = SO_SNDLOWAT;
  692. break;
  693. case SOCK_SOCKO_RECEIVELOWWATER:
  694. nativeOptionName = SO_RCVLOWAT;
  695. break;
  696. // case SOCK_SOCKO_MAXCONNECTIONS: //don't support
  697. case SOCK_SOCKO_USELOOPBACK: //
  698. case SOCK_SOCKO_UPDATE_ACCEPT_CTX:
  699. case SOCK_SOCKO_UPDATE_CONNECT_CTX:
  700. nativeOptionName = 0;
  701. break;
  702. // allow the C# user to specify LINUX options that our managed enum
  703. // doesn't support
  704. default:
  705. nativeOptionName = optname;
  706. break;
  707. }
  708. return nativeOptionName;
  709. }
  710. int LINUX_SOCKETS_Driver::GetNativeIPOption (int optname)
  711. {
  712. NATIVE_PROFILE_PAL_NETWORK();
  713. int nativeOptionName = 0;
  714. switch(optname)
  715. {
  716. case SOCK_IPO_TTL:
  717. nativeOptionName = IP_TTL;
  718. break;
  719. case SOCK_IPO_TOS:
  720. nativeOptionName = IP_TOS;
  721. break;
  722. case SOCK_IPO_MULTICAST_IF:
  723. nativeOptionName = IP_MULTICAST_IF;
  724. break;
  725. case SOCK_IPO_MULTICAST_TTL:
  726. nativeOptionName = IP_MULTICAST_TTL;
  727. break;
  728. case SOCK_IPO_MULTICAST_LOOP:
  729. nativeOptionName = IP_MULTICAST_LOOP;
  730. break;
  731. case SOCK_IPO_ADD_MEMBERSHIP:
  732. nativeOptionName = IP_ADD_MEMBERSHIP;
  733. break;
  734. case SOCK_IPO_DROP_MEMBERSHIP:
  735. nativeOptionName = IP_DROP_MEMBERSHIP;
  736. break;
  737. case SOCK_IPO_ADD_SOURCE_MEMBERSHIP:
  738. nativeOptionName = IP_ADD_SOURCE_MEMBERSHIP;
  739. break;
  740. case SOCK_IPO_DROP_SOURCE_MEMBERSHIP:
  741. nativeOptionName = IP_DROP_SOURCE_MEMBERSHIP;
  742. break;
  743. case SOCK_IPO_OPTIONS:
  744. nativeOptionName = IP_OPTIONS;
  745. break;
  746. case SOCK_IPO_HDRINCL:
  747. nativeOptionName = IP_HDRINCL;
  748. break;
  749. case SOCK_IPO_BLOCK_SOURCE:
  750. nativeOptionName = IP_OPTIONS;
  751. break;
  752. case SOCK_IPO_UBLOCK_SOURCE:
  753. nativeOptionName = IP_UNBLOCK_SOURCE;
  754. break;
  755. case SOCK_IPO_PACKET_INFO:
  756. case SOCK_IPO_IP_DONTFRAGMENT:
  757. nativeOptionName = 0;
  758. break;
  759. // allow the C# user to specify LINUX options that our managed enum
  760. // doesn't support
  761. default:
  762. nativeOptionName = optname;
  763. break;
  764. }
  765. return nativeOptionName;
  766. }
  767. int LINUX_SOCKETS_Driver::GetNativeError ( int error )
  768. {
  769. NATIVE_PROFILE_PAL_NETWORK();
  770. int ret;
  771. switch(error)
  772. {
  773. case EINTR:
  774. ret = SOCK_EINTR;
  775. break;
  776. case EACCES:
  777. ret = SOCK_EACCES;
  778. break;
  779. case EFAULT:
  780. ret = SOCK_EFAULT;
  781. break;
  782. case EINVAL:
  783. ret = SOCK_EINVAL;
  784. break;
  785. case EMFILE:
  786. ret = SOCK_EMFILE;
  787. break;
  788. case EAGAIN:
  789. case EBUSY:
  790. /* case EWOULDBLOCK: same as EINPROGRESS */
  791. case EINPROGRESS:
  792. ret = SOCK_EWOULDBLOCK;
  793. break;
  794. case EALREADY:
  795. ret = SOCK_EALREADY;
  796. break;
  797. case ENOTSOCK:
  798. ret = SOCK_ENOTSOCK;
  799. break;
  800. case EDESTADDRREQ:
  801. ret = SOCK_EDESTADDRREQ;
  802. break;
  803. case EMSGSIZE:
  804. ret = SOCK_EMSGSIZE;
  805. break;
  806. case EPROTOTYPE:
  807. ret = SOCK_EPROTOTYPE;
  808. break;
  809. case ENOPROTOOPT:
  810. ret = SOCK_ENOPROTOOPT;
  811. break;
  812. case EPROTONOSUPPORT:
  813. ret = SOCK_EPROTONOSUPPORT;
  814. break;
  815. case ESOCKTNOSUPPORT:
  816. ret = SOCK_ESOCKTNOSUPPORT;
  817. break;
  818. case EPFNOSUPPORT:
  819. ret = SOCK_EPFNOSUPPORT;
  820. break;
  821. case EAFNOSUPPORT:
  822. ret = SOCK_EAFNOSUPPORT;
  823. break;
  824. case EADDRINUSE:
  825. ret = SOCK_EADDRINUSE;
  826. break;
  827. case EADDRNOTAVAIL:
  828. ret = SOCK_EADDRNOTAVAIL;
  829. break;
  830. case ENETDOWN:
  831. ret = SOCK_ENETDOWN;
  832. break;
  833. case ENETUNREACH:
  834. ret = SOCK_ENETUNREACH;
  835. break;
  836. case ENETRESET:
  837. ret = SOCK_ENETRESET;
  838. break;
  839. case ECONNABORTED:
  840. ret = SOCK_ECONNABORTED;
  841. break;
  842. case ECONNRESET:
  843. ret = SOCK_ECONNRESET;
  844. break;
  845. case ENOBUFS:
  846. case ENOMEM:
  847. ret = SOCK_ENOBUFS;
  848. break;
  849. case EISCONN:
  850. ret = SOCK_EISCONN;
  851. break;
  852. case ENOTCONN:
  853. ret = SOCK_EISCONN;
  854. break;
  855. case ESHUTDOWN:
  856. ret = SOCK_ESHUTDOWN;
  857. break;
  858. case ETIMEDOUT:
  859. ret = SOCK_ETIMEDOUT;
  860. break;
  861. case ECONNREFUSED:
  862. ret = SOCK_ECONNREFUSED;
  863. break;
  864. case EHOSTDOWN:
  865. ret = SOCK_EHOSTDOWN;
  866. break;
  867. case EHOSTUNREACH:
  868. ret = SOCK_EHOSTUNREACH;
  869. break;
  870. case ENODATA:
  871. ret = SOCK_NO_DATA;
  872. break;
  873. default:
  874. ret = error;
  875. break;
  876. }
  877. return (ret);
  878. }