/home/brooks/ng_gif.message

This commit is contained in:
Brooks Davis 2001-09-26 23:50:17 +00:00
parent 20af0ffaa1
commit 94408d94c3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=83998
14 changed files with 1418 additions and 1 deletions

View File

@ -90,6 +90,7 @@ MAN= aac.4 \
ng_echo.4 \
ng_ether.4 \
ng_frame_relay.4 \
ng_gif.4 \
ng_hole.4 \
ng_iface.4 \
ng_ksocket.4 \

129
share/man/man4/ng_gif.4 Normal file
View File

@ -0,0 +1,129 @@
.\" Copyright 2000 The Aerospace Corporation. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions, and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions, and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. The name of The Aerospace Corporation may not be used to endorse or
.\" promote products derived from this software.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION "AS IS" AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE FOR
.\" ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" Author: Brooks Davis <brooks@FreeBSD.org>
.\"
.\" $FreeBSD$
.\"
.Dd September 18, 2001
.Dt NG_GIF 4
.Os
.Sh NAME
.Nm ng_gif
.Nd Generic tunnel interface netgraph node type
.Sh SYNOPSIS
.Fd #include <netgraph/ng_gif.h>
.Sh DESCRIPTION
The
.Nm
netgraph node type allows
.Xr gif 4
interfaces to interact with
the
.Xr netgraph 4
networking subsystem.
Once the
.Nm
module is loaded in the kernel, a node is automatically created
for each
.Xr gif 4
interface in the system.
Each node will attempt to name itself with the same name
as the associated interface.
All
.Nm
nodes are persistent for as long as the interface itself exists.
.Pp
Two hooks are supported:
.Dv lower
and
.Dv orphans .
The hook name
.Dv divert
may be used as an alias for
.Dv lower ,
and is provided for compatibility with
.Xr ng_ether 4 .
In reality the two names represent the same hook.
.Pp
The
.Dv lower
hook is a connection to the raw
.Xr gif 4
device.
When connected, all incoming packets are diverted out this hook.
Writing to this hook results in a raw encapsulated packet being transmitted
by the device.
Normal outgoing packets are not affected by
.Dv lower
being connected.
.Pp
The
.Dv orphans
hook is equivalent to
.Dv lower ,
except that only unrecognized packets (that would otherwise be discarded)
are written to the hook, and normal incoming traffic is unaffected.
At most one of
.Dv orphans
and
.Dv lower
may be connected at any time.
.Pp
In all cases, frames are raw packets with the address family of the
packet attached to the front.
.Pp
When no hooks are connected, packets flow normally upwards and downwards.
.Sh HOOKS
This node type supports the following hooks:
.Pp
.Bl -tag -width orphans
.It Dv lower
Connection to the lower device link layer.
.It Dv orphans
Like
.Dv lower ,
but only receives unrecognized packets.
.El
.Sh CONTROL MESSAGES
This node type supports only the generic control messages generic
control messages.
.Sh EXAMPLES
This command dumps all unrecognized packets received by the
.Dv gif0
interface to standard output decoded in hex and ASCII:
.Bd -literal -offset indent
nghook -a gif0: orphans
.Ed
.Sh SEE ALSO
.Xr gif 4 ,
.Xr netgraph 4 ,
.Xr netintro 4 ,
.Xr ifconfig 8 ,
.Xr ngctl 8 ,
.Xr nghook 8
.Sh AUTHORS
.An Brooks Davis Aq brooks@FreeBSD.org

View File

@ -0,0 +1,114 @@
.\" Copyright 2000 The Aerospace Corporation. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions, and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions, and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. The name of The Aerospace Corporation may not be used to endorse or
.\" promote products derived from this software.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION "AS IS" AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE FOR
.\" ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" Author: Brooks Davis <brooks@FreeBSD.org>
.\"
.\" $FreeBSD$
.\"
.Dd September 18, 2001
.Dt NG_GIF_DEMUX 4
.Os
.Sh NAME
.Nm ng_gif_demux
.Nd Demultiplexr for packets from
.Xr ng_gif 4
nodes
.Sh SYNOPSIS
.Fd #include <netgraph/ng_gif_demux.h>
.Sh DESCRIPTION
The
.Nm
netgraph node type demultiplexes the output from
.Xr ng_gif 4
nodes in the
.Xr netgraph 4
networking subsystem.
.Pp
The
.Dv gif
hook is ment to be connected to the
.Dv lower
or
.Dv orphans
hook of an
.Xr ng_gif 4
node.
The
.Dv inet ,
.Dv inet6 ,
.Dv atalk ,
.Dv ipx ,
.Dv atm ,
.Dv natm ,
and
.Dv ns
hooks output frames of the given type when they are recieved on the
.Dv gif
hook.
When a frame is recived on one of these hooks, it is encapsulated and
sent out the
.Dv gif
hook.
.Sh HOOKS
This node type supports the following hooks:
.Pp
.Bl -tag -width inet6
.It Dv gif
Connection to the
.Dv lower
or
.Dv orphans
hook of an
.Xr ng_gif 4
node.
.It Dv inet
Hook for input and output of IP frames.
.It Dv inet6
Hook for input and output of IPv6 frames.
.It Dv atalk
Hook for input and output of AppleTalk frames.
.It Dv ipx
Hook for input and output of IPX frames.
.It Dv atm
Hook for input and output of ATM frames.
.It Dv natm
Hook for input and output of NATM frames.
.It Dv ns
Hook for input and output of NS frames.
.El
.Sh CONTROL MESSAGES
This node type supports only the generic control messages generic
control messages.
.Sh SEE ALSO
.Xr gif 4 ,
.Xr netgraph 4 ,
.Xr netintro 4 ,
.Xr ng_gif 4 ,
.Xr ifconfig 8 ,
.Xr ngctl 8 ,
.Xr nghook 8
.Sh AUTHORS
.An Brooks Davis Aq brooks@FreeBSD.org

