ng_UI.c revision 243882
1264095Semaste/* 2264095Semaste * ng_UI.c 3264095Semaste */ 4264095Semaste 5264095Semaste/*- 6264095Semaste * Copyright (c) 1996-1999 Whistle Communications, Inc. 7264095Semaste * All rights reserved. 8264095Semaste * 9264095Semaste * Subject to the following obligations and disclaimer of warranty, use and 10264095Semaste * redistribution of this software, in source or object code forms, with or 11264095Semaste * without modifications are expressly permitted by Whistle Communications; 12264095Semaste * provided, however, that: 13264095Semaste * 1. Any and all reproductions of the source or object code must include the 14264095Semaste * copyright notice above and the following disclaimer of warranties; and 15264095Semaste * 2. No rights are granted, in any manner or form, to use Whistle 16264095Semaste * Communications, Inc. trademarks, including the mark "WHISTLE 17264095Semaste * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 18264095Semaste * such appears in the above copyright notice or in the software. 19264095Semaste * 20264095Semaste * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 21264095Semaste * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 22264095Semaste * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 23264095Semaste * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 24264095Semaste * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 25264095Semaste * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 26264095Semaste * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 27264095Semaste * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 28264095Semaste * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 29264095Semaste * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 30264095Semaste * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 31264095Semaste * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 32264095Semaste * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 33264095Semaste * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34264095Semaste * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35264095Semaste * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 36264095Semaste * OF SUCH DAMAGE. 37264095Semaste * 38264095Semaste * Author: Julian Elischer <julian@freebsd.org> 39264095Semaste * 40264095Semaste * $FreeBSD: head/sys/netgraph/ng_UI.c 243882 2012-12-05 08:04:20Z glebius $ 41264095Semaste * $Whistle: ng_UI.c,v 1.14 1999/11/01 09:24:51 julian Exp $ 42264095Semaste */ 43264095Semaste 44264095Semaste#include <sys/param.h> 45264095Semaste#include <sys/systm.h> 46264095Semaste#include <sys/errno.h> 47264095Semaste#include <sys/kernel.h> 48264095Semaste#include <sys/malloc.h> 49264095Semaste#include <sys/mbuf.h> 50264095Semaste#include <sys/errno.h> 51264095Semaste 52264095Semaste 53264095Semaste#include <netgraph/ng_message.h> 54264095Semaste#include <netgraph/netgraph.h> 55264095Semaste#include <netgraph/ng_UI.h> 56264095Semaste 57264095Semaste/* 58264095Semaste * DEFINITIONS 59264095Semaste */ 60264095Semaste 61264095Semaste/* Everything, starting with sdlc on has defined UI as 0x03 */ 62264095Semaste#define HDLC_UI 0x03 63271880Semaste 64264095Semaste/* Node private data */ 65264095Semastestruct ng_UI_private { 66264095Semaste hook_p downlink; 67264095Semaste hook_p uplink; 68264095Semaste}; 69264095Semastetypedef struct ng_UI_private *priv_p; 70264095Semaste 71264095Semaste/* Netgraph node methods */ 72264095Semastestatic ng_constructor_t ng_UI_constructor; 73264095Semastestatic ng_rcvmsg_t ng_UI_rcvmsg; 74271880Semastestatic ng_shutdown_t ng_UI_shutdown; 75271880Semastestatic ng_newhook_t ng_UI_newhook; 76271880Semastestatic ng_rcvdata_t ng_UI_rcvdata; 77271880Semastestatic ng_disconnect_t ng_UI_disconnect; 78271880Semaste 79271880Semaste/* Node type descriptor */ 80271880Semastestatic struct ng_type typestruct = { 81271880Semaste .version = NG_ABI_VERSION, 82264095Semaste .name = NG_UI_NODE_TYPE, 83264095Semaste .constructor = ng_UI_constructor, 84264095Semaste .rcvmsg = ng_UI_rcvmsg, 85264095Semaste .shutdown = ng_UI_shutdown, 86264095Semaste .newhook = ng_UI_newhook, 87264095Semaste .rcvdata = ng_UI_rcvdata, 88264095Semaste .disconnect = ng_UI_disconnect, 89264095Semaste}; 90264095SemasteNETGRAPH_INIT(UI, &typestruct); 91264095Semaste 92264095Semaste/************************************************************************ 93264095Semaste NETGRAPH NODE STUFF 94264095Semaste ************************************************************************/ 95264095Semaste 96264095Semaste/* 97264095Semaste * Create a newborn node. We start with an implicit reference. 98264095Semaste */ 99264095Semaste 100264095Semastestatic int 101264095Semasteng_UI_constructor(node_p node) 102264095Semaste{ 103264095Semaste priv_p priv; 104264095Semaste 105264095Semaste /* Allocate private structure */ 106264095Semaste priv = malloc(sizeof(*priv), M_NETGRAPH, M_WAITOK | M_ZERO); 107264095Semaste NG_NODE_SET_PRIVATE(node, priv); 108264095Semaste return (0); 109264095Semaste} 110264095Semaste 111264095Semaste/* 112264095Semaste * Give our ok for a hook to be added 113264095Semaste */ 114264095Semastestatic int 115264095Semasteng_UI_newhook(node_p node, hook_p hook, const char *name) 116264095Semaste{ 117264095Semaste const priv_p priv = NG_NODE_PRIVATE(node); 118264095Semaste 119264095Semaste if (!strcmp(name, NG_UI_HOOK_DOWNSTREAM)) { 120264095Semaste if (priv->downlink) 121264095Semaste return (EISCONN); 122264095Semaste priv->downlink = hook; 123264095Semaste } else if (!strcmp(name, NG_UI_HOOK_UPSTREAM)) { 124264095Semaste if (priv->uplink) 125264095Semaste return (EISCONN); 126264095Semaste priv->uplink = hook; 127264095Semaste } else 128264095Semaste return (EINVAL); 129264095Semaste return (0); 130264095Semaste} 131264095Semaste 132264095Semaste/* 133264095Semaste * Receive a control message 134264095Semaste */ 135264095Semastestatic int 136264095Semasteng_UI_rcvmsg(node_p node, item_p item, hook_p lasthook) 137264095Semaste{ 138264095Semaste int error; 139264095Semaste const priv_p priv = NG_NODE_PRIVATE(node); 140264095Semaste struct ng_mesg *msg; 141264095Semaste 142264095Semaste msg = NGI_MSG(item); /* only peeking */ 143264095Semaste if ((msg->header.typecookie == NGM_FLOW_COOKIE) && lasthook) { 144264095Semaste if (lasthook == priv->downlink) { 145264095Semaste if (priv->uplink) { 146264095Semaste NG_FWD_ITEM_HOOK(error, item, priv->uplink); 147264095Semaste return (error); 148264095Semaste } 149264095Semaste } else { 150264095Semaste if (priv->downlink) { 151264095Semaste NG_FWD_ITEM_HOOK(error, item, priv->downlink); 152264095Semaste return (error); 153264095Semaste } 154264095Semaste } 155264095Semaste } 156264095Semaste 157264095Semaste NG_FREE_ITEM(item); 158264095Semaste return (EINVAL); 159264095Semaste} 160264095Semaste 161264095Semaste#define MAX_ENCAPS_HDR 1 162264095Semaste#define ERROUT(x) do { error = (x); goto done; } while (0) 163264095Semaste 164264095Semaste/* 165264095Semaste * Receive a data frame 166264095Semaste */ 167264095Semastestatic int 168264095Semasteng_UI_rcvdata(hook_p hook, item_p item) 169264095Semaste{ 170264095Semaste const node_p node = NG_HOOK_NODE(hook); 171264095Semaste const priv_p priv = NG_NODE_PRIVATE(node); 172264095Semaste struct mbuf *m; 173264095Semaste int error = 0; 174264095Semaste 175264095Semaste NGI_GET_M(item, m); 176264095Semaste if (hook == priv->downlink) { 177264095Semaste u_char *start, *ptr; 178264095Semaste 179264095Semaste if (m->m_len < MAX_ENCAPS_HDR 180264095Semaste && !(m = m_pullup(m, MAX_ENCAPS_HDR))) 181264095Semaste ERROUT(ENOBUFS); 182264095Semaste ptr = start = mtod(m, u_char *); 183264095Semaste 184264095Semaste /* Must be UI frame */ 185264095Semaste if (*ptr++ != HDLC_UI) 186264095Semaste ERROUT(0); 187264095Semaste 188264095Semaste m_adj(m, ptr - start); 189264095Semaste NG_FWD_NEW_DATA(error, item, priv->uplink, m); /* m -> NULL */ 190264095Semaste } else if (hook == priv->uplink) { 191264095Semaste M_PREPEND(m, 1, M_NOWAIT); /* Prepend IP NLPID */ 192264095Semaste if (!m) 193264095Semaste ERROUT(ENOBUFS); 194264095Semaste mtod(m, u_char *)[0] = HDLC_UI; 195264095Semaste NG_FWD_NEW_DATA(error, item, priv->downlink, m); /* m -> NULL */ 196264095Semaste } else 197264095Semaste panic("%s", __func__); 198264095Semaste 199264095Semastedone: 200264095Semaste NG_FREE_M(m); /* does nothing if m == NULL */ 201264095Semaste if (item) 202264095Semaste NG_FREE_ITEM(item); 203264095Semaste return (error); 204264095Semaste} 205264095Semaste 206264095Semaste/* 207264095Semaste * Shutdown node 208264095Semaste */ 209264095Semastestatic int 210264095Semasteng_UI_shutdown(node_p node) 211264095Semaste{ 212264095Semaste const priv_p priv = NG_NODE_PRIVATE(node); 213264095Semaste 214264095Semaste /* Take down netgraph node */ 215264095Semaste free(priv, M_NETGRAPH); 216264095Semaste NG_NODE_SET_PRIVATE(node, NULL); 217264095Semaste NG_NODE_UNREF(node); 218264095Semaste return (0); 219264095Semaste} 220264095Semaste 221264095Semaste/* 222264095Semaste * Hook disconnection 223264095Semaste */ 224264095Semastestatic int 225264095Semasteng_UI_disconnect(hook_p hook) 226264095Semaste{ 227264095Semaste const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); 228264095Semaste 229264095Semaste if (hook == priv->downlink) 230264095Semaste priv->downlink = NULL; 231264095Semaste else if (hook == priv->uplink) 232264095Semaste priv->uplink = NULL; 233264095Semaste else 234264095Semaste panic("%s", __func__); 235264095Semaste /* 236264095Semaste * If we are not already shutting down, 237264095Semaste * and we have no more hooks, then DO shut down. 238264095Semaste */ 239264095Semaste if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) 240264095Semaste && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) { 241264095Semaste ng_rmnode_self(NG_HOOK_NODE(hook)); 242264095Semaste } 243264095Semaste return (0); 244264095Semaste} 245264095Semaste 246264095Semaste