1#include "utils.h" 2#include <pico_ipv4.h> 3#include <pico_socket.h> 4 5extern void app_udpecho(char *arg); 6 7/*** START Multicast RECEIVE + ECHO ***/ 8/* 9 * multicast receive expects the following format: mcastreceive:link_addr:mcast_addr:listen_port:sendto_port 10 * link_addr: mcastreceive picoapp IP address 11 * mcast_addr: multicast IP address to receive 12 * listen_port: port number on which the mcastreceive listens 13 * sendto_port: port number to echo multicast traffic to (echo to originating IP address) 14 * 15 * f.e.: ./build/test/picoapp.elf --vde pic1:/tmp/pic0.ctl:10.40.0.3:255.255.0.0: -a mcastreceive:10.40.0.3:224.7.7.7:6667:6667 16 */ 17extern struct udpclient_pas *udpclient_pas; 18extern struct udpecho_pas *udpecho_pas; 19#ifdef PICO_SUPPORT_MCAST 20void app_mcastreceive(char *arg) 21{ 22 char *new_arg = NULL, *p = NULL, *nxt = arg; 23 char *laddr = NULL, *maddr = NULL, *lport = NULL, *sport = NULL; 24 uint16_t listen_port = 0; 25 union pico_address inaddr_link = { 26 0 27 }, inaddr_mcast = { 28 0 29 }; 30 struct pico_ip_mreq mreq = ZERO_MREQ; 31 struct pico_ip_mreq_source mreq_source = ZERO_MREQ_SRC; 32 33 /* start of parameter parsing */ 34 if (nxt) { 35 nxt = cpy_arg(&laddr, nxt); 36 if (laddr) { 37 pico_string_to_ipv4(laddr, &inaddr_link.ip4.addr); 38 } else { 39 goto out; 40 } 41 } else { 42 /* no arguments */ 43 goto out; 44 } 45 46 if (nxt) { 47 nxt = cpy_arg(&maddr, nxt); 48 if (maddr) { 49 pico_string_to_ipv4(maddr, &inaddr_mcast.ip4.addr); 50 } else { 51 goto out; 52 } 53 } else { 54 /* missing multicast address */ 55 goto out; 56 } 57 58 if (nxt) { 59 nxt = cpy_arg(&lport, nxt); 60 if (lport && atoi(lport)) { 61 listen_port = short_be(atoi(lport)); 62 } else { 63 /* incorrect listen_port */ 64 goto out; 65 } 66 } else { 67 /* missing listen_port */ 68 goto out; 69 } 70 71 if (nxt) { 72 nxt = cpy_arg(&sport, nxt); 73 if (sport && atoi(sport)) { 74 /* unused at this moment */ 75 /* send_port = short_be(atoi(sport)); */ 76 } else { 77 /* incorrect send_port */ 78 goto out; 79 } 80 } else { 81 /* missing send_port */ 82 goto out; 83 } 84 85 /* end of parameter parsing */ 86 87 printf("\n%s: multicast receive started. Receiving packets on %s:%d\n\n", __FUNCTION__, maddr, short_be(listen_port)); 88 89 /* udpecho:bind_addr:listen_port[:sendto_port:datasize] */ 90 new_arg = calloc(1, strlen(laddr) + 1 + strlen(lport) + 1 + strlen(sport) + strlen(":64:") + 1); 91 p = strcat(new_arg, laddr); 92 p = strcat(p + strlen(laddr), ":"); 93 p = strcat(p + 1, lport); 94 p = strcat(p + strlen(lport), ":"); 95 p = strcat(p + 1, sport); 96 p = strcat(p + strlen(sport), ":64:"); 97 98 app_udpecho(new_arg); 99 100 mreq.mcast_group_addr = mreq_source.mcast_group_addr = inaddr_mcast; 101 mreq.mcast_link_addr = mreq_source.mcast_link_addr = inaddr_link; 102 mreq_source.mcast_source_addr.ip4.addr = long_be(0XAC100101); 103 if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_MEMBERSHIP, &mreq) < 0) { 104 printf("%s: socket_setoption PICO_IP_ADD_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err)); 105 } 106 107 if(pico_socket_setoption(udpecho_pas->s, PICO_IP_DROP_MEMBERSHIP, &mreq) < 0) { 108 printf("%s: socket_setoption PICO_IP_DROP_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err)); 109 } 110 111 if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_MEMBERSHIP, &mreq) < 0) { 112 printf("%s: socket_setoption PICO_IP_ADD_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err)); 113 } 114 115 if(pico_socket_setoption(udpecho_pas->s, PICO_IP_BLOCK_SOURCE, &mreq_source) < 0) { 116 printf("%s: socket_setoption PICO_IP_BLOCK_SOURCE failed: %s\n", __FUNCTION__, strerror(pico_err)); 117 } 118 119 if(pico_socket_setoption(udpecho_pas->s, PICO_IP_UNBLOCK_SOURCE, &mreq_source) < 0) { 120 printf("%s: socket_setoption PICO_IP_UNBLOCK_SOURCE failed: %s\n", __FUNCTION__, strerror(pico_err)); 121 } 122 123 if(pico_socket_setoption(udpecho_pas->s, PICO_IP_DROP_MEMBERSHIP, &mreq) < 0) { 124 printf("%s: socket_setoption PICO_IP_DROP_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err)); 125 } 126 127 if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source) < 0) { 128 printf("%s: socket_setoption PICO_IP_ADD_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err)); 129 } 130 131 if(pico_socket_setoption(udpecho_pas->s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source) < 0) { 132 printf("%s: socket_setoption PICO_IP_DROP_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err)); 133 } 134 135 if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source) < 0) { 136 printf("%s: socket_setoption PICO_IP_ADD_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err)); 137 } 138 139 mreq_source.mcast_source_addr.ip4.addr = long_be(0XAC10010A); 140 if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source) < 0) { 141 printf("%s: socket_setoption PICO_IP_ADD_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err)); 142 } 143 144 if(pico_socket_setoption(udpecho_pas->s, PICO_IP_DROP_MEMBERSHIP, &mreq) < 0) { 145 printf("%s: socket_setoption PICO_IP_DROP_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err)); 146 } 147 148 mreq_source.mcast_source_addr.ip4.addr = long_be(0XAC100101); 149 if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source) < 0) { 150 printf("%s: socket_setoption PICO_IP_ADD_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err)); 151 } 152 153 mreq_source.mcast_group_addr.ip4.addr = long_be(0XE0010101); 154 if(pico_socket_setoption(udpecho_pas->s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source) < 0) { 155 printf("%s: socket_setoption PICO_IP_ADD_SOURCE_MEMBERSHIP: %s\n", __FUNCTION__, strerror(pico_err)); 156 } 157 158 return; 159 160out: 161 fprintf(stderr, "mcastreceive expects the following format: mcastreceive:link_addr:mcast_addr:listen_port[:send_port]\n"); 162 exit(255); 163} 164#else 165void app_mcastreceive(char *arg) 166{ 167 printf("ERROR: PICO_SUPPORT_MCAST disabled\n"); 168 return; 169} 170#endif 171/*** END Multicast RECEIVE + ECHO ***/ 172