Creation of Cybook 2416 (actually Gen4) repository

This commit is contained in:
mlt
2009-12-18 17:10:00 +00:00
committed by godzil
commit 76f20f4d40
13791 changed files with 6812321 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
#
# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
# Licensed under the GPL
#
ethertap-objs := ethertap_kern.o ethertap_user.o
tuntap-objs := tuntap_kern.o tuntap_user.o
obj-y =
obj-$(CONFIG_UML_NET_ETHERTAP) += ethertap.o
obj-$(CONFIG_UML_NET_TUNTAP) += tuntap.o
include arch/um/scripts/Makefile.rules

View File

@@ -0,0 +1,27 @@
/*
* Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#include "net_user.h"
struct ethertap_data {
char *dev_name;
char *gate_addr;
int data_fd;
int control_fd;
void *dev;
};
extern const struct net_user_info ethertap_user_info;
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/

View File

@@ -0,0 +1,108 @@
/*
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
* James Leu (jleu@mindspring.net).
* Copyright (C) 2001 by various other people who didn't put their name here.
* Licensed under the GPL.
*/
#include "linux/init.h"
#include "linux/netdevice.h"
#include "linux/etherdevice.h"
#include "net_kern.h"
#include "net_user.h"
#include "etap.h"
struct ethertap_init {
char *dev_name;
char *gate_addr;
};
static void etap_init(struct net_device *dev, void *data)
{
struct uml_net_private *pri;
struct ethertap_data *epri;
struct ethertap_init *init = data;
pri = dev->priv;
epri = (struct ethertap_data *) pri->user;
epri->dev_name = init->dev_name;
epri->gate_addr = init->gate_addr;
epri->data_fd = -1;
epri->control_fd = -1;
epri->dev = dev;
printk("ethertap backend - %s", epri->dev_name);
if (epri->gate_addr != NULL)
printk(", IP = %s", epri->gate_addr);
printk("\n");
}
static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
{
int len;
*skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP);
if(*skb == NULL) return(-ENOMEM);
len = net_recvfrom(fd, (*skb)->mac.raw,
(*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
if(len <= 0) return(len);
skb_pull(*skb, 2);
len -= 2;
return(len);
}
static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
{
if(skb_headroom(*skb) < 2){
struct sk_buff *skb2;
skb2 = skb_realloc_headroom(*skb, 2);
dev_kfree_skb(*skb);
if (skb2 == NULL) return(-ENOMEM);
*skb = skb2;
}
skb_push(*skb, 2);
return(net_send(fd, (*skb)->data, (*skb)->len));
}
const struct net_kern_info ethertap_kern_info = {
.init = etap_init,
.protocol = eth_protocol,
.read = etap_read,
.write = etap_write,
};
int ethertap_setup(char *str, char **mac_out, void *data)
{
struct ethertap_init *init = data;
*init = ((struct ethertap_init)
{ .dev_name = NULL,
.gate_addr = NULL });
if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
&init->gate_addr))
return(0);
if(init->dev_name == NULL){
printk("ethertap_setup : Missing tap device name\n");
return(0);
}
return(1);
}
static struct transport ethertap_transport = {
.list = LIST_HEAD_INIT(ethertap_transport.list),
.name = "ethertap",
.setup = ethertap_setup,
.user = &ethertap_user_info,
.kern = &ethertap_kern_info,
.private_size = sizeof(struct ethertap_data),
};
static int register_ethertap(void)
{
register_transport(&ethertap_transport);
return 0;
}
late_initcall(register_ethertap);

View File

