/** Open the linux interface */ static int af_packet_nic_open ( struct net_device * netdev ) { struct af_packet_nic * nic = netdev->priv; struct sockaddr_ll socket_address; struct ifreq if_data; int ret; nic->fd = linux_socket(LINUX_AF_PACKET, LINUX_SOCK_RAW, htons(ETH_P_ALL)); if (nic->fd < 0) { DBGC(nic, "af_packet %p socket(AF_PACKET) = %d (%s)\n", nic, nic->fd, linux_strerror(linux_errno)); return nic->fd; } /* resolve ifindex of ifname */ memset(&if_data, 0, sizeof(if_data)); strncpy(if_data.ifr_name, nic->ifname, sizeof(if_data.ifr_name)); ret = linux_ioctl(nic->fd, LINUX_SIOCGIFINDEX, &if_data); if (ret < 0) { DBGC(nic, "af_packet %p ioctl(SIOCGIFINDEX) = %d (%s)\n", nic, ret, linux_strerror(linux_errno)); linux_close(nic->fd); return ret; } nic->ifindex = if_data.ifr_ifindex; /* bind to interface */ memset(&socket_address, 0, sizeof(socket_address)); socket_address.sll_family = LINUX_AF_PACKET; socket_address.sll_ifindex = nic->ifindex; socket_address.sll_protocol = htons(ETH_P_ALL); ret = linux_bind(nic->fd, (void *) &socket_address, sizeof(socket_address)); if (ret == -1) { DBGC(nic, "af_packet %p bind() = %d (%s)\n", nic, ret, linux_strerror(linux_errno)); linux_close(nic->fd); return ret; } /* Set nonblocking mode to make af_packet_nic_poll() easier */ ret = linux_fcntl(nic->fd, F_SETFL, O_NONBLOCK); if (ret != 0) { DBGC(nic, "af_packet %p fcntl(%d, ...) = %d (%s)\n", nic, nic->fd, ret, linux_strerror(linux_errno)); linux_close(nic->fd); return ret; } return 0; }
int linux_socketcall(struct proc *p, struct linux_socketcall_args *args,int *retval) { switch (args->what) { case LINUX_SOCKET: return linux_socket(p, args->args, retval); case LINUX_BIND: return linux_bind(p, args->args, retval); case LINUX_CONNECT: return linux_connect(p, args->args, retval); case LINUX_LISTEN: return linux_listen(p, args->args, retval); case LINUX_ACCEPT: return linux_accept(p, args->args, retval); case LINUX_GETSOCKNAME: return linux_getsockname(p, args->args, retval); case LINUX_GETPEERNAME: return linux_getpeername(p, args->args, retval); case LINUX_SOCKETPAIR: return linux_socketpair(p, args->args, retval); case LINUX_SEND: return linux_send(p, args->args, retval); case LINUX_RECV: return linux_recv(p, args->args, retval); case LINUX_SENDTO: return linux_sendto(p, args->args, retval); case LINUX_RECVFROM: return linux_recvfrom(p, args->args, retval); case LINUX_SHUTDOWN: return linux_shutdown(p, args->args, retval); case LINUX_SETSOCKOPT: return linux_setsockopt(p, args->args, retval); case LINUX_GETSOCKOPT: return linux_getsockopt(p, args->args, retval); default: uprintf("LINUX: 'socket' typ=%d not implemented\n", args->what); return ENOSYS; } }