Annotation of embedaddon/mpd/src/l2tp.c, revision 1.1.1.3
1.1 misho 1:
2: /*
3: * l2tp.c
4: *
5: * Written by Alexander Motin <mav@FreeBSD.org>
6: */
7:
8: #include "ppp.h"
9: #include "phys.h"
10: #include "mbuf.h"
11: #include "ngfunc.h"
12: #include "l2tp.h"
13: #include "l2tp_avp.h"
14: #include "l2tp_ctrl.h"
15: #include "log.h"
16: #include "util.h"
17:
18: #include <sys/types.h>
19: #ifdef NOLIBPDEL
20: #include "contrib/libpdel/util/ghash.h"
21: #else
22: #include <pdel/util/ghash.h>
23: #endif
24:
1.1.1.2 misho 25: #include <net/ethernet.h>
1.1 misho 26: #include <netgraph/ng_message.h>
27: #include <netgraph/ng_socket.h>
28: #include <netgraph/ng_ksocket.h>
29: #include <netgraph/ng_l2tp.h>
30: #include <netgraph.h>
1.1.1.3 ! misho 31: #include <fnmatch.h>
1.1 misho 32:
33: /*
34: * DEFINITIONS
35: */
36:
37: #define L2TP_MTU 1600
38: #define L2TP_MRU L2TP_MTU
39:
40: #define L2TP_PORT 1701
41:
42: #define L2TP_CALL_MIN_BPS 56000
43: #define L2TP_CALL_MAX_BPS 64000
44:
45: struct l2tp_server {
46: struct u_addr self_addr; /* self IP address */
47: in_port_t self_port; /* self port */
48: int refs;
49: int sock; /* server listen socket */
50: EventRef event; /* listen for data messages */
51: };
52:
53: struct l2tp_tun {
54: struct u_addr self_addr; /* self IP address */
55: struct u_addr peer_addr; /* peer IP address */
56: char peer_iface[IFNAMSIZ]; /* Peer iface */
57: u_char peer_mac_addr[6]; /* Peer MAC address */
58: in_port_t self_port; /* self port */
59: in_port_t peer_port; /* peer port */
60: u_char connected; /* control connection is connected */
61: u_char alive; /* control connection is not dying */
62: u_int active_sessions;/* number of calls in this sunnels */
63: struct ppp_l2tp_ctrl *ctrl; /* control connection for this tunnel */
64: };
65:
66: struct l2tpinfo {
67: struct {
68: struct u_addr self_addr; /* self IP address */
69: struct u_range peer_addr; /* Peer IP addresses allowed */
70: in_port_t self_port; /* self port */
71: in_port_t peer_port; /* Peer port required (or zero) */
72: struct optinfo options;
73: char callingnum[64]; /* L2TP phone number to use */
74: char callednum[64]; /* L2TP phone number to use */
75: char hostname[MAXHOSTNAMELEN]; /* L2TP local hostname */
76: char secret[64]; /* L2TP tunnel secret */
77: char *fqdn_peer_addr; /* FQDN Peer address */
1.1.1.3 ! misho 78: char *peer_mask; /* L2TP peer hostname mask */
1.1 misho 79: } conf;
80: u_char opened; /* L2TP opened by phys */
81: u_char incoming; /* Call is incoming vs. outgoing */
82: u_char outcall; /* incall or outcall */
83: u_char sync; /* sync or async call */
84: struct l2tp_server *server; /* server associated with link */
85: struct l2tp_tun *tun; /* tunnel associated with link */
86: struct ppp_l2tp_sess *sess; /* current session for this link */
87: char callingnum[64]; /* current L2TP phone number */
88: char callednum[64]; /* current L2TP phone number */
89: };
90: typedef struct l2tpinfo *L2tpInfo;
91:
92: /* Set menu options */
93: enum {
94: SET_SELFADDR,
95: SET_PEERADDR,
96: SET_CALLINGNUM,
97: SET_CALLEDNUM,
98: SET_HOSTNAME,
1.1.1.3 ! misho 99: SET_PEERMASK,
1.1 misho 100: SET_SECRET,
101: SET_ENABLE,
102: SET_DISABLE
103: };
104:
105: /* Binary options */
106: enum {
107: L2TP_CONF_OUTCALL, /* when originating, calls are "outgoing" */
108: L2TP_CONF_HIDDEN, /* enable AVP hidding */
109: L2TP_CONF_LENGTH, /* enable Length field in data packets */
110: L2TP_CONF_DATASEQ, /* enable sequence fields in data packets */
111: L2TP_CONF_RESOLVE_ONCE /* Only once resolve peer_addr */
112: };
113:
114: /*
115: * INTERNAL FUNCTIONS
116: */
117:
118: static int L2tpTInit(void);
119: static void L2tpTShutdown(void);
120: static int L2tpInit(Link l);
121: static int L2tpInst(Link l, Link lt);
122: static void L2tpOpen(Link l);
123: static void L2tpClose(Link l);
124: static void L2tpShutdown(Link l);
125: static void L2tpStat(Context ctx);
126: static int L2tpOriginated(Link l);
127: static int L2tpIsSync(Link l);
128: static int L2tpSetAccm(Link l, u_int32_t xmit, u_int32_t recv);
129: static int L2tpSelfName(Link l, void *buf, size_t buf_len);
130: static int L2tpPeerName(Link l, void *buf, size_t buf_len);
131: static int L2tpSelfAddr(Link l, void *buf, size_t buf_len);
132: static int L2tpPeerAddr(Link l, void *buf, size_t buf_len);
133: static int L2tpPeerPort(Link l, void *buf, size_t buf_len);
134: static int L2tpPeerMacAddr(Link l, void *buf, size_t buf_len);
135: static int L2tpPeerIface(Link l, void *buf, size_t buf_len);
136: static int L2tpCallingNum(Link l, void *buf, size_t buf_len);
137: static int L2tpCalledNum(Link l, void *buf, size_t buf_len);
138: static int L2tpSetCallingNum(Link l, void *buf);
139: static int L2tpSetCalledNum(Link l, void *buf);
140:
141: static void L2tpHookUp(Link l);
142: static void L2tpUnhook(Link l);
143:
144: static void L2tpNodeUpdate(Link l);
145: static int L2tpListen(Link l);
146: static void L2tpUnListen(Link l);
147: static int L2tpSetCommand(Context ctx, int ac, char *av[], void *arg);
148:
149: /* L2TP control callbacks */
150: static ppp_l2tp_ctrl_connected_t ppp_l2tp_ctrl_connected_cb;
151: static ppp_l2tp_ctrl_terminated_t ppp_l2tp_ctrl_terminated_cb;
152: static ppp_l2tp_ctrl_destroyed_t ppp_l2tp_ctrl_destroyed_cb;
153: static ppp_l2tp_initiated_t ppp_l2tp_initiated_cb;
154: static ppp_l2tp_connected_t ppp_l2tp_connected_cb;
155: static ppp_l2tp_terminated_t ppp_l2tp_terminated_cb;
156: static ppp_l2tp_set_link_info_t ppp_l2tp_set_link_info_cb;
157:
158: static const struct ppp_l2tp_ctrl_cb ppp_l2tp_server_ctrl_cb = {
159: ppp_l2tp_ctrl_connected_cb,
160: ppp_l2tp_ctrl_terminated_cb,
161: ppp_l2tp_ctrl_destroyed_cb,
162: ppp_l2tp_initiated_cb,
163: ppp_l2tp_connected_cb,
164: ppp_l2tp_terminated_cb,
165: ppp_l2tp_set_link_info_cb,
166: NULL,
167: };
168:
169: /*
170: * GLOBAL VARIABLES
171: */
172:
173: const struct phystype gL2tpPhysType = {
174: .name = "l2tp",
175: .descr = "Layer Two Tunneling Protocol",
176: .mtu = L2TP_MTU,
177: .mru = L2TP_MRU,
178: .tmpl = 1,
179: .tinit = L2tpTInit,
180: .tshutdown = L2tpTShutdown,
181: .init = L2tpInit,
182: .inst = L2tpInst,
183: .open = L2tpOpen,
184: .close = L2tpClose,
185: .update = L2tpNodeUpdate,
186: .shutdown = L2tpShutdown,
187: .showstat = L2tpStat,
188: .originate = L2tpOriginated,
189: .issync = L2tpIsSync,
190: .setaccm = L2tpSetAccm,
191: .setcallingnum = L2tpSetCallingNum,
192: .setcallednum = L2tpSetCalledNum,
193: .selfname = L2tpSelfName,
194: .peername = L2tpPeerName,
195: .selfaddr = L2tpSelfAddr,
196: .peeraddr = L2tpPeerAddr,
197: .peerport = L2tpPeerPort,
198: .peermacaddr = L2tpPeerMacAddr,
199: .peeriface = L2tpPeerIface,
200: .callingnum = L2tpCallingNum,
201: .callednum = L2tpCalledNum,
202: };
203:
204: const struct cmdtab L2tpSetCmds[] = {
205: { "self {ip} [{port}]", "Set local IP address",
206: L2tpSetCommand, NULL, 2, (void *) SET_SELFADDR },
207: { "peer {ip} [{port}]", "Set remote IP address",
208: L2tpSetCommand, NULL, 2, (void *) SET_PEERADDR },
209: { "callingnum {number}", "Set calling L2TP telephone number",
210: L2tpSetCommand, NULL, 2, (void *) SET_CALLINGNUM },
211: { "callednum {number}", "Set called L2TP telephone number",
212: L2tpSetCommand, NULL, 2, (void *) SET_CALLEDNUM },
213: { "hostname {name}", "Set L2TP local hostname",
214: L2tpSetCommand, NULL, 2, (void *) SET_HOSTNAME },
1.1.1.3 ! misho 215: { "pmask {mask}", "Set L2TP peer hostname mask",
! 216: L2tpSetCommand, NULL, 2, (void *) SET_PEERMASK },
1.1 misho 217: { "secret {sec}", "Set L2TP tunnel secret",
218: L2tpSetCommand, NULL, 2, (void *) SET_SECRET },
219: { "enable [opt ...]", "Enable option",
220: L2tpSetCommand, NULL, 2, (void *) SET_ENABLE },
221: { "disable [opt ...]", "Disable option",
222: L2tpSetCommand, NULL, 2, (void *) SET_DISABLE },
223: { NULL },
224: };
225:
226: /*
227: * INTERNAL VARIABLES
228: */
229:
230: static struct confinfo gConfList[] = {
231: { 0, L2TP_CONF_OUTCALL, "outcall" },
232: { 0, L2TP_CONF_HIDDEN, "hidden" },
233: { 0, L2TP_CONF_LENGTH, "length" },
234: { 0, L2TP_CONF_DATASEQ, "dataseq" },
235: { 0, L2TP_CONF_RESOLVE_ONCE, "resolve-once" },
236: { 0, 0, NULL },
237: };
238:
239: int L2tpListenUpdateSheduled = 0;
240: struct pppTimer L2tpListenUpdateTimer;
241:
242: struct ghash *gL2tpServers;
243: struct ghash *gL2tpTuns;
244: int one = 1;
245:
246: /*
247: * L2tpTInit()
248: */
249:
250: static int
251: L2tpTInit(void)
252: {
253: if ((gL2tpServers = ghash_create(NULL, 0, 0, MB_PHYS, NULL, NULL, NULL, NULL))
254: == NULL)
255: return(-1);
256: if ((gL2tpTuns = ghash_create(NULL, 0, 0, MB_PHYS, NULL, NULL, NULL, NULL))
257: == NULL)
258: return(-1);
259: return(0);
260: }
261:
262: /*
263: * L2tpTShutdown()
264: */
265:
266: static void
267: L2tpTShutdown(void)
268: {
269: struct ghash_walk walk;
270: struct l2tp_tun *tun;
271:
272: Log(LG_PHYS2, ("L2TP: Total shutdown"));
273: ghash_walk_init(gL2tpTuns, &walk);
274: while ((tun = ghash_walk_next(gL2tpTuns, &walk)) != NULL) {
275: if (tun->ctrl) {
276: if (tun->alive)
277: ppp_l2tp_ctrl_shutdown(tun->ctrl,
278: L2TP_RESULT_SHUTDOWN, 0, NULL);
279: ppp_l2tp_ctrl_destroy(&tun->ctrl);
280: }
281: }
282: ghash_destroy(&gL2tpServers);
283: ghash_destroy(&gL2tpTuns);
284: }
285:
286: /*
287: * L2tpInit()
288: */
289:
290: static int
291: L2tpInit(Link l)
292: {
293: L2tpInfo l2tp;
294:
295: /* Initialize this link */
296: l2tp = (L2tpInfo) (l->info = Malloc(MB_PHYS, sizeof(*l2tp)));
297:
298: u_addrclear(&l2tp->conf.self_addr);
299: l2tp->conf.self_addr.family = AF_INET;
300: l2tp->conf.self_port = 0;
301: u_rangeclear(&l2tp->conf.peer_addr);
302: l2tp->conf.peer_addr.addr.family = AF_INET;
303: l2tp->conf.peer_addr.width = 0;
304: l2tp->conf.peer_port = 0;
305: l2tp->conf.fqdn_peer_addr = NULL;
1.1.1.3 ! misho 306: l2tp->conf.peer_mask = NULL;
1.1 misho 307:
308: Enable(&l2tp->conf.options, L2TP_CONF_DATASEQ);
309: Enable(&l2tp->conf.options, L2TP_CONF_RESOLVE_ONCE);
310:
311: return(0);
312: }
313:
314: /*
315: * L2tpInst()
316: */
317:
318: static int
319: L2tpInst(Link l, Link lt)
320: {
321: L2tpInfo pi;
322: L2tpInfo const pit = (L2tpInfo) lt->info;
323:
324: /* Initialize this link */
325: pi = (L2tpInfo) (l->info = Mdup(MB_PHYS, lt->info, sizeof(*pit)));
326: if (pit->conf.fqdn_peer_addr != NULL)
327: pi->conf.fqdn_peer_addr =
328: Mstrdup(MB_PHYS, pit->conf.fqdn_peer_addr);
1.1.1.3 ! misho 329: if (pit->conf.peer_mask != NULL)
! 330: pi->conf.peer_mask = Mstrdup(MB_PHYS, pit->conf.peer_mask);
1.1 misho 331: if (pi->server)
332: pi->server->refs++;
333:
334: return(0);
335: }
336:
337: /*
338: * L2tpOpen()
339: */
340:
341: static void
342: L2tpOpen(Link l)
343: {
344: L2tpInfo const pi = (L2tpInfo) l->info;
345:
346: struct l2tp_tun *tun = NULL;
347: struct ppp_l2tp_sess *sess;
348: struct ppp_l2tp_avp_list *avps = NULL;
349: union {
350: u_char buf[sizeof(struct ng_ksocket_sockopt) + sizeof(int)];
351: struct ng_ksocket_sockopt sockopt;
352: } sockopt_buf;
353: struct ng_ksocket_sockopt *const sockopt = &sockopt_buf.sockopt;
354: union {
355: u_char buf[sizeof(struct ng_mesg) + sizeof(struct sockaddr_storage)];
356: struct ng_mesg reply;
357: } ugetsas;
358: struct sockaddr_storage *const getsas = (struct sockaddr_storage *)(void *)ugetsas.reply.data;
359: struct ngm_mkpeer mkpeer;
360: struct sockaddr_storage sas;
361: char hook[NG_HOOKSIZ];
362: char namebuf[64];
363: char buf[32], buf2[32];
364: char hostname[MAXHOSTNAMELEN];
365: ng_ID_t node_id;
366: int csock = -1;
367: int dsock = -1;
368: struct ghash_walk walk;
369: u_int32_t cap;
370: u_int16_t win;
371:
372: pi->opened=1;
373:
374: if (pi->incoming == 1) {
375: Log(LG_PHYS2, ("[%s] L2tpOpen() on incoming call", l->name));
376: if (l->state==PHYS_STATE_READY) {
377: l->state = PHYS_STATE_UP;
378: if (pi->outcall) {
379: pi->sync = 1;
380: if (l->rep) {
381: uint32_t fr;
382: avps = ppp_l2tp_avp_list_create();
383: if (RepIsSync(l)) {
384: fr = htonl(L2TP_FRAMING_SYNC);
385: } else {
386: fr = htonl(L2TP_FRAMING_ASYNC);
387: pi->sync = 0;
388: }
389: if (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_FRAMING_TYPE,
390: &fr, sizeof(fr)) == -1) {
391: Perror("[%s] ppp_l2tp_avp_list_append",
392: l->name);
393: }
394: } else {
395: avps = NULL;
396: }
397: Log(LG_PHYS, ("[%s] L2TP: Call #%u connected", l->name,
398: ppp_l2tp_sess_get_serial(pi->sess)));
399: ppp_l2tp_connected(pi->sess, avps);
400: if (avps)
401: ppp_l2tp_avp_list_destroy(&avps);
402: }
403: L2tpHookUp(l);
404: PhysUp(l);
405: }
406: return;
407: }
408:
409: /* Sanity check. */
410: if (l->state != PHYS_STATE_DOWN) {
411: Log(LG_PHYS, ("[%s] L2TP: allready active", l->name));
412: return;
413: };
414:
415: l->state = PHYS_STATE_CONNECTING;
416: strlcpy(pi->callingnum, pi->conf.callingnum, sizeof(pi->callingnum));
417: strlcpy(pi->callednum, pi->conf.callednum, sizeof(pi->callednum));
418:
419: if ((!Enabled(&pi->conf.options, L2TP_CONF_RESOLVE_ONCE)) &&
420: (pi->conf.fqdn_peer_addr != NULL)) {
421: struct u_range rng;
422: if (ParseRange(pi->conf.fqdn_peer_addr, &rng, ALLOW_IPV4|ALLOW_IPV6))
423: pi->conf.peer_addr = rng;
424: }
425:
426: ghash_walk_init(gL2tpTuns, &walk);
427: while ((tun = ghash_walk_next(gL2tpTuns, &walk)) != NULL) {
428: if (tun->ctrl && tun->alive && tun->active_sessions < gL2TPtunlimit &&
429: (IpAddrInRange(&pi->conf.peer_addr, &tun->peer_addr)) &&
430: (u_addrempty(&pi->conf.self_addr) || u_addrempty(&tun->self_addr) ||
431: u_addrcompare(&pi->conf.self_addr, &tun->self_addr) == 0) &&
432: (pi->conf.peer_port == 0 || pi->conf.peer_port == tun->peer_port)) {
433: pi->tun = tun;
434: tun->active_sessions++;
435: if (tun->connected) { /* if tun is connected then just initiate */
436:
437: /* Create number AVPs */
438: avps = ppp_l2tp_avp_list_create();
439: if (pi->conf.callingnum[0]) {
440: if (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_CALLING_NUMBER,
441: pi->conf.callingnum, strlen(pi->conf.callingnum)) == -1) {
442: Perror("[%s] ppp_l2tp_avp_list_append", l->name);
443: }
444: }
445: if (pi->conf.callednum[0]) {
446: if (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_CALLED_NUMBER,
447: pi->conf.callednum, strlen(pi->conf.callednum)) == -1) {
448: Perror("[%s] ppp_l2tp_avp_list_append", l->name);
449: }
450: }
451: if ((sess = ppp_l2tp_initiate(tun->ctrl,
452: Enabled(&pi->conf.options, L2TP_CONF_OUTCALL)?1:0,
453: Enabled(&pi->conf.options, L2TP_CONF_LENGTH)?1:0,
454: Enabled(&pi->conf.options, L2TP_CONF_DATASEQ)?1:0,
455: avps)) == NULL) {
456: Perror("[%s] ppp_l2tp_initiate", l->name);
457: ppp_l2tp_avp_list_destroy(&avps);
458: pi->sess = NULL;
459: pi->tun = NULL;
460: tun->active_sessions--;
461: l->state = PHYS_STATE_DOWN;
462: PhysDown(l, STR_ERROR, NULL);
463: return;
464: };
465: ppp_l2tp_avp_list_destroy(&avps);
466: pi->sess = sess;
467: pi->outcall = Enabled(&pi->conf.options, L2TP_CONF_OUTCALL);
468: Log(LG_PHYS, ("[%s] L2TP: %s call #%u via control connection %p initiated",
469: l->name, (pi->outcall?"Outgoing":"Incoming"),
470: ppp_l2tp_sess_get_serial(sess), tun->ctrl));
471: ppp_l2tp_sess_set_cookie(sess, l);
472: if (!pi->outcall) {
473: pi->sync = 1;
474: if (l->rep) {
475: uint32_t fr;
476: avps = ppp_l2tp_avp_list_create();
477: if (RepIsSync(l)) {
478: fr = htonl(L2TP_FRAMING_SYNC);
479: } else {
480: fr = htonl(L2TP_FRAMING_ASYNC);
481: pi->sync = 0;
482: }
483: if (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_FRAMING_TYPE,
484: &fr, sizeof(fr)) == -1) {
485: Perror("[%s] ppp_l2tp_avp_list_append",
486: l->name);
487: }
488: } else {
489: avps = NULL;
490: }
491: ppp_l2tp_connected(pi->sess, avps);
492: if (avps)
493: ppp_l2tp_avp_list_destroy(&avps);
494: }
495: } /* Else wait while it will be connected */
496: return;
497: }
498: }
499:
500: /* There is no tun which we need. Create a new one. */
501: tun = Malloc(MB_PHYS, sizeof(*tun));
502: memset(tun, 0, sizeof(*tun));
503: u_addrcopy(&pi->conf.peer_addr.addr, &tun->peer_addr);
504: tun->peer_port = pi->conf.peer_port?pi->conf.peer_port:L2TP_PORT;
505: u_addrcopy(&pi->conf.self_addr, &tun->self_addr);
506: tun->self_port = pi->conf.self_port;
507: tun->alive = 1;
508: tun->connected = 0;
509:
510: /* Create vendor name AVP */
511: avps = ppp_l2tp_avp_list_create();
512:
513: if (pi->conf.hostname[0] != 0) {
514: strlcpy(hostname, pi->conf.hostname, sizeof(hostname));
515: } else {
516: (void)gethostname(hostname, sizeof(hostname) - 1);
517: hostname[sizeof(hostname) - 1] = '\0';
518: }
519: cap = htonl(L2TP_BEARER_DIGITAL|L2TP_BEARER_ANALOG);
520: win = htons(8); /* XXX: this value is empirical. */
521: if ((ppp_l2tp_avp_list_append(avps, 1, 0, AVP_HOST_NAME,
522: hostname, strlen(hostname)) == -1) ||
1.1.1.3 ! misho 523: (ppp_l2tp_avp_list_append(avps, 0, 0, AVP_VENDOR_NAME,
1.1 misho 524: MPD_VENDOR, strlen(MPD_VENDOR)) == -1) ||
525: (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_BEARER_CAPABILITIES,
526: &cap, sizeof(cap)) == -1) ||
527: (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_RECEIVE_WINDOW_SIZE,
528: &win, sizeof(win)) == -1)) {
529: Perror("L2TP: ppp_l2tp_avp_list_append");
530: goto fail;
531: }
532:
533: /* Create a new control connection */
534: if ((tun->ctrl = ppp_l2tp_ctrl_create(gPeventCtx, &gGiantMutex,
535: &ppp_l2tp_server_ctrl_cb, u_addrtoid(&tun->peer_addr),
536: &node_id, hook, avps,
537: pi->conf.secret, strlen(pi->conf.secret),
538: Enabled(&pi->conf.options, L2TP_CONF_HIDDEN))) == NULL) {
539: Perror("[%s] ppp_l2tp_ctrl_create", l->name);
540: goto fail;
541: }
542: ppp_l2tp_ctrl_set_cookie(tun->ctrl, tun);
543:
544: Log(LG_PHYS, ("L2TP: Initiating control connection %p %s %u <-> %s %u",
545: tun->ctrl, u_addrtoa(&tun->self_addr,buf,sizeof(buf)), tun->self_port,
546: u_addrtoa(&tun->peer_addr,buf2,sizeof(buf2)), tun->peer_port));
547:
548: /* Get a temporary netgraph socket node */
549: if (NgMkSockNode(NULL, &csock, &dsock) == -1) {
550: Perror("[%s] NgMkSockNode", l->name);
551: goto fail;
552: }
553:
554: /* Attach a new UDP socket to "lower" hook */
555: snprintf(namebuf, sizeof(namebuf), "[%lx]:", (u_long)node_id);
556: memset(&mkpeer, 0, sizeof(mkpeer));
557: strlcpy(mkpeer.type, NG_KSOCKET_NODE_TYPE, sizeof(mkpeer.type));
558: strlcpy(mkpeer.ourhook, hook, sizeof(mkpeer.ourhook));
559: if (tun->peer_addr.family==AF_INET6) {
560: snprintf(mkpeer.peerhook, sizeof(mkpeer.peerhook), "%d/%d/%d", PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
561: } else {
562: snprintf(mkpeer.peerhook, sizeof(mkpeer.peerhook), "inet/dgram/udp");
563: }
564: if (NgSendMsg(csock, namebuf, NGM_GENERIC_COOKIE,
565: NGM_MKPEER, &mkpeer, sizeof(mkpeer)) == -1) {
566: Perror("[%s] mkpeer", l->name);
567: goto fail;
568: }
569:
570: /* Point name at ksocket node */
571: strlcat(namebuf, hook, sizeof(namebuf));
572:
573: /* Make UDP port reusable */
574: memset(&sockopt_buf, 0, sizeof(sockopt_buf));
575: sockopt->level = SOL_SOCKET;
576: sockopt->name = SO_REUSEADDR;
577: memcpy(sockopt->value, &one, sizeof(int));
578: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
579: NGM_KSOCKET_SETOPT, sockopt, sizeof(sockopt_buf)) == -1) {
580: Perror("[%s] setsockopt", l->name);
581: goto fail;
582: }
583: sockopt->name = SO_REUSEPORT;
584: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
585: NGM_KSOCKET_SETOPT, sockopt, sizeof(sockopt_buf)) == -1) {
586: Perror("[%s] setsockopt", l->name);
587: goto fail;
588: }
589:
590: if (!u_addrempty(&tun->self_addr)) {
591: /* Bind socket to a new port */
592: u_addrtosockaddr(&tun->self_addr,tun->self_port,&sas);
593: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
594: NGM_KSOCKET_BIND, &sas, sas.ss_len) == -1) {
595: Perror("[%s] bind", l->name);
596: goto fail;
597: }
598: }
599: /* Connect socket to remote peer's IP and port */
600: u_addrtosockaddr(&tun->peer_addr,tun->peer_port,&sas);
601: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
602: NGM_KSOCKET_CONNECT, &sas, sas.ss_len) == -1
603: && errno != EINPROGRESS) {
604: Perror("[%s] connect", l->name);
605: goto fail;
606: }
607:
608: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
609: NGM_KSOCKET_GETNAME, NULL, 0) == -1) {
610: Perror("[%s] getname send", l->name);
611: } else
612: if (NgRecvMsg(csock, &ugetsas.reply, sizeof(ugetsas), NULL) == -1) {
613: Perror("[%s] getname recv", l->name);
614: } else {
615: sockaddrtou_addr(getsas,&tun->self_addr,&tun->self_port);
616: }
617:
618: /* Add peer to our hash table */
619: if (ghash_put(gL2tpTuns, tun) == -1) {
620: Perror("[%s] ghash_put", l->name);
621: goto fail;
622: }
623: pi->tun = tun;
624: tun->active_sessions++;
625: Log(LG_PHYS2, ("L2TP: Control connection %p %s %u <-> %s %u initiated",
626: tun->ctrl, u_addrtoa(&tun->self_addr,buf,sizeof(buf)), tun->self_port,
627: u_addrtoa(&tun->peer_addr,buf2,sizeof(buf2)), tun->peer_port));
628: ppp_l2tp_ctrl_initiate(tun->ctrl);
629:
630: /* Clean up and return */
631: ppp_l2tp_avp_list_destroy(&avps);
632: (void)close(csock);
633: (void)close(dsock);
634: return;
635:
636: fail:
637: /* Clean up after failure */
638: if (csock != -1)
639: (void)close(csock);
640: if (dsock != -1)
641: (void)close(dsock);
642: if (tun != NULL) {
643: ppp_l2tp_ctrl_destroy(&tun->ctrl);
644: Freee(tun);
645: }
646: l->state = PHYS_STATE_DOWN;
647: PhysDown(l, STR_ERROR, NULL);
648: }
649:
650: /*
651: * L2tpClose()
652: */
653:
654: static void
655: L2tpClose(Link l)
656: {
657: L2tpInfo const pi = (L2tpInfo) l->info;
658:
659: pi->opened = 0;
660: pi->incoming = 0;
661: pi->outcall = 0;
662: if (l->state == PHYS_STATE_DOWN)
663: return;
664: L2tpUnhook(l);
665: if (pi->sess) {
666: Log(LG_PHYS, ("[%s] L2TP: Call #%u terminated locally", l->name,
667: ppp_l2tp_sess_get_serial(pi->sess)));
668: ppp_l2tp_terminate(pi->sess, L2TP_RESULT_ADMIN, 0, NULL);
669: pi->sess = NULL;
670: }
671: if (pi->tun)
672: pi->tun->active_sessions--;
673: pi->tun = NULL;
674: pi->callingnum[0]=0;
675: pi->callednum[0]=0;
676: l->state = PHYS_STATE_DOWN;
677: PhysDown(l, STR_MANUALLY, NULL);
678: }
679:
680: /*
681: * L2tpShutdown()
682: */
683:
684: static void
685: L2tpShutdown(Link l)
686: {
687: L2tpInfo const pi = (L2tpInfo) l->info;
688:
689: if (pi->conf.fqdn_peer_addr)
690: Freee(pi->conf.fqdn_peer_addr);
1.1.1.3 ! misho 691: if (pi->conf.peer_mask)
! 692: Freee(pi->conf.peer_mask);
1.1 misho 693: L2tpUnListen(l);
694: Freee(l->info);
695: }
696:
697: /*
698: * L2tpUnhook()
699: */
700:
701: static void
702: L2tpUnhook(Link l)
703: {
704: int csock = -1;
705: L2tpInfo const pi = (L2tpInfo) l->info;
706: const char *hook;
707: ng_ID_t node_id;
708: char path[NG_PATHSIZ];
709:
710: if (pi->sess) { /* avoid double close */
711:
712: /* Get this link's node and hook */
713: ppp_l2tp_sess_get_hook(pi->sess, &node_id, &hook);
714:
715: if (node_id != 0) {
716:
717: /* Get a temporary netgraph socket node */
718: if (NgMkSockNode(NULL, &csock, NULL) == -1) {
719: Perror("L2TP: NgMkSockNode");
720: return;
721: }
722:
723: /* Disconnect session hook. */
724: snprintf(path, sizeof(path), "[%lx]:", (u_long)node_id);
725: NgFuncDisconnect(csock, l->name, path, hook);
726:
727: close(csock);
728: }
729: }
730: }
731:
732: /*
733: * L2tpOriginated()
734: */
735:
736: static int
737: L2tpOriginated(Link l)
738: {
739: L2tpInfo const l2tp = (L2tpInfo) l->info;
740:
741: return(l2tp->incoming ? LINK_ORIGINATE_REMOTE : LINK_ORIGINATE_LOCAL);
742: }
743:
744: /*
745: * L2tpIsSync()
746: */
747:
748: static int
749: L2tpIsSync(Link l)
750: {
751: L2tpInfo const l2tp = (L2tpInfo) l->info;
752:
753: return (l2tp->sync);
754: }
755:
756: static int
757: L2tpSetAccm(Link l, u_int32_t xmit, u_int32_t recv)
758: {
759: L2tpInfo const l2tp = (L2tpInfo) l->info;
760:
761: if (!l2tp->sess)
762: return (-1);
763:
764: return (ppp_l2tp_set_link_info(l2tp->sess, xmit, recv));
765: }
766:
767: static int
768: L2tpSetCallingNum(Link l, void *buf)
769: {
770: L2tpInfo const l2tp = (L2tpInfo) l->info;
771:
772: strlcpy(l2tp->conf.callingnum, buf, sizeof(l2tp->conf.callingnum));
773: return(0);
774: }
775:
776: static int
777: L2tpSetCalledNum(Link l, void *buf)
778: {
779: L2tpInfo const l2tp = (L2tpInfo) l->info;
780:
781: strlcpy(l2tp->conf.callednum, buf, sizeof(l2tp->conf.callednum));
782: return(0);
783: }
784:
785: static int
786: L2tpSelfName(Link l, void *buf, size_t buf_len)
787: {
788: L2tpInfo const l2tp = (L2tpInfo) l->info;
789:
790: if (l2tp->tun && l2tp->tun->ctrl)
791: return (ppp_l2tp_ctrl_get_self_name(l2tp->tun->ctrl, buf, buf_len));
792: ((char*)buf)[0]=0;
793: return (0);
794: }
795:
796: static int
797: L2tpPeerName(Link l, void *buf, size_t buf_len)
798: {
799: L2tpInfo const l2tp = (L2tpInfo) l->info;
800:
801: if (l2tp->tun && l2tp->tun->ctrl)
802: return (ppp_l2tp_ctrl_get_peer_name(l2tp->tun->ctrl, buf, buf_len));
803: ((char*)buf)[0]=0;
804: return (0);
805: }
806:
807: static int
808: L2tpSelfAddr(Link l, void *buf, size_t buf_len)
809: {
810: L2tpInfo const l2tp = (L2tpInfo) l->info;
811:
812: if (l2tp->tun && !u_addrempty(&l2tp->tun->self_addr)) {
813: if (u_addrtoa(&l2tp->tun->self_addr, buf, buf_len))
814: return (0);
815: else {
816: ((char*)buf)[0]=0;
817: return (-1);
818: }
819: }
820: ((char*)buf)[0]=0;
821: return (0);
822: }
823:
824: static int
825: L2tpPeerAddr(Link l, void *buf, size_t buf_len)
826: {
827: L2tpInfo const l2tp = (L2tpInfo) l->info;
828:
829: if (l2tp->tun) {
830: if (u_addrtoa(&l2tp->tun->peer_addr, buf, buf_len))
831: return(0);
832: else {
833: ((char*)buf)[0]=0;
834: return(-1);
835: }
836: }
837: ((char*)buf)[0]=0;
838: return(0);
839: }
840:
841: static int
842: L2tpPeerPort(Link l, void *buf, size_t buf_len)
843: {
844: L2tpInfo const l2tp = (L2tpInfo) l->info;
845:
846: if (l2tp->tun) {
847: if (snprintf(buf, buf_len, "%d", l2tp->tun->peer_port))
848: return(0);
849: else {
850: ((char*)buf)[0]=0;
851: return(-1);
852: }
853: }
854: ((char*)buf)[0]=0;
855: return(0);
856: }
857:
858: static int
859: L2tpPeerMacAddr(Link l, void *buf, size_t buf_len)
860: {
861: L2tpInfo const l2tp = (L2tpInfo) l->info;
862:
863: if (l2tp->tun && l2tp->tun->peer_iface[0]) {
1.1.1.2 misho 864: ether_ntoa_r((struct ether_addr *)l2tp->tun->peer_mac_addr, buf);
1.1 misho 865: return (0);
866: }
867: ((char*)buf)[0]=0;
868: return(0);
869: }
870:
871: static int
872: L2tpPeerIface(Link l, void *buf, size_t buf_len)
873: {
874: L2tpInfo const l2tp = (L2tpInfo) l->info;
875:
876: if (l2tp->tun && l2tp->tun->peer_iface[0]) {
877: strlcpy(buf, l2tp->tun->peer_iface, buf_len);
878: return (0);
879: }
880: ((char*)buf)[0]=0;
881: return(0);
882: }
883:
884: static int
885: L2tpCallingNum(Link l, void *buf, size_t buf_len)
886: {
887: L2tpInfo const l2tp = (L2tpInfo) l->info;
888:
889: strlcpy((char*)buf, l2tp->callingnum, buf_len);
890: return(0);
891: }
892:
893: static int
894: L2tpCalledNum(Link l, void *buf, size_t buf_len)
895: {
896: L2tpInfo const l2tp = (L2tpInfo) l->info;
897:
898: strlcpy((char*)buf, l2tp->callednum, buf_len);
899: return(0);
900: }
901:
902: /*
903: * L2tpStat()
904: */
905:
906: void
907: L2tpStat(Context ctx)
908: {
909: L2tpInfo const l2tp = (L2tpInfo) ctx->lnk->info;
910: char buf[32];
911:
912: Printf("L2TP configuration:\r\n");
913: Printf("\tSelf addr : %s, port %u",
914: u_addrtoa(&l2tp->conf.self_addr, buf, sizeof(buf)), l2tp->conf.self_port);
915: Printf("\r\n");
916: Printf("\tPeer FQDN : %s\r\n", l2tp->conf.fqdn_peer_addr);
917: Printf("\tPeer range : %s",
918: u_rangetoa(&l2tp->conf.peer_addr, buf, sizeof(buf)));
919: if (l2tp->conf.peer_port)
920: Printf(", port %u", l2tp->conf.peer_port);
921: Printf("\r\n");
922: Printf("\tHostname : %s\r\n", l2tp->conf.hostname);
1.1.1.3 ! misho 923: Printf("\tPeer mask : %s\r\n", l2tp->conf.peer_mask);
1.1 misho 924: Printf("\tSecret : %s\r\n", (l2tp->conf.callingnum[0])?"******":"");
925: Printf("\tCalling number: %s\r\n", l2tp->conf.callingnum);
926: Printf("\tCalled number: %s\r\n", l2tp->conf.callednum);
927: Printf("L2TP options:\r\n");
928: OptStat(ctx, &l2tp->conf.options, gConfList);
929: Printf("L2TP status:\r\n");
930: if (ctx->lnk->state != PHYS_STATE_DOWN) {
931: Printf("\tIncoming : %s\r\n", (l2tp->incoming?"YES":"NO"));
932: if (l2tp->tun) {
933: Printf("\tCurrent self : %s, port %u",
934: u_addrtoa(&l2tp->tun->self_addr, buf, sizeof(buf)), l2tp->tun->self_port);
935: L2tpSelfName(ctx->lnk, buf, sizeof(buf));
936: Printf(" (%s)\r\n", buf);
937: Printf("\tCurrent peer : %s, port %u",
938: u_addrtoa(&l2tp->tun->peer_addr, buf, sizeof(buf)), l2tp->tun->peer_port);
939: L2tpPeerName(ctx->lnk, buf, sizeof(buf));
940: Printf(" (%s)\r\n", buf);
941: if (l2tp->tun->peer_iface[0]) {
1.1.1.2 misho 942: ether_ntoa_r((struct ether_addr *)l2tp->tun->peer_mac_addr, buf);
943: Printf("\tCurrent peer : %s at %s\r\n", buf,
1.1 misho 944: l2tp->tun->peer_iface);
945: }
946: Printf("\tFraming : %s\r\n", (l2tp->sync?"Sync":"Async"));
947: }
948: Printf("\tCalling number: %s\r\n", l2tp->callingnum);
949: Printf("\tCalled number: %s\r\n", l2tp->callednum);
950: }
951: }
952:
953: /*
954: * This is called when a control connection gets opened.
955: */
956: static void
957: ppp_l2tp_ctrl_connected_cb(struct ppp_l2tp_ctrl *ctrl)
958: {
959: struct l2tp_tun *tun = ppp_l2tp_ctrl_get_cookie(ctrl);
960: struct ppp_l2tp_sess *sess;
961: struct ppp_l2tp_avp_list *avps = NULL;
962: struct sockaddr_dl hwa;
963: char buf[32], buf2[32];
964: int k;
965:
966: Log(LG_PHYS, ("L2TP: Control connection %p %s %u <-> %s %u connected",
967: ctrl, u_addrtoa(&tun->self_addr,buf,sizeof(buf)), tun->self_port,
968: u_addrtoa(&tun->peer_addr,buf2,sizeof(buf2)), tun->peer_port));
969:
970: if (GetPeerEther(&tun->peer_addr, &hwa)) {
971: if_indextoname(hwa.sdl_index, tun->peer_iface);
972: memcpy(tun->peer_mac_addr, LLADDR(&hwa), sizeof(tun->peer_mac_addr));
973: };
974:
975: /* Examine all L2TP links. */
976: for (k = 0; k < gNumLinks; k++) {
977: Link l;
978: L2tpInfo pi;
979:
980: if (!gLinks[k] || gLinks[k]->type != &gL2tpPhysType)
981: continue;
982:
983: l = gLinks[k];
984: pi = (L2tpInfo)l->info;
985:
986: if (pi->tun != tun)
987: continue;
988:
989: tun->connected = 1;
990: /* Create number AVPs */
991: avps = ppp_l2tp_avp_list_create();
992: if (pi->conf.callingnum[0]) {
993: if (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_CALLING_NUMBER,
994: pi->conf.callingnum, strlen(pi->conf.callingnum)) == -1) {
995: Perror("[%s] ppp_l2tp_avp_list_append", l->name);
996: }
997: }
998: if (pi->conf.callednum[0]) {
999: if (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_CALLED_NUMBER,
1000: pi->conf.callednum, strlen(pi->conf.callednum)) == -1) {
1001: Perror("[%s] ppp_l2tp_avp_list_append", l->name);
1002: }
1003: }
1004: if ((sess = ppp_l2tp_initiate(tun->ctrl,
1005: Enabled(&pi->conf.options, L2TP_CONF_OUTCALL)?1:0,
1006: Enabled(&pi->conf.options, L2TP_CONF_LENGTH)?1:0,
1007: Enabled(&pi->conf.options, L2TP_CONF_DATASEQ)?1:0,
1008: avps)) == NULL) {
1009: Perror("ppp_l2tp_initiate");
1010: pi->sess = NULL;
1011: pi->tun = NULL;
1012: tun->active_sessions--;
1013: l->state = PHYS_STATE_DOWN;
1014: PhysDown(l, STR_ERROR, NULL);
1015: continue;
1016: };
1017: ppp_l2tp_avp_list_destroy(&avps);
1018: pi->sess = sess;
1019: pi->outcall = Enabled(&pi->conf.options, L2TP_CONF_OUTCALL);
1020: Log(LG_PHYS, ("[%s] L2TP: %s call #%u via control connection %p initiated",
1021: l->name, (pi->outcall?"Outgoing":"Incoming"),
1022: ppp_l2tp_sess_get_serial(sess), tun->ctrl));
1023: ppp_l2tp_sess_set_cookie(sess, l);
1024: if (!pi->outcall) {
1025: pi->sync = 1;
1026: if (l->rep) {
1027: uint32_t fr;
1028: avps = ppp_l2tp_avp_list_create();
1029: if (RepIsSync(l)) {
1030: fr = htonl(L2TP_FRAMING_SYNC);
1031: } else {
1032: fr = htonl(L2TP_FRAMING_ASYNC);
1033: pi->sync = 0;
1034: }
1035: if (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_FRAMING_TYPE,
1036: &fr, sizeof(fr)) == -1) {
1037: Perror("[%s] ppp_l2tp_avp_list_append", l->name);
1038: }
1039: } else {
1040: avps = NULL;
1041: }
1042: ppp_l2tp_connected(pi->sess, avps);
1043: if (avps)
1044: ppp_l2tp_avp_list_destroy(&avps);
1045: }
1046: };
1047: }
1048:
1049: /*
1050: * This is called when a control connection is terminated for any reason
1051: * other than a call ppp_l2tp_ctrl_destroy().
1052: */
1053: static void
1054: ppp_l2tp_ctrl_terminated_cb(struct ppp_l2tp_ctrl *ctrl,
1055: u_int16_t result, u_int16_t error, const char *errmsg)
1056: {
1057: struct l2tp_tun *tun = ppp_l2tp_ctrl_get_cookie(ctrl);
1058: int k;
1059:
1060: Log(LG_PHYS, ("L2TP: Control connection %p terminated: %d (%s)",
1061: ctrl, error, errmsg));
1062:
1063: /* Examine all L2TP links. */
1064: for (k = 0; k < gNumLinks; k++) {
1065: Link l;
1066: L2tpInfo pi;
1067:
1068: if (!gLinks[k] || gLinks[k]->type != &gL2tpPhysType)
1069: continue;
1070:
1071: l = gLinks[k];
1072: pi = (L2tpInfo)l->info;
1073:
1074: if (pi->tun != tun)
1075: continue;
1076:
1077: l->state = PHYS_STATE_DOWN;
1078: L2tpUnhook(l);
1079: pi->sess = NULL;
1080: pi->tun = NULL;
1081: tun->active_sessions--;
1082: pi->callingnum[0]=0;
1083: pi->callednum[0]=0;
1084: PhysDown(l, STR_DROPPED, NULL);
1085: };
1086:
1087: tun->alive = 0;
1088: }
1089:
1090: /*
1091: * This is called before control connection is destroyed for any reason
1092: * other than a call ppp_l2tp_ctrl_destroy().
1093: */
1094: static void
1095: ppp_l2tp_ctrl_destroyed_cb(struct ppp_l2tp_ctrl *ctrl)
1096: {
1097: struct l2tp_tun *tun = ppp_l2tp_ctrl_get_cookie(ctrl);
1098:
1099: Log(LG_PHYS, ("L2TP: Control connection %p destroyed", ctrl));
1100:
1101: ghash_remove(gL2tpTuns, tun);
1102: Freee(tun);
1103: }
1104:
1105: /*
1106: * This callback is used to report the peer's initiating a new incoming
1107: * or outgoing call.
1108: */
1109: static void
1110: ppp_l2tp_initiated_cb(struct ppp_l2tp_ctrl *ctrl,
1111: struct ppp_l2tp_sess *sess, int out,
1112: const struct ppp_l2tp_avp_list *avps,
1113: u_char *include_length, u_char *enable_dseq)
1114: {
1115: struct l2tp_tun *const tun = ppp_l2tp_ctrl_get_cookie(ctrl);
1.1.1.3 ! misho 1116: char *peername = ppp_l2tp_ctrl_get_peer_name_p(ctrl);
1.1 misho 1117: struct ppp_l2tp_avp_ptrs *ptrs = NULL;
1118: Link l = NULL;
1119: L2tpInfo pi = NULL;
1120: int k;
1121:
1122: /* Convert AVP's to friendly form */
1123: if ((ptrs = ppp_l2tp_avp_list2ptrs(avps)) == NULL) {
1124: Perror("L2TP: error decoding AVP list");
1125: ppp_l2tp_terminate(sess, L2TP_RESULT_ERROR,
1126: L2TP_ERROR_GENERIC, strerror(errno));
1127: return;
1128: }
1129:
1130: Log(LG_PHYS, ("L2TP: %s call #%u via connection %p received",
1131: (out?"Outgoing":"Incoming"),
1132: ppp_l2tp_sess_get_serial(sess), ctrl));
1133:
1134: if (gShutdownInProgress) {
1135: Log(LG_PHYS, ("Shutdown sequence in progress, ignoring request."));
1136: goto failed;
1137: }
1138:
1139: if (OVERLOAD()) {
1140: Log(LG_PHYS, ("Daemon overloaded, ignoring request."));
1141: goto failed;
1142: }
1143:
1144: /* Examine all L2TP links. */
1145: for (k = 0; k < gNumLinks; k++) {
1146: Link l2;
1147: L2tpInfo pi2;
1148:
1149: if (!gLinks[k] || gLinks[k]->type != &gL2tpPhysType)
1150: continue;
1151:
1152: l2 = gLinks[k];
1153: pi2 = (L2tpInfo)l2->info;
1154:
1155: if ((!PhysIsBusy(l2)) &&
1156: Enabled(&l2->conf.options, LINK_CONF_INCOMING) &&
1157: ((u_addrempty(&pi2->conf.self_addr)) || (u_addrcompare(&pi2->conf.self_addr, &tun->self_addr) == 0)) &&
1158: (pi2->conf.self_port == 0 || pi2->conf.self_port == tun->self_port) &&
1159: (IpAddrInRange(&pi2->conf.peer_addr, &tun->peer_addr)) &&
1.1.1.3 ! misho 1160: (pi2->conf.peer_port == 0 || pi2->conf.peer_port == tun->peer_port) &&
! 1161: (peername == NULL || *peername == 0 || pi2->conf.peer_mask == 0 || fnmatch(pi2->conf.peer_mask, peername, 0) == 0)) {
1.1 misho 1162:
1163: if (pi == NULL || pi2->conf.peer_addr.width > pi->conf.peer_addr.width) {
1164: l = l2;
1165: pi = pi2;
1166: if (u_rangehost(&pi->conf.peer_addr)) {
1167: break; /* Nothing could be better */
1168: }
1169: }
1170: }
1171: }
1172: if (l != NULL && l->tmpl)
1173: l = LinkInst(l, NULL, 0, 0);
1174:
1175: if (l != NULL) {
1176: pi = (L2tpInfo)l->info;
1177: Log(LG_PHYS, ("[%s] L2TP: %s call #%u via control connection %p accepted",
1178: l->name, (out?"Outgoing":"Incoming"),
1179: ppp_l2tp_sess_get_serial(sess), ctrl));
1.1.1.3 ! misho 1180: if (peername && *peername)
! 1181: Log(LG_PHYS2, ("[%s] L2TP: Call #%u remote hostname is %s",
! 1182: l->name, ppp_l2tp_sess_get_serial(sess), peername));
1.1 misho 1183:
1184: if (out)
1185: l->state = PHYS_STATE_READY;
1186: else
1187: l->state = PHYS_STATE_CONNECTING;
1188: pi->incoming = 1;
1189: pi->outcall = out;
1190: pi->tun = tun;
1191: tun->active_sessions++;
1192: pi->sess = sess;
1193: if (ptrs->callingnum && ptrs->callingnum->number)
1194: strlcpy(pi->callingnum, ptrs->callingnum->number, sizeof(pi->callingnum));
1195: if (ptrs->callednum && ptrs->callednum->number)
1196: strlcpy(pi->callednum, ptrs->callednum->number, sizeof(pi->callednum));
1197:
1198: *include_length = (Enabled(&pi->conf.options, L2TP_CONF_LENGTH)?1:0);
1199: *enable_dseq = (Enabled(&pi->conf.options, L2TP_CONF_DATASEQ)?1:0);
1200:
1201: PhysIncoming(l);
1202:
1203: ppp_l2tp_sess_set_cookie(sess, l);
1204: ppp_l2tp_avp_ptrs_destroy(&ptrs);
1205: return;
1206: }
1207: Log(LG_PHYS, ("L2TP: No free link with requested parameters "
1208: "was found"));
1209: failed:
1210: ppp_l2tp_terminate(sess, L2TP_RESULT_AVAIL_TEMP, 0, NULL);
1211: ppp_l2tp_avp_ptrs_destroy(&ptrs);
1212: }
1213:
1214: /*
1215: * This callback is used to report successful connection of a remotely
1216: * initiated incoming call (see ppp_l2tp_initiated_t) or a locally initiated
1217: * outgoing call (see ppp_l2tp_initiate()).
1218: */
1219: static void
1220: ppp_l2tp_connected_cb(struct ppp_l2tp_sess *sess,
1221: const struct ppp_l2tp_avp_list *avps)
1222: {
1223: Link l;
1224: L2tpInfo pi;
1225: struct ppp_l2tp_avp_ptrs *ptrs = NULL;
1226:
1227: l = ppp_l2tp_sess_get_cookie(sess);
1228: pi = (L2tpInfo)l->info;
1229:
1230: Log(LG_PHYS, ("[%s] L2TP: Call #%u connected", l->name,
1231: ppp_l2tp_sess_get_serial(sess)));
1232:
1233: if ((pi->incoming != pi->outcall) && avps != NULL) {
1234: /* Convert AVP's to friendly form */
1235: if ((ptrs = ppp_l2tp_avp_list2ptrs(avps)) == NULL) {
1236: Perror("L2TP: error decoding AVP list");
1237: } else {
1238: if (ptrs->framing && ptrs->framing->sync) {
1239: pi->sync = 1;
1240: } else {
1241: pi->sync = 0;
1242: }
1243: ppp_l2tp_avp_ptrs_destroy(&ptrs);
1244: }
1245: }
1246:
1247: if (pi->opened) {
1248: l->state = PHYS_STATE_UP;
1249: L2tpHookUp(l);
1250: PhysUp(l);
1251: } else {
1252: l->state = PHYS_STATE_READY;
1253: }
1254: }
1255:
1256: /*
1257: * This callback is called when any call, whether successfully connected
1258: * or not, is terminated for any reason other than explict termination
1259: * from the link side (via a call to either ppp_l2tp_terminate() or
1260: * ppp_l2tp_ctrl_destroy()).
1261: */
1262: static void
1263: ppp_l2tp_terminated_cb(struct ppp_l2tp_sess *sess,
1264: u_int16_t result, u_int16_t error, const char *errmsg)
1265: {
1266: char buf[128];
1267: Link l;
1268: L2tpInfo pi;
1269:
1270: l = ppp_l2tp_sess_get_cookie(sess);
1271: pi = (L2tpInfo) l->info;
1272:
1273: /* Control side is notifying us session is down */
1274: snprintf(buf, sizeof(buf), "result=%u error=%u errmsg=\"%s\"",
1275: result, error, (errmsg != NULL) ? errmsg : "");
1276: Log(LG_PHYS, ("[%s] L2TP: call #%u terminated: %s", l->name,
1277: ppp_l2tp_sess_get_serial(sess), buf));
1278:
1279: l->state = PHYS_STATE_DOWN;
1280: L2tpUnhook(l);
1281: pi->sess = NULL;
1282: if (pi->tun)
1283: pi->tun->active_sessions--;
1284: pi->tun = NULL;
1285: pi->callingnum[0]=0;
1286: pi->callednum[0]=0;
1287: PhysDown(l, STR_DROPPED, NULL);
1288: }
1289:
1290: /*
1291: * This callback called on receiving link info from peer.
1292: */
1293: void
1294: ppp_l2tp_set_link_info_cb(struct ppp_l2tp_sess *sess,
1295: u_int32_t xmit, u_int32_t recv)
1296: {
1297: Link l = ppp_l2tp_sess_get_cookie(sess);
1298:
1299: if (l->rep != NULL) {
1300: RepSetAccm(l, xmit, recv);
1301: }
1302: }
1303:
1304: /*
1305: * Connect L2TP and link hooks.
1306: */
1307:
1308: static void
1309: L2tpHookUp(Link l)
1310: {
1311: int csock = -1;
1312: L2tpInfo pi = (L2tpInfo)l->info;
1313: const char *hook;
1314: ng_ID_t node_id;
1315: char path[NG_PATHSIZ];
1316: struct ngm_connect cn;
1317:
1318: /* Get a temporary netgraph socket node */
1319: if (NgMkSockNode(NULL, &csock, NULL) == -1) {
1320: Perror("L2TP: NgMkSockNode");
1321: goto fail;
1322: }
1323:
1324: /* Get this link's node and hook */
1325: ppp_l2tp_sess_get_hook(pi->sess, &node_id, &hook);
1326:
1327: /* Initialize cn */
1328: memset(&cn, 0, sizeof(cn));
1329:
1330: /* Connect our ng_ppp(4) node link hook and ng_l2tp(4) node. */
1331: if (!PhysGetUpperHook(l, cn.path, cn.peerhook)) {
1332: Log(LG_PHYS, ("[%s] L2TP: can't get upper hook", l->name));
1333: goto fail;
1334: }
1335: snprintf(path, sizeof(path), "[%lx]:", (u_long)node_id);
1336: strlcpy(cn.ourhook, hook, sizeof(cn.ourhook));
1337: if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, NGM_CONNECT,
1338: &cn, sizeof(cn)) < 0) {
1339: Perror("[%s] L2TP: can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
1340: l->name, path, cn.ourhook, cn.path, cn.peerhook);
1341: goto fail;
1342: }
1343: ppp_l2tp_sess_hooked(pi->sess);
1344: close(csock);
1345: return;
1346:
1347: fail:
1348: /* Clean up after failure */
1349: ppp_l2tp_terminate(pi->sess, L2TP_RESULT_ERROR,
1350: L2TP_ERROR_GENERIC, strerror(errno));
1351: pi->sess = NULL;
1352: if (csock != -1)
1353: (void)close(csock);
1354: }
1355:
1356: /*
1357: * Read an incoming packet that might be a new L2TP connection.
1358: */
1359:
1360: static void
1361: L2tpServerEvent(int type, void *arg)
1362: {
1363: struct l2tp_server *const s = arg;
1364: L2tpInfo pi = NULL;
1365: struct ppp_l2tp_avp_list *avps = NULL;
1366: struct l2tp_tun *tun = NULL;
1367: union {
1368: u_char buf[sizeof(struct ng_ksocket_sockopt) + sizeof(int)];
1369: struct ng_ksocket_sockopt sockopt;
1370: } sockopt_buf;
1371: struct ng_ksocket_sockopt *const sockopt = &sockopt_buf.sockopt;
1372: struct ngm_connect connect;
1373: struct ngm_rmhook rmhook;
1374: struct ngm_mkpeer mkpeer;
1375: struct sockaddr_storage peer_sas;
1376: struct sockaddr_storage sas;
1377: const size_t bufsize = 8192;
1378: u_int16_t *buf = NULL;
1379: char hook[NG_HOOKSIZ];
1380: char hostname[MAXHOSTNAMELEN];
1381: socklen_t sas_len;
1382: char namebuf[64];
1383: char buf1[32], buf2[32];
1384: ng_ID_t node_id;
1385: int csock = -1;
1386: int dsock = -1;
1387: int len;
1388: u_int32_t cap;
1389: u_int16_t win;
1390: int k;
1391:
1392: /* Allocate buffer */
1393: buf = Malloc(MB_PHYS, bufsize);
1394:
1395: /* Read packet */
1396: sas_len = sizeof(peer_sas);
1397: if ((len = recvfrom(s->sock, buf, bufsize, 0,
1398: (struct sockaddr *)&peer_sas, &sas_len)) == -1) {
1399: Perror("L2TP: recvfrom");
1400: goto fail;
1401: }
1402:
1403: /* Drop it if it's not an initial L2TP packet */
1404: if (len < 12)
1405: goto fail;
1406: if ((ntohs(buf[0]) & 0xcb0f) != 0xc802 || ntohs(buf[1]) < 12
1407: || buf[2] != 0 || buf[3] != 0 || buf[4] != 0 || buf[5] != 0)
1408: goto fail;
1409:
1410: /* Create a new tun */
1411: tun = Malloc(MB_PHYS, sizeof(*tun));
1412: sockaddrtou_addr(&peer_sas,&tun->peer_addr,&tun->peer_port);
1413: u_addrcopy(&s->self_addr, &tun->self_addr);
1414: tun->self_port = s->self_port;
1415: tun->alive = 1;
1416:
1417: Log(LG_PHYS, ("Incoming L2TP packet from %s %d",
1418: u_addrtoa(&tun->peer_addr, namebuf, sizeof(namebuf)), tun->peer_port));
1419:
1420: /* Examine all L2TP links to get best possible fit tunnel parameters. */
1421: for (k = 0; k < gNumLinks; k++) {
1422: Link l2;
1423: L2tpInfo pi2;
1424:
1425: if (!gLinks[k] || gLinks[k]->type != &gL2tpPhysType)
1426: continue;
1427:
1428: l2 = gLinks[k];
1429: pi2 = (L2tpInfo)l2->info;
1430:
1431: /* Simplified comparation as it is not a final one. */
1432: if ((!PhysIsBusy(l2)) &&
1433: (pi2->server == s) &&
1434: (IpAddrInRange(&pi2->conf.peer_addr, &tun->peer_addr)) &&
1435: (pi2->conf.peer_port == 0 || pi2->conf.peer_port == tun->peer_port)) {
1436:
1437: if (pi == NULL || pi2->conf.peer_addr.width > pi->conf.peer_addr.width) {
1438: pi = pi2;
1439: if (u_rangehost(&pi->conf.peer_addr)) {
1440: break; /* Nothing could be better */
1441: }
1442: }
1443: }
1444: }
1445: if (pi == NULL) {
1446: Log(LG_PHYS, ("L2TP: No link with requested parameters "
1447: "was found"));
1448: goto fail;
1449: }
1450:
1451: /* Create vendor name AVP */
1452: avps = ppp_l2tp_avp_list_create();
1453:
1454: if (pi->conf.hostname[0] != 0) {
1455: strlcpy(hostname, pi->conf.hostname, sizeof(hostname));
1456: } else {
1457: (void)gethostname(hostname, sizeof(hostname) - 1);
1458: hostname[sizeof(hostname) - 1] = '\0';
1459: }
1460: cap = htonl(L2TP_BEARER_DIGITAL|L2TP_BEARER_ANALOG);
1461: win = htons(8); /* XXX: this value is empirical. */
1462: if ((ppp_l2tp_avp_list_append(avps, 1, 0, AVP_HOST_NAME,
1463: hostname, strlen(hostname)) == -1) ||
1464: (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_VENDOR_NAME,
1465: MPD_VENDOR, strlen(MPD_VENDOR)) == -1) ||
1466: (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_BEARER_CAPABILITIES,
1467: &cap, sizeof(cap)) == -1) ||
1468: (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_RECEIVE_WINDOW_SIZE,
1469: &win, sizeof(win)) == -1)) {
1470: Perror("L2TP: ppp_l2tp_avp_list_append");
1471: goto fail;
1472: }
1473:
1474: /* Create a new control connection */
1475: if ((tun->ctrl = ppp_l2tp_ctrl_create(gPeventCtx, &gGiantMutex,
1476: &ppp_l2tp_server_ctrl_cb, u_addrtoid(&tun->peer_addr),
1477: &node_id, hook, avps,
1478: pi->conf.secret, strlen(pi->conf.secret),
1479: Enabled(&pi->conf.options, L2TP_CONF_HIDDEN))) == NULL) {
1480: Perror("L2TP: ppp_l2tp_ctrl_create");
1481: goto fail;
1482: }
1483: ppp_l2tp_ctrl_set_cookie(tun->ctrl, tun);
1484:
1485: /* Get a temporary netgraph socket node */
1486: if (NgMkSockNode(NULL, &csock, &dsock) == -1) {
1487: Perror("L2TP: NgMkSockNode");
1488: goto fail;
1489: }
1490:
1491: /* Connect to l2tp netgraph node "lower" hook */
1492: snprintf(namebuf, sizeof(namebuf), "[%lx]:", (u_long)node_id);
1493: memset(&connect, 0, sizeof(connect));
1494: strlcpy(connect.path, namebuf, sizeof(connect.path));
1495: strlcpy(connect.ourhook, hook, sizeof(connect.ourhook));
1496: strlcpy(connect.peerhook, hook, sizeof(connect.peerhook));
1497: if (NgSendMsg(csock, ".:", NGM_GENERIC_COOKIE,
1498: NGM_CONNECT, &connect, sizeof(connect)) == -1) {
1499: Perror("L2TP: connect");
1500: goto fail;
1501: }
1502:
1503: /* Write the received packet to the node */
1504: if (NgSendData(dsock, hook, (u_char *)buf, len) == -1) {
1505: Perror("L2TP: NgSendData");
1506: goto fail;
1507: }
1508:
1509: /* Disconnect from netgraph node "lower" hook */
1510: memset(&rmhook, 0, sizeof(rmhook));
1511: strlcpy(rmhook.ourhook, hook, sizeof(rmhook.ourhook));
1512: if (NgSendMsg(csock, ".:", NGM_GENERIC_COOKIE,
1513: NGM_RMHOOK, &rmhook, sizeof(rmhook)) == -1) {
1514: Perror("L2TP: rmhook");
1515: goto fail;
1516: }
1517:
1518: /* Attach a new UDP socket to "lower" hook */
1519: memset(&mkpeer, 0, sizeof(mkpeer));
1520: strlcpy(mkpeer.type, NG_KSOCKET_NODE_TYPE, sizeof(mkpeer.type));
1521: strlcpy(mkpeer.ourhook, hook, sizeof(mkpeer.ourhook));
1522: if (s->self_addr.family==AF_INET6) {
1523: snprintf(mkpeer.peerhook, sizeof(mkpeer.peerhook), "%d/%d/%d", PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
1524: } else {
1525: snprintf(mkpeer.peerhook, sizeof(mkpeer.peerhook), "inet/dgram/udp");
1526: }
1527: if (NgSendMsg(csock, namebuf, NGM_GENERIC_COOKIE,
1528: NGM_MKPEER, &mkpeer, sizeof(mkpeer)) == -1) {
1529: Perror("L2TP: mkpeer");
1530: goto fail;
1531: }
1532:
1533: /* Point name at ksocket node */
1534: strlcat(namebuf, hook, sizeof(namebuf));
1535:
1536: /* Make UDP port reusable */
1537: memset(&sockopt_buf, 0, sizeof(sockopt_buf));
1538: sockopt->level = SOL_SOCKET;
1539: sockopt->name = SO_REUSEADDR;
1540: memcpy(sockopt->value, &one, sizeof(int));
1541: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
1542: NGM_KSOCKET_SETOPT, sockopt, sizeof(sockopt_buf)) == -1) {
1543: Perror("L2TP: setsockopt");
1544: goto fail;
1545: }
1546: sockopt->name = SO_REUSEPORT;
1547: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
1548: NGM_KSOCKET_SETOPT, sockopt, sizeof(sockopt_buf)) == -1) {
1549: Perror("L2TP: setsockopt");
1550: goto fail;
1551: }
1552:
1553: /* Bind socket to a new port */
1554: u_addrtosockaddr(&s->self_addr,s->self_port,&sas);
1555: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
1556: NGM_KSOCKET_BIND, &sas, sas.ss_len) == -1) {
1557: Perror("L2TP: bind");
1558: goto fail;
1559: }
1560:
1561: /* Connect socket to remote peer's IP and port */
1562: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
1563: NGM_KSOCKET_CONNECT, &peer_sas, peer_sas.ss_len) == -1
1564: && errno != EINPROGRESS) {
1565: Perror("L2TP: connect");
1566: goto fail;
1567: }
1568:
1569: /* Add peer to our hash table */
1570: if (ghash_put(gL2tpTuns, tun) == -1) {
1571: Perror("L2TP: ghash_put");
1572: goto fail;
1573: }
1574:
1575: Log(LG_PHYS2, ("L2TP: Control connection %p %s %u <-> %s %u accepted",
1576: tun->ctrl, u_addrtoa(&tun->self_addr,buf1,sizeof(buf1)), tun->self_port,
1577: u_addrtoa(&tun->peer_addr,buf2,sizeof(buf2)), tun->peer_port));
1578:
1579: /* Clean up and return */
1580: ppp_l2tp_avp_list_destroy(&avps);
1581: (void)close(csock);
1582: (void)close(dsock);
1583: Freee(buf);
1584: return;
1585:
1586: fail:
1587: /* Clean up after failure */
1588: if (csock != -1)
1589: (void)close(csock);
1590: if (dsock != -1)
1591: (void)close(dsock);
1592: if (tun != NULL) {
1593: ppp_l2tp_ctrl_destroy(&tun->ctrl);
1594: Freee(tun);
1595: }
1596: ppp_l2tp_avp_list_destroy(&avps);
1597: Freee(buf);
1598: }
1599:
1600:
1601: /*
1602: * L2tpListen()
1603: */
1604:
1605: static int
1606: L2tpListen(Link l)
1607: {
1608: L2tpInfo p = (L2tpInfo)l->info;
1609: struct l2tp_server *s;
1610: struct sockaddr_storage sa;
1611: char buf[48];
1612: struct ghash_walk walk;
1613:
1614: if (p->server)
1615: return(1);
1616:
1617: ghash_walk_init(gL2tpServers, &walk);
1618: while ((s = ghash_walk_next(gL2tpServers, &walk)) != NULL) {
1619: if ((u_addrcompare(&s->self_addr, &p->conf.self_addr) == 0) &&
1620: s->self_port == (p->conf.self_port?p->conf.self_port:L2TP_PORT)) {
1621: s->refs++;
1622: p->server = s;
1623: return(1);
1624: }
1625: }
1626:
1627: s = Malloc(MB_PHYS, sizeof(struct l2tp_server));
1628: s->refs = 1;
1629: u_addrcopy(&p->conf.self_addr, &s->self_addr);
1630: s->self_port = p->conf.self_port?p->conf.self_port:L2TP_PORT;
1631:
1632: /* Setup UDP socket that listens for new connections */
1633: if (s->self_addr.family==AF_INET6) {
1634: s->sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
1635: } else {
1636: s->sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
1637: }
1638: if (s->sock == -1) {
1639: Perror("L2TP: socket");
1640: goto fail;
1641: }
1642: if (setsockopt(s->sock, SOL_SOCKET,
1643: SO_REUSEADDR, &one, sizeof(one)) == -1) {
1644: Perror("L2TP: setsockopt");
1645: goto fail;
1646: }
1647: if (setsockopt(s->sock, SOL_SOCKET,
1648: SO_REUSEPORT, &one, sizeof(one)) == -1) {
1649: Perror("L2TP: setsockopt");
1650: goto fail;
1651: }
1652: u_addrtosockaddr(&s->self_addr, s->self_port, &sa);
1653: if (bind(s->sock, (struct sockaddr *)&sa, sa.ss_len) == -1) {
1654: Perror("L2TP: bind");
1655: goto fail;
1656: }
1657:
1658: EventRegister(&s->event, EVENT_READ, s->sock,
1659: EVENT_RECURRING, L2tpServerEvent, s);
1660:
1661: Log(LG_PHYS, ("L2TP: waiting for connection on %s %u",
1662: u_addrtoa(&s->self_addr, buf, sizeof(buf)), s->self_port));
1663:
1664: p->server = s;
1665: ghash_put(gL2tpServers, s);
1666: return (1);
1667: fail:
1668: if (s->sock)
1669: close(s->sock);
1670: Freee(s);
1671: return (0);
1672: }
1673:
1674: /*
1675: * L2tpUnListen()
1676: */
1677:
1678: static void
1679: L2tpUnListen(Link l)
1680: {
1681: L2tpInfo p = (L2tpInfo)l->info;
1682: struct l2tp_server *s = p->server;
1683: char buf[48];
1684:
1685: if (!s)
1686: return;
1687:
1688: s->refs--;
1689: if (s->refs == 0) {
1690: Log(LG_PHYS, ("L2TP: stop waiting for connection on %s %u",
1691: u_addrtoa(&s->self_addr, buf, sizeof(buf)), s->self_port));
1692:
1693: ghash_remove(gL2tpServers, s);
1694: EventUnRegister(&s->event);
1695: if (s->sock)
1696: close(s->sock);
1697: Freee(s);
1698: p->server = NULL;
1699: }
1700: return;
1701: }
1702:
1703: /*
1704: * L2tpNodeUpdate()
1705: */
1706:
1707: static void
1708: L2tpNodeUpdate(Link l)
1709: {
1710: L2tpInfo const pi = (L2tpInfo) l->info;
1711: if (!pi->server) {
1712: if (Enabled(&l->conf.options, LINK_CONF_INCOMING))
1713: L2tpListen(l);
1714: } else {
1715: if (!Enabled(&l->conf.options, LINK_CONF_INCOMING))
1716: L2tpUnListen(l);
1717: }
1718: }
1719:
1720: /*
1721: * L2tpSetCommand()
1722: */
1723:
1724: static int
1725: L2tpSetCommand(Context ctx, int ac, char *av[], void *arg)
1726: {
1727: L2tpInfo const l2tp = (L2tpInfo) ctx->lnk->info;
1728: char **fqdn_peer_addr = &l2tp->conf.fqdn_peer_addr;
1.1.1.3 ! misho 1729: char **peer_mask = &l2tp->conf.peer_mask;
1.1 misho 1730: struct u_range rng;
1731: int port;
1732:
1733: switch ((intptr_t)arg) {
1734: case SET_SELFADDR:
1735: case SET_PEERADDR:
1736: if ((ac == 1 || ac == 2) && (intptr_t)arg == SET_PEERADDR) {
1737: if (*fqdn_peer_addr)
1738: Freee(*fqdn_peer_addr);
1739: *fqdn_peer_addr = Mstrdup(MB_PHYS, av[0]);
1740: }
1741: if (ac < 1 || ac > 2 || !ParseRange(av[0], &rng, ALLOW_IPV4|ALLOW_IPV6))
1742: return(-1);
1743: if (ac > 1) {
1744: if ((port = atoi(av[1])) < 0 || port > 0xffff)
1745: return(-1);
1746: } else {
1747: port = 0;
1748: }
1749: if ((intptr_t)arg == SET_SELFADDR) {
1750: l2tp->conf.self_addr = rng.addr;
1751: l2tp->conf.self_port = port;
1752: if (l2tp->server) {
1753: L2tpUnListen(ctx->lnk);
1754: L2tpListen(ctx->lnk);
1755: }
1756: } else {
1757: l2tp->conf.peer_addr = rng;
1758: l2tp->conf.peer_port = port;
1759: }
1760: break;
1761: case SET_CALLINGNUM:
1762: if (ac != 1)
1763: return(-1);
1764: strlcpy(l2tp->conf.callingnum, av[0], sizeof(l2tp->conf.callingnum));
1765: break;
1766: case SET_CALLEDNUM:
1767: if (ac != 1)
1768: return(-1);
1769: strlcpy(l2tp->conf.callednum, av[0], sizeof(l2tp->conf.callednum));
1770: break;
1771: case SET_HOSTNAME:
1772: if (ac != 1)
1773: return(-1);
1774: strlcpy(l2tp->conf.hostname, av[0], sizeof(l2tp->conf.hostname));
1.1.1.3 ! misho 1775: break;
! 1776: case SET_PEERMASK:
! 1777: if (ac != 1)
! 1778: return(-1);
! 1779: if (*peer_mask)
! 1780: Freee(*peer_mask);
! 1781: *peer_mask = Mstrdup(MB_PHYS, av[0]);
1.1 misho 1782: break;
1783: case SET_SECRET:
1784: if (ac != 1)
1785: return(-1);
1786: strlcpy(l2tp->conf.secret, av[0], sizeof(l2tp->conf.secret));
1787: break;
1788: case SET_ENABLE:
1789: EnableCommand(ac, av, &l2tp->conf.options, gConfList);
1790: break;
1791: case SET_DISABLE:
1792: DisableCommand(ac, av, &l2tp->conf.options, gConfList);
1793: break;
1794: default:
1795: assert(0);
1796: }
1797: return(0);
1798: }
1799:
1800: /*
1801: * L2tpsStat()
1802: */
1803:
1804: int
1805: L2tpsStat(Context ctx, int ac, char *av[], void *arg)
1806: {
1807: struct l2tp_tun *tun;
1808: struct ghash_walk walk;
1809: char buf1[64], buf2[64], buf3[64];
1810:
1811: Printf("Active L2TP tunnels:\r\n");
1812: ghash_walk_init(gL2tpTuns, &walk);
1813: while ((tun = ghash_walk_next(gL2tpTuns, &walk)) != NULL) {
1814:
1815: u_addrtoa(&tun->self_addr, buf1, sizeof(buf1));
1816: u_addrtoa(&tun->peer_addr, buf2, sizeof(buf2));
1817: ppp_l2tp_ctrl_stats(tun->ctrl, buf3, sizeof(buf3));
1818: Printf("%p\t %s %d <=> %s %d\t%s %d calls\r\n",
1819: tun->ctrl, buf1, tun->self_port, buf2, tun->peer_port,
1820: buf3, tun->active_sessions);
1821: }
1822:
1823: return 0;
1824: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>