View File

@ -1029,6 +1029,8 @@ netgraph/ng_cisco.c optional netgraph_cisco
netgraph/ng_echo.c optional netgraph_echo
netgraph/ng_ether.c optional netgraph_ether
netgraph/ng_frame_relay.c optional netgraph_frame_relay
netgraph/ng_gif.c optional netgraph_gif
netgraph/ng_gif_demux.c optional netgraph_gif_demux
netgraph/ng_hole.c optional netgraph_hole
netgraph/ng_iface.c optional netgraph_iface
netgraph/ng_ksocket.c optional netgraph_ksocket

View File

@ -311,6 +311,8 @@ NETGRAPH_CISCO opt_netgraph.h
NETGRAPH_ECHO opt_netgraph.h
NETGRAPH_ETHER opt_netgraph.h
NETGRAPH_FRAME_RELAY opt_netgraph.h
NETGRAPH_GIF opt_netgraph.h
NETGRAPH_GIF_DEMUX opt_netgraph.h
NETGRAPH_HOLE opt_netgraph.h
NETGRAPH_IFACE opt_netgraph.h
NETGRAPH_KSOCKET opt_netgraph.h

View File

@ -9,6 +9,8 @@ SUBDIR= async \
eiface \
ether \
frame_relay \
gif \
gif_demux \
hole \
iface \
ksocket \

View File

@ -0,0 +1,12 @@
# $FreeBSD$
KMOD= ng_gif
SRCS= ng_gif.c opt_inet.h opt_inet6.h
opt_inet.h:
echo "#define INET 1" > ${.TARGET}
opt_inet6.h:
echo "#define INET6 1" > ${.TARGET}
.include <bsd.kmod.mk>

View File

@ -0,0 +1,6 @@
# $FreeBSD$
KMOD= ng_gif_demux
SRCS= ng_gif_demux.c
.include <bsd.kmod.mk>

View File

@ -87,6 +87,11 @@ static MALLOC_DEFINE(M_GIF, "gif", "Generic Tunnel Interface");
static struct rman gifunits[1];
LIST_HEAD(, gif_softc) gif_softc_list;
void (*ng_gif_input_p)(struct ifnet *ifp, struct mbuf **mp, int af);
void (*ng_gif_input_orphan_p)(struct ifnet *ifp, struct mbuf *m, int af);
void (*ng_gif_attach_p)(struct ifnet *ifp);
void (*ng_gif_detach_p)(struct ifnet *ifp);
int gif_clone_create __P((struct if_clone *, int *));
void gif_clone_destroy __P((struct ifnet *));
@ -199,6 +204,8 @@ gif_clone_create(ifc, unit)
sc->gif_if.if_snd.ifq_maxlen = IFQ_MAXLEN;
if_attach(&sc->gif_if);
bpfattach(&sc->gif_if, DLT_NULL, sizeof(u_int));
if (ng_gif_attach_p != NULL)
(*ng_gif_attach_p)(&sc->gif_if);
LIST_INSERT_HEAD(&gif_softc_list, sc, gif_link);
return (0);
}
@ -221,6 +228,8 @@ gif_clone_destroy(ifp)
KASSERT(err == 0, ("Unexpected error detaching encap_cookie6"));
}
if (ng_gif_detach_p != NULL)
(*ng_gif_detach_p)(ifp);
bpfdetach(ifp);
if_detach(ifp);
@ -462,6 +471,12 @@ gif_input(m, af, gifp)
bpf_mtap(gifp, &m0);
}
if (ng_gif_input_p != NULL) {
(*ng_gif_input_p)(gifp, &m, af);
if (m == NULL)
return;
}
/*
* Put the packet to the network layer input queue according to the
* specified address family.
@ -488,7 +503,10 @@ gif_input(m, af, gifp)
break;
#endif
default:
m_freem(m);
if (ng_gif_input_orphan_p != NULL)
(*ng_gif_input_orphan_p)(gifp, m, af);
else
m_freem(m);
return;
}

View File

@ -47,6 +47,14 @@
struct encaptab;
extern void (*ng_gif_input_p)(struct ifnet *ifp, struct mbuf **mp,
int af);
extern void (*ng_gif_input_orphan_p)(struct ifnet *ifp, struct mbuf *m,
int af);
extern int (*ng_gif_output_p)(struct ifnet *ifp, struct mbuf **mp);
extern void (*ng_gif_attach_p)(struct ifnet *ifp);
extern void (*ng_gif_detach_p)(struct ifnet *ifp);
struct gif_softc {
struct ifnet gif_if; /* common area - must be at the top */
struct sockaddr *gif_psrc; /* Physical src addr */
@ -61,6 +69,7 @@ struct gif_softc {
const struct encaptab *encap_cookie4;
const struct encaptab *encap_cookie6;
struct resource *r_unit; /* resource allocated for this unit */
void *gif_netgraph; /* ng_gif(4) netgraph node info */
LIST_ENTRY(gif_softc) gif_link; /* all gif's are linked */
};

