ng_UI.c revision 52419
152419Sjulian 252419Sjulian/* 352419Sjulian * ng_UI.c 452419Sjulian * 552419Sjulian * Copyright (c) 1996-1999 Whistle Communications, Inc. 652419Sjulian * All rights reserved. 752419Sjulian * 852419Sjulian * Subject to the following obligations and disclaimer of warranty, use and 952419Sjulian * redistribution of this software, in source or object code forms, with or 1052419Sjulian * without modifications are expressly permitted by Whistle Communications; 1152419Sjulian * provided, however, that: 1252419Sjulian * 1. Any and all reproductions of the source or object code must include the 1352419Sjulian * copyright notice above and the following disclaimer of warranties; and 1452419Sjulian * 2. No rights are granted, in any manner or form, to use Whistle 1552419Sjulian * Communications, Inc. trademarks, including the mark "WHISTLE 1652419Sjulian * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 1752419Sjulian * such appears in the above copyright notice or in the software. 1852419Sjulian * 1952419Sjulian * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 2052419Sjulian * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 2152419Sjulian * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 2252419Sjulian * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 2352419Sjulian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 2452419Sjulian * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 2552419Sjulian * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 2652419Sjulian * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 2752419Sjulian * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 2852419Sjulian * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 2952419Sjulian * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 3052419Sjulian * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 3152419Sjulian * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 3252419Sjulian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3352419Sjulian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3452419Sjulian * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 3552419Sjulian * OF SUCH DAMAGE. 3652419Sjulian * 3752419Sjulian * Author: Julian Elischer <julian@whistle.com> 3852419Sjulian * 3952419Sjulian * $FreeBSD: head/sys/netgraph/ng_UI.c 52419 1999-10-21 09:06:11Z julian $ 4052419Sjulian * $Whistle: ng_UI.c,v 1.11 1999/01/28 23:54:52 julian Exp $ 4152419Sjulian */ 4252419Sjulian 4352419Sjulian#include <sys/param.h> 4452419Sjulian#include <sys/systm.h> 4552419Sjulian#include <sys/errno.h> 4652419Sjulian#include <sys/kernel.h> 4752419Sjulian#include <sys/malloc.h> 4852419Sjulian#include <sys/mbuf.h> 4952419Sjulian#include <sys/conf.h> 5052419Sjulian#include <sys/errno.h> 5152419Sjulian#include <sys/socket.h> 5252419Sjulian#include <sys/syslog.h> 5352419Sjulian 5452419Sjulian#include <net/if.h> 5552419Sjulian#include <netinet/in.h> 5652419Sjulian#include <netinet/if_ether.h> 5752419Sjulian 5852419Sjulian#include <netgraph/ng_message.h> 5952419Sjulian#include <netgraph/netgraph.h> 6052419Sjulian#include <netgraph/ng_UI.h> 6152419Sjulian 6252419Sjulian/* 6352419Sjulian * DEFINITIONS 6452419Sjulian */ 6552419Sjulian 6652419Sjulian/* Everything, starting with sdlc on has defined UI as 0x03 */ 6752419Sjulian#define HDLC_UI 0x03 6852419Sjulian 6952419Sjulian/* Node private data */ 7052419Sjulianstruct private { 7152419Sjulian hook_p downlink; 7252419Sjulian hook_p uplink; 7352419Sjulian}; 7452419Sjuliantypedef struct private *priv_p; 7552419Sjulian 7652419Sjulian/* Netgraph node methods */ 7752419Sjulianstatic int ng_UI_constructor(node_p *nodep); 7852419Sjulianstatic int ng_UI_rcvmsg(node_p node, struct ng_mesg *msg, 7952419Sjulian const char *retaddr, struct ng_mesg **resp); 8052419Sjulianstatic int ng_UI_rmnode(node_p node); 8152419Sjulianstatic int ng_UI_newhook(node_p node, hook_p hook, const char *name); 8252419Sjulianstatic int ng_UI_rcvdata(hook_p hook, struct mbuf *m, meta_p meta); 8352419Sjulianstatic int ng_UI_disconnect(hook_p hook); 8452419Sjulian 8552419Sjulian/* Node type descriptor */ 8652419Sjulianstatic struct ng_type typestruct = { 8752419Sjulian NG_VERSION, 8852419Sjulian NG_UI_NODE_TYPE, 8952419Sjulian NULL, 9052419Sjulian ng_UI_constructor, 9152419Sjulian ng_UI_rcvmsg, 9252419Sjulian ng_UI_rmnode, 9352419Sjulian ng_UI_newhook, 9452419Sjulian NULL, 9552419Sjulian NULL, 9652419Sjulian ng_UI_rcvdata, 9752419Sjulian ng_UI_rcvdata, 9852419Sjulian ng_UI_disconnect 9952419Sjulian}; 10052419SjulianNETGRAPH_INIT(UI, &typestruct); 10152419Sjulian 10252419Sjulian/************************************************************************ 10352419Sjulian NETGRAPH NODE STUFF 10452419Sjulian ************************************************************************/ 10552419Sjulian 10652419Sjulian/* 10752419Sjulian * Create a newborn node. We start with an implicit reference. 10852419Sjulian */ 10952419Sjulian 11052419Sjulianstatic int 11152419Sjulianng_UI_constructor(node_p *nodep) 11252419Sjulian{ 11352419Sjulian priv_p priv; 11452419Sjulian int error; 11552419Sjulian 11652419Sjulian /* Allocate private structure */ 11752419Sjulian MALLOC(priv, priv_p, sizeof(*priv), M_NETGRAPH, M_WAITOK); 11852419Sjulian if (priv == NULL) 11952419Sjulian return (ENOMEM); 12052419Sjulian bzero(priv, sizeof(*priv)); 12152419Sjulian 12252419Sjulian /* Call generic node constructor */ 12352419Sjulian if ((error = ng_make_node_common(&typestruct, nodep))) { 12452419Sjulian FREE(priv, M_NETGRAPH); 12552419Sjulian return (error); 12652419Sjulian } 12752419Sjulian (*nodep)->private = priv; 12852419Sjulian 12952419Sjulian /* Done */ 13052419Sjulian return (0); 13152419Sjulian} 13252419Sjulian 13352419Sjulian/* 13452419Sjulian * Give our ok for a hook to be added 13552419Sjulian */ 13652419Sjulianstatic int 13752419Sjulianng_UI_newhook(node_p node, hook_p hook, const char *name) 13852419Sjulian{ 13952419Sjulian const priv_p priv = node->private; 14052419Sjulian 14152419Sjulian if (!strcmp(name, NG_UI_HOOK_DOWNSTREAM)) { 14252419Sjulian if (priv->downlink) 14352419Sjulian return (EISCONN); 14452419Sjulian priv->downlink = hook; 14552419Sjulian } else if (!strcmp(name, NG_UI_HOOK_UPSTREAM)) { 14652419Sjulian if (priv->uplink) 14752419Sjulian return (EISCONN); 14852419Sjulian priv->uplink = hook; 14952419Sjulian } else 15052419Sjulian return (EINVAL); 15152419Sjulian return (0); 15252419Sjulian} 15352419Sjulian 15452419Sjulian/* 15552419Sjulian * Receive a control message 15652419Sjulian */ 15752419Sjulianstatic int 15852419Sjulianng_UI_rcvmsg(node_p node, struct ng_mesg *msg, 15952419Sjulian const char *raddr, struct ng_mesg **rp) 16052419Sjulian{ 16152419Sjulian FREE(msg, M_NETGRAPH); 16252419Sjulian return (EINVAL); 16352419Sjulian} 16452419Sjulian 16552419Sjulian#define MAX_ENCAPS_HDR 1 16652419Sjulian#define ERROUT(x) do { error = (x); goto done; } while (0) 16752419Sjulian 16852419Sjulian/* 16952419Sjulian * Receive a data frame 17052419Sjulian */ 17152419Sjulianstatic int 17252419Sjulianng_UI_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) 17352419Sjulian{ 17452419Sjulian const node_p node = hook->node; 17552419Sjulian const priv_p priv = node->private; 17652419Sjulian int error = 0; 17752419Sjulian 17852419Sjulian if (hook == priv->downlink) { 17952419Sjulian u_char *start, *ptr; 18052419Sjulian 18152419Sjulian if (!m || !(m = m_pullup(m, MAX_ENCAPS_HDR))) 18252419Sjulian ERROUT(ENOBUFS); 18352419Sjulian ptr = start = mtod(m, u_char *); 18452419Sjulian 18552419Sjulian /* Must be UI frame */ 18652419Sjulian if (*ptr++ != HDLC_UI) 18752419Sjulian ERROUT(0); 18852419Sjulian 18952419Sjulian m_adj(m, ptr - start); 19052419Sjulian NG_SEND_DATA(error, priv->uplink, m, meta); /* m -> NULL */ 19152419Sjulian } else if (hook == priv->uplink) { 19252419Sjulian M_PREPEND(m, 1, M_DONTWAIT); /* Prepend IP NLPID */ 19352419Sjulian if (!m) 19452419Sjulian ERROUT(ENOBUFS); 19552419Sjulian mtod(m, u_char *)[0] = HDLC_UI; 19652419Sjulian NG_SEND_DATA(error, priv->downlink, m, meta); /* m -> NULL */ 19752419Sjulian } else 19852419Sjulian panic(__FUNCTION__); 19952419Sjulian 20052419Sjuliandone: 20152419Sjulian NG_FREE_DATA(m, meta); /* does nothing if m == NULL */ 20252419Sjulian return (error); 20352419Sjulian} 20452419Sjulian 20552419Sjulian/* 20652419Sjulian * Shutdown node 20752419Sjulian */ 20852419Sjulianstatic int 20952419Sjulianng_UI_rmnode(node_p node) 21052419Sjulian{ 21152419Sjulian const priv_p priv = node->private; 21252419Sjulian 21352419Sjulian /* Take down netgraph node */ 21452419Sjulian node->flags |= NG_INVALID; 21552419Sjulian ng_cutlinks(node); 21652419Sjulian ng_unname(node); 21752419Sjulian bzero(priv, sizeof(*priv)); 21852419Sjulian FREE(priv, M_NETGRAPH); 21952419Sjulian node->private = NULL; 22052419Sjulian ng_unref(node); 22152419Sjulian return (0); 22252419Sjulian} 22352419Sjulian 22452419Sjulian/* 22552419Sjulian * Hook disconnection 22652419Sjulian */ 22752419Sjulianstatic int 22852419Sjulianng_UI_disconnect(hook_p hook) 22952419Sjulian{ 23052419Sjulian const priv_p priv = hook->node->private; 23152419Sjulian 23252419Sjulian if (hook->node->numhooks == 0) 23352419Sjulian ng_rmnode(hook->node); 23452419Sjulian else if (hook == priv->downlink) 23552419Sjulian priv->downlink = NULL; 23652419Sjulian else if (hook == priv->uplink) 23752419Sjulian priv->uplink = NULL; 23852419Sjulian else 23952419Sjulian panic(__FUNCTION__); 24052419Sjulian return (0); 24152419Sjulian} 24252419Sjulian 243