static int plugin_ipc_init(void) { struct sockaddr_in sock_in; uint32_t yes = 1; if (ipc_socket != -1) { close(ipc_socket); } /* Init ipc socket */ ipc_socket = socket(AF_INET, SOCK_STREAM, 0); if (ipc_socket == -1) { olsr_printf(1, "(DOT DRAW)IPC socket %s\n", strerror(errno)); return 0; } if (setsockopt(ipc_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)) < 0) { perror("SO_REUSEADDR failed"); CLOSE(ipc_socket); return 0; } #if (defined __FreeBSD__ || defined __FreeBSD_kernel__) && defined SO_NOSIGPIPE if (setsockopt(ipc_socket, SOL_SOCKET, SO_NOSIGPIPE, (char *)&yes, sizeof(yes)) < 0) { perror("SO_REUSEADDR failed"); CLOSE(ipc_socket); return 0; } #endif /* (defined __FreeBSD__ || defined __FreeBSD_kernel__) && defined SO_NOSIGPIPE */ /* Bind the socket */ /* complete the socket structure */ memset(&sock_in, 0, sizeof(sock_in)); sock_in.sin_family = AF_INET; sock_in.sin_addr.s_addr = ipc_listen_ip.v4.s_addr; sock_in.sin_port = htons(ipc_port); /* bind the socket to the port number */ if (bind(ipc_socket, (struct sockaddr *)&sock_in, sizeof(sock_in)) == -1) { olsr_printf(1, "(DOT DRAW)IPC bind %s\n", strerror(errno)); CLOSE(ipc_socket); return 0; } /* show that we are willing to listen */ if (listen(ipc_socket, 1) == -1) { olsr_printf(1, "(DOT DRAW)IPC listen %s\n", strerror(errno)); CLOSE(ipc_socket); return 0; } /* Register with olsrd */ add_olsr_socket(ipc_socket, &ipc_action, NULL, NULL, SP_PR_READ); return 1; }
/** *Create the socket to use for IPC to the *GUI front-end * *@return the socket FD */ int ipc_init(void) { //int flags; struct sockaddr_in sin; int yes = 1; /* Add parser function */ olsr_parser_add_function(&frontend_msgparser, PROMISCUOUS, 0); /* get an internet domain socket */ if ((ipc_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("IPC socket"); olsr_exit("IPC socket", EXIT_FAILURE); } if(setsockopt(ipc_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)) < 0) { perror("SO_REUSEADDR failed"); return 0; } /* complete the socket structure */ memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(IPC_PORT); /* bind the socket to the port number */ if(bind(ipc_sock, (struct sockaddr *) &sin, sizeof(sin)) == -1) { perror("IPC bind"); OLSR_PRINTF(1, "Will retry in 10 seconds...\n"); sleep(10); if(bind(ipc_sock, (struct sockaddr *) &sin, sizeof(sin)) == -1) { perror("IPC bind"); olsr_exit("IPC bind", EXIT_FAILURE); } OLSR_PRINTF(1, "OK\n"); } /* show that we are willing to listen */ if(listen(ipc_sock, olsr_cnf->ipc_connections) == -1) { perror("IPC listen"); olsr_exit("IPC listen", EXIT_FAILURE); } /* Register the socket with the socket parser */ add_olsr_socket(ipc_sock, &ipc_accept); return ipc_sock; }
int rtnetlink_register_socket(int rtnl_mgrp) { int sock = socket(AF_NETLINK,SOCK_RAW,NETLINK_ROUTE); struct sockaddr_nl addr; if (sock<0) { OLSR_PRINTF(1,"could not create rtnetlink socket! %s (%d)", strerror(errno), errno); return -1; } memset(&addr, 0, sizeof(addr)); addr.nl_family = AF_NETLINK; addr.nl_pid = 0; //kernel will assign appropiate number instead of pid (which is already used by primaray rtnetlink socket to add/delete routes) addr.nl_groups = rtnl_mgrp; if (bind(sock,(struct sockaddr *)&addr,sizeof(addr))<0) { OLSR_PRINTF(1,"could not bind rtnetlink socket! %s (%d)",strerror(errno), errno); return -1; } add_olsr_socket(sock, NULL, &rtnetlink_read, NULL, SP_IMM_READ); return sock; }
static int plugin_ipc_init(void) { union olsr_sockaddr sst; uint32_t yes = 1; socklen_t addrlen; /* Init ipc socket */ if ((ipc_socket = socket(olsr_cnf->ip_version, SOCK_STREAM, 0)) == -1) { #ifndef NODEBUG olsr_printf(1, "(JSONINFO) socket()=%s\n", strerror(errno)); #endif /* NODEBUG */ return 0; } else { if (setsockopt(ipc_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)) < 0) { #ifndef NODEBUG olsr_printf(1, "(JSONINFO) setsockopt()=%s\n", strerror(errno)); #endif /* NODEBUG */ return 0; } #if (defined __FreeBSD__ || defined __FreeBSD_kernel__) && defined SO_NOSIGPIPE if (setsockopt(ipc_socket, SOL_SOCKET, SO_NOSIGPIPE, (char *)&yes, sizeof(yes)) < 0) { perror("SO_REUSEADDR failed"); return 0; } #endif /* (defined __FreeBSD__ || defined __FreeBSD_kernel__) && defined SO_NOSIGPIPE */ #if defined linux && defined IPV6_V6ONLY if (jsoninfo_ipv6_only && olsr_cnf->ip_version == AF_INET6) { if (setsockopt(ipc_socket, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&yes, sizeof(yes)) < 0) { perror("IPV6_V6ONLY failed"); return 0; } } #endif /* defined linux && defined IPV6_V6ONLY */ /* Bind the socket */ /* complete the socket structure */ memset(&sst, 0, sizeof(sst)); if (olsr_cnf->ip_version == AF_INET) { sst.in4.sin_family = AF_INET; addrlen = sizeof(struct sockaddr_in); #ifdef SIN6_LEN sst.in4.sin_len = addrlen; #endif /* SIN6_LEN */ sst.in4.sin_addr.s_addr = jsoninfo_listen_ip.v4.s_addr; sst.in4.sin_port = htons(ipc_port); } else { sst.in6.sin6_family = AF_INET6; addrlen = sizeof(struct sockaddr_in6); #ifdef SIN6_LEN sst.in6.sin6_len = addrlen; #endif /* SIN6_LEN */ sst.in6.sin6_addr = jsoninfo_listen_ip.v6; sst.in6.sin6_port = htons(ipc_port); } /* bind the socket to the port number */ if (bind(ipc_socket, &sst.in, addrlen) == -1) { #ifndef NODEBUG olsr_printf(1, "(JSONINFO) bind()=%s\n", strerror(errno)); #endif /* NODEBUG */ return 0; } /* show that we are willing to listen */ if (listen(ipc_socket, 1) == -1) { #ifndef NODEBUG olsr_printf(1, "(JSONINFO) listen()=%s\n", strerror(errno)); #endif /* NODEBUG */ return 0; } /* Register with olsrd */ add_olsr_socket(ipc_socket, &ipc_action, NULL, NULL, SP_PR_READ); #ifndef NODEBUG olsr_printf(2, "(JSONINFO) listening on port %d\n", ipc_port); #endif /* NODEBUG */ } return 1; }
/* ------------------------------------------------------------------------- * Function : CreateCaptureSocket * Description: Create socket for promiscuously capturing multicast IP traffic * Input : ifname - network interface (e.g. "eth0") * Output : none * Return : the socket descriptor ( >= 0), or -1 if an error occurred * Data Used : none * Notes : The socket is a cooked IP packet socket, bound to the specified * network interface * ------------------------------------------------------------------------- */ static int CreateCaptureSocket(const char *ifName) { int ifIndex = if_nametoindex(ifName); struct packet_mreq mreq; struct ifreq req; struct sockaddr_ll bindTo; int skfd = 0; /* Open cooked IP packet socket */ if (olsr_cnf->ip_version == AF_INET) { skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); } else { skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6)); } if (skfd < 0) { BmfPError("socket(PF_PACKET) error"); return -1; } /* Set interface to promiscuous mode */ memset(&mreq, 0, sizeof(struct packet_mreq)); mreq.mr_ifindex = ifIndex; mreq.mr_type = PACKET_MR_PROMISC; if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { BmfPError("setsockopt(PACKET_MR_PROMISC) error"); close(skfd); return -1; } /* Get hardware (MAC) address */ memset(&req, 0, sizeof(struct ifreq)); strncpy(req.ifr_name, ifName, IFNAMSIZ - 1); req.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */ if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0) { BmfPError("error retrieving MAC address"); close(skfd); return -1; } /* Bind the socket to the specified interface */ memset(&bindTo, 0, sizeof(bindTo)); bindTo.sll_family = AF_PACKET; if (olsr_cnf->ip_version == AF_INET) { bindTo.sll_protocol = htons(ETH_P_IP); } else { bindTo.sll_protocol = htons(ETH_P_IPV6); } bindTo.sll_ifindex = ifIndex; memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN); bindTo.sll_halen = IFHWADDRLEN; if (bind(skfd, (struct sockaddr *)&bindTo, sizeof(bindTo)) < 0) { BmfPError("bind() error"); close(skfd); return -1; } /* Set socket to blocking operation */ if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0) { BmfPError("fcntl() error"); close(skfd); return -1; } //AddDescriptorToInputSet(skfd); add_olsr_socket(skfd, &DoMDNS,NULL, NULL, SP_PR_READ); return skfd; } /* CreateCaptureSocket */
/** Create a receive socket for a network interface @param networkInterface The network interface object. This function expects it to be filled with all information, except for the socket descriptor. @param rxSocketHandlerFunction The function that handles reception of data on the network interface @param rxMcAddr The receive multicast address @return - the socket descriptor (>= 0) - -1 if an error occurred */ static int createRxSocket(TRxTxNetworkInterface * networkInterface, socket_handler_func rxSocketHandlerFunction, union olsr_sockaddr * rxMcAddr) { int ipFamilySetting; int ipProtoSetting; int ipMcLoopSetting; int ipAddMembershipSetting; union olsr_sockaddr address; void * addr; size_t addrSize; int rxSocket = -1; int socketReuseFlagValue = 1; int mcLoopValue = 1; assert(networkInterface != NULL); assert(rxSocketHandlerFunction != NULL); assert(strncmp((char *) &networkInterface->name[0], "", sizeof(networkInterface->name)) != 0); memset(&address, 0, sizeof(address)); if (rxMcAddr->in.sa_family == AF_INET) { assert(rxMcAddr->in4.sin_addr.s_addr != INADDR_ANY); ipFamilySetting = AF_INET; ipProtoSetting = IPPROTO_IP; ipMcLoopSetting = IP_MULTICAST_LOOP; ipAddMembershipSetting = IP_ADD_MEMBERSHIP; address.in4.sin_family = ipFamilySetting; address.in4.sin_addr.s_addr = INADDR_ANY; address.in4.sin_port = getRxMcPort(); addr = &address.in4; addrSize = sizeof(struct sockaddr_in); } else { assert(rxMcAddr->in6.sin6_addr.s6_addr != in6addr_any.s6_addr); ipFamilySetting = AF_INET6; ipProtoSetting = IPPROTO_IPV6; ipMcLoopSetting = IPV6_MULTICAST_LOOP; ipAddMembershipSetting = IPV6_ADD_MEMBERSHIP; address.in6.sin6_family = ipFamilySetting; address.in6.sin6_addr = in6addr_any; address.in6.sin6_port = getRxMcPort(); addr = &address.in6; addrSize = sizeof(struct sockaddr_in6); } /* Create a datagram socket on which to receive. */ errno = 0; rxSocket = socket(ipFamilySetting, SOCK_DGRAM, 0); if (rxSocket < 0) { pudError(true, "Could not create a receive socket for interface %s", networkInterface->name); goto bail; } /* Enable SO_REUSEADDR to allow multiple applications to receive the same * multicast messages */ errno = 0; if (setsockopt(rxSocket, SOL_SOCKET, SO_REUSEADDR, &socketReuseFlagValue, sizeof(socketReuseFlagValue)) < 0) { pudError(true, "Could not set the reuse flag on the receive socket for" " interface %s", networkInterface->name); goto bail; } /* Bind to the proper port number with the IP address INADDR_ANY * (INADDR_ANY is really required here, do not change it) */ errno = 0; if (bind(rxSocket, addr, addrSize) < 0) { pudError(true, "Could not bind the receive socket for interface" " %s to port %u", networkInterface->name, ntohs(getRxMcPort())); goto bail; } /* Enable multicast local loopback */ errno = 0; if (setsockopt(rxSocket, ipProtoSetting, ipMcLoopSetting, &mcLoopValue, sizeof(mcLoopValue)) < 0) { pudError(true, "Could not enable multicast loopback on the" " receive socket for interface %s", networkInterface->name); goto bail; } /* Join the multicast group on the local interface. Note that this * ADD_MEMBERSHIP option must be called for each local interface over * which the multicast datagrams are to be received. */ if (ipFamilySetting == AF_INET) { struct ip_mreq mc_settings; struct ifreq ifr; struct in_addr * ifAddr = getIPv4Address(networkInterface->name, &ifr); if (!ifAddr) { pudError(true, "Could not get interface address of %s", networkInterface->name); goto bail; } (void) memset(&mc_settings, 0, sizeof(mc_settings)); mc_settings.imr_multiaddr = rxMcAddr->in4.sin_addr; mc_settings.imr_interface = *ifAddr; errno = 0; if (setsockopt(rxSocket, ipProtoSetting, ipAddMembershipSetting, &mc_settings, sizeof(mc_settings)) < 0) { pudError(true, "Could not subscribe interface %s to the configured" " multicast group", networkInterface->name); goto bail; } } else { struct ipv6_mreq mc6_settings; (void) memset(&mc6_settings, 0, sizeof(mc6_settings)); mc6_settings.ipv6mr_multiaddr = rxMcAddr->in6.sin6_addr; mc6_settings.ipv6mr_interface = if_nametoindex(networkInterface->name); errno = 0; if (setsockopt(rxSocket, ipProtoSetting, ipAddMembershipSetting, &mc6_settings, sizeof(mc6_settings)) < 0) { pudError(true, "Could not subscribe interface %s to the configured" " multicast group", networkInterface->name); goto bail; } } add_olsr_socket(rxSocket, rxSocketHandlerFunction, NULL, networkInterface, SP_PR_READ); return rxSocket; bail: if (rxSocket >= 0) { close(rxSocket); } return -1; }
/** Create an downlink socket @param ipVersion The IP version (AF_INET or AF_INET6) for the socket @param rxSocketHandlerFunction The socket handler function @return - the socket descriptor (>= 0) - -1 if an error occurred */ static int createDownlinkSocket(int ipVersion, socket_handler_func rxSocketHandlerFunction) { union olsr_sockaddr address; void * addr; size_t addrSize; int downlinkSocket = -1; int socketReuseFlagValue = 1; memset(&address, 0, sizeof(address)); if (ipVersion == AF_INET) { address.in4.sin_family = AF_INET; address.in4.sin_addr.s_addr = INADDR_ANY; address.in4.sin_port = getDownlinkPort(); addr = &address.in4; addrSize = sizeof(struct sockaddr_in); } else { address.in6.sin6_family = AF_INET6; address.in6.sin6_addr = in6addr_any; address.in6.sin6_port = getDownlinkPort(); addr = &address.in6; addrSize = sizeof(struct sockaddr_in6); } /* Create a datagram socket on which to receive */ errno = 0; downlinkSocket = socket(ipVersion, SOCK_DGRAM, 0); if (downlinkSocket < 0) { pudError(true, "Could not create the downlink socket"); goto bail; } /* Enable SO_REUSEADDR to allow multiple applications to receive the same * messages */ errno = 0; if (setsockopt(downlinkSocket, SOL_SOCKET, SO_REUSEADDR, &socketReuseFlagValue, sizeof(socketReuseFlagValue)) < 0) { pudError(true, "Could not set REUSE option on the downlink socket"); goto bail; } /* Bind to the proper port number with the IP address INADDR_ANY * (INADDR_ANY is really required here, do not change it) */ errno = 0; if (bind(downlinkSocket, addr, addrSize)) { pudError(true, "Could not bind downlink socket to port %d", getDownlinkPort()); goto bail; } add_olsr_socket(downlinkSocket, rxSocketHandlerFunction, NULL, NULL, SP_PR_READ); downlinkHandler = rxSocketHandlerFunction; return downlinkSocket; bail: if (downlinkSocket >= 0) { close(downlinkSocket); } return -1; }