596
sys/netgraph/ng_gif.c Normal file
View File

@ -0,0 +1,596 @@
/*
* ng_gif.c
*
* Copyright 2001 The Aerospace Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
* Copyright (c) 1996-2000 Whistle Communications, Inc.
* All rights reserved.
*
* Subject to the following obligations and disclaimer of warranty, use and
* redistribution of this software, in source or object code forms, with or
* without modifications are expressly permitted by Whistle Communications;
* provided, however, that:
* 1. Any and all reproductions of the source or object code must include the
* copyright notice above and the following disclaimer of warranties; and
* 2. No rights are granted, in any manner or form, to use Whistle
* Communications, Inc. trademarks, including the mark "WHISTLE
* COMMUNICATIONS" on advertising, endorsements, or otherwise except as
* such appears in the above copyright notice or in the software.
*
* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
* INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
* WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
* REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
* SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
* IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
* RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
* WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* ng_gif(4) netgraph node type
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/errno.h>
#include <sys/syslog.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/route.h>
#include <net/if_types.h>
#include <net/if_var.h>
#include <net/if_gif.h>
#include <netgraph/ng_message.h>
#include <netgraph/netgraph.h>
#include <netgraph/ng_parse.h>
#include <netgraph/ng_gif.h>
#define IFP2NG(ifp) ((struct ng_node *)((struct gif_softc *)(ifp))->gif_netgraph)
/* Per-node private data */
struct private {
struct ifnet *ifp; /* associated interface */
hook_p lower; /* lower OR orphan hook connection */
u_char lowerOrphan; /* whether lower is lower or orphan */
};
typedef struct private *priv_p;
/* Functional hooks called from if_gif.c */
static void ng_gif_input(struct ifnet *ifp, struct mbuf **mp, int af);
static void ng_gif_input_orphan(struct ifnet *ifp, struct mbuf *m, int af);
static void ng_gif_attach(struct ifnet *ifp);
static void ng_gif_detach(struct ifnet *ifp);
/* Other functions */
static void ng_gif_input2(node_p node, struct mbuf **mp, int af);
static int ng_gif_glue_af(struct mbuf **mp, int af);
static int ng_gif_rcv_lower(node_p node, struct mbuf *m, meta_p meta);
/* Netgraph node methods */
static ng_constructor_t ng_gif_constructor;
static ng_rcvmsg_t ng_gif_rcvmsg;
static ng_shutdown_t ng_gif_shutdown;
static ng_newhook_t ng_gif_newhook;
static ng_connect_t ng_gif_connect;
static ng_rcvdata_t ng_gif_rcvdata;
static ng_disconnect_t ng_gif_disconnect;
static int ng_gif_mod_event(module_t mod, int event, void *data);
/* List of commands and how to convert arguments to/from ASCII */
static const struct ng_cmdlist ng_gif_cmdlist[] = {
{
NGM_GIF_COOKIE,
NGM_GIF_GET_IFNAME,
"getifname",
NULL,
&ng_parse_string_type
},
{
NGM_GIF_COOKIE,
NGM_GIF_GET_IFINDEX,
"getifindex",
NULL,
&ng_parse_int32_type
},
{ 0 }
};
static struct ng_type ng_gif_typestruct = {
NG_ABI_VERSION,
NG_GIF_NODE_TYPE,
ng_gif_mod_event,
ng_gif_constructor,
ng_gif_rcvmsg,
ng_gif_shutdown,
ng_gif_newhook,
NULL,
ng_gif_connect,
ng_gif_rcvdata,
ng_gif_disconnect,
ng_gif_cmdlist,
};
MODULE_VERSION(ng_gif, 1);
MODULE_DEPEND(ng_gif, if_gif, 1,1,1);
NETGRAPH_INIT(gif, &ng_gif_typestruct);
/******************************************************************
GIF FUNCTION HOOKS
******************************************************************/
/*
* Handle a packet that has come in on an interface. We get to
* look at it here before any upper layer protocols do.
*
* NOTE: this function will get called at splimp()
*/
static void
ng_gif_input(struct ifnet *ifp, struct mbuf **mp, int af)
{
const node_p node = IFP2NG(ifp);
const priv_p priv = NG_NODE_PRIVATE(node);
/* If "lower" hook not connected, let packet continue */
if (priv->lower == NULL || priv->lowerOrphan)
return;
ng_gif_input2(node, mp, af);
}
/*
* Handle a packet that has come in on an interface, and which
* does not match any of our known protocols (an ``orphan'').
*
* NOTE: this function will get called at splimp()
*/
static void
ng_gif_input_orphan(struct ifnet *ifp, struct mbuf *m, int af)
{
const node_p node = IFP2NG(ifp);
const priv_p priv = NG_NODE_PRIVATE(node);
/* If "orphan" hook not connected, let packet continue */
if (priv->lower == NULL || !priv->lowerOrphan) {
m_freem(m);
return;
}
ng_gif_input2(node, &m, af);
if (m != NULL)
m_freem(m);
}
/*
* Handle a packet that has come in on a gif interface.
* Attach the address family to the mbuf for later use.
*
* NOTE: this function will get called at splimp()
*/
static void
ng_gif_input2(node_p node, struct mbuf **mp, int af)
{
const priv_p priv = NG_NODE_PRIVATE(node);
int error;
/* Glue address family on */
if ((error = ng_gif_glue_af(mp, af)) != 0)
return;
/* Send out lower/orphan hook */
NG_SEND_DATA_ONLY(error, priv->lower, *mp);
*mp = NULL;
}
/*
* A new gif interface has been attached.
* Create a new node for it, etc.
*/
static void
ng_gif_attach(struct ifnet *ifp)
{
char name[IFNAMSIZ + 1];
priv_p priv;
node_p node;
/* Create node */
KASSERT(!IFP2NG(ifp), ("%s: node already exists?", __FUNCTION__));
snprintf(name, sizeof(name), "%s%d", ifp->if_name, ifp->if_unit);
if (ng_make_node_common(&ng_gif_typestruct, &node) != 0) {
log(LOG_ERR, "%s: can't %s for %s\n",
__FUNCTION__, "create node", name);
return;
}
/* Allocate private data */
MALLOC(priv, priv_p, sizeof(*priv), M_NETGRAPH, M_NOWAIT | M_ZERO);
if (priv == NULL) {
log(LOG_ERR, "%s: can't %s for %s\n",
__FUNCTION__, "allocate memory", name);
NG_NODE_UNREF(node);
return;
}
NG_NODE_SET_PRIVATE(node, priv);
priv->ifp = ifp;
IFP2NG(ifp) = node;
/* Try to give the node the same name as the interface */
if (ng_name_node(node, name) != 0) {
log(LOG_WARNING, "%s: can't name node %s\n",
__FUNCTION__, name);
}
}
/*
* An Ethernet interface is being detached.
* REALLY Destroy its node.
*/
static void
ng_gif_detach(struct ifnet *ifp)
{
const node_p node = IFP2NG(ifp);
const priv_p priv = NG_NODE_PRIVATE(node);
if (node == NULL) /* no node (why not?), ignore */
return;
NG_NODE_REALLY_DIE(node); /* Force real removal of node */
/*
* We can't assume the ifnet is still around when we run shutdown
* So zap it now. XXX We HOPE that anything running at this time
* handles it (as it should in the non netgraph case).
*/
IFP2NG(ifp) = NULL;
priv->ifp = NULL; /* XXX race if interrupted an output packet */
ng_rmnode_self(node); /* remove all netgraph parts */
}
/*
* Optimization for gluing the Ethernet header back onto
* the front of an incoming packet.
*/
static int
ng_gif_glue_af(struct mbuf **mp, int af)
{
struct mbuf *m = *mp;
int error = 0;
sa_family_t tmp_af;
tmp_af = (sa_family_t) af;
/*
* XXX: should try to bring back some of the optimizations from
* ng_ether.c
*/
/*
* Doing anything more is likely to get more
* expensive than it's worth..
* it's probable that everything else is in one
* big lump. The next node will do an m_pullup()
* for exactly the amount of data it needs and
* hopefully everything after that will not
* need one. So let's just use M_PREPEND.
*/
M_PREPEND(m, sizeof (tmp_af), M_DONTWAIT);
if (m == NULL) {
error = ENOBUFS;
goto done;
}
#if 0
copy:
#endif
/* Copy header and return (possibly new) mbuf */
*mtod(m, sa_family_t *) = tmp_af;
#if 0
bcopy((caddr_t)&tmp_af, mtod(m, sa_family_t *), sizeof(tmp_af));
#endif
done:
*mp = m;
return error;
}
/******************************************************************
NETGRAPH NODE METHODS
******************************************************************/
/*
* It is not possible or allowable to create a node of this type.
* Nodes get created when the interface is attached (or, when
* this node type's KLD is loaded).
*/
static int
ng_gif_constructor(node_p node)
{
return (EINVAL);
}
/*
* Check for attaching a new hook.
*/
static int
ng_gif_newhook(node_p node, hook_p hook, const char *name)
{
const priv_p priv = NG_NODE_PRIVATE(node);
u_char orphan = priv->lowerOrphan;
hook_p *hookptr;
/* Divert hook is an alias for lower */
if (strcmp(name, NG_GIF_HOOK_DIVERT) == 0)
name = NG_GIF_HOOK_LOWER;
/* Which hook? */
if (strcmp(name, NG_GIF_HOOK_LOWER) == 0) {
hookptr = &priv->lower;
orphan = 0;
} else if (strcmp(name, NG_GIF_HOOK_ORPHAN) == 0) {
hookptr = &priv->lower;
orphan = 1;
} else
return (EINVAL);
/* Check if already connected (shouldn't be, but doesn't hurt) */
if (*hookptr != NULL)
return (EISCONN);
/* OK */
*hookptr = hook;
priv->lowerOrphan = orphan;
return (0);
}
/*
* Hooks are attached, adjust to force queueing.
* We don't really care which hook it is.
* they should all be queuing for outgoing data.
*/
static int
ng_gif_connect(hook_p hook)
{
NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook));
return (0);
}
/*
* Receive an incoming control message.
*/
static int
ng_gif_rcvmsg(node_p node, item_p item, hook_p lasthook)
{
const priv_p priv = NG_NODE_PRIVATE(node);
struct ng_mesg *resp = NULL;
int error = 0;
struct ng_mesg *msg;
NGI_GET_MSG(item, msg);
switch (msg->header.typecookie) {
case NGM_GIF_COOKIE:
switch (msg->header.cmd) {
case NGM_GIF_GET_IFNAME:
NG_MKRESPONSE(resp, msg, IFNAMSIZ + 1, M_NOWAIT);
if (resp == NULL) {
error = ENOMEM;
break;
}
snprintf(resp->data, IFNAMSIZ + 1,
"%s%d", priv->ifp->if_name, priv->ifp->if_unit);
break;
case NGM_GIF_GET_IFINDEX:
NG_MKRESPONSE(resp, msg, sizeof(u_int32_t), M_NOWAIT);
if (resp == NULL) {
error = ENOMEM;
break;
}
*((u_int32_t *)resp->data) = priv->ifp->if_index;
break;
default:
error = EINVAL;
break;
}
break;
default:
error = EINVAL;
break;
}
NG_RESPOND_MSG(error, node, item, resp);
NG_FREE_MSG(msg);
return (error);
}
/*
* Receive data on a hook.
*/
static int
ng_gif_rcvdata(hook_p hook, item_p item)
{
const node_p node = NG_HOOK_NODE(hook);
const priv_p priv = NG_NODE_PRIVATE(node);
struct mbuf *m;
meta_p meta;
NGI_GET_M(item, m);
NGI_GET_META(item, meta);
NG_FREE_ITEM(item);
if (hook == priv->lower)
return ng_gif_rcv_lower(node, m, meta);
panic("%s: weird hook", __FUNCTION__);
}
/*
* Handle an mbuf received on the "lower" hook.
*/
static int
ng_gif_rcv_lower(node_p node, struct mbuf *m, meta_p meta)
{
struct sockaddr dst;
const priv_p priv = NG_NODE_PRIVATE(node);
bzero(&dst, sizeof(dst));
/* We don't process metadata. */
NG_FREE_META(meta);
/* Make sure header is fully pulled up */
if (m->m_pkthdr.len < sizeof(sa_family_t)) {
NG_FREE_M(m);
return (EINVAL);
}
if (m->m_len < sizeof(sa_family_t)
&& (m = m_pullup(m, sizeof(sa_family_t))) == NULL) {
return (ENOBUFS);
}
dst.sa_family = *mtod(m, sa_family_t *);
m_adj(m, sizeof(sa_family_t));
/* Send it on its way */
/*
* XXX: gif_output only uses dst for the family and passes the
* fourth argument (rt) to in{,6}_gif_output which ignore it.
* If this changes ng_gif will probably break.
*/
return gif_output(priv->ifp, m, &dst, NULL);
}
/*
* Shutdown node. This resets the node but does not remove it
* unless the REALLY_DIE flag is set.
*/
static int
ng_gif_shutdown(node_p node)
{
const priv_p priv = NG_NODE_PRIVATE(node);
if (node->nd_flags & NG_REALLY_DIE) {
/*
* WE came here because the gif interface is being destroyed,
* so stop being persistant.
* Actually undo all the things we did on creation.
* Assume the ifp has already been freed.
*/
NG_NODE_SET_PRIVATE(node, NULL);
FREE(priv, M_NETGRAPH);
NG_NODE_UNREF(node); /* free node itself */
return (0);
}
node->nd_flags &= ~NG_INVALID; /* Signal ng_rmnode we are persisant */
return (0);
}
/*
* Hook disconnection.
*/
static int
ng_gif_disconnect(hook_p hook)
{
const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
if (hook == priv->lower) {
priv->lower = NULL;
priv->lowerOrphan = 0;
} else
panic("%s: weird hook", __FUNCTION__);
if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
&& (NG_NODE_IS_VALID(NG_HOOK_NODE(hook))))
ng_rmnode_self(NG_HOOK_NODE(hook)); /* reset node */
return (0);
}
/******************************************************************
INITIALIZATION
******************************************************************/
/*
* Handle loading and unloading for this node type.
*/
static int
ng_gif_mod_event(module_t mod, int event, void *data)
{
struct ifnet *ifp;
int error = 0;
int s;
s = splnet();
switch (event) {
case MOD_LOAD:
/* Register function hooks */
if (ng_gif_attach_p != NULL) {
error = EEXIST;
break;
}
ng_gif_attach_p = ng_gif_attach;
ng_gif_detach_p = ng_gif_detach;
ng_gif_input_p = ng_gif_input;
ng_gif_input_orphan_p = ng_gif_input_orphan;
/* Create nodes for any already-existing gif interfaces */
TAILQ_FOREACH(ifp, &ifnet, if_link) {
if (ifp->if_type == IFT_GIF)
ng_gif_attach(ifp);
}
break;
case MOD_UNLOAD:
/*
* Note that the base code won't try to unload us until
* all nodes have been removed, and that can't happen
* until all gif interfaces are destroyed. In any
* case, we know there are no nodes left if the action
* is MOD_UNLOAD, so there's no need to detach any nodes.
*
* XXX: what about manual unloads?!?
*/
/* Unregister function hooks */
ng_gif_attach_p = NULL;
ng_gif_detach_p = NULL;
ng_gif_input_p = NULL;
ng_gif_input_orphan_p = NULL;
break;
default:
error = EOPNOTSUPP;
break;
}
splx(s);
return (error);
}

