int mpls_socket_udp_recvfrom(mpls_socket_mgr_handle handle, mpls_socket_handle socket, uint8_t * buffer, int size, mpls_dest * from) { int ret; unsigned int ifindex = 0; struct iovec iov; struct cmsghdr *cmsg; struct in_pktinfo *pktinfo; struct sockaddr addr; char buff [sizeof (*cmsg) + sizeof (*pktinfo)]; struct msghdr msgh = {&addr, sizeof(struct sockaddr), &iov, 1, buff, sizeof (*cmsg) + sizeof (*pktinfo), 0}; iov.iov_base = buffer; iov.iov_len = size; ret = recvmsg(socket->fd,&msgh,0); if (ret < 0 && errno != EAGAIN) { return 0; } cmsg = CMSG_FIRSTHDR(&msgh); if (cmsg != NULL && cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg); ifindex = pktinfo->ipi_ifindex; from->if_handle = if_lookup_by_index(ifindex); _sockaddr2mpls_dest((const struct sockaddr*)&addr, from); } return ret; }
mpls_socket_handle mpls_socket_tcp_accept(mpls_socket_mgr_handle handle, mpls_socket_handle socket, mpls_dest * from) { struct mpls_socket *sock = mpls_malloc(sizeof(struct mpls_socket)); struct sockaddr addr; int size = sizeof(addr); if ((sock->fd = accept(socket->fd,&addr,&size)) < 0) { return NULL; } _sockaddr2mpls_dest(&addr, from); return sock; }
int mpls_socket_udp_recvfrom(mpls_socket_mgr_handle handle, mpls_socket_handle socket, uint8_t *buffer, int size, mpls_dest *from) { int ret; struct sockaddr addr; struct iovec iov; struct cmsghdr *cmsg; struct sockaddr_dl *sdl; char buf[sizeof(struct cmsghdr) + sizeof(struct sockaddr_dl)]; struct msghdr msg = { .msg_name = &addr, .msg_namelen = sizeof(struct sockaddr), .msg_iov = &iov, .msg_iovlen = 1, .msg_control = buf, .msg_controllen = sizeof(buf), .msg_flags = 0 }; iov.iov_base = buffer; iov.iov_len = size; ret = recvmsg(socket->fd, &msg, 0); if(ret < 0 && errno != EAGAIN) return 0; _sockaddr2mpls_dest(&addr, from); // struct in_addr *i = (struct in_addr *)getsockopt_cmsg_data(&msg, IPPROTO_IP, IP_RECVDSTADDR); // sdl = (struct sockaddr_dl *)getsockopt_cmsg_data(&msg, IPPROTO_IP, IP_RECVIF); // from->if_handle = sdl ? Interface_FindByIndex(sdl->sdl_index) : NULL; from->if_handle = NULL; cmsg = CMSG_FIRSTHDR(&msg); if(cmsg && cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVIF) { sdl = (struct sockaddr_dl *)CMSG_DATA(cmsg); from->if_handle = (sdl) ? Interface_FindByIndex(sdl->sdl_index) : NULL; } return ret; } mpls_return_enum mpls_socket_get_local_name(mpls_socket_mgr_handle handle, mpls_socket_handle socket, mpls_dest *name) { struct sockaddr addr; unsigned int size; size = sizeof(addr); if(getsockname(socket->fd, &addr, &size) == -1) return MPLS_FAILURE; _sockaddr2mpls_dest(&addr, name); return MPLS_SUCCESS; } mpls_return_enum mpls_socket_get_remote_name(mpls_socket_mgr_handle handle, mpls_socket_handle socket, mpls_dest *name) { struct sockaddr addr; unsigned int size; size = sizeof(addr); if(getpeername(socket->fd, &addr, &size) == -1) return MPLS_FAILURE; _sockaddr2mpls_dest(&addr, name); return MPLS_SUCCESS; }