ng_hole.c revision 184205
1112918Sjeff/*
2112918Sjeff * ng_hole.c
3112918Sjeff */
4112918Sjeff
5112918Sjeff/*-
6112918Sjeff * Copyright (c) 1996-1999 Whistle Communications, Inc.
7112918Sjeff * All rights reserved.
8112918Sjeff *
9112918Sjeff * Subject to the following obligations and disclaimer of warranty, use and
10112918Sjeff * redistribution of this software, in source or object code forms, with or
11112918Sjeff * without modifications are expressly permitted by Whistle Communications;
12112918Sjeff * provided, however, that:
13112918Sjeff * 1. Any and all reproductions of the source or object code must include the
14112918Sjeff *    copyright notice above and the following disclaimer of warranties; and
15112918Sjeff * 2. No rights are granted, in any manner or form, to use Whistle
16112918Sjeff *    Communications, Inc. trademarks, including the mark "WHISTLE
17112918Sjeff *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
18112918Sjeff *    such appears in the above copyright notice or in the software.
19112918Sjeff *
20112918Sjeff * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
21112918Sjeff * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
22112918Sjeff * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
23112918Sjeff * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
24112918Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
25112918Sjeff * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
26112918Sjeff * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
27112918Sjeff * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
28112918Sjeff * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
29112918Sjeff * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
30112918Sjeff * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
31112918Sjeff * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
32112918Sjeff * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
33112918Sjeff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34112918Sjeff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35112918Sjeff * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
36112918Sjeff * OF SUCH DAMAGE.
37112918Sjeff *
38112918Sjeff * Author: Julian Elisher <julian@freebsd.org>
39112918Sjeff *
40112918Sjeff * $FreeBSD: head/sys/netgraph/ng_hole.c 184205 2008-10-23 15:53:51Z des $
41112918Sjeff * $Whistle: ng_hole.c,v 1.10 1999/11/01 09:24:51 julian Exp $
42112918Sjeff */
43112918Sjeff
44112918Sjeff/*
45112918Sjeff * This node is a 'black hole' that simply discards everything it receives
46112918Sjeff */
47112918Sjeff
48112918Sjeff#include <sys/param.h>
49112918Sjeff#include <sys/systm.h>
50112918Sjeff#include <sys/kernel.h>
51112918Sjeff#include <sys/malloc.h>
52112918Sjeff#include <sys/mbuf.h>
53112918Sjeff#include <netgraph/ng_message.h>
54112918Sjeff#include <netgraph/netgraph.h>
55112918Sjeff#include <netgraph/ng_parse.h>
56112918Sjeff#include <netgraph/ng_hole.h>
57112918Sjeff
58112918Sjeff/* Per hook private info. */
59112918Sjeffstruct ng_hole_hookinfo {
60112918Sjeff	struct ng_hole_hookstat	stats;
61112918Sjeff};
62112918Sjefftypedef struct ng_hole_hookinfo *hinfo_p;
63112918Sjeff
64112918Sjeff/* Parse type for struct ng_hole_hookstat. */
65144518Sdavidxustatic const struct ng_parse_struct_field ng_hole_hookstat_type_fields[] =
66144518Sdavidxu	NG_HOLE_HOOKSTAT_TYPE_INFO;
67144518Sdavidxustatic const struct ng_parse_type ng_hole_hookstat_type = {
68144518Sdavidxu	&ng_parse_struct_type,
69144518Sdavidxu	&ng_hole_hookstat_type_fields
70144518Sdavidxu};
71144518Sdavidxu
72144518Sdavidxu/* List of commands and how to convert arguments to/from ASCII. */
73144518Sdavidxustatic const struct ng_cmdlist ng_hole_cmdlist[] = {
74144518Sdavidxu	{
75144518Sdavidxu	  NGM_HOLE_COOKIE,
76144518Sdavidxu	  NGM_HOLE_GET_STATS,
77165967Simp	  "getstats",
78144518Sdavidxu	  &ng_parse_hookbuf_type,
79144518Sdavidxu	  &ng_hole_hookstat_type
80144518Sdavidxu	},
81144518Sdavidxu	{
82144518Sdavidxu	  NGM_HOLE_COOKIE,
83144518Sdavidxu	  NGM_HOLE_CLR_STATS,
84144518Sdavidxu	  "clrstats",
85144518Sdavidxu	  &ng_parse_hookbuf_type,
86144518Sdavidxu	  NULL
87144518Sdavidxu	},
88144518Sdavidxu	{
89144518Sdavidxu	  NGM_HOLE_COOKIE,
90144518Sdavidxu	  NGM_HOLE_GETCLR_STATS,
91144518Sdavidxu	  "getclrstats",
92144518Sdavidxu	  &ng_parse_hookbuf_type,
93144518Sdavidxu	  &ng_hole_hookstat_type
94144518Sdavidxu	},
95112918Sjeff	{ 0 }
96157457Sdavidxu};
97112918Sjeff
98112918Sjeff/* Netgraph methods */
99112918Sjeffstatic ng_constructor_t	ngh_cons;
100112918Sjeffstatic ng_rcvmsg_t	ngh_rcvmsg;
101144518Sdavidxustatic ng_newhook_t	ngh_newhook;
102176815Sdavidxustatic ng_rcvdata_t	ngh_rcvdata;
103157457Sdavidxustatic ng_disconnect_t	ngh_disconnect;
104112918Sjeff
105112918Sjeffstatic struct ng_type typestruct = {
106112918Sjeff	.version =	NG_ABI_VERSION,
107125963Smtm	.name =		NG_HOLE_NODE_TYPE,
108112918Sjeff	.constructor =	ngh_cons,
109112918Sjeff	.rcvmsg =	ngh_rcvmsg,
110144518Sdavidxu	.newhook = 	ngh_newhook,
111112918Sjeff	.rcvdata =	ngh_rcvdata,
112144518Sdavidxu	.disconnect =	ngh_disconnect,
113112918Sjeff	.cmdlist =	ng_hole_cmdlist,
114144518Sdavidxu};
115144518SdavidxuNETGRAPH_INIT(hole, &typestruct);
116144518Sdavidxu
117144518Sdavidxu/*
118144518Sdavidxu * Be obliging. but no work to do.
119144518Sdavidxu */
120144518Sdavidxustatic int
121112918Sjeffngh_cons(node_p node)
122144518Sdavidxu{
123144518Sdavidxu	return(0);
124144518Sdavidxu}
125144518Sdavidxu
126144518Sdavidxu/*
127144518Sdavidxu * Add a hook.
128144518Sdavidxu */
129144518Sdavidxustatic int
130112918Sjeffngh_newhook(node_p node, hook_p hook, const char *name)
131112918Sjeff{
132144518Sdavidxu	hinfo_p hip;
133144518Sdavidxu
134112918Sjeff	/* Create hook private structure. */
135144518Sdavidxu	hip = malloc(sizeof(*hip), M_NETGRAPH, M_NOWAIT | M_ZERO);
136112918Sjeff	if (hip == NULL)
137144518Sdavidxu		return (ENOMEM);
138144518Sdavidxu	NG_HOOK_SET_PRIVATE(hook, hip);
139144518Sdavidxu	return (0);
140144518Sdavidxu}
141144518Sdavidxu
142112918Sjeff/*
143112918Sjeff * Receive a control message.
144144518Sdavidxu */
145144518Sdavidxustatic int
146144518Sdavidxungh_rcvmsg(node_p node, item_p item, hook_p lasthook)
147144518Sdavidxu{
148154126Sdavidxu	struct ng_mesg *msg;
149154126Sdavidxu	struct ng_mesg *resp = NULL;
150144518Sdavidxu	int error = 0;
151144518Sdavidxu	struct ng_hole_hookstat *stats;
152176781Sdavidxu	hook_p hook;
153176781Sdavidxu
154176781Sdavidxu	NGI_GET_MSG(item, msg);
155112918Sjeff	switch (msg->header.typecookie) {
156112918Sjeff	case NGM_HOLE_COOKIE:
157112918Sjeff		switch (msg->header.cmd) {
158144518Sdavidxu		case NGM_HOLE_GET_STATS:
159144518Sdavidxu		case NGM_HOLE_CLR_STATS:
160112918Sjeff		case NGM_HOLE_GETCLR_STATS:
161144518Sdavidxu			/* Sanity check. */
162112918Sjeff			if (msg->header.arglen != NG_HOOKSIZ) {
163144518Sdavidxu				error = EINVAL;
164144518Sdavidxu				break;
165144518Sdavidxu			}
166144518Sdavidxu			/* Find hook. */
167144518Sdavidxu			hook = ng_findhook(node, (char *)msg->data);
168144518Sdavidxu			if (hook == NULL) {
169144518Sdavidxu				error = ENOENT;
170144518Sdavidxu				break;
171144518Sdavidxu			}
172144518Sdavidxu			stats = &((hinfo_p)NG_HOOK_PRIVATE(hook))->stats;
173144518Sdavidxu			/* Build response (if desired). */
174144518Sdavidxu			if (msg->header.cmd != NGM_HOLE_CLR_STATS) {
175144518Sdavidxu				NG_MKRESPONSE(resp, msg, sizeof(*stats),
176144518Sdavidxu				    M_NOWAIT);
177112918Sjeff				if (resp == NULL) {
178144518Sdavidxu					error = ENOMEM;
179112918Sjeff					break;
180112918Sjeff				}
181144518Sdavidxu				bcopy(stats, resp->data, sizeof(*stats));
182144518Sdavidxu			}
183112918Sjeff			/* Clear stats (if desired). */
184144518Sdavidxu			if (msg->header.cmd != NGM_HOLE_GET_STATS)
185112918Sjeff				bzero(stats, sizeof(*stats));
186144518Sdavidxu			break;
187112918Sjeff		default:		/* Unknown command. */
188144518Sdavidxu			error = EINVAL;
189144518Sdavidxu			break;
190144518Sdavidxu		}
191144518Sdavidxu		break;
192144518Sdavidxu	default:			/* Unknown type cookie. */
193144518Sdavidxu		error = EINVAL;
194144518Sdavidxu		break;
195144518Sdavidxu	}
196144518Sdavidxu	NG_RESPOND_MSG(error, node, item, resp);
197112918Sjeff	NG_FREE_MSG(msg);
198112918Sjeff	return (error);
199144518Sdavidxu}
200144518Sdavidxu
201112918Sjeff/*
202144518Sdavidxu * Receive data
203112918Sjeff */
204144518Sdavidxustatic int
205112918Sjeffngh_rcvdata(hook_p hook, item_p item)
206144518Sdavidxu{
207144518Sdavidxu	const hinfo_p hip = NG_HOOK_PRIVATE(hook);
208144518Sdavidxu
209144518Sdavidxu	hip->stats.frames++;
210112918Sjeff	hip->stats.octets += NGI_M(item)->m_pkthdr.len;
211144518Sdavidxu	NG_FREE_ITEM(item);
212112918Sjeff	return 0;
213112918Sjeff}
214144518Sdavidxu
215144518Sdavidxu/*
216112918Sjeff * Hook disconnection
217144518Sdavidxu */
218112918Sjeffstatic int
219144518Sdavidxungh_disconnect(hook_p hook)
220112918Sjeff{
221144518Sdavidxu
222144518Sdavidxu	free(NG_HOOK_PRIVATE(hook), M_NETGRAPH);
223144518Sdavidxu	NG_HOOK_SET_PRIVATE(hook, NULL);
224144518Sdavidxu	if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
225112918Sjeff		ng_rmnode_self(NG_HOOK_NODE(hook));
226144518Sdavidxu	return (0);
227112918Sjeff}
228112918Sjeff