@@ -0,0 +1,240 @@
/*
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
* James Leu (jleu@mindspring.net).
* Copyright (C) 2001 by various other people who didn't put their name here.
* Licensed under the GPL.
*/
#include <stdio.h>
#include <unistd.h>
#include <stddef.h>
#include <stdlib.h>
#include <sys/errno.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/un.h>
#include <net/if.h>
#include "user.h"
#include "kern_util.h"
#include "user_util.h"
#include "net_user.h"
#include "etap.h"
#include "os.h"
#include "um_malloc.h"
#define MAX_PACKET ETH_MAX_PACKET
void etap_user_init(void *data, void *dev)
{
struct ethertap_data *pri = data;
pri->dev = dev;
}
struct addr_change {
enum { ADD_ADDR, DEL_ADDR } what;
unsigned char addr[4];
unsigned char netmask[4];
};
static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
int fd)
{
struct addr_change change;
char *output;
int n;
change.what = op;
memcpy(change.addr, addr, sizeof(change.addr));
memcpy(change.netmask, netmask, sizeof(change.netmask));
n = os_write_file(fd, &change, sizeof(change));
if(n != sizeof(change))
printk("etap_change - request failed, err = %d\n", -n);
output = um_kmalloc(page_size());
if(output == NULL)
printk("etap_change : Failed to allocate output buffer\n");
read_output(fd, output, page_size());
if(output != NULL){
printk("%s", output);
kfree(output);
}
}
static void etap_open_addr(unsigned char *addr, unsigned char *netmask,
void *arg)
{
etap_change(ADD_ADDR, addr, netmask, *((int *) arg));
}
static void etap_close_addr(unsigned char *addr, unsigned char *netmask,
void *arg)
{
etap_change(DEL_ADDR, addr, netmask, *((int *) arg));
}
struct etap_pre_exec_data {
int control_remote;
int control_me;
int data_me;
};
static void etap_pre_exec(void *arg)
{
struct etap_pre_exec_data *data = arg;
dup2(data->control_remote, 1);
os_close_file(data->data_me);
os_close_file(data->control_me);
}
static int etap_tramp(char *dev, char *gate, int control_me,
int control_remote, int data_me, int data_remote)
{
struct etap_pre_exec_data pe_data;
int pid, status, err, n;
char version_buf[sizeof("nnnnn\0")];
char data_fd_buf[sizeof("nnnnnn\0")];
char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
char *setup_args[] = { "uml_net", version_buf, "ethertap", dev,
data_fd_buf, gate_buf, NULL };
char *nosetup_args[] = { "uml_net", version_buf, "ethertap",
dev, data_fd_buf, NULL };
char **args, c;
sprintf(data_fd_buf, "%d", data_remote);
sprintf(version_buf, "%d", UML_NET_VERSION);
if(gate != NULL){
strcpy(gate_buf, gate);
args = setup_args;
}
else args = nosetup_args;
err = 0;
pe_data.control_remote = control_remote;
pe_data.control_me = control_me;
pe_data.data_me = data_me;
pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
if(pid < 0) err = pid;
os_close_file(data_remote);
os_close_file(control_remote);
n = os_read_file(control_me, &c, sizeof(c));
if(n != sizeof(c)){
printk("etap_tramp : read of status failed, err = %d\n", -n);
return(-EINVAL);
}
if(c != 1){
printk("etap_tramp : uml_net failed\n");
err = -EINVAL;
CATCH_EINTR(n = waitpid(pid, &status, 0));
if(n < 0)
err = -errno;
else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
printk("uml_net didn't exit with status 1\n");
}
return(err);
}
static int etap_open(void *data)
{
struct ethertap_data *pri = data;
char *output;
int data_fds[2], control_fds[2], err, output_len;
err = tap_open_common(pri->dev, pri->gate_addr);
if(err) return(err);
err = os_pipe(data_fds, 0, 0);
if(err < 0){
printk("data os_pipe failed - err = %d\n", -err);
return(err);
}
err = os_pipe(control_fds, 1, 0);
if(err < 0){
printk("control os_pipe failed - err = %d\n", -err);
return(err);
}
err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
control_fds[1], data_fds[0], data_fds[1]);
output_len = page_size();
output = um_kmalloc(output_len);
read_output(control_fds[0], output, output_len);
if(output == NULL)
printk("etap_open : failed to allocate output buffer\n");
else {
printk("%s", output);
kfree(output);
}
if(err < 0){
printk("etap_tramp failed - err = %d\n", -err);
return(err);
}
pri->data_fd = data_fds[0];
pri->control_fd = control_fds[0];
iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
return(data_fds[0]);
}
static void etap_close(int fd, void *data)
{
struct ethertap_data *pri = data;
iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
os_close_file(fd);
os_shutdown_socket(pri->data_fd, 1, 1);
os_close_file(pri->data_fd);
pri->data_fd = -1;
os_close_file(pri->control_fd);
pri->control_fd = -1;
}
static int etap_set_mtu(int mtu, void *data)
{
return(mtu);
}
static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
void *data)
{
struct ethertap_data *pri = data;
tap_check_ips(pri->gate_addr, addr);
if(pri->control_fd == -1) return;
etap_open_addr(addr, netmask, &pri->control_fd);
}
static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
void *data)
{
struct ethertap_data *pri = data;
if(pri->control_fd == -1) return;
etap_close_addr(addr, netmask, &pri->control_fd);
}
const struct net_user_info ethertap_user_info = {
.init = etap_user_init,
.open = etap_open,
.close = etap_close,
.remove = NULL,
.set_mtu = etap_set_mtu,
.add_address = etap_add_addr,
.delete_address = etap_del_addr,
.max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP
};
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#ifndef __UM_TUNTAP_H
#define __UM_TUNTAP_H
#include "net_user.h"
struct tuntap_data {
char *dev_name;
int fixed_config;
char *gate_addr;
int fd;
void *dev;
};
extern const struct net_user_info tuntap_user_info;
#endif
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/