81
sys/netgraph/ng_gif.h Normal file
View File

@ -0,0 +1,81 @@
/*
* ng_gif.h
*
* Copyright 2001 The Aerospace Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
* Copyright (c) 1996-1999 Whistle Communications, Inc.
* All rights reserved.
*
* Subject to the following obligations and disclaimer of warranty, use and
* redistribution of this software, in source or object code forms, with or
* without modifications are expressly permitted by Whistle Communications;
* provided, however, that:
* 1. Any and all reproductions of the source or object code must include the
* copyright notice above and the following disclaimer of warranties; and
* 2. No rights are granted, in any manner or form, to use Whistle
* Communications, Inc. trademarks, including the mark "WHISTLE
* COMMUNICATIONS" on advertising, endorsements, or otherwise except as
* such appears in the above copyright notice or in the software.
*
* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
* INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
* WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
* REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
* SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
* IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
* RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
* WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _NETGRAPH_NG_GIF_H_
#define _NETGRAPH_NG_GIF_H_
/* Node type name and magic cookie */
#define NG_GIF_NODE_TYPE "gif"
#define NGM_GIF_COOKIE 994115727
/* Hook names */
#define NG_GIF_HOOK_LOWER "lower" /* connection to raw device */
#define NG_GIF_HOOK_DIVERT "divert" /* alias for lower */
#define NG_GIF_HOOK_ORPHAN "orphans" /* like lower, unknowns only */
/* Netgraph control messages */
enum {
NGM_GIF_GET_IFNAME = 1, /* get the interface name */
NGM_GIF_GET_IFINDEX, /* get the interface global index # */
};
#endif /* _NETGRAPH_NG_GIF_H_ */

