/** * Transmit an ethernet packet. * * The packet can be written to the socket and marked as complete immediately. */ static int af_packet_nic_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { struct af_packet_nic * nic = netdev->priv; struct sockaddr_ll socket_address; const struct ethhdr * eh; int rc; memset(&socket_address, 0, sizeof(socket_address)); socket_address.sll_family = LINUX_AF_PACKET; socket_address.sll_ifindex = nic->ifindex; socket_address.sll_halen = ETH_ALEN; eh = iobuf->data; memcpy(socket_address.sll_addr, eh->h_dest, ETH_ALEN); rc = linux_sendto(nic->fd, iobuf->data, iobuf->tail - iobuf->data, 0, (struct sockaddr *)&socket_address, sizeof(socket_address)); DBGC2(nic, "af_packet %p wrote %d bytes\n", nic, rc); netdev_tx_complete(netdev, iobuf); 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; } }