summaryrefslogtreecommitdiff
path: root/pfinet.old/tunnel.c~
diff options
context:
space:
mode:
authorZheng Da <zhengda1936@gmail.com>2010-05-04 16:08:14 +0200
committerZheng Da <zhengda1936@gmail.com>2010-05-04 16:08:14 +0200
commita03e2da13bfbed30eedd589977595a5f3398a478 (patch)
treee17d290e2ded14b5abbd51cdf8ddc8430e365fd8 /pfinet.old/tunnel.c~
parent045fb6a578e0e4d97f0e581bbf514654686a86c1 (diff)
remove all temporary files created by vim.
Diffstat (limited to 'pfinet.old/tunnel.c~')
-rw-r--r--pfinet.old/tunnel.c~636
1 files changed, 0 insertions, 636 deletions
diff --git a/pfinet.old/tunnel.c~ b/pfinet.old/tunnel.c~
deleted file mode 100644
index c4f95804..00000000
--- a/pfinet.old/tunnel.c~
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- Copyright (C) 1995,96,98,99,2000,02 Free Software Foundation, Inc.
- Written by Michael I. Bushnell, p/BSG.
-
- This file is part of the GNU Hurd.
-
- The GNU Hurd is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- The GNU Hurd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-
-#include "pfinet.h"
-
-#include <hurd.h>
-#include <cthreads.h>
-#include <fcntl.h>
-#include <device/device.h>
-#include <device/net_status.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <error.h>
-#include <errno.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/if_arp.h>
-#include <linux/ppp_defs.h>
-#include <linux/if_ppp.h>
-
-struct port_class *tunnel_cntlclass;
-struct port_class *tunnel_class;
-
-struct tunnel_device
-{
- struct tunnel_device *next;
- struct trivfs_control *cntl;
- char *devname;
- file_t underlying;
- struct iouser *user;
- struct sk_buff_head xq; /* Transmit queue. */
- struct condition wait; /* For read and select. */
- struct condition select_alert; /* For read and select. */
- struct mutex lock; /* For read and select. */
- int read_blocked; /* For read and select. */
- struct device dev;
- struct net_device_stats stats;
-};
-
-
-/* Linked list of all tunnel devices. */
-struct tunnel_device *tunnel_dev;
-
-
-struct net_device_stats *
-tunnel_get_stats (struct device *dev)
-{
- struct tunnel_device *tdev = (struct tunnel_device *) dev->priv;
-
- assert (tdev);
-
- return &tdev->stats;
-}
-
-int
-tunnel_stop (struct device *dev)
-{
- struct tunnel_device *tdev = (struct tunnel_device *) dev->priv;
- struct sk_buff *skb;
-
- assert (tdev);
-
- while ((skb = skb_dequeue (&tdev->xq)) != 0)
- dev_kfree_skb(skb);
-
- /* Call those only if removing the device completely. */
- /* free (tdev->devname); */
- /* XXX??? mach_port_deallocate (mach_task_self, tdev->underlying) */
- return 0;
-}
-
-void
-tunnel_set_multi (struct device *dev)
-{
-}
-
-void
-tunnel_initialize (void)
-{
-}
-
-int
-tunnel_open (struct device *dev)
-{
- struct tunnel_device *tdev = (struct tunnel_device *) dev->priv;
-
- assert (tdev);
-
- skb_queue_head_init(&tdev->xq);
-
- return 0;
-}
-
-/* Transmit an ethernet frame */
-int
-tunnel_xmit (struct sk_buff *skb, struct device *dev)
-{
- struct tunnel_device *tdev = (struct tunnel_device *) dev->priv;
-
- assert (tdev);
-
- __mutex_lock (&tdev->lock);
-
- /* Avoid unlimited growth. */
- if (skb_queue_len(&tdev->xq) > 128)
- {
- struct sk_buff *skb;
-
- skb = skb_dequeue(&tdev->xq);
- dev_kfree_skb(skb);
- }
-
- /* Queue it for processing. */
- skb_queue_tail(&tdev->xq, skb);
-
- if (tdev->read_blocked)
- {
- tdev->read_blocked = 0;
- condition_broadcast (&tdev->wait);
- }
-
- __mutex_unlock (&tdev->lock);
-
- return 0;
-}
-
-void
-setup_tunnel_device (char *name, struct device **device)
-{
- error_t err;
- struct tunnel_device *tdev;
- struct device *dev;
-
- /* Do global initialization before setting up first tunnel device. */
- if (!tunnel_dev)
- {
- trivfs_add_control_port_class (&tunnel_cntlclass);
- trivfs_add_protid_port_class (&tunnel_class);
- }
-
- tdev = calloc (1, sizeof (struct tunnel_device));
- if (!tdev)
- error (2, ENOMEM, "%s", name);
- tdev->next = tunnel_dev;
- tunnel_dev = tdev;
-
- *device = dev = &tdev->dev;
-
- dev->name = strdup (name);
-
- dev->priv = tdev;
- dev->get_stats = tunnel_get_stats;
-
- /* Functions. These ones are the true "hardware layer" in Linux. */
- dev->open = tunnel_open;
- dev->stop = tunnel_stop;
- dev->hard_start_xmit = tunnel_xmit;
- dev->set_multicast_list = tunnel_set_multi;
-
- /* These are the ones set by drivers/net/ppp_generic.c::ppp_net_init. */
- dev->hard_header = 0;
- dev->hard_header_len = 0;
- dev->mtu = PPP_MTU;
- dev->addr_len = 0;
- dev->tx_queue_len = 3;
- dev->type = ARPHRD_PPP;
- dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
-
- dev_init_buffers (dev);
-
- /* Setting up the translator at /dev/tunX. */
- asprintf (&tdev->devname, "/dev/%s", tdev->dev.name);
- tdev->underlying = file_name_lookup (tdev->devname, O_CREAT|O_NOTRANS, 0664);
-
- if (tdev->underlying == MACH_PORT_NULL)
- error (2, /* XXX */ 1, "%s", tdev->dev.name);
-
- err = trivfs_create_control (tdev->underlying, tunnel_cntlclass,
- pfinet_bucket, tunnel_class, pfinet_bucket,
- &tdev->cntl);
- tdev->cntl->hook = tdev;
-
- if (! err)
- {
- mach_port_t right = ports_get_send_right (tdev->cntl);
- err = file_set_translator (tdev->underlying, 0, FS_TRANS_EXCL
- | FS_TRANS_SET, 0, 0, 0, right,
- MACH_MSG_TYPE_COPY_SEND);
- mach_port_deallocate (mach_task_self (), right);
- }
-
- if (err)
- error (2, err, "%s", tdev->dev.name);
-
- __mutex_init (&tdev->lock);
- condition_init (&tdev->wait);
- condition_init (&tdev->select_alert);
- condition_implies (&tdev->wait, &tdev->select_alert);
-
- /* This call adds the device to the `dev_base' chain,
- initializes its `ifindex' member (which matters!),
- and tells the protocol stacks about the device. */
- err = - register_netdevice (dev);
- assert_perror (err);
-}
-
-/* If a new open with read and/or write permissions is requested,
- restrict to exclusive usage. */
-static error_t
-check_open_hook (struct trivfs_control *cntl,
- struct iouser *user,
- int flags)
-{
- struct tunnel_device *tdev;
-
- for (tdev = tunnel_dev; tdev; tdev = tdev->next)
- if (tdev->cntl == cntl)
- break;
-
- if (tdev && flags != O_NORW)
- {
- if (tdev->user)
- return EBUSY;
- else
- tdev->user = user;
- }
- return 0;
-}
-
-/* When a protid is destroyed, check if it is the current user.
- If yes, release the interface for other users. */
-static void
-pi_destroy_hook (struct trivfs_protid *cred)
-{
- struct tunnel_device *tdev;
-
- if (cred->pi.class != tunnel_class)
- return;
-
- tdev = (struct tunnel_device *) cred->po->cntl->hook;
-
- if (tdev->user == cred->user)
- tdev->user = 0;
-}
-
-/* If this variable is set, it is called every time a new peropen
- structure is created and initialized. */
-error_t (*trivfs_check_open_hook)(struct trivfs_control *,
- struct iouser *, int)
- = check_open_hook;
-
-/* If this variable is set, it is called every time a protid structure
- is about to be destroyed. */
-void (*trivfs_protid_destroy_hook) (struct trivfs_protid *) = pi_destroy_hook;
-
-/* Read data from an IO object. If offset is -1, read from the object
- maintained file pointer. If the object is not seekable, offset is
- ignored. The amount desired to be read is in AMOUNT. */
-error_t
-trivfs_S_io_read (struct trivfs_protid *cred,
- mach_port_t reply, mach_msg_type_name_t reply_type,
- char **data, mach_msg_type_number_t *data_len,
- loff_t offs, size_t amount)
-{
- struct tunnel_device *tdev;
- struct sk_buff *skb;
-
- /* Deny access if they have bad credentials. */
- if (! cred)
- return EOPNOTSUPP;
- else if (! (cred->po->openmodes & O_READ))
- return EBADF;
-
- if (cred->pi.class != tunnel_class)
- return EOPNOTSUPP;
-
- tdev = (struct tunnel_device *) cred->po->cntl->hook;
-
- __mutex_lock (&tdev->lock);
-
- while (skb_queue_len(&tdev->xq) == 0)
- {
- if (cred->po->openmodes & O_NONBLOCK)
- {
- __mutex_unlock (&tdev->lock);
- return EWOULDBLOCK;
- }
-
- tdev->read_blocked = 1;
- if (hurd_condition_wait (&tdev->wait, &tdev->lock))
- {
- __mutex_unlock (&tdev->lock);
- return EINTR;
- }
- /* See term/users.c for possible race? */
- }
-
- skb = skb_dequeue (&tdev->xq);
- assert(skb);
-
- if (skb->len < amount)
- amount = skb->len;
- if (amount > 0)
- {
- /* Possibly allocate a new buffer. */
- if (*data_len < amount)
- {
- *data = mmap (0, amount, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
- if (*data == MAP_FAILED)
- {
- dev_kfree_skb (skb);
- __mutex_unlock (&tdev->lock);
- return ENOMEM;
- }
- }
-
- /* Copy the constant data into the buffer. */
- memcpy ((char *) *data, skb->data, amount);
- }
- *data_len = amount;
- dev_kfree_skb (skb);
-
- /* Set atime, see term/users.c */
-
- __mutex_unlock (&tdev->lock);
-
- return 0;
-}
-
-/* Write data to an IO object. If offset is -1, write at the object
- maintained file pointer. If the object is not seekable, offset is
- ignored. The amount successfully written is returned in amount. A
- given user should not have more than one outstanding io_write on an
- object at a time; servers implement congestion control by delaying
- responses to io_write. Servers may drop data (returning ENOBUFS)
- if they receive more than one write when not prepared for it. */
-error_t
-trivfs_S_io_write (struct trivfs_protid *cred,
- mach_port_t reply,
- mach_msg_type_name_t replytype,
- char *data,
- mach_msg_type_number_t datalen,
- off_t offset,
- mach_msg_type_number_t *amount)
-{
- struct tunnel_device *tdev;
- struct sk_buff *skb;
-
- /* Deny access if they have bad credentials. */
- if (! cred)
- return EOPNOTSUPP;
- else if (! (cred->po->openmodes & O_WRITE))
- return EBADF;
-
- if (cred->pi.class != tunnel_class)
- return EOPNOTSUPP;
-
- tdev = (struct tunnel_device *) cred->po->cntl->hook;
-
- __mutex_lock (&tdev->lock);
-
- __mutex_lock (&net_bh_lock);
- skb = alloc_skb (datalen, GFP_ATOMIC);
- skb->len = datalen;
- skb->dev = &tdev->dev;
-
- bcopy (data, skb->data, datalen);
-
- /* Drop it on the queue. */
- skb->mac.raw = skb->data;
- skb->protocol = htons (ETH_P_IP);
- netif_rx (skb);
- __mutex_unlock (&net_bh_lock);
-
- *amount = datalen;
-
- __mutex_unlock (&tdev->lock);
- return 0;
-}
-
-/* Tell how much data can be read from the object without blocking for
- a "long time" (this should be the same meaning of "long time" used
- by the nonblocking flag. */
-kern_return_t
-trivfs_S_io_readable (struct trivfs_protid *cred,
- mach_port_t reply, mach_msg_type_name_t replytype,
- mach_msg_type_number_t *amount)
-{
- struct tunnel_device *tdev;
- struct sk_buff *skb;
-
- /* Deny access if they have bad credentials. */
- if (! cred)
- return EOPNOTSUPP;
- else if (! (cred->po->openmodes & O_READ))
- return EBADF;
-
- if (cred->pi.class != tunnel_class)
- return EOPNOTSUPP;
-
- tdev = (struct tunnel_device *) cred->po->cntl->hook;
-
- __mutex_lock (&tdev->lock);
-
- /* XXX: Now return the length of the next entry in the queue.
- From the BSD manual:
- The tunnel device, normally /dev/tunN, is exclusive-open (it cannot be
- opened if it is already open) and is restricted to the super-user. A
- read() call will return an error (EHOSTDOWN) if the interface is not
- ``ready'' address has been set (which means that the control device is
- open and the interface's). Once the interface is ready, read() will re-
- turn a packet if one is available; if not, it will either block until one
- is or return EWOULDBLOCK, depending on whether non-blocking I/O has been
- enabled. If the packet is longer than is allowed for in the buffer
- passed to read(), the extra data will be silently dropped.
- */
-
- skb = skb_dequeue(&tdev->xq);
- if (skb)
- {
- *amount = skb->len;
- skb_queue_head(&tdev->xq, skb);
- }
- else
- *amount = 0;
-
- __mutex_unlock (&tdev->lock);
-
- return 0;
-}
-
-/* SELECT_TYPE is the bitwise OR of SELECT_READ, SELECT_WRITE, and SELECT_URG.
- Block until one of the indicated types of i/o can be done "quickly", and
- return the types that are then available. ID_TAG is returned as passed; it
- is just for the convenience of the user in matching up reply messages with
- specific requests sent. */
-error_t
-trivfs_S_io_select (struct trivfs_protid *cred,
- mach_port_t reply,
- mach_msg_type_name_t reply_type,
- int *type)
-{
- struct tunnel_device *tdev;
-
- if (!cred)
- return EOPNOTSUPP;
-
- if (cred->pi.class != tunnel_class)
- return EOPNOTSUPP;
-
- tdev = (struct tunnel_device *) cred->po->cntl->hook;
-
- /* We only deal with SELECT_READ here. */
- if (*type & ~SELECT_READ)
- return EINVAL;
-
- if (*type == 0)
- return 0;
-
- __mutex_lock (&tdev->lock);
-
- while (1)
- {
- if (skb_queue_len (&tdev->xq) != 0)
- {
- *type = SELECT_READ;
- __mutex_unlock (&tdev->lock);
- return 0;
- }
-
- ports_interrupt_self_on_port_death (cred, reply);
- tdev->read_blocked = 1;
- if (hurd_condition_wait (&tdev->select_alert, &tdev->lock))
- {
- *type = 0;
- __mutex_unlock (&tdev->lock);
- return EINTR;
- }
- }
-}
-
-/* Change current read/write offset */
-error_t
-trivfs_S_io_seek (struct trivfs_protid *cred,
- mach_port_t reply, mach_msg_type_name_t reply_type,
- off_t offs, int whence, off_t *new_offs)
-{
- if (!cred)
- return EOPNOTSUPP;
-
- if (cred->pi.class != tunnel_class)
- return EOPNOTSUPP;
-
- return ESPIPE;
-}
-
-/* Change the size of the file. If the size increases, new blocks are
- zero-filled. After successful return, it is safe to reference mapped
- areas of the file up to NEW_SIZE. */
-error_t
-trivfs_S_file_set_size (struct trivfs_protid *cred,
- mach_port_t reply, mach_msg_type_name_t reply_type,
- off_t size)
-{
- if (!cred)
- return EOPNOTSUPP;
-
- if (cred->pi.class != tunnel_class)
- return EOPNOTSUPP;
-
- return size == 0 ? 0 : EINVAL;
-}
-
-/* These four routines modify the O_APPEND, O_ASYNC, O_FSYNC, and
- O_NONBLOCK bits for the IO object. In addition, io_get_openmodes
- will tell you which of O_READ, O_WRITE, and O_EXEC the object can
- be used for. The O_ASYNC bit affects icky async I/O; good async
- I/O is done through io_async which is orthogonal to these calls. */
-error_t
-trivfs_S_io_set_all_openmodes(struct trivfs_protid *cred,
- mach_port_t reply,
- mach_msg_type_name_t reply_type,
- int mode)
-{
- if (!cred)
- return EOPNOTSUPP;
-
- if (cred->pi.class != tunnel_class)
- return EOPNOTSUPP;
-
- return 0;
-}
-
-error_t
-trivfs_S_io_set_some_openmodes (struct trivfs_protid *cred,
- mach_port_t reply,
- mach_msg_type_name_t reply_type,
- int bits)
-{
- if (!cred)
- return EOPNOTSUPP;
-
- if (cred->pi.class != tunnel_class)
- return EOPNOTSUPP;
-
- return 0;
-}
-
-error_t
-trivfs_S_io_clear_some_openmodes (struct trivfs_protid *cred,
- mach_port_t reply,
- mach_msg_type_name_t reply_type,
- int bits)
-{
- if (!cred)
- return EOPNOTSUPP;
-
- if (cred->pi.class != tunnel_class)
- return EOPNOTSUPP;
-
- return 0;
-}
-
-error_t
-trivfs_S_io_get_owner (struct trivfs_protid *cred,
- mach_port_t reply,
- mach_msg_type_name_t reply_type,
- pid_t *owner)
-{
- if (!cred)
- return EOPNOTSUPP;
-
- if (cred->pi.class != tunnel_class)
- return EOPNOTSUPP;
-
- *owner = 0;
- return 0;
-}
-
-error_t
-trivfs_S_io_mod_owner (struct trivfs_protid *cred,
- mach_port_t reply, mach_msg_type_name_t reply_type,
- pid_t owner)
-{
- if (!cred)
- return EOPNOTSUPP;
-
- if (cred->pi.class != tunnel_class)
- return EOPNOTSUPP;
-
- return EINVAL;
-}
-
-/* Return objects mapping the data underlying this memory object. If
- the object can be read then memobjrd will be provided; if the
- object can be written then memobjwr will be provided. For objects
- where read data and write data are the same, these objects will be
- equal, otherwise they will be disjoint. Servers are permitted to
- implement io_map but not io_map_cntl. Some objects do not provide
- mapping; they will set none of the ports and return an error. Such
- objects can still be accessed by io_read and io_write. */
-error_t
-trivfs_S_io_map (struct trivfs_protid *cred,
- mach_port_t reply,
- mach_msg_type_name_t replyPoly,
- memory_object_t *rdobj,
- mach_msg_type_name_t *rdtype,
- memory_object_t *wrobj,
- mach_msg_type_name_t *wrtype)
-{
- if (!cred)
- return EOPNOTSUPP;
-
- if (cred->pi.class != tunnel_class)
- return EOPNOTSUPP;
-
- return EINVAL;
-}