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>