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>