View File

@@ -0,0 +1,93 @@
/*
* Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#include "linux/stddef.h"
#include "linux/netdevice.h"
#include "linux/etherdevice.h"
#include "linux/skbuff.h"
#include "linux/init.h"
#include "asm/errno.h"
#include "net_kern.h"
#include "net_user.h"
#include "tuntap.h"
struct tuntap_init {
char *dev_name;
char *gate_addr;
};
static void tuntap_init(struct net_device *dev, void *data)
{
struct uml_net_private *pri;
struct tuntap_data *tpri;
struct tuntap_init *init = data;
pri = dev->priv;
tpri = (struct tuntap_data *) pri->user;
tpri->dev_name = init->dev_name;
tpri->fixed_config = (init->dev_name != NULL);
tpri->gate_addr = init->gate_addr;
tpri->fd = -1;
tpri->dev = dev;
printk("TUN/TAP backend - ");
if (tpri->gate_addr != NULL)
printk("IP = %s", tpri->gate_addr);
printk("\n");
}
static int tuntap_read(int fd, struct sk_buff **skb,
struct uml_net_private *lp)
{
*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
if(*skb == NULL) return(-ENOMEM);
return(net_read(fd, (*skb)->mac.raw,
(*skb)->dev->mtu + ETH_HEADER_OTHER));
}
static int tuntap_write(int fd, struct sk_buff **skb,
struct uml_net_private *lp)
{
return(net_write(fd, (*skb)->data, (*skb)->len));
}
const struct net_kern_info tuntap_kern_info = {
.init = tuntap_init,
.protocol = eth_protocol,
.read = tuntap_read,
.write = tuntap_write,
};
int tuntap_setup(char *str, char **mac_out, void *data)
{
struct tuntap_init *init = data;
*init = ((struct tuntap_init)
{ .dev_name = NULL,
.gate_addr = NULL });
if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out,
&init->gate_addr))
return(0);
return(1);
}
static struct transport tuntap_transport = {
.list = LIST_HEAD_INIT(tuntap_transport.list),
.name = "tuntap",
.setup = tuntap_setup,
.user = &tuntap_user_info,
.kern = &tuntap_kern_info,
.private_size = sizeof(struct tuntap_data),
.setup_size = sizeof(struct tuntap_init),
};
static int register_tuntap(void)
{
register_transport(&tuntap_transport);
return 0;
}
late_initcall(register_tuntap);

View File

@@ -0,0 +1,228 @@
/*
* Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/uio.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/if_tun.h>
#include "net_user.h"
#include "tuntap.h"
#include "kern_util.h"
#include "user_util.h"
#include "user.h"
#include "os.h"
#define MAX_PACKET ETH_MAX_PACKET
void tuntap_user_init(void *data, void *dev)
{
struct tuntap_data *pri = data;
pri->dev = dev;
}
static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
void *data)
{
struct tuntap_data *pri = data;
tap_check_ips(pri->gate_addr, addr);
if((pri->fd == -1) || pri->fixed_config) return;
open_addr(addr, netmask, pri->dev_name);
}
static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
void *data)
{
struct tuntap_data *pri = data;
if((pri->fd == -1) || pri->fixed_config) return;
close_addr(addr, netmask, pri->dev_name);
}
struct tuntap_pre_exec_data {
int stdout;
int close_me;
};
static void tuntap_pre_exec(void *arg)
{
struct tuntap_pre_exec_data *data = arg;
dup2(data->stdout, 1);
os_close_file(data->close_me);
}
static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
char *buffer, int buffer_len, int *used_out)
{
struct tuntap_pre_exec_data data;
char version_buf[sizeof("nnnnn\0")];
char *argv[] = { "uml_net", version_buf, "tuntap", "up", gate,
NULL };
char buf[CMSG_SPACE(sizeof(*fd_out))];
struct msghdr msg;
struct cmsghdr *cmsg;
struct iovec iov;
int pid, n, err;
sprintf(version_buf, "%d", UML_NET_VERSION);
data.stdout = remote;
data.close_me = me;
pid = run_helper(tuntap_pre_exec, &data, argv, NULL);
if(pid < 0) return(-pid);
os_close_file(remote);
msg.msg_name = NULL;
msg.msg_namelen = 0;
if(buffer != NULL){
iov = ((struct iovec) { buffer, buffer_len });
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
}
else {
msg.msg_iov = NULL;
msg.msg_iovlen = 0;
}
msg.msg_control = buf;
msg.msg_controllen = sizeof(buf);
msg.msg_flags = 0;
n = recvmsg(me, &msg, 0);
*used_out = n;
if(n < 0){
err = -errno;
printk("tuntap_open_tramp : recvmsg failed - errno = %d\n",
errno);
return err;
}
CATCH_EINTR(waitpid(pid, NULL, 0));
cmsg = CMSG_FIRSTHDR(&msg);
if(cmsg == NULL){
printk("tuntap_open_tramp : didn't receive a message\n");
return(-EINVAL);
}
if((cmsg->cmsg_level != SOL_SOCKET) ||
(cmsg->cmsg_type != SCM_RIGHTS)){
printk("tuntap_open_tramp : didn't receive a descriptor\n");
return(-EINVAL);
}
*fd_out = ((int *) CMSG_DATA(cmsg))[0];
os_set_exec_close(*fd_out, 1);
return(0);
}
static int tuntap_open(void *data)
{
struct ifreq ifr;
struct tuntap_data *pri = data;
char *output, *buffer;
int err, fds[2], len, used;
err = tap_open_common(pri->dev, pri->gate_addr);
if(err < 0)
return(err);
if(pri->fixed_config){
pri->fd = os_open_file("/dev/net/tun",
of_cloexec(of_rdwr(OPENFLAGS())), 0);
if(pri->fd < 0){
printk("Failed to open /dev/net/tun, err = %d\n",
-pri->fd);
return(pri->fd);
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
err = -errno;
printk("TUNSETIFF failed, errno = %d\n", errno);
os_close_file(pri->fd);
return err;
}
}
else {
err = os_pipe(fds, 0, 0);
if(err < 0){
printk("tuntap_open : os_pipe failed - err = %d\n",
-err);
return(err);
}
buffer = get_output_buffer(&len);
if(buffer != NULL) len--;
used = 0;
err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0],
fds[1], buffer, len, &used);
output = buffer;
if(err < 0) {
printk("%s", output);
free_output_buffer(buffer);
printk("tuntap_open_tramp failed - err = %d\n", -err);
return(err);
}
pri->dev_name = uml_strdup(buffer);
output += IFNAMSIZ;
printk("%s", output);
free_output_buffer(buffer);
os_close_file(fds[0]);
iter_addresses(pri->dev, open_addr, pri->dev_name);
}
return(pri->fd);
}
static void tuntap_close(int fd, void *data)
{
struct tuntap_data *pri = data;
if(!pri->fixed_config)
iter_addresses(pri->dev, close_addr, pri->dev_name);
os_close_file(fd);
pri->fd = -1;
}
static int tuntap_set_mtu(int mtu, void *data)
{
return(mtu);
}
const struct net_user_info tuntap_user_info = {
.init = tuntap_user_init,
.open = tuntap_open,
.close = tuntap_close,
.remove = NULL,
.set_mtu = tuntap_set_mtu,
.add_address = tuntap_add_addr,
.delete_address = tuntap_del_addr,
.max_packet = MAX_PACKET
};
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/