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

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: 
1.1.1.3 ! misho      54:   const struct phystype *gPhysTypes[] = {
1.1       misho      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: {
1.1.1.3 ! misho     249:   const struct phystype *pt = l->type;
1.1       misho     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: {
1.1.1.3 ! misho     263:   const struct phystype *pt = l->type;
1.1       misho     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: {
1.1.1.3 ! misho     275:     const struct phystype *pt = l->type;
1.1       misho     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: {
1.1.1.3 ! misho     290:     const struct phystype *pt = l->type;
1.1       misho     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: {
1.1.1.3 ! misho     305:     const struct phystype *pt = l->type;
1.1       misho     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: {
1.1.1.3 ! misho     322:     const struct phystype *pt = l->type;
1.1       misho     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: {
1.1.1.3 ! misho     339:     const struct phystype *pt = l->type;
1.1       misho     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: {
1.1.1.3 ! misho     356:     const struct phystype *pt = l->type;
1.1       misho     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: {
1.1.1.3 ! misho     373:     const struct phystype *pt = l->type;
1.1       misho     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: {
1.1.1.3 ! misho     390:     const struct phystype *pt = l->type;
1.1       misho     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: {
1.1.1.3 ! misho     407:     const struct phystype *pt = l->type;
1.1       misho     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: {
1.1.1.3 ! misho     424:     const struct phystype *pt = l->type;
1.1       misho     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: {
1.1.1.3 ! misho     458:     const struct phystype *pt = l->type;
1.1       misho     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: /*
1.1.1.2   misho     469:  * PhysGetMtu()
                    470:  */
                    471: 
                    472: u_short
                    473: PhysGetMtu(Link l, int conf)
                    474: {
1.1.1.3 ! misho     475:     const struct phystype *pt = l->type;
1.1.1.2   misho     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: {
1.1.1.3 ! misho     498:     const struct phystype *pt = l->type;
1.1.1.2   misho     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: /*
1.1       misho     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: {
1.1.1.3 ! misho     535:     const struct phystype *pt = l->type;
1.1       misho     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: {
1.1.1.3 ! misho     550:   const struct phystype *pt;
1.1       misho     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
1.1.1.3 ! misho     618: PhysStat(Context ctx, int ac, const char *const av[], const void *arg)
1.1       misho     619: {
                    620:     Link       const l = ctx->lnk;
                    621: 
1.1.1.3 ! misho     622:     (void)ac;
        !           623:     (void)av;
        !           624:     (void)arg;
        !           625: 
1.1       misho     626:     Printf("Device '%s' (%s)\r\n", l->name, (l->tmpl)?"template":"instance");
                    627:     Printf("\tType         : %s\r\n", l->type->name);
                    628:     if (!l->tmpl) {
                    629:        Printf("\tState        : %s\r\n", gPhysStateNames[l->state]);
                    630:        if (l->state == PHYS_STATE_UP)
                    631:            Printf("\tSession time : %ld seconds\r\n", (long int)(time(NULL) - l->last_up));
                    632:     }
                    633: 
                    634:     if (l->type->showstat)
                    635:        (*l->type->showstat)(ctx);
                    636:     return 0;
                    637: }
                    638: 

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