sockets_ext.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "lwip/sockets.h"
  7. #include "lwip/priv/sockets_priv.h"
  8. #include "lwip/api.h"
  9. #include "lwip/sys.h"
  10. #include "lwip/tcp.h"
  11. #include "lwip/raw.h"
  12. #include "lwip/udp.h"
  13. #define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype) do { \
  14. if (((optlen) < sizeof(opttype)) || ((sock)->conn == NULL) || ((sock)->conn->pcb.tcp == NULL)) { *err=EINVAL; goto exit; } }while(0)
  15. #define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, opttype, netconntype) do { \
  16. LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype); \
  17. if (NETCONNTYPE_GROUP(netconn_type((sock)->conn)) != netconntype) { *err=ENOPROTOOPT; goto exit; } } while(0)
  18. bool lwip_setsockopt_impl_ext(struct lwip_sock* sock, int level, int optname, const void *optval, socklen_t optlen, int *err)
  19. {
  20. #if LWIP_IPV6
  21. if (level != IPPROTO_IPV6)
  22. #endif /* LWIP_IPV6 */
  23. {
  24. return false;
  25. }
  26. #if LWIP_IPV6
  27. switch (optname) {
  28. default:
  29. return false;
  30. case IPV6_MULTICAST_IF: /* NB: like IP_MULTICAST_IF, this takes an IP not an index */
  31. {
  32. LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP);
  33. udp_set_multicast_netif_index(sock->conn->pcb.udp, (u8_t)(*(const u8_t*)optval));
  34. }
  35. break;
  36. case IPV6_MULTICAST_HOPS:
  37. LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP);
  38. udp_set_multicast_ttl(sock->conn->pcb.udp, (u8_t)(*(const u8_t*)optval));
  39. break;
  40. case IPV6_MULTICAST_LOOP:
  41. LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP);
  42. if (*(const u8_t*)optval) {
  43. udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_MULTICAST_LOOP);
  44. } else {
  45. udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP);
  46. }
  47. break;
  48. }
  49. exit:
  50. return true;
  51. #endif /* LWIP_IPV6 */
  52. }
  53. bool lwip_getsockopt_impl_ext(struct lwip_sock* sock, int level, int optname, void *optval, uint32_t *optlen, int *err)
  54. {
  55. #if LWIP_IPV6
  56. if (level != IPPROTO_IPV6)
  57. #endif /* LWIP_IPV6 */
  58. {
  59. return false;
  60. }
  61. #if LWIP_IPV6
  62. switch (optname) {
  63. default:
  64. return false;
  65. case IPV6_MULTICAST_IF: /* NB: like IP_MULTICAST_IF, this returns an IP not an index */
  66. LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t);
  67. if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) {
  68. *err = ENOPROTOOPT;
  69. goto exit;
  70. }
  71. *(u8_t*)optval = udp_get_multicast_netif_index(sock->conn->pcb.udp);
  72. LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt_ext(IPPROTO_IPV6, IPV6_MULTICAST_IF) = 0x%"X32_F"\n",
  73. *(u32_t *)optval));
  74. break;
  75. case IPV6_MULTICAST_HOPS:
  76. printf("IPV6_MULTICAST_HOPS\n");
  77. LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t);
  78. if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) {
  79. *err = ENOPROTOOPT;
  80. goto exit;
  81. }
  82. *(u8_t*)optval = udp_get_multicast_ttl(sock->conn->pcb.udp);
  83. LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt_ext(IPPROTO_IPV6, IP_MULTICAST_LOOP) = %d\n",
  84. *(int *)optval));
  85. break;
  86. case IPV6_MULTICAST_LOOP:
  87. LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t);
  88. if ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_MULTICAST_LOOP) != 0) {
  89. *(u8_t*)optval = 1;
  90. } else {
  91. *(u8_t*)optval = 0;
  92. }
  93. LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt_ext(IPPROTO_IPV6, IP_MULTICAST_LOOP) = %d\n",
  94. *(int *)optval));
  95. break;
  96. }
  97. exit:
  98. return true;
  99. #endif /* LWIP_IPV6 */
  100. }