void ikev2_msg_cb(int fd, short event, void *arg) { struct iked_socket *sock = arg; struct iked *env = sock->sock_env; struct iked_message msg; struct ike_header hdr; u_int32_t natt = 0x00000000; u_int8_t buf[IKED_MSGBUF_MAX]; ssize_t len; off_t off; struct iovec iov[2]; bzero(&msg, sizeof(msg)); bzero(buf, sizeof(buf)); msg.msg_peerlen = sizeof(msg.msg_peer); msg.msg_locallen = sizeof(msg.msg_local); msg.msg_parent = &msg; memcpy(&msg.msg_local, &sock->sock_addr, sizeof(sock->sock_addr)); if ((len = recvfromto(fd, buf, sizeof(buf), 0, (struct sockaddr *)&msg.msg_peer, &msg.msg_peerlen, (struct sockaddr *)&msg.msg_local, &msg.msg_locallen)) < (ssize_t)sizeof(natt)) return; if (socket_getport(&msg.msg_local) == IKED_NATT_PORT) { if (bcmp(&natt, buf, sizeof(natt)) != 0) return; msg.msg_natt = 1; off = sizeof(natt); } else off = 0; if ((size_t)(len - off) <= sizeof(hdr)) return; memcpy(&hdr, buf + off, sizeof(hdr)); if ((msg.msg_data = ibuf_new(buf + off, len - off)) == NULL) return; if (hdr.ike_version == IKEV1_VERSION) { iov[0].iov_base = &msg; iov[0].iov_len = sizeof(msg); iov[1].iov_base = buf; iov[1].iov_len = len; proc_composev_imsg(env, PROC_IKEV1, IMSG_IKE_MESSAGE, -1, iov, 2); goto done; } TAILQ_INIT(&msg.msg_proposals); msg.msg_fd = fd; ikev2_recv(env, &msg); done: ikev2_msg_cleanup(env, &msg); }
void ikev2_msg_cb(int fd, short event, void *arg) { struct iked_socket *sock = arg; struct iked *env = sock->sock_env; struct iked_message msg; struct ike_header hdr; uint32_t natt = 0x00000000; uint8_t buf[IKED_MSGBUF_MAX]; ssize_t len; off_t off; bzero(&msg, sizeof(msg)); bzero(buf, sizeof(buf)); msg.msg_peerlen = sizeof(msg.msg_peer); msg.msg_locallen = sizeof(msg.msg_local); msg.msg_parent = &msg; memcpy(&msg.msg_local, &sock->sock_addr, sizeof(sock->sock_addr)); if ((len = recvfromto(fd, buf, sizeof(buf), 0, (struct sockaddr *)&msg.msg_peer, &msg.msg_peerlen, (struct sockaddr *)&msg.msg_local, &msg.msg_locallen)) < (ssize_t)sizeof(natt)) return; if (socket_getport((struct sockaddr *)&msg.msg_local) == IKED_NATT_PORT) { if (memcmp(&natt, buf, sizeof(natt)) != 0) return; msg.msg_natt = 1; off = sizeof(natt); } else off = 0; if ((size_t)(len - off) <= sizeof(hdr)) return; memcpy(&hdr, buf + off, sizeof(hdr)); if ((msg.msg_data = ibuf_new(buf + off, len - off)) == NULL) return; TAILQ_INIT(&msg.msg_proposals); msg.msg_fd = fd; if (hdr.ike_version == IKEV1_VERSION) ikev1_recv(env, &msg); else ikev2_recv(env, &msg); ikev2_msg_cleanup(env, &msg); }
static struct rtp_packet * rtpp_socket_rtp_recv(struct rtpp_socket *self, const struct rtpp_timestamp *dtime, struct sockaddr *laddr, int port) { struct rtpp_socket_priv *pvt; struct rtp_packet *packet; struct timeval rtime; size_t llen; packet = rtp_packet_alloc(); if (packet == NULL) { return NULL; } pvt = PUB2PVT(self); packet->rlen = sizeof(packet->raddr); llen = sizeof(packet->_laddr); memset(&rtime, '\0', sizeof(rtime)); packet->size = recvfromto(pvt->fd, packet->data.buf, sizeof(packet->data.buf), sstosa(&packet->raddr), &packet->rlen, sstosa(&packet->_laddr), &llen, &rtime); if (packet->size == -1) { rtp_packet_free(packet); return (NULL); } if (llen > 0) { packet->laddr = sstosa(&packet->_laddr); packet->lport = getport(packet->laddr); } else { packet->laddr = laddr; packet->lport = port; } if (!timevaliszero(&rtime)) { packet->rtime.wall = timeval2dtime(&rtime); } else { packet->rtime.wall = dtime->wall; } RTPP_DBG_ASSERT(packet->rtime.wall > 0); packet->rtime.mono = dtime->mono; return (packet); }
void ikev1_msg_cb(int fd, short event, void *arg) { struct iked_socket *sock = arg; struct iked *env = sock->sock_env; struct iked_message msg; struct ike_header hdr; uint8_t buf[IKED_MSGBUF_MAX]; size_t len; struct iovec iov[2]; msg.msg_peerlen = sizeof(msg.msg_peer); msg.msg_locallen = sizeof(msg.msg_local); if ((len = recvfromto(fd, buf, sizeof(buf), 0, (struct sockaddr*)&msg.msg_peer, &msg.msg_peerlen, (struct sockaddr*)&msg.msg_local, &msg.msg_locallen)) < 1) return; if ((size_t)len <= sizeof(hdr)) return; memcpy(&hdr, buf, sizeof(hdr)); if ((msg.msg_data = ibuf_new(buf, len)) == NULL) return; if (hdr.ike_version == IKEV2_VERSION) { iov[0].iov_base = &msg; iov[0].iov_len = sizeof(msg); iov[1].iov_base = buf; iov[1].iov_len = len; proc_composev_imsg(&env->sc_ps, PROC_IKEV2, -1, IMSG_IKE_MESSAGE, -1, iov, 2); goto done; } ikev1_recv(env, &msg); done: ikev2_msg_cleanup(env, &msg); }
static void read_loop(int fd) { struct sockaddr_in from; struct sockaddr_in to; socklen_t fromlen = sizeof(from); socklen_t tolen = sizeof(to); int ifindex = -1; uint8_t buf[10000]; int rd; char str_from[100]; char str_to[100]; char ifname[100]; for (;;) { rd = recvfromto(fd, buf, sizeof buf, &from, &fromlen, &to, &tolen, &ifindex); if (rd < 0) { fprintf(stderr, "%s: error: errno=%d: %s\n", prog_name, errno, strerror(errno)); continue; } inet_ntop(AF_INET, &from.sin_addr, str_from, sizeof str_from); inet_ntop(AF_INET, &to.sin_addr, str_to, sizeof str_to); index_to_name(ifindex, ifname, sizeof ifname); printf("%s: read %d bytes from %s:%d to %s:%d on %s ifindex=%d\n", prog_name, rd, str_from, ntohs(from.sin_port), str_to, ntohs(to.sin_port), ifname, ifindex); } }
int main(int argc, char **argv) { int ret = EX_OK; int i; struct group *grgid; struct passwd *pwuid; timer_t timerid_mld, timerid_pim; struct pollfd fds[4]; nfds_t nfds = 0; struct sockaddr_storage from, to; socklen_t addrlen = sizeof(struct sockaddr_storage); unsigned int from_ifindex; char *buf; ret = parse_args(argc, argv); if (ret) return -ret; if (getuid()) { fprintf(stderr, "need to run as root\n"); return EX_NOPERM; } if (!nofork) { pid_t pid = fork(); if (pid < 0) { perror("fork()"); return EX_OSERR; } else if (pid > 0) return EX_OK; if (setsid() < 0) { perror("setsid()"); return EX_OSERR; } if (chdir("/") < 0) { perror("chdir(\"/\")"); return EX_OSERR; } openlog(basename(argv[0]), LOG_PID, LOG_DAEMON); } else openlog(basename(argv[0]), LOG_PID | LOG_PERROR, LOG_DAEMON); setlogmask(LOG_UPTO(debug)); logger(LOG_NOTICE, 0, "started"); errno = 0; mroute4 = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP); if (mroute4 >= 0) { if (pktinfo(mroute4) < 0) { close(mroute4); mroute4 = -1; } else { pim4 = pim_init(mroute4); if (pim4 < 0) { close(mroute4); mroute4 = -1; } else { add_poll(fds, &nfds, mroute4); add_poll(fds, &nfds, pim4); } } } if (mroute4 < 0) logger(LOG_WARNING, errno, "no IPv4 support"); errno = 0; mroute6 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); if (mroute6 >= 0) { if (pktinfo(mroute6) < 0) { close(mroute6); mroute6 = -1; } else { pim6 = pim_init(mroute6); if (pim6 < 0) { close(mroute6); mroute6 = -1; } else { add_poll(fds, &nfds, mroute6); add_poll(fds, &nfds, pim6); } } } if (mroute6 < 0) logger(LOG_WARNING, errno, "no IPv6 support"); if (mroute4 < 0 && mroute6 < 0) { logger(LOG_ERR, 0, "multicast routing unavailable"); ret = -EX_OSERR; goto exit; } ret = route_init(); if (ret) goto mroute; errno = 0; grgid = getgrnam(gid); if (grgid) { if (setgid(grgid->gr_gid)) logger(LOG_WARNING, errno, "unable to drop group privileges"); } else logger(LOG_WARNING, errno, "unable to find group '%s' to drop privileges to", gid); errno = 0; pwuid = getpwnam(uid); if (pwuid) { if (setuid(pwuid->pw_uid)) logger(LOG_WARNING, errno, "unable to drop user privileges"); } else logger(LOG_WARNING, errno, "unable to find user '%s' to drop privileges to", uid); ret = signals(&sig_handler); if (ret) goto route; ret = prime_timers(&timerid_mld, &timerid_pim); if (ret) goto signal; buf = malloc(SOCK_BUFLEN); if (buf == NULL) { logger(LOG_ERR, 0, "malloc()"); ret = -EX_OSERR; goto timer; } while (running) { ret = poll(fds, nfds, -1); if (ret == -1) { if (errno == EINTR) continue; logger(LOG_ERR, errno, "poll()"); ret = -EX_OSERR; running = 0; continue; } for (i = 0; i < nfds; i++) { /* TODO handle errors */ assert(!(fds[i].revents & (POLLERR | POLLHUP))); /* either a non-event or there is something to read */ assert(!fds[i].revents || fds[i].revents & POLLIN); if (!fds[i].revents) continue; if (fds[i].revents & POLLIN) { ret = recvfromto(fds[i].fd, buf, SOCK_BUFLEN, 0, (struct sockaddr *)&from, (struct sockaddr *)&to, &addrlen, &from_ifindex); if (ret == -1) continue; if (fds[i].fd == pim4 || fds[i].fd == pim6) pim_recv(fds[i].fd, buf, ret, &from, &to, addrlen, from_ifindex); else mld_recv(fds[i].fd, buf, ret, &from, &to, addrlen, from_ifindex); } } } free(buf); timer: timer_delete(timerid_mld); timer_delete(timerid_pim); signal: signals(SIG_IGN); route: route_shutdown(); mroute: if (mroute4 > 0) { close(pim4); pim_shutdown(mroute4); } if (mroute6 > 0) { close(pim6); pim_shutdown(mroute6); } exit: logger(LOG_NOTICE, 0, "exiting"); closelog(); assert(ret <= 0); return -ret; }
int main(int argc, char **argv) { struct sockaddr_in from, to, in; char buf[TESTLEN]; char *destip = DESTIP; int port = DEF_PORT; int n, server_socket, client_socket, fl, tl, pid; if (argc > 1) destip = argv[1]; if (argc > 2) port = atoi(argv[2]); in.sin_family = AF_INET; #ifdef NEED_SIN_LEN in.sin_len = sizeof( struct sockaddr_in ); #endif in.sin_addr.s_addr = INADDR_ANY; in.sin_port = htons(port); fl = tl = sizeof(struct sockaddr_in); memset(&from, 0, sizeof(from)); memset(&to, 0, sizeof(to)); switch(pid = fork()) { case -1: perror("fork"); return 0; case 0: /* child */ usleep(100000); goto client; } /* parent: server */ server_socket = safe_socket(PF_INET, SOCK_DGRAM, 0); if (udpfromto_init(server_socket) != 0) { perror("udpfromto_init\n"); waitpid(pid, NULL, WNOHANG); return 0; } if (bind(server_socket, (struct sockaddr *)&in, sizeof(in)) < 0) { perror("server: bind"); waitpid(pid, NULL, WNOHANG); return 0; } printf("server: waiting for packets on INADDR_ANY:%d\n", port); if ((n = recvfromto(server_socket, buf, sizeof(buf), 0, (struct sockaddr *)&from, &fl, (struct sockaddr *)&to, &tl)) < 0) { perror("server: recvfromto"); waitpid(pid, NULL, WNOHANG); return 0; } printf("server: received a packet of %d bytes [%s] ", n, buf); printf("(src ip:port %s:%d ", inet_ntoa(from.sin_addr), ntohs(from.sin_port)); printf(" dst ip:port %s:%d)\n", inet_ntoa(to.sin_addr), ntohs(to.sin_port)); printf("server: replying from address packet was received on to source address\n"); if ((n = sendfromto(server_socket, buf, n, 0, (struct sockaddr *)&to, tl, (struct sockaddr *)&from, fl)) < 0) { perror("server: sendfromto"); } waitpid(pid, NULL, 0); return 0; client: close(server_socket); client_socket = safe_socket(PF_INET, SOCK_DGRAM, 0); if (udpfromto_init(client_socket) != 0) { perror("udpfromto_init"); _exit(0); } /* bind client on different port */ in.sin_port = htons(port+1); if (bind(client_socket, (struct sockaddr *)&in, sizeof(in)) < 0) { perror("client: bind"); _exit(0); } in.sin_port = htons(port); in.sin_addr.s_addr = inet_addr(destip); printf("client: sending packet to %s:%d\n", destip, port); if (sendto(client_socket, TESTSTRING, TESTLEN, 0, (struct sockaddr *)&in, sizeof(in)) < 0) { perror("client: sendto"); _exit(0); } printf("client: waiting for reply from server on INADDR_ANY:%d\n", port+1); if ((n = recvfromto(client_socket, buf, sizeof(buf), 0, (struct sockaddr *)&from, &fl, (struct sockaddr *)&to, &tl)) < 0) { perror("client: recvfromto"); _exit(0); } printf("client: received a packet of %d bytes [%s] ", n, buf); printf("(src ip:port %s:%d", inet_ntoa(from.sin_addr), ntohs(from.sin_port)); printf(" dst ip:port %s:%d)\n", inet_ntoa(to.sin_addr), ntohs(to.sin_port)); _exit(0); }
/* * Wrapper for recvfrom, which handles recvfromto, IPv6, and all * possible combinations. * * FIXME: This is copied from rad_recvfrom, with minor edits. */ static ssize_t vqp_recvfrom(int sockfd, uint8_t **pbuf, int flags, fr_ipaddr_t *src_ipaddr, uint16_t *src_port, fr_ipaddr_t *dst_ipaddr, uint16_t *dst_port) { struct sockaddr_storage src; struct sockaddr_storage dst; socklen_t sizeof_src = sizeof(src); socklen_t sizeof_dst = sizeof(dst); ssize_t data_len; uint8_t header[4]; void *buf; size_t len; int port; memset(&src, 0, sizeof_src); memset(&dst, 0, sizeof_dst); /* * Get address family, etc. first, so we know if we * need to do udpfromto. * * FIXME: udpfromto also does this, but it's not * a critical problem. */ if (getsockname(sockfd, (struct sockaddr *)&dst, &sizeof_dst) < 0) return -1; /* * Read the length of the packet, from the packet. * This lets us allocate the buffer to use for * reading the rest of the packet. */ data_len = recvfrom(sockfd, header, sizeof(header), MSG_PEEK, (struct sockaddr *)&src, &sizeof_src); if (data_len < 0) return -1; /* * Too little data is available, discard the packet. */ if (data_len < 4) { recvfrom(sockfd, header, sizeof(header), flags, (struct sockaddr *)&src, &sizeof_src); return 0; /* * Invalid version, packet type, or too many * attributes. Die. */ } else if ((header[0] != VQP_VERSION) || (header[1] < 1) || (header[1] > 4) || (header[3] > VQP_MAX_ATTRIBUTES)) { recvfrom(sockfd, header, sizeof(header), flags, (struct sockaddr *)&src, &sizeof_src); return 0; } else { /* we got 4 bytes of data. */ /* * We don't care about the contents for now... */ #if 0 /* * How many attributes are in the packet. */ len = header[3]; if ((header[1] == 1) || (header[1] == 3)) { if (len != VQP_MAX_ATTRIBUTES) { recvfrom(sockfd, header, sizeof(header), 0, (struct sockaddr *)&src, &sizeof_src); return 0; } /* * Maximum length we support. */ len = (12 * (4 + 4 + MAX_VMPS_LEN)); } else { if (len != 2) { recvfrom(sockfd, header, sizeof(header), 0, (struct sockaddr *)&src, &sizeof_src); return 0; } /* * Maximum length we support. */ len = (12 * (4 + 4 + MAX_VMPS_LEN)); } #endif } /* * For now, be generous. */ len = (12 * (4 + 4 + MAX_VMPS_LEN)); buf = malloc(len); if (!buf) return -1; /* * Receive the packet. The OS will discard any data in the * packet after "len" bytes. */ #ifdef WITH_UDPFROMTO if (dst.ss_family == AF_INET) { data_len = recvfromto(sockfd, buf, len, flags, (struct sockaddr *)&src, &sizeof_src, (struct sockaddr *)&dst, &sizeof_dst); } else #endif /* * No udpfromto, OR an IPv6 socket. Fail gracefully. */ data_len = recvfrom(sockfd, buf, len, flags, (struct sockaddr *)&src, &sizeof_src); if (data_len < 0) { free(buf); return data_len; } if (!fr_sockaddr2ipaddr(&src, sizeof_src, src_ipaddr, &port)) { free(buf); return -1; /* Unknown address family, Die Die Die! */ } *src_port = port; fr_sockaddr2ipaddr(&dst, sizeof_dst, dst_ipaddr, &port); *dst_port = port; /* * Different address families should never happen. */ if (src.ss_family != dst.ss_family) { free(buf); return -1; } /* * Tell the caller about the data */ *pbuf = buf; return data_len; }