Annotation of embedaddon/mpd/src/phys.c, revision 1.1

1.1     ! misho       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:  * PhysIsBusy()
        !           470:  *
        !           471:  * This returns 1 if link is busy
        !           472:  */
        !           473: 
        !           474: int
        !           475: PhysIsBusy(Link l)
        !           476: {
        !           477:     return (l->die || l->rep || l->state != PHYS_STATE_DOWN ||
        !           478:        l->lcp.fsm.state != ST_INITIAL || l->lcp.auth.acct_thread != NULL ||
        !           479:        (l->tmpl && (l->children >= l->conf.max_children || gChildren >= gMaxChildren)));
        !           480: }
        !           481: 
        !           482: /*
        !           483:  * PhysShutdown()
        !           484:  */
        !           485: 
        !           486: void
        !           487: PhysShutdown(Link l)
        !           488: {
        !           489:     PhysType   const pt = l->type;
        !           490: 
        !           491:     MsgUnRegister(&l->pmsgs);
        !           492: 
        !           493:     if (pt && pt->shutdown)
        !           494:        (*pt->shutdown)(l);
        !           495: }
        !           496: 
        !           497: /*
        !           498:  * PhysSetDeviceType()
        !           499:  */
        !           500: 
        !           501: void
        !           502: PhysSetDeviceType(Link l, char *typename)
        !           503: {
        !           504:   PhysType     pt;
        !           505:   int          k;
        !           506: 
        !           507:   /* Make sure device type not already set */
        !           508:   if (l->type) {
        !           509:     Log(LG_ERR, ("[%s] device type already set to %s",
        !           510:       l->name, l->type->name));
        !           511:     return;
        !           512:   }
        !           513: 
        !           514:   /* Locate type */
        !           515:   for (k = 0; (pt = gPhysTypes[k]); k++) {
        !           516:     if (!strcmp(pt->name, typename))
        !           517:       break;
        !           518:   }
        !           519:   if (pt == NULL) {
        !           520:     Log(LG_ERR, ("[%s] device type \"%s\" unknown", l->name, typename));
        !           521:     return;
        !           522:   }
        !           523:   l->type = pt;
        !           524: 
        !           525:   /* Initialize type specific stuff */
        !           526:   if ((l->type->init)(l) < 0) {
        !           527:     Log(LG_ERR, ("[%s] type \"%s\" initialization failed",
        !           528:       l->name, l->type->name));
        !           529:     l->type = NULL;
        !           530:     return;
        !           531:   }
        !           532: }
        !           533: 
        !           534: /*
        !           535:  * PhysMsg()
        !           536:  */
        !           537: 
        !           538: static void
        !           539: PhysMsg(int type, void *arg)
        !           540: {
        !           541:     Link       const l = (Link)arg;
        !           542: 
        !           543:     if (l->dead) {
        !           544:        UNREF(l);
        !           545:        return;
        !           546:     }
        !           547:     Log(LG_PHYS2, ("[%s] device: %s event",
        !           548:        l->name, MsgName(type)));
        !           549:     switch (type) {
        !           550:     case MSG_OPEN:
        !           551:        l->downReasonValid=0;
        !           552:         if (l->rep && l->state == PHYS_STATE_UP) {
        !           553:            PhysUp(l);
        !           554:            break;
        !           555:        }
        !           556:         (*l->type->open)(l);
        !           557:         break;
        !           558:     case MSG_CLOSE:
        !           559:         (*l->type->close)(l);
        !           560:         break;
        !           561:     default:
        !           562:         assert(FALSE);
        !           563:     }
        !           564:     UNREF(l);
        !           565: }
        !           566: 
        !           567: /*
        !           568:  * PhysStat()
        !           569:  */
        !           570: 
        !           571: int
        !           572: PhysStat(Context ctx, int ac, char *av[], void *arg)
        !           573: {
        !           574:     Link       const l = ctx->lnk;
        !           575: 
        !           576:     Printf("Device '%s' (%s)\r\n", l->name, (l->tmpl)?"template":"instance");
        !           577:     Printf("\tType         : %s\r\n", l->type->name);
        !           578:     if (!l->tmpl) {
        !           579:        Printf("\tState        : %s\r\n", gPhysStateNames[l->state]);
        !           580:        if (l->state == PHYS_STATE_UP)
        !           581:            Printf("\tSession time : %ld seconds\r\n", (long int)(time(NULL) - l->last_up));
        !           582:     }
        !           583: 
        !           584:     if (l->type->showstat)
        !           585:        (*l->type->showstat)(ctx);
        !           586:     return 0;
        !           587: }
        !           588: 

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