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