static int af_packet_update_properties ( struct net_device *netdev ) { struct af_packet_nic *nic = netdev->priv; struct ifreq if_data; int ret; /* retrieve default MAC address */ int fd = linux_socket(LINUX_AF_PACKET, LINUX_SOCK_RAW, 0); if (fd < 0) { DBGC(nic, "af_packet %p cannot create raw socket (%s)\n", nic, linux_strerror(linux_errno)); return fd; } /* retrieve host's MAC address */ memset(&if_data, 0, sizeof(if_data)); strncpy(if_data.ifr_name, nic->ifname, sizeof(if_data.ifr_name)); ret = linux_ioctl(fd, LINUX_SIOCGIFHWADDR, &if_data); if (ret < 0) { DBGC(nic, "af_packet %p cannot get mac addr (%s)\n", nic, linux_strerror(linux_errno)); linux_close(fd); return ret; } linux_close(fd); /* struct sockaddr = { u16 family, u8 pad[14] (equiv. sa_data) }; */ memcpy(netdev->ll_addr, if_data.ifr_hwaddr.pad, ETH_ALEN); return 0; }
/** 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; }
static int linux_tcsetattr(int fd, int optional_actions, const struct termios *termios_p) { unsigned long int cmd; switch (optional_actions) { case TCSANOW: cmd = TCSETS; break; case TCSADRAIN: cmd = TCSETSW; break; case TCSAFLUSH: cmd = TCSETSF; break; default: linux_errno = EINVAL; return -1; } return linux_ioctl(fd, cmd, termios_p); }
static int linux_tcgetattr(int fd, struct termios *termios_p) { return linux_ioctl(fd, TCGETS, termios_p); }