apr_socket_t * create_mcast_server(apr_pool_t *context, int32_t family, char *mcast_ip, apr_port_t port, char *bind_addr, char *interface) { apr_status_t status = APR_SUCCESS; /* NOTE: If bind is set to mcast_ip in the configuration file, then we will bind the * the multicast address to the socket as well as the port and prevent any * datagrams that might be delivered to this port from being processed. Otherwise, * packets destined to the same port (but a different multicast/unicast channel) will be * processed. */ apr_socket_t *socket = create_udp_server(context, family, port, bind_addr); if(!socket) { return NULL; } /* TODO: We can probe for a list of interfaces and perform multiple join calls for the same * socket to have it listen for multicast traffic on all interfaces (important for * multihomed machines). */ if(interface && !apr_strnatcasecmp(interface, "ALL")) { /* for(each interface) * { * join_mcast(...); * } */ } else { status = join_mcast(context, socket, mcast_ip, port, interface ); } return status == APR_SUCCESS? socket: NULL; }
void intercom_update_interfaces(intercom_ctx *ctx) { for (int i = 0; i < VECTOR_LEN(ctx->interfaces); i++) { intercom_if *iface = &VECTOR_INDEX(ctx->interfaces, i); iface->ifindex = if_nametoindex(iface->ifname); if (!iface->ifindex) continue; if (join_mcast(ctx->fd, ctx->groupaddr.sin6_addr, iface)) iface->ok = true; } }
void os_socket_set_olsr_options(struct interface * ifs, int sock, union olsr_sockaddr *mcast) { /* Set TOS */ int data = IPTOS_PREC(olsr_cnf->tos); if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, (char *)&data, sizeof(data)) < 0) { OLSR_WARN(LOG_INTERFACE, "setsockopt(SO_PRIORITY) error %s", strerror(errno)); } data = IPTOS_TOS(olsr_cnf->tos); if (setsockopt(sock, SOL_IP, IP_TOS, (char *)&data, sizeof(data)) < 0) { OLSR_WARN(LOG_INTERFACE, "setsockopt(IP_TOS) error %s", strerror(errno)); } if (mcast) { join_mcast(ifs, sock, mcast); } }
int servopen(char* host, char* port) { int fd, newfd, i, on, pid; const char* protocol; struct in_addr inaddr; struct servent* sp; protocol = udp ? "udp" : "tcp"; /* Initialize the socket address structure */ bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; /* Caller normally wildcards the local Internet address, meaning a connection will be accepted on any connected interface. We only allow an IP address for the "host", not a name. */ if (host == NULL) servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* wildcard */ else { if (inet_aton(host, &inaddr) == 0) err_quit("invalid host name for server: %s", host); servaddr.sin_addr = inaddr; } /* See if "port" is a service name or number */ if ((i = atoi(port)) == 0) { if ((sp = getservbyname(port, protocol)) == NULL) err_ret("getservbyname() error for: %s/%s", port, protocol); servaddr.sin_port = sp->s_port; } else servaddr.sin_port = htons(i); if ((fd = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) err_sys("socket() error"); if (reuseaddr) { on = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) err_sys("setsockopt of SO_REUSEADDR error"); } #ifdef SO_REUSEPORT if (reuseport) { on = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0) err_sys("setsockopt of SO_REUSEPORT error"); } #endif /* Bind our well-known port so the client can connect to us. */ if (bind(fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) err_sys("can't bind local address"); join_mcast(fd, &servaddr); if (udp) { buffers(fd); if (foreignip[0] != 0) { /* connect to foreignip/port# */ bzero(&cliaddr, sizeof(cliaddr)); if (inet_aton(foreignip, &cliaddr.sin_addr) == 0) err_quit("invalid IP address: %s", foreignip); cliaddr.sin_family = AF_INET; cliaddr.sin_port = htons(foreignport); /* connect() for datagram socket doesn't appear to allow wildcarding of either IP address or port number */ if (connect(fd, (struct sockaddr*)&cliaddr, sizeof(cliaddr)) < 0) err_sys("connect() error"); } sockopts(fd, 1); return (fd); /* nothing else to do */ } buffers(fd); /* may set receive buffer size; must do here to get correct window advertised on SYN */ sockopts(fd, 0); /* only set some socket options for fd */ listen(fd, listenq); if (pauselisten) sleep_us(pauselisten * 1000); /* lets connection queue build up */ if (dofork) TELL_WAIT(); /* initialize synchronization primitives */ for (;;) { i = sizeof(cliaddr); if ((newfd = accept(fd, (struct sockaddr*)&cliaddr, &i)) < 0) err_sys("accept() error"); if (dofork) { if ((pid = fork()) < 0) err_sys("fork error"); if (pid > 0) { close(newfd); /* parent closes connected socket */ WAIT_CHILD(); /* wait for child to output to terminal */ continue; /* and back to for(;;) for another accept() */ } else { close(fd); /* child closes listening socket */ } } /* child (or iterative server) continues here */ if (verbose) { /* Call getsockname() to find local address bound to socket: local internet address is now determined (if multihomed). */ i = sizeof(servaddr); if (getsockname(newfd, (struct sockaddr*)&servaddr, &i) < 0) err_sys("getsockname() error"); /* Can't do one fprintf() since inet_ntoa() stores the result in a static location. */ fprintf(stderr, "connection on %s.%d ", INET_NTOA(servaddr.sin_addr), ntohs(servaddr.sin_port)); fprintf(stderr, "from %s.%d\n", INET_NTOA(cliaddr.sin_addr), ntohs(cliaddr.sin_port)); } buffers(newfd); /* setsockopt() again, in case it didn't propagate from listening socket to connected socket */ sockopts(newfd, 1); /* can set all socket options for this socket */ if (dofork) TELL_PARENT(getppid()); /* tell parent we're done with terminal */ return (newfd); } }
int main(int argc, char **argv){ const int on = 1; unsigned char ttl = 1; time_t rawtime; time_t lasttime; int maxfd; fd_set rset; ssize_t how_much_read; char msg[MAXLINE]; rt = Socket(AF_INET, SOCK_RAW, MY_IP_PROTO); Setsockopt(rt, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)); pg = Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); request_sock = Socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); multicast_sock = Socket(AF_INET, SOCK_DGRAM, 0); multicast_recv = Socket(AF_INET, SOCK_DGRAM, 0); Mcast_set_loop(multicast_sock,0); Setsockopt(multicast_sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)); Setsockopt(multicast_recv, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)); gethostname(our_hostname, sizeof(our_hostname)); //printf("My our_hostname: %s\n", our_hostname); get_eth0_stuff(); if(argc > 1) { //DEBUG("%s is the start of the tour!\n",our_hostname); int i = 1; tour tour_pkt; // separate func bzero(&tour_pkt, sizeof(tour_pkt)); fill_buff_with_ip_of_hostname(our_hostname); //printf("fill buff ok\n"); inet_aton(ip_static_buff, &(tour_pkt.payload[0])); join_mcast(MULTICAST_ADDRESS, MULTICAST_PORT); #if 0 // tokenize by ' ' and send each char* to gethostbyname char *token, *prev_token; const char s[2] = " "; /* get the first token */ token = strtok(argv[1], s); /* walk through other tokens */ while(token != NULL) { DEBUG("token = %s\n", token ); fill_buff_with_ip_of_hostname(token); inet_aton(ip_static_buff, &tour_pkt.payload[i]); prev_token = token; token = strtok(NULL, s); if(!strcmp(prev_token, token)){ perror("The same node should not appear consequentively in the tour list – i.e., the next node on the tour cannot be the current node itself"); exit(0); } i++; } // separate func #endif while(i< argc) { //printf("argv[%d] is %s\n",i, argv[i]); fill_buff_with_ip_of_hostname(argv[i]); //printf("fill buff ok\n"); inet_aton(ip_static_buff, &(tour_pkt.payload[i])); i++; } tour_pkt.index = 0; // We're the origin tour_pkt.total = i-1; //printf("tour_pkt total %d\n", tour_pkt.total); send_raw_tour_packet(&tour_pkt); }else{ //DEBUG("We're NOT the start of the tour!"); #if 0 while(1) { int len = 0; len = Recv(rt, msg, sizeof(msg), 0); printf("received len %d\n",len); int j = 0; for(;j<len; j++) { printf("%.2x ", msg[j]); if((i-9) % 10 == 0) printf("\n"); fflush(stdout); } } #endif } #if 0 fill_buff_with_ip_of_hostname("vm2"); inet_aton(ip_static_buff, (struct in_addr *)&dest_of_echo_req); printf("destofechoreq %x\n", dest_of_echo_req.s_addr); struct sockaddr_in IPaddr; struct hwaddr HWaddr; bzero(&IPaddr, sizeof(IPaddr)); bzero(&HWaddr, sizeof(HWaddr)); IPaddr.sin_addr = dest_of_echo_req; //Areq((struct sockaddr *)&IPaddr, sizeof(struct sockaddr_in), &HWaddr); //printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",HWaddr.sll_addr[0],HWaddr.sll_addr[1],HWaddr.sll_addr[2], // HWaddr.sll_addr[3],HWaddr.sll_addr[4],HWaddr.sll_addr[5]); void sig_alrm(int signo); if(argc > 1){ Signal(SIGALRM, sig_alrm); sig_alrm(SIGALRM); } //send_icmp_request(HWaddr.sll_addr); int n = 0; struct timeval tval; while(1) { n = recv(pg, msg, sizeof(msg), 0); if(n<0) { if (errno == EINTR) continue; } printf("receive ping packet\n"); //int j = 0; //for (; j < n; j++) //{ // printf("%.2x ", msg[j]); // if((j-9) % 10 == 0) printf("\n"); // fflush(stdout); //} Gettimeofday(&tval, NULL); proc_v4(msg,n,NULL, &tval); } #endif #if 1 //act_open.sa_flags = 0; //sigemptyset(&act_open.sa_mask); //sigaddset(&act_open.sa_mask, SIGALRM); //act_open.sa_handler = terminate; Signal(SIGALRM, sig_alrm); FD_ZERO(&rset); maxfd = max(pg, multicast_recv); maxfd = max(rt, maxfd); while(1){ FD_SET(multicast_recv, &rset); FD_SET(rt, &rset); FD_SET(pg, &rset); if(select(maxfd+1, &rset, NULL, NULL, NULL)<0) { if(errno == EINTR) { continue; } } if(FD_ISSET(rt, &rset)){ //DEBUG("possibly totally wrong here\n"); //DEBUG("possibly totally wrong here\n"); //DEBUG("possibly totally wrong here\n"); alarm(0); bzero(msg, sizeof(msg)); how_much_read = Recv(rt, msg, sizeof(msg), 0); //assert(how_much_read == sizeof(sizeof(my_ip_header)+sizeof(tour))); //printf("rt receive pkt len %d\n", how_much_read); my_ip_header *head = (my_ip_header *)msg; tour *tour_pkt = (tour *)(msg+sizeof(my_ip_header)); if(ntohs(head->id) != MY_IP_ID){ //DEBUG("head->id != MY_IP_ID\n"); continue; } char *name = find_vm_name(inet_ntoa(*(struct in_addr *)&head->saddr)); time(&rawtime); printf("<%s> recieved source routing packet from <%s>\n", ctime (&rawtime), name); if(!already_here){ already_here = 1; // IP_MULTICAST_TTL - If not otherwise specified, has a default value of 1. join_mcast(inet_ntoa(tour_pkt->multicast_addr), ntohs(tour_pkt->multicast_port)); stop_pinging = 0; } // start icmp echo reqs for(i = 0; i < prev_sender_list.index; i++) { if(!memcmp(&prev_sender_list.previous_senders[i], &tour_pkt->payload[(tour_pkt->index)], sizeof(struct in_addr))) we_dont_need_to_send_echo_req = 1; else{ we_dont_need_to_send_echo_req = 0; break; } } if(!we_dont_need_to_send_echo_req){ //DEBUG("We Need To Send Echo Request\n"); prev_sender_list.previous_senders[prev_sender_list.index] = tour_pkt->payload[(tour_pkt->index)]; prev_sender_list.index++; dest_of_echo_req = tour_pkt->payload[(tour_pkt->index)]; char *name = find_vm_name(inet_ntoa(*(struct in_addr *)&tour_pkt->payload[(tour_pkt->index)])); printf("PING %s (%s): %d data bytes\n",name,inet_ntoa(dest_of_echo_req), icmpdata); sig_alrm(SIGALRM); } else { char *name = find_vm_name(inet_ntoa(*(struct in_addr *)&tour_pkt->payload[(tour_pkt->index)])); printf("We have ping %s before\n",name); } // INCREMENTING THE INDEX tour_pkt->index = (tour_pkt->index)+1; if((tour_pkt->index) == MAX_VISITS){ perror("MAX_VISITS has been reached."); exit(0); } // Now blank //bzero(&for_comparisons, sizeof(for_comparisons)); // ghiTODO this may not work ghiTODO //if(!memcmp(&tour_pkt->payload[ntohl(tour_pkt->index)], &for_comparisons, sizeof(for_comparisons))){ //printf("rt current pkt index %d, total index %d\n",tour_pkt->index, tour_pkt->total); if(tour_pkt->index == tour_pkt->total) { //printf("We're the final destination.\n"); // ping the saddr final_destination = 1; char buffer[100]; snprintf(buffer, 100, "<<<<< This is node %s. Tour has ended. Group members please identify yourselves. >>>>>",our_hostname); printf("Node %s. Sending: <%s>. ",our_hostname, buffer); send_multicast_message(buffer,strlen(buffer)+1); //printf("send mulitcast msg ok\n"); }else{ //printf("We're NOT the final destination, keep touring.\n"); // pass it along send_raw_tour_packet(tour_pkt); } }else if(FD_ISSET(multicast_recv, &rset)){ //DEBUG("Receiving multicast message.\n"); printf(""); bzero(msg, sizeof(msg)); how_much_read = Recv(multicast_recv, msg, sizeof(msg), 0); //printf("multicast msg len %d\n", how_much_read); msg[how_much_read]='\0'; if(!first_term){ printf("Node %s. Received <%s>. ",our_hostname,msg); // then should immediately stop ping //DEBUG("how_much_read is %lu\n", how_much_read); stop_pinging = 1; alarm(0); bzero(msg, sizeof(msg)); snprintf(msg, sizeof(msg), "<<<<< Node %s I am a member of the group. >>>>>", our_hostname); printf("Node %s. Sending <%s>. ", our_hostname, msg); fflush(stdout); first_term = 1; send_multicast_message(msg,strlen(msg)+1); } else { Signal(SIGALRM, terminate); alarm(5); printf(""); printf("Node %s. Received <%s>. ",our_hostname,msg); fflush(stdout); } //send_multicast_message(msg); }else if(FD_ISSET(pg, &rset)){ //DEBUG("Receiving echo reply message.\n"); struct timeval tval; bzero(msg, sizeof(msg)); how_much_read = Recv(pg, msg, sizeof(msg), 0); Gettimeofday(&tval, NULL); proc_v4(msg,how_much_read,NULL, &tval); //assert(how_much_read == sizeof(sizeof(my_eth_header)+sizeof(my_ip_header)+sizeof(my_icmp_header))); //DEBUG("how_much_read is %lu\n", how_much_read); //DEBUG("Node %s recieved %s\n", our_hostname, msg); // my_eth_header *eh = (my_eth_header *)msg; // my_ip_header *iph = (my_ip_header *)msg+sizeof(my_eth_header); // my_icmp_header *icmph = (my_icmp_header *)msg+sizeof(my_eth_header)+sizeof(my_ip_header); //my_ip_header *iph = (my_ip_header *)(msg+sizeof(my_eth_header)); //if(!memcmp(&iph->saddr, &dest_of_echo_req, sizeof(dest_of_echo_req))){ // DEBUG("ghiTODO\n"); // count_of_replies++; // DEBUG("ghiTODO\n"); //DEBUG("ghiTODO\n"); //DEBUG("ghiTODO\n"); // if(final_destination && count_of_replies >= 5){ // stop_pinging = 1; // bzero(msg, sizeof(msg)); /// snprintf(msg, sizeof(msg), "<<<<< This is node %s Tour has ended. Group members please identify yourselves.>>>>>", our_hostname); // printf("Node %s sending %s", our_hostname, msg); // send_multicast_message(msg, strlen(msg)+1); // alarm(5); // } //}else{ //DEBUG("The following is FALSE !memcmp(&iph->saddr, &dest_of_echo_req, sizeof(dest_of_echo_req))"); //} } #if 0 time(&rawtime); if(lasttime+1 <= rawtime){ if(!stop_pinging){ struct sockaddr_in IPaddr; struct hwaddr HWaddr; bzero(&IPaddr, sizeof(IPaddr)); bzero(&HWaddr, sizeof(HWaddr)); IPaddr.sin_addr = dest_of_echo_req; Areq((struct sockaddr *)&IPaddr, sizeof(struct sockaddr_in), &HWaddr); send_raw_echo_request_message(HWaddr.sll_addr); } }else{ lasttime = rawtime; } #endif } #endif }
int main(int argc, char **argv) { int sock; struct sockaddr_in6 server_addr = {}; char *script = NULL; struct in6_addr mgroup_addr; sock = socket(PF_INET6, SOCK_DGRAM, 0); if (sock < 0) { perror("creating socket"); exit(EXIT_FAILURE); } server_addr.sin6_family = AF_INET6; server_addr.sin6_addr = in6addr_any; opterr = 0; int group_set = 0; int c; while ((c = getopt(argc, argv, "p:g:s:i:h")) != -1) switch (c) { case 'p': server_addr.sin6_port = htons(atoi(optarg)); break; case 'g': if (!inet_pton(AF_INET6, optarg, &mgroup_addr)) { perror("Invalid multicast group. This message will probably confuse you"); exit(EXIT_FAILURE); } group_set = 1; break; case 's': free(script); // in case -s is given multiple times script = strdup(optarg); if (script == NULL) { perror("Couldn't duplicate string"); exit(EXIT_FAILURE); } break; case 'i': if (!group_set) { fprintf(stderr, "Multicast group must be given before interface.\n"); exit(EXIT_FAILURE); } join_mcast(sock, mgroup_addr, optarg); break; case 'h': usage(); exit(EXIT_SUCCESS); break; default: fprintf(stderr, "Invalid parameter %c ignored.\n", c); } if (script == NULL) { fprintf(stderr, "No script given\n"); exit(EXIT_FAILURE); } if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } serve(sock, script); free(script); return EXIT_FAILURE; }