/*
* ng.c
*
* Written by Archie Cobbs <archie@freebsd.org>
* 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 <netgraph/ng_message.h>
#ifdef __DragonFly__
#include <netgraph/socket/ng_socket.h>
#else
#include <netgraph/ng_socket.h>
#endif
#include <netgraph.h>
/*
* DEFINITIONS
*/
#define NG_MTU 1600
#define NG_MRU 1600
#define NG_REOPEN_PAUSE 5
struct nginfo {
char path[NG_PATHLEN + 1]; /* Node that takes PPP frames */
char hook[NG_HOOKLEN + 1]; /* Hook on that node */
};
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(Context ctx);
static int NgSetCommand(Context ctx, int ac, char *av[], void *arg);
static int NgIsSync(PhysInfo p);
static int NgPeerAddr(PhysInfo p, void *buf, int buf_len);
/*
* GLOBAL VARIABLES
*/
const struct phystype gNgPhysType = {
.name = "ng",
.minReopenDelay = NG_REOPEN_PAUSE,
.mtu = NG_MTU,
.mru = NG_MRU,
.init = NgInit,
.open = NgOpen,
.close = NgClose,
.showstat = NgStat,
.issync = NgIsSync,
.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 path[NG_PATHLEN + 1];
int csock = -1;
struct ngm_connect cn;
if (!PhysGetUpperHook(p, path, cn.ourhook)) {
Log(LG_PHYS, ("[%s] NG: can't get upper hook", p->name));
goto fail;
}
/* Get a temporary netgraph socket node */
if (NgMkSockNode(NULL, &csock, NULL) == -1) {
Log(LG_ERR, ("[%s] NG: NgMkSockNode: %s",
p->name, strerror(errno)));
goto fail;
}
snprintf(cn.path, sizeof(cn.path), "%s", ng->path);
snprintf(cn.peerhook, sizeof(cn.peerhook), "%s", ng->hook);
if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, NGM_CONNECT, &cn, sizeof(cn)) < 0) {
Log(LG_ERR, ("[%s] NG: can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\": %s",
p->name, path, cn.ourhook, cn.path, cn.peerhook, strerror(errno)));
goto fail;
}
close(csock);
p->state = PHYS_STATE_UP;
PhysUp(p);
return;
fail:
if (csock>=0) {
close(csock);
csock = -1;
}
p->state = PHYS_STATE_DOWN;
PhysDown(p, STR_CON_FAILED0, NULL);
}
/*
* NgClose()
*/
static void
NgClose(PhysInfo p)
{
NgInfo const ng = (NgInfo) p->info;
int csock = -1;
/* Get a temporary netgraph socket node */
if (NgMkSockNode(NULL, &csock, NULL) == -1) {
Log(LG_ERR, ("[%s] NG: NgMkSockNode: %s",
p->name, strerror(errno)));
goto fail;
}
NgFuncDisconnect(csock, p->name, ng->path, ng->hook);
close(csock);
/* FALL */
fail:
p->state = PHYS_STATE_DOWN;
PhysDown(p, 0, NULL);
}
/*
* NgStat()
*/
void
NgStat(Context ctx)
{
NgInfo const ng = (NgInfo) ctx->phys->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(Context ctx, int ac, char *av[], void *arg)
{
NgInfo const ng = (NgInfo) ctx->phys->info;
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);
}
/*
* NgIsSync()
*/
static int
NgIsSync(PhysInfo p)
{
return (1);
}
/*
* 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);
}
syntax highlighted by Code2HTML, v. 0.9.1