Annotation of embedaddon/mpd/src/phys.c, revision 1.1.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>