398
sys/netgraph/ng_gif_demux.c Normal file
View File

@ -0,0 +1,398 @@
/*
* ng_gif_demux.c
*
* Copyright 2001 The Aerospace Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
* Copyright (c) 1996-1999 Whistle Communications, Inc.
* All rights reserved.
*
* Subject to the following obligations and disclaimer of warranty, use and
* redistribution of this software, in source or object code forms, with or
* without modifications are expressly permitted by Whistle Communications;
* provided, however, that:
* 1. Any and all reproductions of the source or object code must include the
* copyright notice above and the following disclaimer of warranties; and
* 2. No rights are granted, in any manner or form, to use Whistle
* Communications, Inc. trademarks, including the mark "WHISTLE
* COMMUNICATIONS" on advertising, endorsements, or otherwise except as
* such appears in the above copyright notice or in the software.
*
* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
* INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
* WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
* REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
* SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
* IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
* RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
* WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* ng_gif_demux(4) netgraph node type
*
* Packets received on the "gif" hook have their type header removed
* and are passed to the appropriate hook protocol hook. Packets
* recieved on a protocol hook have a type header added back and are
* passed out the gif hook. The currently supported protocol hooks are:
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/ctype.h>
#include <sys/mbuf.h>
#include <sys/errno.h>
#include <sys/socket.h>
#include <netgraph/ng_message.h>
#include <netgraph/netgraph.h>
#include <netgraph/ng_parse.h>
#include <netgraph/ng_gif_demux.h>
#ifdef NG_SEPARATE_MALLOC
MALLOC_DEFINE(M_NETGRAPH_GIF_DEMUX, "netgraph_gif_demux",
"netgraph gif demux node");
#else
#define M_NETGRAPH_GIF_DEMUX M_NETGRAPH
#endif
/* This struct describes one address family */
struct iffam {
sa_family_t family; /* Address family */
const char *hookname; /* Name for hook */
};
typedef const struct iffam *iffam_p;
/* List of address families supported by our interface */
const static struct iffam gFamilies[] = {
{ AF_INET, NG_GIF_DEMUX_HOOK_INET },
{ AF_INET6, NG_GIF_DEMUX_HOOK_INET6 },
{ AF_APPLETALK, NG_GIF_DEMUX_HOOK_ATALK },
{ AF_IPX, NG_GIF_DEMUX_HOOK_IPX },
{ AF_ATM, NG_GIF_DEMUX_HOOK_ATM },
{ AF_NATM, NG_GIF_DEMUX_HOOK_NATM },
{ AF_NS, NG_GIF_DEMUX_HOOK_NS },
};
#define NUM_FAMILIES (sizeof(gFamilies) / sizeof(*gFamilies))
/* Per-node private data */
struct ng_gif_demux_private {
node_p node; /* Our netgraph node */
hook_p gif; /* The gif hook */
hook_p hooks[NUM_FAMILIES]; /* The protocol hooks */
};
typedef struct ng_gif_demux_private *priv_p;
/* Netgraph node methods */
static ng_constructor_t ng_gif_demux_constructor;
static ng_rcvmsg_t ng_gif_demux_rcvmsg;
static ng_shutdown_t ng_gif_demux_shutdown;
static ng_newhook_t ng_gif_demux_newhook;
static ng_rcvdata_t ng_gif_demux_rcvdata;
static ng_disconnect_t ng_gif_demux_disconnect;
/* Helper stuff */
static iffam_p get_iffam_from_af(sa_family_t family);
static iffam_p get_iffam_from_hook(priv_p priv, hook_p hook);
static iffam_p get_iffam_from_name(const char *name);
static hook_p *get_hook_from_iffam(priv_p priv, iffam_p iffam);
/******************************************************************
NETGRAPH PARSE TYPES
******************************************************************/
/* List of commands and how to convert arguments to/from ASCII */
static const struct ng_cmdlist ng_gif_demux_cmdlist[] = {
{ 0 }
};
/* Node type descriptor */
static struct ng_type ng_gif_demux_typestruct = {
NG_ABI_VERSION,
NG_GIF_DEMUX_NODE_TYPE,
NULL,
ng_gif_demux_constructor,
ng_gif_demux_rcvmsg,
ng_gif_demux_shutdown,
ng_gif_demux_newhook,
NULL,
NULL,
ng_gif_demux_rcvdata,
ng_gif_demux_disconnect,
ng_gif_demux_cmdlist,
};
NETGRAPH_INIT(gif_demux, &ng_gif_demux_typestruct);
/************************************************************************
HELPER STUFF
************************************************************************/
/*
* Get the family descriptor from the family ID
*/
static __inline__ iffam_p
get_iffam_from_af(sa_family_t family)
{
iffam_p iffam;
int k;
for (k = 0; k < NUM_FAMILIES; k++) {
iffam = &gFamilies[k];
if (iffam->family == family)
return (iffam);
}
return (NULL);
}
/*
* Get the family descriptor from the hook
*/
static __inline__ iffam_p
get_iffam_from_hook(priv_p priv, hook_p hook)
{
int k;
for (k = 0; k < NUM_FAMILIES; k++)
if (priv->hooks[k] == hook)
return (&gFamilies[k]);
return (NULL);
}
/*
* Get the hook from the iffam descriptor
*/
static __inline__ hook_p *
get_hook_from_iffam(priv_p priv, iffam_p iffam)
{
return (&priv->hooks[iffam - gFamilies]);
}
/*
* Get the iffam descriptor from the name
*/
static __inline__ iffam_p
get_iffam_from_name(const char *name)
{
iffam_p iffam;
int k;
for (k = 0; k < NUM_FAMILIES; k++) {
iffam = &gFamilies[k];
if (!strcmp(iffam->hookname, name))
return (iffam);
}
return (NULL);
}
/******************************************************************
NETGRAPH NODE METHODS
******************************************************************/
/*
* Node constructor
*/
static int
ng_gif_demux_constructor(node_p node)
{
priv_p priv;
/* Allocate and initialize private info */
MALLOC(priv, priv_p, sizeof(*priv), M_NETGRAPH_GIF_DEMUX,
M_NOWAIT | M_ZERO);
if (priv == NULL)
return (ENOMEM);
priv->node = node;
NG_NODE_SET_PRIVATE(node, priv);
/* Done */
return (0);
}
/*
* Method for attaching a new hook
*/
static int
ng_gif_demux_newhook(node_p node, hook_p hook, const char *name)
{
const priv_p priv = NG_NODE_PRIVATE(node);
iffam_p iffam;
hook_p *hookptr;
if (strcmp(NG_GIF_DEMUX_HOOK_GIF, name) == 0)
hookptr = &priv->gif;
else {
iffam = get_iffam_from_name(name);
if (iffam == NULL)
return (EPFNOSUPPORT);
hookptr = get_hook_from_iffam(NG_NODE_PRIVATE(node), iffam);
}
if (*hookptr != NULL)
return (EISCONN);
*hookptr = hook;
return (0);
}
/*
* Receive a control message
*/
static int
ng_gif_demux_rcvmsg(node_p node, item_p item, hook_p lasthook)
{
struct ng_mesg *resp = NULL;
int error = 0;
struct ng_mesg *msg;
NGI_GET_MSG(item, msg);
switch (msg->header.typecookie) {
case NGM_GIF_DEMUX_COOKIE:
switch (msg->header.cmd) {
/* XXX: Add commands here. */
default:
error = EINVAL;
break;
}
break;
default:
error = EINVAL;
break;
}
/* Done */
NG_RESPOND_MSG(error, node, item, resp);
NG_FREE_MSG(msg);
return (error);
}
/*
* Receive data on a hook
*/
static int
ng_gif_demux_rcvdata(hook_p hook, item_p item)
{
const node_p node = NG_HOOK_NODE(hook);
const priv_p priv = NG_NODE_PRIVATE(node);
iffam_p iffam;
hook_p outhook;
int error = 0;
struct mbuf *m;
/* Pull the mbuf out of the item for processing. */
NGI_GET_M(item, m);
if (hook == priv->gif) {
/*
* Pull off the address family header and find the
* output hook.
*/
if (m->m_pkthdr.len < sizeof(sa_family_t)) {
NG_FREE_M(m);
NG_FREE_ITEM(item);
return (EINVAL);
}
if (m->m_len < sizeof(sa_family_t)
&& (m = m_pullup(m, sizeof(sa_family_t))) == NULL) {
NG_FREE_ITEM(item);
return (ENOBUFS);
}
iffam = get_iffam_from_af(*mtod(m, sa_family_t *));
if (iffam == NULL) {
NG_FREE_M(m);
NG_FREE_ITEM(item);
return (EINVAL);
}
outhook = *get_hook_from_iffam(priv, iffam);
m_adj(m, sizeof(sa_family_t));
} else {
/*
* Add address family header and set the output hook.
*/
iffam = get_iffam_from_hook(priv, hook);
M_PREPEND(m, sizeof (iffam->family), M_DONTWAIT);
if (m == NULL) {
NG_FREE_M(m);
NG_FREE_ITEM(item);
return (ENOBUFS);
}
bcopy(&iffam->family, mtod(m, sa_family_t *),
sizeof(iffam->family));
outhook = priv->gif;
}
/* Stuff the mbuf back in. */
NGI_M(item) = m;
/* Deliver packet */
NG_FWD_ITEM_HOOK(error, item, outhook);
return (error);
}
/*
* Shutdown node
*/
static int
ng_gif_demux_shutdown(node_p node)
{
const priv_p priv = NG_NODE_PRIVATE(node);
FREE(priv, M_NETGRAPH_GIF_DEMUX);
NG_NODE_SET_PRIVATE(node, NULL);
NG_NODE_UNREF(node);
return (0);
}
/*
* Hook disconnection.
*/
static int
ng_gif_demux_disconnect(hook_p hook)
{
const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
iffam_p iffam;
if (hook == priv->gif)
priv->gif = NULL;
else {
iffam = get_iffam_from_hook(priv, hook);
if (iffam == NULL)
panic(__FUNCTION__);
*get_hook_from_iffam(priv, iffam) = NULL;
}
return (0);
}

View File

@ -0,0 +1,47 @@
/*
* ng_gif_demux.h
*
* Copyright 2001 The Aerospace Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _NETGRAPH_NG_GIF_DEMUX_H_
#define _NETGRAPH_NG_GIF_DEMUX_H_
/* Node type name and magic cookie */
#define NG_GIF_DEMUX_NODE_TYPE "gif_demux"
#define NGM_GIF_DEMUX_COOKIE 995567329
/* Hook names */
#define NG_GIF_DEMUX_HOOK_GIF "gif"
#define NG_GIF_DEMUX_HOOK_INET "inet"
#define NG_GIF_DEMUX_HOOK_INET6 "inet6"
#define NG_GIF_DEMUX_HOOK_ATALK "atalk"
#define NG_GIF_DEMUX_HOOK_IPX "ipx"
#define NG_GIF_DEMUX_HOOK_ATM "atm"
#define NG_GIF_DEMUX_HOOK_NATM "natm"
#define NG_GIF_DEMUX_HOOK_NS "ns"
#endif /* _NETGRAPH_NG_GIF_DEMUX_H_ */