File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / phys.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Nov 1 09:56:12 2016 UTC (7 years, 8 months ago) by misho
Branches: mpd, MAIN
CVS tags: v5_8p7, v5_8p1_cross, v5_8p1, v5_8, HEAD
mpd 5.8

    1: 
    2: /*
    3:  * phys.c
    4:  *
    5:  * Written by Archie Cobbs <archie@freebsd.org>
    6:  * Copyright (c) 1995-1999 Whistle Communications, Inc. All rights reserved.
    7:  * See ``COPYRIGHT.whistle''
    8:  */
    9: 
   10: #include "ppp.h"
   11: #include "msg.h"
   12: #include "link.h"
   13: #include "devices.h"
   14: #include "util.h"
   15: 
   16: #include <netgraph/ng_tee.h>
   17: 
   18: /*
   19:  * The physical layer has four states: DOWN, OPENING, CLOSING, and UP.
   20:  * Each device type must implement this set of standard methods:
   21:  *
   22:  *  init	Called once for each device to initialize it.
   23:  *  open	Called in the DOWN state to initiate connection.
   24:  *		Device should eventually call PhysUp() or PhysDown().
   25:  *  close	Called in the OPENING or UP states.
   26:  *		Device should eventually call PhysDown().
   27:  *  update	Called when LCP reaches the UP state. Device should
   28:  *		update its configuration based on LCP negotiated
   29:  *		settings, if necessary.
   30:  *  showstat	Display device statistics.
   31:  *
   32:  * The device should generate UP and DOWN events in response to OPEN
   33:  * and CLOSE events. If the device goes down suddenly after being OPEN,
   34:  * the close method will not be explicitly called to clean up.
   35:  *
   36:  * All device types must support MRU's of at least 1500.
   37:  *
   38:  * Each device is responsible for connecting the appropriate netgraph
   39:  * node to the PPP node when the link comes up, and disconnecting it
   40:  * when the link goes down (or is closed). The device should NOT send
   41:  * any NGM_PPP_SET_CONFIG messsages to the ppp node.
   42:  */
   43: 
   44: /*
   45:  * INTERNAL FUNCTIONS
   46:  */
   47: 
   48:   static void	PhysMsg(int type, void *arg);
   49: 
   50: /*
   51:  * GLOBAL VARIABLES
   52:  */
   53: 
   54:   const PhysType gPhysTypes[] = {
   55: #define _WANT_DEVICE_TYPES
   56: #include "devices.h"
   57:     NULL,
   58:   };
   59: 
   60:   const char *gPhysStateNames[] = {
   61:     "DOWN",
   62:     "CONNECTING",
   63:     "READY",
   64:     "UP",
   65:   };
   66: 
   67: int
   68: PhysInit(Link l)
   69: {
   70:     MsgRegister(&l->pmsgs, PhysMsg);
   71: 
   72:     /* Initialize type specific stuff */
   73:     if ((l->type->init)(l) < 0) {
   74: 	Log(LG_ERR, ("[%s] type \"%s\" initialization failed",
   75:     	    l->name, l->type->name));
   76: 	l->type = NULL;
   77: 	return (0);
   78:     }
   79: 
   80:     return (0);
   81: }
   82: 
   83: /*
   84:  * PhysInst()
   85:  */
   86: 
   87: int
   88: PhysInst(Link l, Link lt)
   89: {
   90:     return ((l->type->inst)(l, lt));
   91: }
   92: 
   93: /*
   94:  * PhysOpenCmd()
   95:  */
   96: 
   97: int
   98: PhysOpenCmd(Context ctx)
   99: {
  100:     if (ctx->lnk->tmpl)
  101: 	Error("impossible to open template");
  102:     RecordLinkUpDownReason(NULL, ctx->lnk, 1, STR_MANUALLY, NULL);
  103:     PhysOpen(ctx->lnk);
  104:     return (0);
  105: }
  106: 
  107: /*
  108:  * PhysOpen()
  109:  */
  110: 
  111: void
  112: PhysOpen(Link l)
  113: {
  114:     REF(l);
  115:     MsgSend(&l->pmsgs, MSG_OPEN, l);
  116: }
  117: 
  118: /*
  119:  * PhysCloseCmd()
  120:  */
  121: 
  122: int
  123: PhysCloseCmd(Context ctx)
  124: {
  125:     if (ctx->lnk->tmpl)
  126: 	Error("impossible to close template");
  127:     RecordLinkUpDownReason(NULL, ctx->lnk, 0, STR_MANUALLY, NULL);
  128:     PhysClose(ctx->lnk);
  129:     return (0);
  130: }
  131: 
  132: /*
  133:  * PhysClose()
  134:  */
  135: 
  136: void
  137: PhysClose(Link l)
  138: {
  139:     REF(l);
  140:     MsgSend(&l->pmsgs, MSG_CLOSE, l);
  141: }
  142: 
  143: /*
  144:  * PhysUp()
  145:  */
  146: 
  147: void
  148: PhysUp(Link l)
  149: {
  150:     Log(LG_PHYS2, ("[%s] device: UP event", l->name));
  151:     l->last_up = time(NULL);
  152:     if (!l->rep) {
  153: 	LinkUp(l);
  154:     } else {
  155: 	RepUp(l);
  156:     }
  157: }
  158: 
  159: /*
  160:  * PhysDown()
  161:  */
  162: 
  163: void
  164: PhysDown(Link l, const char *reason, const char *details)
  165: {
  166:     Log(LG_PHYS2, ("[%s] device: DOWN event", l->name));
  167:     if (!l->rep) {
  168: 	RecordLinkUpDownReason(NULL, l, 0, reason, details);
  169: 	l->upReasonValid=0;
  170: 	LinkDown(l);
  171: 	LinkShutdownCheck(l, l->lcp.fsm.state);
  172: 
  173:     } else {
  174: 	RepDown(l);
  175:     }
  176: }
  177: 
  178: /*
  179:  * PhysIncoming()
  180:  */
  181: 
  182: void
  183: PhysIncoming(Link l)
  184: {
  185:     const char	*rept;
  186:     
  187:     rept = LinkMatchAction(l, 1, NULL);
  188:     if (rept) {
  189: 	if (strcmp(rept,"##DROP##") == 0) {
  190: 	    /* Action told we must drop this connection */
  191: 	    Log(LG_PHYS, ("[%s] Drop connection", l->name));
  192: 	    PhysClose(l);
  193: 	    return;
  194: 	}
  195: 	if (RepCreate(l, rept)) {
  196: 	    Log(LG_ERR, ("[%s] Repeater to \"%s\" creation error", l->name, rept));
  197: 	    PhysClose(l);
  198: 	    return;
  199: 	}
  200:     }
  201: 
  202:     if (!l->rep) {
  203: 	RecordLinkUpDownReason(NULL, l, 1, STR_INCOMING_CALL, NULL);
  204: 	LinkOpen(l);
  205:     } else {
  206:         RepIncoming(l);
  207:     }
  208: }
  209: 
  210: /*
  211:  * PhysSetAccm()
  212:  */
  213: 
  214: int
  215: PhysSetAccm(Link l, uint32_t xmit, u_int32_t recv)
  216: {
  217:     if (l->type && l->type->setaccm)
  218: 	return (*l->type->setaccm)(l, xmit, recv);
  219:     else 
  220: 	return (0);
  221: }
  222: 
  223: /*
  224:  * PhysGetUpperHook()
  225:  */
  226: 
  227: int
  228: PhysGetUpperHook(Link l, char *path, char *hook)
  229: {
  230:     if (!l->rep) {
  231: 	snprintf(path, NG_PATHSIZ, "[%lx]:", (u_long)l->nodeID);
  232: 	strcpy(hook, NG_TEE_HOOK_LEFT);
  233: 	return 1;
  234:     } else {
  235: 	return RepGetHook(l, path, hook);
  236:     }
  237:     return 0;
  238: }
  239: 
  240: /*
  241:  * PhysGetOriginate()
  242:  *
  243:  * This returns one of LINK_ORIGINATE_{UNKNOWN, LOCAL, REMOTE}
  244:  */
  245: 
  246: int
  247: PhysGetOriginate(Link l)
  248: {
  249:   PhysType	const pt = l->type;
  250: 
  251:   return((pt && pt->originate) ? (*pt->originate)(l) : LINK_ORIGINATE_UNKNOWN);
  252: }
  253: 
  254: /*
  255:  * PhysIsSync()
  256:  *
  257:  * This returns 1 if link is synchronous
  258:  */
  259: 
  260: int
  261: PhysIsSync(Link l)
  262: {
  263:   PhysType	const pt = l->type;
  264: 
  265:   return((pt && pt->issync) ? (*pt->issync)(l) : 0);
  266: }
  267: 
  268: /*
  269:  * PhysSetCalledNum()
  270:  */
  271: 
  272: int
  273: PhysSetCallingNum(Link l, char *buf)
  274: {
  275:     PhysType	const pt = l->type;
  276: 
  277:     if (pt && pt->setcallingnum)
  278: 	return ((*pt->setcallingnum)(l, buf));
  279:     else
  280: 	return (0);
  281: }
  282: 
  283: /*
  284:  * PhysSetCalledNum()
  285:  */
  286: 
  287: int
  288: PhysSetCalledNum(Link l, char *buf)
  289: {
  290:     PhysType	const pt = l->type;
  291: 
  292:     if (pt && pt->setcallednum)
  293: 	return ((*pt->setcallednum)(l, buf));
  294:     else
  295: 	return (0);
  296: }
  297: 
  298: /*
  299:  * PhysGetSelfName()
  300:  */
  301: 
  302: int
  303: PhysGetSelfName(Link l, char *buf, size_t buf_len)
  304: {
  305:     PhysType	const pt = l->type;
  306: 
  307:     buf[0] = 0;
  308: 
  309:     if (pt && pt->selfname)
  310: 	return ((*pt->selfname)(l, buf, buf_len));
  311:     else
  312: 	return (0);
  313: }
  314: 
  315: /*
  316:  * PhysGetPeerName()
  317:  */
  318: 
  319: int
  320: PhysGetPeerName(Link l, char *buf, size_t buf_len)
  321: {
  322:     PhysType	const pt = l->type;
  323: 
  324:     buf[0] = 0;
  325: 
  326:     if (pt && pt->peername)
  327: 	return ((*pt->peername)(l, buf, buf_len));
  328:     else
  329: 	return (0);
  330: }
  331: 
  332: /*
  333:  * PhysGetSelfAddr()
  334:  */
  335: 
  336: int
  337: PhysGetSelfAddr(Link l, char *buf, size_t buf_len)
  338: {
  339:     PhysType	const pt = l->type;
  340: 
  341:     buf[0] = 0;
  342: 
  343:     if (pt && pt->selfaddr)
  344: 	return ((*pt->selfaddr)(l, buf, buf_len));
  345:     else
  346: 	return (0);
  347: }
  348: 
  349: /*
  350:  * PhysGetPeerAddr()
  351:  */
  352: 
  353: int
  354: PhysGetPeerAddr(Link l, char *buf, size_t buf_len)
  355: {
  356:     PhysType	const pt = l->type;
  357: 
  358:     buf[0] = 0;
  359: 
  360:     if (pt && pt->peeraddr)
  361: 	return ((*pt->peeraddr)(l, buf, buf_len));
  362:     else
  363: 	return (0);
  364: }
  365: 
  366: /*
  367:  * PhysGetPeerPort()
  368:  */
  369: 
  370: int
  371: PhysGetPeerPort(Link l, char *buf, size_t buf_len)
  372: {
  373:     PhysType	const pt = l->type;
  374: 
  375:     buf[0] = 0;
  376: 
  377:     if (pt && pt->peerport)
  378: 	return ((*pt->peerport)(l, buf, buf_len));
  379:     else
  380: 	return (0);
  381: }
  382: 
  383: /*
  384:  * PhysGetPeerMacAddr()
  385:  */
  386: 
  387: int
  388: PhysGetPeerMacAddr(Link l, char *buf, size_t buf_len)
  389: {
  390:     PhysType	const pt = l->type;
  391: 
  392:     buf[0] = 0;
  393: 
  394:     if (pt && pt->peermacaddr)
  395: 	return ((*pt->peermacaddr)(l, buf, buf_len));
  396:     else
  397: 	return (0);
  398: }
  399: 
  400: /*
  401:  * PhysGetPeerIface()
  402:  */
  403: 
  404: int
  405: PhysGetPeerIface(Link l, char *buf, size_t buf_len)
  406: {
  407:     PhysType	const pt = l->type;
  408: 
  409:     buf[0] = 0;
  410: 
  411:     if (pt && pt->peeriface)
  412: 	return ((*pt->peeriface)(l, buf, buf_len));
  413:     else
  414: 	return (0);
  415: }
  416: 
  417: /*
  418:  * PhysGetCallingNum()
  419:  */
  420: 
  421: int
  422: PhysGetCallingNum(Link l, char *buf, size_t buf_len)
  423: {
  424:     PhysType	const pt = l->type;
  425: 
  426:     buf[0] = 0;
  427: 
  428:     if (pt) {
  429: 	/* For untrusted peers use peeraddr as calling */
  430: 	if (Enabled(&l->conf.options, LINK_CONF_PEER_AS_CALLING) && pt->peeraddr)
  431: 	    (*pt->peeraddr)(l, buf, buf_len);
  432: 	else if (pt->callingnum)
  433: 	    (*pt->callingnum)(l, buf, buf_len);
  434: 	if (Enabled(&l->conf.options, LINK_CONF_REPORT_MAC)) {
  435: 	    char tmp[64];
  436: 	    strlcat(buf, " / ", buf_len);
  437: 	    if (pt->peermacaddr) {
  438: 		(*pt->peermacaddr)(l, tmp, sizeof(tmp));
  439: 		strlcat(buf, tmp, buf_len);
  440: 	    }
  441: 	    strlcat(buf, " / ", buf_len);
  442: 	    if (pt->peeriface) {
  443: 		(*pt->peeriface)(l, tmp, sizeof(tmp));
  444: 		strlcat(buf, tmp, buf_len);
  445: 	    }
  446: 	}
  447:     }
  448:     return (0);
  449: }
  450: 
  451: /*
  452:  * PhysGetCalledNum()
  453:  */
  454: 
  455: int
  456: PhysGetCalledNum(Link l, char *buf, size_t buf_len)
  457: {
  458:     PhysType	const pt = l->type;
  459: 
  460:     buf[0] = 0;
  461: 
  462:     if (pt && pt->callednum)
  463: 	return ((*pt->callednum)(l, buf, buf_len));
  464:     else
  465: 	return (0);
  466: }
  467: 
  468: /*
  469:  * PhysGetMtu()
  470:  */
  471: 
  472: u_short
  473: PhysGetMtu(Link l, int conf)
  474: {
  475:     PhysType	const pt = l->type;
  476: 
  477:     if (pt) {
  478: 	if (pt->getmtu)
  479: 	    return ((*pt->getmtu)(l, conf));
  480: 	if (conf == 0) {
  481: 	    if (pt->mtu)
  482: 		return (pt->mtu);
  483: 	    else
  484: 		return (0);
  485: 	} else
  486: 	    return (l->conf.mtu);
  487:     } else
  488: 	return (0);
  489: }
  490: 
  491: /*
  492:  * PhysGetMru()
  493:  */
  494: 
  495: u_short
  496: PhysGetMru(Link l, int conf)
  497: {
  498:     PhysType	const pt = l->type;
  499: 
  500:     if (pt) {
  501: 	if (pt->getmru)
  502: 	    return ((*pt->getmru)(l, conf));
  503: 	if (conf == 0) {
  504: 	    if (pt->mru)
  505: 		return (pt->mru);
  506: 	    else
  507: 		return (0);
  508: 	} else
  509: 	    return (l->conf.mru);
  510:     } else
  511: 	return (0);
  512: }
  513: 
  514: /*
  515:  * PhysIsBusy()
  516:  *
  517:  * This returns 1 if link is busy
  518:  */
  519: 
  520: int
  521: PhysIsBusy(Link l)
  522: {
  523:     return (l->die || l->rep || l->state != PHYS_STATE_DOWN ||
  524: 	l->lcp.fsm.state != ST_INITIAL || l->lcp.auth.acct_thread != NULL ||
  525: 	(l->tmpl && (l->children >= l->conf.max_children || gChildren >= gMaxChildren)));
  526: }
  527: 
  528: /*
  529:  * PhysShutdown()
  530:  */
  531: 
  532: void
  533: PhysShutdown(Link l)
  534: {
  535:     PhysType	const pt = l->type;
  536: 
  537:     MsgUnRegister(&l->pmsgs);
  538: 
  539:     if (pt && pt->shutdown)
  540: 	(*pt->shutdown)(l);
  541: }
  542: 
  543: /*
  544:  * PhysSetDeviceType()
  545:  */
  546: 
  547: void
  548: PhysSetDeviceType(Link l, char *typename)
  549: {
  550:   PhysType	pt;
  551:   int		k;
  552: 
  553:   /* Make sure device type not already set */
  554:   if (l->type) {
  555:     Log(LG_ERR, ("[%s] device type already set to %s",
  556:       l->name, l->type->name));
  557:     return;
  558:   }
  559: 
  560:   /* Locate type */
  561:   for (k = 0; (pt = gPhysTypes[k]); k++) {
  562:     if (!strcmp(pt->name, typename))
  563:       break;
  564:   }
  565:   if (pt == NULL) {
  566:     Log(LG_ERR, ("[%s] device type \"%s\" unknown", l->name, typename));
  567:     return;
  568:   }
  569:   l->type = pt;
  570: 
  571:   /* Initialize type specific stuff */
  572:   if ((l->type->init)(l) < 0) {
  573:     Log(LG_ERR, ("[%s] type \"%s\" initialization failed",
  574:       l->name, l->type->name));
  575:     l->type = NULL;
  576:     return;
  577:   }
  578: }
  579: 
  580: /*
  581:  * PhysMsg()
  582:  */
  583: 
  584: static void
  585: PhysMsg(int type, void *arg)
  586: {
  587:     Link	const l = (Link)arg;
  588: 
  589:     if (l->dead) {
  590: 	UNREF(l);
  591: 	return;
  592:     }
  593:     Log(LG_PHYS2, ("[%s] device: %s event",
  594: 	l->name, MsgName(type)));
  595:     switch (type) {
  596:     case MSG_OPEN:
  597:     	l->downReasonValid=0;
  598:         if (l->rep && l->state == PHYS_STATE_UP) {
  599: 	    PhysUp(l);
  600: 	    break;
  601: 	}
  602:         (*l->type->open)(l);
  603:         break;
  604:     case MSG_CLOSE:
  605:         (*l->type->close)(l);
  606:         break;
  607:     default:
  608:         assert(FALSE);
  609:     }
  610:     UNREF(l);
  611: }
  612: 
  613: /*
  614:  * PhysStat()
  615:  */
  616: 
  617: int
  618: PhysStat(Context ctx, int ac, char *av[], void *arg)
  619: {
  620:     Link	const l = ctx->lnk;
  621: 
  622:     Printf("Device '%s' (%s)\r\n", l->name, (l->tmpl)?"template":"instance");
  623:     Printf("\tType         : %s\r\n", l->type->name);
  624:     if (!l->tmpl) {
  625: 	Printf("\tState        : %s\r\n", gPhysStateNames[l->state]);
  626: 	if (l->state == PHYS_STATE_UP)
  627:     	    Printf("\tSession time : %ld seconds\r\n", (long int)(time(NULL) - l->last_up));
  628:     }
  629: 
  630:     if (l->type->showstat)
  631: 	(*l->type->showstat)(ctx);
  632:     return 0;
  633: }
  634: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>