mdns_networking.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /*
  2. * MDNS Server Networking
  3. *
  4. */
  5. #include <string.h>
  6. #include "mdns_networking.h"
  7. #include "esp_log.h"
  8. #include "esp_netif_net_stack.h"
  9. extern mdns_server_t * _mdns_server;
  10. /*
  11. * MDNS Server Networking
  12. *
  13. */
  14. static const char *TAG = "MDNS_Networking";
  15. static struct udp_pcb * _pcb_main = NULL;
  16. static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip_addr_t *raddr, uint16_t rport);
  17. /**
  18. * @brief Low level UDP PCB Initialize
  19. */
  20. static esp_err_t _udp_pcb_main_init(void)
  21. {
  22. if(_pcb_main) {
  23. return ESP_OK;
  24. }
  25. _pcb_main = udp_new();
  26. if (!_pcb_main) {
  27. return ESP_ERR_NO_MEM;
  28. }
  29. if (udp_bind(_pcb_main, IP_ANY_TYPE, MDNS_SERVICE_PORT) != 0) {
  30. udp_remove(_pcb_main);
  31. _pcb_main = NULL;
  32. return ESP_ERR_INVALID_STATE;
  33. }
  34. _pcb_main->mcast_ttl = 255;
  35. _pcb_main->remote_port = MDNS_SERVICE_PORT;
  36. ip_addr_copy(_pcb_main->remote_ip, *(IP_ANY_TYPE));
  37. udp_recv(_pcb_main, &_udp_recv, _mdns_server);
  38. return ESP_OK;
  39. }
  40. /**
  41. * @brief Low level UDP PCB Free
  42. */
  43. static void _udp_pcb_main_deinit(void)
  44. {
  45. if(_pcb_main){
  46. udp_recv(_pcb_main, NULL, NULL);
  47. udp_disconnect(_pcb_main);
  48. udp_remove(_pcb_main);
  49. _pcb_main = NULL;
  50. }
  51. }
  52. /**
  53. * @brief Low level UDP Multicast membership control
  54. */
  55. static esp_err_t _udp_join_group(mdns_if_t if_inx, mdns_ip_protocol_t ip_protocol, bool join)
  56. {
  57. struct netif * netif = NULL;
  58. esp_netif_t *tcpip_if = _mdns_get_esp_netif(if_inx);
  59. if (!esp_netif_is_netif_up(tcpip_if)) {
  60. // Network interface went down before event propagated, skipping IGMP config
  61. return ESP_ERR_INVALID_STATE;
  62. }
  63. netif = esp_netif_get_netif_impl(tcpip_if);
  64. assert(netif);
  65. if (ip_protocol == MDNS_IP_PROTOCOL_V4) {
  66. ip4_addr_t multicast_addr;
  67. IP4_ADDR(&multicast_addr, 224, 0, 0, 251);
  68. if(join){
  69. if (igmp_joingroup_netif(netif, &multicast_addr)) {
  70. return ESP_ERR_INVALID_STATE;
  71. }
  72. } else {
  73. if (igmp_leavegroup_netif(netif, &multicast_addr)) {
  74. return ESP_ERR_INVALID_STATE;
  75. }
  76. }
  77. }
  78. #if CONFIG_LWIP_IPV6
  79. else {
  80. ip_addr_t multicast_addr = IPADDR6_INIT(0x000002ff, 0, 0, 0xfb000000);
  81. if(join){
  82. if (mld6_joingroup_netif(netif, &(multicast_addr.u_addr.ip6))) {
  83. return ESP_ERR_INVALID_STATE;
  84. }
  85. } else {
  86. if (mld6_leavegroup_netif(netif, &(multicast_addr.u_addr.ip6))) {
  87. return ESP_ERR_INVALID_STATE;
  88. }
  89. }
  90. }
  91. #endif
  92. return ESP_OK;
  93. }
  94. /**
  95. * @brief the receive callback of the raw udp api. Packets are received here
  96. *
  97. */
  98. static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip_addr_t *raddr, uint16_t rport)
  99. {
  100. uint8_t i;
  101. while (pb != NULL) {
  102. struct pbuf * this_pb = pb;
  103. pb = pb->next;
  104. this_pb->next = NULL;
  105. mdns_rx_packet_t * packet = (mdns_rx_packet_t *)malloc(sizeof(mdns_rx_packet_t));
  106. if (!packet) {
  107. HOOK_MALLOC_FAILED;
  108. //missed packet - no memory
  109. pbuf_free(this_pb);
  110. continue;
  111. }
  112. packet->tcpip_if = MDNS_IF_MAX;
  113. packet->pb = this_pb;
  114. packet->src_port = rport;
  115. #if CONFIG_LWIP_IPV6
  116. packet->src.type = raddr->type;
  117. memcpy(&packet->src.u_addr, &raddr->u_addr, sizeof(raddr->u_addr));
  118. #else
  119. packet->src.type = IPADDR_TYPE_V4;
  120. memcpy(&packet->src.u_addr.ip4, &raddr->addr, sizeof(ip_addr_t));
  121. #endif
  122. packet->dest.type = packet->src.type;
  123. if (packet->src.type == IPADDR_TYPE_V4) {
  124. packet->ip_protocol = MDNS_IP_PROTOCOL_V4;
  125. struct ip_hdr * iphdr = (struct ip_hdr *)(((uint8_t *)(packet->pb->payload)) - UDP_HLEN - IP_HLEN);
  126. packet->dest.u_addr.ip4.addr = iphdr->dest.addr;
  127. packet->multicast = ip4_addr_ismulticast(&(packet->dest.u_addr.ip4));
  128. }
  129. #if CONFIG_LWIP_IPV6
  130. else {
  131. packet->ip_protocol = MDNS_IP_PROTOCOL_V6;
  132. struct ip6_hdr * ip6hdr = (struct ip6_hdr *)(((uint8_t *)(packet->pb->payload)) - UDP_HLEN - IP6_HLEN);
  133. memcpy(&packet->dest.u_addr.ip6.addr, (uint8_t *)ip6hdr->dest.addr, 16);
  134. packet->multicast = ip6_addr_ismulticast(&(packet->dest.u_addr.ip6));
  135. }
  136. #endif
  137. //lwip does not return the proper pcb if you have more than one for the same multicast address (but different interfaces)
  138. struct netif * netif = NULL;
  139. struct udp_pcb * pcb = NULL;
  140. for (i=0; i<MDNS_IF_MAX; i++) {
  141. pcb = _mdns_server->interfaces[i].pcbs[packet->ip_protocol].pcb;
  142. netif = esp_netif_get_netif_impl(_mdns_get_esp_netif(i));
  143. if (pcb && netif && netif == ip_current_input_netif ()) {
  144. if (packet->src.type == IPADDR_TYPE_V4) {
  145. #if CONFIG_LWIP_IPV6
  146. if ((packet->src.u_addr.ip4.addr & netif->netmask.u_addr.ip4.addr) != (netif->ip_addr.u_addr.ip4.addr & netif->netmask.u_addr.ip4.addr)) {
  147. #else
  148. if ((packet->src.u_addr.ip4.addr & netif->netmask.addr) != (netif->ip_addr.addr & netif->netmask.addr)) {
  149. #endif //packet source is not in the same subnet
  150. pcb = NULL;
  151. break;
  152. }
  153. }
  154. packet->tcpip_if = i;
  155. break;
  156. }
  157. pcb = NULL;
  158. }
  159. if (!pcb || !_mdns_server || !_mdns_server->action_queue
  160. || _mdns_send_rx_action(packet) != ESP_OK) {
  161. pbuf_free(this_pb);
  162. free(packet);
  163. }
  164. }
  165. }
  166. /**
  167. * @brief Check if any of the interfaces is up
  168. */
  169. static bool _udp_pcb_is_in_use(void){
  170. int i, p;
  171. for (i=0; i<MDNS_IF_MAX; i++) {
  172. for (p=0; p<MDNS_IP_PROTOCOL_MAX; p++) {
  173. if(_mdns_server->interfaces[i].pcbs[p].pcb){
  174. return true;
  175. }
  176. }
  177. }
  178. return false;
  179. }
  180. /**
  181. * @brief Stop PCB Main code
  182. */
  183. static void _udp_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
  184. {
  185. if (!_mdns_server) {
  186. return;
  187. }
  188. mdns_pcb_t * _pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
  189. if (_pcb->pcb) {
  190. free(_pcb->probe_services);
  191. _pcb->state = PCB_OFF;
  192. _pcb->pcb = NULL;
  193. _pcb->probe_ip = false;
  194. _pcb->probe_services = NULL;
  195. _pcb->probe_services_len = 0;
  196. _pcb->probe_running = false;
  197. _pcb->failed_probes = 0;
  198. _udp_join_group(tcpip_if, ip_protocol, false);
  199. if(!_udp_pcb_is_in_use()) {
  200. _udp_pcb_main_deinit();
  201. }
  202. }
  203. }
  204. /**
  205. * @brief Start PCB Main code
  206. */
  207. static esp_err_t _udp_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
  208. {
  209. if (!_mdns_server || _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
  210. return ESP_ERR_INVALID_STATE;
  211. }
  212. esp_err_t err = _udp_join_group(tcpip_if, ip_protocol, true);
  213. if(err){
  214. return err;
  215. }
  216. err = _udp_pcb_main_init();
  217. if(err){
  218. return err;
  219. }
  220. _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb = _pcb_main;
  221. _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].failed_probes = 0;
  222. return ESP_OK;
  223. }
  224. typedef struct {
  225. struct tcpip_api_call_data call;
  226. mdns_if_t tcpip_if;
  227. mdns_ip_protocol_t ip_protocol;
  228. struct pbuf *pbt;
  229. const ip_addr_t *ip;
  230. uint16_t port;
  231. esp_err_t err;
  232. } mdns_api_call_t;
  233. /**
  234. * @brief Start PCB from LwIP thread
  235. */
  236. static err_t _mdns_pcb_init_api(struct tcpip_api_call_data *api_call_msg)
  237. {
  238. mdns_api_call_t * msg = (mdns_api_call_t *)api_call_msg;
  239. msg->err = _udp_pcb_init(msg->tcpip_if, msg->ip_protocol);
  240. return msg->err;
  241. }
  242. /**
  243. * @brief Stop PCB from LwIP thread
  244. */
  245. static err_t _mdns_pcb_deinit_api(struct tcpip_api_call_data *api_call_msg)
  246. {
  247. mdns_api_call_t * msg = (mdns_api_call_t *)api_call_msg;
  248. _udp_pcb_deinit(msg->tcpip_if, msg->ip_protocol);
  249. msg->err = ESP_OK;
  250. return ESP_OK;
  251. }
  252. /*
  253. * Non-static functions below are
  254. * - _mdns prefixed
  255. * - commented in mdns_networking.h header
  256. */
  257. esp_err_t _mdns_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
  258. {
  259. mdns_api_call_t msg = {
  260. .tcpip_if = tcpip_if,
  261. .ip_protocol = ip_protocol
  262. };
  263. tcpip_api_call(_mdns_pcb_init_api, &msg.call);
  264. return msg.err;
  265. }
  266. esp_err_t _mdns_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
  267. {
  268. mdns_api_call_t msg = {
  269. .tcpip_if = tcpip_if,
  270. .ip_protocol = ip_protocol
  271. };
  272. tcpip_api_call(_mdns_pcb_deinit_api, &msg.call);
  273. return msg.err;
  274. }
  275. static err_t _mdns_udp_pcb_write_api(struct tcpip_api_call_data *api_call_msg)
  276. {
  277. void * nif = NULL;
  278. mdns_api_call_t * msg = (mdns_api_call_t *)api_call_msg;
  279. mdns_pcb_t * _pcb = &_mdns_server->interfaces[msg->tcpip_if].pcbs[msg->ip_protocol];
  280. nif = esp_netif_get_netif_impl(_mdns_get_esp_netif(msg->tcpip_if));
  281. if (!nif) {
  282. pbuf_free(msg->pbt);
  283. msg->err = ERR_IF;
  284. return ERR_IF;
  285. }
  286. esp_err_t err = udp_sendto_if (_pcb->pcb, msg->pbt, msg->ip, msg->port, (struct netif *)nif);
  287. pbuf_free(msg->pbt);
  288. msg->err = err;
  289. return err;
  290. }
  291. size_t _mdns_udp_pcb_write(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, const esp_ip_addr_t *ip, uint16_t port, uint8_t * data, size_t len)
  292. {
  293. struct pbuf* pbt = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
  294. if (pbt == NULL) {
  295. return 0;
  296. }
  297. memcpy((uint8_t *)pbt->payload, data, len);
  298. mdns_api_call_t msg = {
  299. .tcpip_if = tcpip_if,
  300. .ip_protocol = ip_protocol,
  301. .pbt = pbt,
  302. .ip = (ip_addr_t *)ip,
  303. .port = port
  304. };
  305. tcpip_api_call(_mdns_udp_pcb_write_api, &msg.call);
  306. if (msg.err) {
  307. return 0;
  308. }
  309. return len;
  310. }