1 2 /* 3 * ng_hole.c 4 * 5 * Copyright (c) 1996-1999 Whistle Communications, Inc. 6 * All rights reserved. 7 * 8 * Subject to the following obligations and disclaimer of warranty, use and 9 * redistribution of this software, in source or object code forms, with or 10 * without modifications are expressly permitted by Whistle Communications; 11 * provided, however, that: 12 * 1. Any and all reproductions of the source or object code must include the 13 * copyright notice above and the following disclaimer of warranties; and 14 * 2. No rights are granted, in any manner or form, to use Whistle 15 * Communications, Inc. trademarks, including the mark "WHISTLE 16 * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 17 * such appears in the above copyright notice or in the software. 18 * 19 * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 20 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 21 * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 22 * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 24 * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 25 * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 26 * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 27 * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 28 * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 29 * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 30 * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 31 * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 35 * OF SUCH DAMAGE. 36 * 37 * Author: Julian Elisher <julian@freebsd.org> 38 * 39 * $FreeBSD$ 40 * $Whistle: ng_hole.c,v 1.10 1999/11/01 09:24:51 julian Exp $ 41 */ 42 43 /* 44 * This node is a 'black hole' that simply discards everything it receives 45 */ 46 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/kernel.h> 50 #include <sys/malloc.h> 51 #include <sys/mbuf.h> 52 #include <netgraph/ng_message.h> 53 #include <netgraph/netgraph.h> 54 #include <netgraph/ng_parse.h> 55 #include <netgraph/ng_hole.h> 56 57 /* Per hook private info. */ 58 struct ng_hole_hookinfo { 59 struct ng_hole_hookstat stats; 60 }; 61 typedef struct ng_hole_hookinfo *hinfo_p; 62 63 /* Parse type for struct ng_hole_hookstat. */ 64 static const struct ng_parse_struct_field ng_hole_hookstat_type_fields[] = 65 NG_HOLE_HOOKSTAT_TYPE_INFO; 66 static const struct ng_parse_type ng_hole_hookstat_type = { 67 &ng_parse_struct_type, 68 &ng_hole_hookstat_type_fields 69 }; 70 71 /* List of commands and how to convert arguments to/from ASCII. */ 72 static const struct ng_cmdlist ng_hole_cmdlist[] = { 73 { 74 NGM_HOLE_COOKIE, 75 NGM_HOLE_GET_STATS, 76 "getstats", 77 &ng_parse_hookbuf_type, 78 &ng_hole_hookstat_type 79 }, 80 { 81 NGM_HOLE_COOKIE, 82 NGM_HOLE_CLR_STATS, 83 "clrstats", 84 &ng_parse_hookbuf_type, 85 NULL 86 }, 87 { 88 NGM_HOLE_COOKIE, 89 NGM_HOLE_GETCLR_STATS, 90 "getclrstats", 91 &ng_parse_hookbuf_type, 92 &ng_hole_hookstat_type 93 }, 94 { 0 } 95 }; 96 97 /* Netgraph methods */ 98 static ng_constructor_t ngh_cons; 99 static ng_rcvmsg_t ngh_rcvmsg; 100 static ng_newhook_t ngh_newhook; 101 static ng_rcvdata_t ngh_rcvdata; 102 static ng_disconnect_t ngh_disconnect; 103 104 static struct ng_type typestruct = { 105 .version = NG_ABI_VERSION, 106 .name = NG_HOLE_NODE_TYPE, 107 .constructor = ngh_cons, 108 .rcvmsg = ngh_rcvmsg, 109 .newhook = ngh_newhook, 110 .rcvdata = ngh_rcvdata, 111 .disconnect = ngh_disconnect, 112 .cmdlist = ng_hole_cmdlist, 113 }; 114 NETGRAPH_INIT(hole, &typestruct); 115 116 /* 117 * Be obliging. but no work to do. 118 */ 119 static int 120 ngh_cons(node_p node) 121 { 122 return(0); 123 } 124 125 /* 126 * Add a hook. 127 */ 128 static int 129 ngh_newhook(node_p node, hook_p hook, const char *name) 130 { 131 hinfo_p hip; 132 133 /* Create hook private structure. */ 134 MALLOC(hip, hinfo_p, sizeof(*hip), M_NETGRAPH, M_NOWAIT | M_ZERO); 135 if (hip == NULL) 136 return (ENOMEM); 137 NG_HOOK_SET_PRIVATE(hook, hip); 138 return (0); 139 } 140 141 /* 142 * Receive a control message. 143 */ 144 static int 145 ngh_rcvmsg(node_p node, item_p item, hook_p lasthook) 146 { 147 struct ng_mesg *msg; 148 struct ng_mesg *resp = NULL; 149 int error = 0; 150 struct ng_hole_hookstat *stats; 151 hook_p hook; 152 153 NGI_GET_MSG(item, msg); 154 switch (msg->header.typecookie) { 155 case NGM_HOLE_COOKIE: 156 switch (msg->header.cmd) { 157 case NGM_HOLE_GET_STATS: 158 case NGM_HOLE_CLR_STATS: 159 case NGM_HOLE_GETCLR_STATS: 160 /* Sanity check. */ 161 if (msg->header.arglen != NG_HOOKSIZ) { 162 error = EINVAL; 163 break; 164 } 165 /* Find hook. */ 166 hook = ng_findhook(node, (char *)msg->data); 167 if (hook == NULL) { 168 error = ENOENT; 169 break; 170 } 171 stats = &((hinfo_p)NG_HOOK_PRIVATE(hook))->stats; 172 /* Build response (if desired). */ 173 if (msg->header.cmd != NGM_HOLE_CLR_STATS) { 174 NG_MKRESPONSE(resp, msg, sizeof(*stats), 175 M_NOWAIT); 176 if (resp == NULL) { 177 error = ENOMEM; 178 break; 179 } 180 bcopy(stats, resp->data, sizeof(*stats)); 181 } 182 /* Clear stats (if desired). */ 183 if (msg->header.cmd != NGM_HOLE_GET_STATS) 184 bzero(stats, sizeof(*stats)); 185 break; 186 default: /* Unknown command. */ 187 error = EINVAL; 188 break; 189 } 190 break; 191 default: /* Unknown type cookie. */ 192 error = EINVAL; 193 break; 194 } 195 NG_RESPOND_MSG(error, node, item, resp); 196 NG_FREE_MSG(msg); 197 return (error); 198 } 199 200 /* 201 * Receive data 202 */ 203 static int 204 ngh_rcvdata(hook_p hook, item_p item) 205 { 206 const hinfo_p hip = NG_HOOK_PRIVATE(hook); 207 208 hip->stats.frames++; 209 hip->stats.octets += NGI_M(item)->m_pkthdr.len; 210 NG_FREE_ITEM(item); 211 return 0; 212 } 213 214 /* 215 * Hook disconnection 216 */ 217 static int 218 ngh_disconnect(hook_p hook) 219 { 220 221 NG_HOOK_SET_PRIVATE(hook, NULL); 222 if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) 223 ng_rmnode_self(NG_HOOK_NODE(hook)); 224 return (0); 225 } 226