/* * ng.c * * Written by Archie Cobbs * Copyright (c) 1995-1999 Whistle Communications, Inc. All rights reserved. * See ``COPYRIGHT.whistle'' */ #include "ppp.h" #include "ng.h" #include "phys.h" #include "ngfunc.h" #include "log.h" #include #ifdef __DragonFly__ #include #else #include #endif #include /* * DEFINITIONS */ #define NG_MTU 1600 #define NG_MRU 1600 #define NG_REOPEN_PAUSE 5 #define MAX_PATH 64 /* XXX should be NG_PATHLEN */ struct nginfo { char path[MAX_PATH + 1]; /* Node that takes PPP frames */ char hook[NG_HOOKLEN + 1]; /* Hook on that node */ u_int ok:1; /* Netgraph nodes are setup */ }; typedef struct nginfo *NgInfo; /* Set menu options */ enum { SET_NODE, SET_HOOK, }; /* * INTERNAL FUNCTIONS */ static int NgInit(PhysInfo p); static void NgOpen(PhysInfo p); static void NgClose(PhysInfo p); static void NgStat(PhysInfo p); static int NgSetCommand(int ac, char *av[], void *arg); static int NgPeerAddr(PhysInfo p, void *buf, int buf_len); /* * GLOBAL VARIABLES */ const struct phystype gNgPhysType = { .name = "ng", .synchronous = TRUE, .minReopenDelay = NG_REOPEN_PAUSE, .mtu = NG_MTU, .mru = NG_MRU, .init = NgInit, .open = NgOpen, .close = NgClose, .showstat = NgStat, .peeraddr = NgPeerAddr, .callingnum = NULL, .callednum = NULL, }; const struct cmdtab NgSetCmds[] = { { "node path", "Set node to attach to", NgSetCommand, NULL, (void *) SET_NODE }, { "hook hook", "Set hook to attach to", NgSetCommand, NULL, (void *) SET_HOOK }, { NULL }, }; /* * NgInit() * * Initialize device-specific data in physical layer info */ static int NgInit(PhysInfo p) { NgInfo ng; /* Allocate private struct */ ng = (NgInfo) (p->info = Malloc(MB_PHYS, sizeof(*ng))); snprintf(ng->path, sizeof(ng->path), "undefined:"); snprintf(ng->hook, sizeof(ng->hook), "undefined"); /* Done */ return(0); } /* * NgOpen() */ static void NgOpen(PhysInfo p) { NgInfo const ng = (NgInfo) p->info; char linkHook[NG_HOOKLEN + 1]; snprintf(linkHook, sizeof(linkHook), "%s%d", NG_PPP_HOOK_LINK_PREFIX, lnk->bundleIndex); if (NgFuncConnect(MPD_HOOK_PPP, linkHook, ng->path, ng->hook) < 0) { p->state = PHYS_STATE_DOWN; PhysDown(STR_CON_FAILED0, NULL); } else { p->state = PHYS_STATE_UP; PhysUp(); } } /* * NgClose() */ static void NgClose(PhysInfo p) { NgInfo const ng = (NgInfo) p->info; NgFuncDisconnect(ng->path, ng->hook); p->state = PHYS_STATE_DOWN; PhysDown(0, NULL); } /* * NgStat() */ void NgStat(PhysInfo p) { NgInfo const ng = (NgInfo) p->info; Printf("Netgraph node configuration:\r\n"); Printf("\tNode : %s\r\n", ng->path); Printf("\tHook : %s\r\n", ng->hook); } /* * NgSetCommand() */ static int NgSetCommand(int ac, char *av[], void *arg) { NgInfo const ng = (NgInfo) lnk->phys->info; if (lnk->phys->type != &gNgPhysType) { Log(LG_ERR, ("[%s] link type is not netgraph!", lnk->name)); return(0); } switch ((intptr_t)arg) { case SET_NODE: if (ac != 1) return(-1); snprintf(ng->path, sizeof(ng->path), "%s", av[0]); break; case SET_HOOK: if (ac != 1) return(-1); snprintf(ng->hook, sizeof(ng->hook), "%s", av[0]); break; default: assert(0); } return(0); } /* * NgPeerAddr() */ static int NgPeerAddr(PhysInfo p, void *buf, int buf_len) { NgInfo const ng = (NgInfo) p->info; if (buf_len < sizeof(ng->path)) return(-1); memcpy(buf, ng->path, sizeof(ng->path)); return(0); }