Annotation of embedaddon/mpd/src/l2tp.c, revision 1.1.1.4.2.1
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);
1.1.1.4 misho 147: static int L2tpSetCommand(Context ctx, int ac, const char *const av[], const void *arg);
1.1 misho 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 },
1.1.1.4 misho 223: { NULL, NULL, NULL, NULL, 0, NULL },
1.1 misho 224: };
225:
226: /*
227: * INTERNAL VARIABLES
228: */
229:
1.1.1.4 misho 230: static const struct confinfo gConfList[] = {
1.1 misho 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:
1.1.1.4 misho 239: static struct ghash *gL2tpServers;
240: static struct ghash *gL2tpTuns;
241: static int one = 1;
1.1 misho 242:
243: /*
244: * L2tpTInit()
245: */
246:
247: static int
248: L2tpTInit(void)
249: {
250: if ((gL2tpServers = ghash_create(NULL, 0, 0, MB_PHYS, NULL, NULL, NULL, NULL))
251: == NULL)
252: return(-1);
253: if ((gL2tpTuns = ghash_create(NULL, 0, 0, MB_PHYS, NULL, NULL, NULL, NULL))
254: == NULL)
255: return(-1);
256: return(0);
257: }
258:
259: /*
260: * L2tpTShutdown()
261: */
262:
263: static void
264: L2tpTShutdown(void)
265: {
266: struct ghash_walk walk;
267: struct l2tp_tun *tun;
268:
269: Log(LG_PHYS2, ("L2TP: Total shutdown"));
270: ghash_walk_init(gL2tpTuns, &walk);
271: while ((tun = ghash_walk_next(gL2tpTuns, &walk)) != NULL) {
272: if (tun->ctrl) {
273: if (tun->alive)
274: ppp_l2tp_ctrl_shutdown(tun->ctrl,
275: L2TP_RESULT_SHUTDOWN, 0, NULL);
276: ppp_l2tp_ctrl_destroy(&tun->ctrl);
277: }
278: }
279: ghash_destroy(&gL2tpServers);
280: ghash_destroy(&gL2tpTuns);
281: }
282:
283: /*
284: * L2tpInit()
285: */
286:
287: static int
288: L2tpInit(Link l)
289: {
290: L2tpInfo l2tp;
291:
292: /* Initialize this link */
293: l2tp = (L2tpInfo) (l->info = Malloc(MB_PHYS, sizeof(*l2tp)));
294:
295: u_addrclear(&l2tp->conf.self_addr);
296: l2tp->conf.self_addr.family = AF_INET;
297: l2tp->conf.self_port = 0;
298: u_rangeclear(&l2tp->conf.peer_addr);
299: l2tp->conf.peer_addr.addr.family = AF_INET;
300: l2tp->conf.peer_addr.width = 0;
301: l2tp->conf.peer_port = 0;
302: l2tp->conf.fqdn_peer_addr = NULL;
1.1.1.3 misho 303: l2tp->conf.peer_mask = NULL;
1.1 misho 304:
305: Enable(&l2tp->conf.options, L2TP_CONF_DATASEQ);
306: Enable(&l2tp->conf.options, L2TP_CONF_RESOLVE_ONCE);
307:
308: return(0);
309: }
310:
311: /*
312: * L2tpInst()
313: */
314:
315: static int
316: L2tpInst(Link l, Link lt)
317: {
318: L2tpInfo pi;
319: L2tpInfo const pit = (L2tpInfo) lt->info;
320:
321: /* Initialize this link */
322: pi = (L2tpInfo) (l->info = Mdup(MB_PHYS, lt->info, sizeof(*pit)));
323: if (pit->conf.fqdn_peer_addr != NULL)
324: pi->conf.fqdn_peer_addr =
325: Mstrdup(MB_PHYS, pit->conf.fqdn_peer_addr);
1.1.1.3 misho 326: if (pit->conf.peer_mask != NULL)
327: pi->conf.peer_mask = Mstrdup(MB_PHYS, pit->conf.peer_mask);
1.1 misho 328: if (pi->server)
329: pi->server->refs++;
330:
331: return(0);
332: }
333:
334: /*
335: * L2tpOpen()
336: */
337:
338: static void
339: L2tpOpen(Link l)
340: {
341: L2tpInfo const pi = (L2tpInfo) l->info;
342:
343: struct l2tp_tun *tun = NULL;
344: struct ppp_l2tp_sess *sess;
345: struct ppp_l2tp_avp_list *avps = NULL;
346: union {
347: u_char buf[sizeof(struct ng_ksocket_sockopt) + sizeof(int)];
348: struct ng_ksocket_sockopt sockopt;
349: } sockopt_buf;
350: struct ng_ksocket_sockopt *const sockopt = &sockopt_buf.sockopt;
351: union {
352: u_char buf[sizeof(struct ng_mesg) + sizeof(struct sockaddr_storage)];
353: struct ng_mesg reply;
354: } ugetsas;
355: struct sockaddr_storage *const getsas = (struct sockaddr_storage *)(void *)ugetsas.reply.data;
356: struct ngm_mkpeer mkpeer;
357: struct sockaddr_storage sas;
358: char hook[NG_HOOKSIZ];
359: char namebuf[64];
360: char buf[32], buf2[32];
361: char hostname[MAXHOSTNAMELEN];
362: ng_ID_t node_id;
363: int csock = -1;
364: int dsock = -1;
365: struct ghash_walk walk;
366: u_int32_t cap;
367: u_int16_t win;
368:
369: pi->opened=1;
370:
371: if (pi->incoming == 1) {
372: Log(LG_PHYS2, ("[%s] L2tpOpen() on incoming call", l->name));
373: if (l->state==PHYS_STATE_READY) {
374: l->state = PHYS_STATE_UP;
375: if (pi->outcall) {
376: pi->sync = 1;
377: if (l->rep) {
378: uint32_t fr;
379: avps = ppp_l2tp_avp_list_create();
380: if (RepIsSync(l)) {
381: fr = htonl(L2TP_FRAMING_SYNC);
382: } else {
383: fr = htonl(L2TP_FRAMING_ASYNC);
384: pi->sync = 0;
385: }
386: if (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_FRAMING_TYPE,
387: &fr, sizeof(fr)) == -1) {
388: Perror("[%s] ppp_l2tp_avp_list_append",
389: l->name);
390: }
391: } else {
392: avps = NULL;
393: }
394: Log(LG_PHYS, ("[%s] L2TP: Call #%u connected", l->name,
395: ppp_l2tp_sess_get_serial(pi->sess)));
396: ppp_l2tp_connected(pi->sess, avps);
397: if (avps)
398: ppp_l2tp_avp_list_destroy(&avps);
399: }
400: L2tpHookUp(l);
401: PhysUp(l);
402: }
403: return;
404: }
405:
406: /* Sanity check. */
407: if (l->state != PHYS_STATE_DOWN) {
408: Log(LG_PHYS, ("[%s] L2TP: allready active", l->name));
409: return;
410: };
411:
412: l->state = PHYS_STATE_CONNECTING;
413: strlcpy(pi->callingnum, pi->conf.callingnum, sizeof(pi->callingnum));
414: strlcpy(pi->callednum, pi->conf.callednum, sizeof(pi->callednum));
415:
416: if ((!Enabled(&pi->conf.options, L2TP_CONF_RESOLVE_ONCE)) &&
417: (pi->conf.fqdn_peer_addr != NULL)) {
418: struct u_range rng;
419: if (ParseRange(pi->conf.fqdn_peer_addr, &rng, ALLOW_IPV4|ALLOW_IPV6))
420: pi->conf.peer_addr = rng;
421: }
422:
423: ghash_walk_init(gL2tpTuns, &walk);
424: while ((tun = ghash_walk_next(gL2tpTuns, &walk)) != NULL) {
425: if (tun->ctrl && tun->alive && tun->active_sessions < gL2TPtunlimit &&
426: (IpAddrInRange(&pi->conf.peer_addr, &tun->peer_addr)) &&
427: (u_addrempty(&pi->conf.self_addr) || u_addrempty(&tun->self_addr) ||
428: u_addrcompare(&pi->conf.self_addr, &tun->self_addr) == 0) &&
429: (pi->conf.peer_port == 0 || pi->conf.peer_port == tun->peer_port)) {
430: pi->tun = tun;
431: tun->active_sessions++;
432: if (tun->connected) { /* if tun is connected then just initiate */
433:
434: /* Create number AVPs */
435: avps = ppp_l2tp_avp_list_create();
436: if (pi->conf.callingnum[0]) {
437: if (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_CALLING_NUMBER,
438: pi->conf.callingnum, strlen(pi->conf.callingnum)) == -1) {
439: Perror("[%s] ppp_l2tp_avp_list_append", l->name);
440: }
441: }
442: if (pi->conf.callednum[0]) {
443: if (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_CALLED_NUMBER,
444: pi->conf.callednum, strlen(pi->conf.callednum)) == -1) {
445: Perror("[%s] ppp_l2tp_avp_list_append", l->name);
446: }
447: }
448: if ((sess = ppp_l2tp_initiate(tun->ctrl,
449: Enabled(&pi->conf.options, L2TP_CONF_OUTCALL)?1:0,
450: Enabled(&pi->conf.options, L2TP_CONF_LENGTH)?1:0,
451: Enabled(&pi->conf.options, L2TP_CONF_DATASEQ)?1:0,
452: avps)) == NULL) {
453: Perror("[%s] ppp_l2tp_initiate", l->name);
454: ppp_l2tp_avp_list_destroy(&avps);
455: pi->sess = NULL;
456: pi->tun = NULL;
457: tun->active_sessions--;
458: l->state = PHYS_STATE_DOWN;
459: PhysDown(l, STR_ERROR, NULL);
460: return;
461: };
462: ppp_l2tp_avp_list_destroy(&avps);
463: pi->sess = sess;
464: pi->outcall = Enabled(&pi->conf.options, L2TP_CONF_OUTCALL);
465: Log(LG_PHYS, ("[%s] L2TP: %s call #%u via control connection %p initiated",
466: l->name, (pi->outcall?"Outgoing":"Incoming"),
467: ppp_l2tp_sess_get_serial(sess), tun->ctrl));
468: ppp_l2tp_sess_set_cookie(sess, l);
469: if (!pi->outcall) {
470: pi->sync = 1;
471: if (l->rep) {
472: uint32_t fr;
473: avps = ppp_l2tp_avp_list_create();
474: if (RepIsSync(l)) {
475: fr = htonl(L2TP_FRAMING_SYNC);
476: } else {
477: fr = htonl(L2TP_FRAMING_ASYNC);
478: pi->sync = 0;
479: }
480: if (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_FRAMING_TYPE,
481: &fr, sizeof(fr)) == -1) {
482: Perror("[%s] ppp_l2tp_avp_list_append",
483: l->name);
484: }
485: } else {
486: avps = NULL;
487: }
488: ppp_l2tp_connected(pi->sess, avps);
489: if (avps)
490: ppp_l2tp_avp_list_destroy(&avps);
491: }
492: } /* Else wait while it will be connected */
493: return;
494: }
495: }
496:
497: /* There is no tun which we need. Create a new one. */
498: tun = Malloc(MB_PHYS, sizeof(*tun));
499: memset(tun, 0, sizeof(*tun));
500: u_addrcopy(&pi->conf.peer_addr.addr, &tun->peer_addr);
501: tun->peer_port = pi->conf.peer_port?pi->conf.peer_port:L2TP_PORT;
502: u_addrcopy(&pi->conf.self_addr, &tun->self_addr);
503: tun->self_port = pi->conf.self_port;
504: tun->alive = 1;
505: tun->connected = 0;
506:
507: /* Create vendor name AVP */
508: avps = ppp_l2tp_avp_list_create();
509:
510: if (pi->conf.hostname[0] != 0) {
511: strlcpy(hostname, pi->conf.hostname, sizeof(hostname));
512: } else {
513: (void)gethostname(hostname, sizeof(hostname) - 1);
514: hostname[sizeof(hostname) - 1] = '\0';
515: }
516: cap = htonl(L2TP_BEARER_DIGITAL|L2TP_BEARER_ANALOG);
517: win = htons(8); /* XXX: this value is empirical. */
518: if ((ppp_l2tp_avp_list_append(avps, 1, 0, AVP_HOST_NAME,
519: hostname, strlen(hostname)) == -1) ||
1.1.1.3 misho 520: (ppp_l2tp_avp_list_append(avps, 0, 0, AVP_VENDOR_NAME,
1.1 misho 521: MPD_VENDOR, strlen(MPD_VENDOR)) == -1) ||
522: (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_BEARER_CAPABILITIES,
523: &cap, sizeof(cap)) == -1) ||
524: (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_RECEIVE_WINDOW_SIZE,
525: &win, sizeof(win)) == -1)) {
526: Perror("L2TP: ppp_l2tp_avp_list_append");
527: goto fail;
528: }
529:
530: /* Create a new control connection */
531: if ((tun->ctrl = ppp_l2tp_ctrl_create(gPeventCtx, &gGiantMutex,
532: &ppp_l2tp_server_ctrl_cb, u_addrtoid(&tun->peer_addr),
533: &node_id, hook, avps,
534: pi->conf.secret, strlen(pi->conf.secret),
535: Enabled(&pi->conf.options, L2TP_CONF_HIDDEN))) == NULL) {
536: Perror("[%s] ppp_l2tp_ctrl_create", l->name);
537: goto fail;
538: }
539: ppp_l2tp_ctrl_set_cookie(tun->ctrl, tun);
540:
541: Log(LG_PHYS, ("L2TP: Initiating control connection %p %s %u <-> %s %u",
542: tun->ctrl, u_addrtoa(&tun->self_addr,buf,sizeof(buf)), tun->self_port,
543: u_addrtoa(&tun->peer_addr,buf2,sizeof(buf2)), tun->peer_port));
544:
545: /* Get a temporary netgraph socket node */
546: if (NgMkSockNode(NULL, &csock, &dsock) == -1) {
547: Perror("[%s] NgMkSockNode", l->name);
548: goto fail;
549: }
550:
551: /* Attach a new UDP socket to "lower" hook */
552: snprintf(namebuf, sizeof(namebuf), "[%lx]:", (u_long)node_id);
553: memset(&mkpeer, 0, sizeof(mkpeer));
554: strlcpy(mkpeer.type, NG_KSOCKET_NODE_TYPE, sizeof(mkpeer.type));
555: strlcpy(mkpeer.ourhook, hook, sizeof(mkpeer.ourhook));
556: if (tun->peer_addr.family==AF_INET6) {
557: snprintf(mkpeer.peerhook, sizeof(mkpeer.peerhook), "%d/%d/%d", PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
558: } else {
559: snprintf(mkpeer.peerhook, sizeof(mkpeer.peerhook), "inet/dgram/udp");
560: }
561: if (NgSendMsg(csock, namebuf, NGM_GENERIC_COOKIE,
562: NGM_MKPEER, &mkpeer, sizeof(mkpeer)) == -1) {
563: Perror("[%s] mkpeer", l->name);
564: goto fail;
565: }
566:
567: /* Point name at ksocket node */
568: strlcat(namebuf, hook, sizeof(namebuf));
569:
570: /* Make UDP port reusable */
571: memset(&sockopt_buf, 0, sizeof(sockopt_buf));
572: sockopt->level = SOL_SOCKET;
573: sockopt->name = SO_REUSEADDR;
574: memcpy(sockopt->value, &one, sizeof(int));
575: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
576: NGM_KSOCKET_SETOPT, sockopt, sizeof(sockopt_buf)) == -1) {
577: Perror("[%s] setsockopt", l->name);
578: goto fail;
579: }
580: sockopt->name = SO_REUSEPORT;
581: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
582: NGM_KSOCKET_SETOPT, sockopt, sizeof(sockopt_buf)) == -1) {
583: Perror("[%s] setsockopt", l->name);
584: goto fail;
585: }
586:
1.1.1.4 misho 587: if (!u_addrempty(&tun->self_addr) || tun->self_port != 0) {
1.1 misho 588: /* Bind socket to a new port */
589: u_addrtosockaddr(&tun->self_addr,tun->self_port,&sas);
590: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
591: NGM_KSOCKET_BIND, &sas, sas.ss_len) == -1) {
592: Perror("[%s] bind", l->name);
593: goto fail;
594: }
595: }
596: /* Connect socket to remote peer's IP and port */
597: u_addrtosockaddr(&tun->peer_addr,tun->peer_port,&sas);
598: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
599: NGM_KSOCKET_CONNECT, &sas, sas.ss_len) == -1
600: && errno != EINPROGRESS) {
601: Perror("[%s] connect", l->name);
602: goto fail;
603: }
604:
605: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
606: NGM_KSOCKET_GETNAME, NULL, 0) == -1) {
607: Perror("[%s] getname send", l->name);
608: } else
609: if (NgRecvMsg(csock, &ugetsas.reply, sizeof(ugetsas), NULL) == -1) {
610: Perror("[%s] getname recv", l->name);
611: } else {
612: sockaddrtou_addr(getsas,&tun->self_addr,&tun->self_port);
613: }
614:
615: /* Add peer to our hash table */
616: if (ghash_put(gL2tpTuns, tun) == -1) {
617: Perror("[%s] ghash_put", l->name);
618: goto fail;
619: }
620: pi->tun = tun;
621: tun->active_sessions++;
622: Log(LG_PHYS2, ("L2TP: Control connection %p %s %u <-> %s %u initiated",
623: tun->ctrl, u_addrtoa(&tun->self_addr,buf,sizeof(buf)), tun->self_port,
624: u_addrtoa(&tun->peer_addr,buf2,sizeof(buf2)), tun->peer_port));
625: ppp_l2tp_ctrl_initiate(tun->ctrl);
626:
627: /* Clean up and return */
628: ppp_l2tp_avp_list_destroy(&avps);
629: (void)close(csock);
630: (void)close(dsock);
631: return;
632:
633: fail:
634: /* Clean up after failure */
635: if (csock != -1)
636: (void)close(csock);
637: if (dsock != -1)
638: (void)close(dsock);
639: if (tun != NULL) {
640: ppp_l2tp_ctrl_destroy(&tun->ctrl);
641: Freee(tun);
642: }
643: l->state = PHYS_STATE_DOWN;
644: PhysDown(l, STR_ERROR, NULL);
645: }
646:
647: /*
648: * L2tpClose()
649: */
650:
651: static void
652: L2tpClose(Link l)
653: {
654: L2tpInfo const pi = (L2tpInfo) l->info;
655:
656: pi->opened = 0;
657: pi->incoming = 0;
658: pi->outcall = 0;
659: if (l->state == PHYS_STATE_DOWN)
660: return;
661: L2tpUnhook(l);
662: if (pi->sess) {
663: Log(LG_PHYS, ("[%s] L2TP: Call #%u terminated locally", l->name,
664: ppp_l2tp_sess_get_serial(pi->sess)));
665: ppp_l2tp_terminate(pi->sess, L2TP_RESULT_ADMIN, 0, NULL);
666: pi->sess = NULL;
667: }
668: if (pi->tun)
669: pi->tun->active_sessions--;
670: pi->tun = NULL;
671: pi->callingnum[0]=0;
672: pi->callednum[0]=0;
673: l->state = PHYS_STATE_DOWN;
674: PhysDown(l, STR_MANUALLY, NULL);
675: }
676:
677: /*
678: * L2tpShutdown()
679: */
680:
681: static void
682: L2tpShutdown(Link l)
683: {
684: L2tpInfo const pi = (L2tpInfo) l->info;
685:
686: if (pi->conf.fqdn_peer_addr)
687: Freee(pi->conf.fqdn_peer_addr);
1.1.1.3 misho 688: if (pi->conf.peer_mask)
689: Freee(pi->conf.peer_mask);
1.1 misho 690: L2tpUnListen(l);
691: Freee(l->info);
692: }
693:
694: /*
695: * L2tpUnhook()
696: */
697:
698: static void
699: L2tpUnhook(Link l)
700: {
701: int csock = -1;
702: L2tpInfo const pi = (L2tpInfo) l->info;
703: const char *hook;
704: ng_ID_t node_id;
705: char path[NG_PATHSIZ];
706:
707: if (pi->sess) { /* avoid double close */
708:
709: /* Get this link's node and hook */
710: ppp_l2tp_sess_get_hook(pi->sess, &node_id, &hook);
711:
712: if (node_id != 0) {
713:
714: /* Get a temporary netgraph socket node */
715: if (NgMkSockNode(NULL, &csock, NULL) == -1) {
716: Perror("L2TP: NgMkSockNode");
717: return;
718: }
719:
720: /* Disconnect session hook. */
721: snprintf(path, sizeof(path), "[%lx]:", (u_long)node_id);
722: NgFuncDisconnect(csock, l->name, path, hook);
723:
724: close(csock);
725: }
726: }
727: }
728:
729: /*
730: * L2tpOriginated()
731: */
732:
733: static int
734: L2tpOriginated(Link l)
735: {
736: L2tpInfo const l2tp = (L2tpInfo) l->info;
737:
738: return(l2tp->incoming ? LINK_ORIGINATE_REMOTE : LINK_ORIGINATE_LOCAL);
739: }
740:
741: /*
742: * L2tpIsSync()
743: */
744:
745: static int
746: L2tpIsSync(Link l)
747: {
748: L2tpInfo const l2tp = (L2tpInfo) l->info;
749:
750: return (l2tp->sync);
751: }
752:
753: static int
754: L2tpSetAccm(Link l, u_int32_t xmit, u_int32_t recv)
755: {
756: L2tpInfo const l2tp = (L2tpInfo) l->info;
757:
758: if (!l2tp->sess)
759: return (-1);
760:
761: return (ppp_l2tp_set_link_info(l2tp->sess, xmit, recv));
762: }
763:
764: static int
765: L2tpSetCallingNum(Link l, void *buf)
766: {
767: L2tpInfo const l2tp = (L2tpInfo) l->info;
768:
769: strlcpy(l2tp->conf.callingnum, buf, sizeof(l2tp->conf.callingnum));
770: return(0);
771: }
772:
773: static int
774: L2tpSetCalledNum(Link l, void *buf)
775: {
776: L2tpInfo const l2tp = (L2tpInfo) l->info;
777:
778: strlcpy(l2tp->conf.callednum, buf, sizeof(l2tp->conf.callednum));
779: return(0);
780: }
781:
782: static int
783: L2tpSelfName(Link l, void *buf, size_t buf_len)
784: {
785: L2tpInfo const l2tp = (L2tpInfo) l->info;
786:
787: if (l2tp->tun && l2tp->tun->ctrl)
788: return (ppp_l2tp_ctrl_get_self_name(l2tp->tun->ctrl, buf, buf_len));
789: ((char*)buf)[0]=0;
790: return (0);
791: }
792:
793: static int
794: L2tpPeerName(Link l, void *buf, size_t buf_len)
795: {
796: L2tpInfo const l2tp = (L2tpInfo) l->info;
797:
798: if (l2tp->tun && l2tp->tun->ctrl)
799: return (ppp_l2tp_ctrl_get_peer_name(l2tp->tun->ctrl, buf, buf_len));
800: ((char*)buf)[0]=0;
801: return (0);
802: }
803:
804: static int
805: L2tpSelfAddr(Link l, void *buf, size_t buf_len)
806: {
807: L2tpInfo const l2tp = (L2tpInfo) l->info;
808:
809: if (l2tp->tun && !u_addrempty(&l2tp->tun->self_addr)) {
810: if (u_addrtoa(&l2tp->tun->self_addr, buf, buf_len))
811: return (0);
812: else {
813: ((char*)buf)[0]=0;
814: return (-1);
815: }
816: }
817: ((char*)buf)[0]=0;
818: return (0);
819: }
820:
821: static int
822: L2tpPeerAddr(Link l, void *buf, size_t buf_len)
823: {
824: L2tpInfo const l2tp = (L2tpInfo) l->info;
825:
826: if (l2tp->tun) {
827: if (u_addrtoa(&l2tp->tun->peer_addr, buf, buf_len))
828: return(0);
829: else {
830: ((char*)buf)[0]=0;
831: return(-1);
832: }
833: }
834: ((char*)buf)[0]=0;
835: return(0);
836: }
837:
838: static int
839: L2tpPeerPort(Link l, void *buf, size_t buf_len)
840: {
841: L2tpInfo const l2tp = (L2tpInfo) l->info;
842:
843: if (l2tp->tun) {
844: if (snprintf(buf, buf_len, "%d", l2tp->tun->peer_port))
845: return(0);
846: else {
847: ((char*)buf)[0]=0;
848: return(-1);
849: }
850: }
851: ((char*)buf)[0]=0;
852: return(0);
853: }
854:
855: static int
856: L2tpPeerMacAddr(Link l, void *buf, size_t buf_len)
857: {
858: L2tpInfo const l2tp = (L2tpInfo) l->info;
859:
1.1.1.4 misho 860: if (buf_len < 18)
861: return 1;
1.1 misho 862: if (l2tp->tun && l2tp->tun->peer_iface[0]) {
1.1.1.2 misho 863: ether_ntoa_r((struct ether_addr *)l2tp->tun->peer_mac_addr, buf);
1.1 misho 864: return (0);
865: }
866: ((char*)buf)[0]=0;
867: return(0);
868: }
869:
870: static int
871: L2tpPeerIface(Link l, void *buf, size_t buf_len)
872: {
873: L2tpInfo const l2tp = (L2tpInfo) l->info;
874:
875: if (l2tp->tun && l2tp->tun->peer_iface[0]) {
876: strlcpy(buf, l2tp->tun->peer_iface, buf_len);
877: return (0);
878: }
879: ((char*)buf)[0]=0;
880: return(0);
881: }
882:
883: static int
884: L2tpCallingNum(Link l, void *buf, size_t buf_len)
885: {
886: L2tpInfo const l2tp = (L2tpInfo) l->info;
887:
888: strlcpy((char*)buf, l2tp->callingnum, buf_len);
889: return(0);
890: }
891:
892: static int
893: L2tpCalledNum(Link l, void *buf, size_t buf_len)
894: {
895: L2tpInfo const l2tp = (L2tpInfo) l->info;
896:
897: strlcpy((char*)buf, l2tp->callednum, buf_len);
898: return(0);
899: }
900:
901: /*
902: * L2tpStat()
903: */
904:
905: void
906: L2tpStat(Context ctx)
907: {
908: L2tpInfo const l2tp = (L2tpInfo) ctx->lnk->info;
909: char buf[32];
910:
911: Printf("L2TP configuration:\r\n");
912: Printf("\tSelf addr : %s, port %u",
913: u_addrtoa(&l2tp->conf.self_addr, buf, sizeof(buf)), l2tp->conf.self_port);
914: Printf("\r\n");
915: Printf("\tPeer FQDN : %s\r\n", l2tp->conf.fqdn_peer_addr);
916: Printf("\tPeer range : %s",
917: u_rangetoa(&l2tp->conf.peer_addr, buf, sizeof(buf)));
918: if (l2tp->conf.peer_port)
919: Printf(", port %u", l2tp->conf.peer_port);
920: Printf("\r\n");
921: Printf("\tHostname : %s\r\n", l2tp->conf.hostname);
1.1.1.3 misho 922: Printf("\tPeer mask : %s\r\n", l2tp->conf.peer_mask);
1.1 misho 923: Printf("\tSecret : %s\r\n", (l2tp->conf.callingnum[0])?"******":"");
924: Printf("\tCalling number: %s\r\n", l2tp->conf.callingnum);
925: Printf("\tCalled number: %s\r\n", l2tp->conf.callednum);
926: Printf("L2TP options:\r\n");
927: OptStat(ctx, &l2tp->conf.options, gConfList);
928: Printf("L2TP status:\r\n");
929: if (ctx->lnk->state != PHYS_STATE_DOWN) {
930: Printf("\tIncoming : %s\r\n", (l2tp->incoming?"YES":"NO"));
931: if (l2tp->tun) {
932: Printf("\tCurrent self : %s, port %u",
933: u_addrtoa(&l2tp->tun->self_addr, buf, sizeof(buf)), l2tp->tun->self_port);
934: L2tpSelfName(ctx->lnk, buf, sizeof(buf));
935: Printf(" (%s)\r\n", buf);
936: Printf("\tCurrent peer : %s, port %u",
937: u_addrtoa(&l2tp->tun->peer_addr, buf, sizeof(buf)), l2tp->tun->peer_port);
938: L2tpPeerName(ctx->lnk, buf, sizeof(buf));
939: Printf(" (%s)\r\n", buf);
940: if (l2tp->tun->peer_iface[0]) {
1.1.1.2 misho 941: ether_ntoa_r((struct ether_addr *)l2tp->tun->peer_mac_addr, buf);
942: Printf("\tCurrent peer : %s at %s\r\n", buf,
1.1 misho 943: l2tp->tun->peer_iface);
944: }
945: Printf("\tFraming : %s\r\n", (l2tp->sync?"Sync":"Async"));
946: }
947: Printf("\tCalling number: %s\r\n", l2tp->callingnum);
948: Printf("\tCalled number: %s\r\n", l2tp->callednum);
949: }
950: }
951:
952: /*
953: * This is called when a control connection gets opened.
954: */
955: static void
956: ppp_l2tp_ctrl_connected_cb(struct ppp_l2tp_ctrl *ctrl)
957: {
958: struct l2tp_tun *tun = ppp_l2tp_ctrl_get_cookie(ctrl);
959: struct ppp_l2tp_sess *sess;
960: struct ppp_l2tp_avp_list *avps = NULL;
961: struct sockaddr_dl hwa;
962: char buf[32], buf2[32];
963: int k;
964:
965: Log(LG_PHYS, ("L2TP: Control connection %p %s %u <-> %s %u connected",
966: ctrl, u_addrtoa(&tun->self_addr,buf,sizeof(buf)), tun->self_port,
967: u_addrtoa(&tun->peer_addr,buf2,sizeof(buf2)), tun->peer_port));
968:
969: if (GetPeerEther(&tun->peer_addr, &hwa)) {
970: if_indextoname(hwa.sdl_index, tun->peer_iface);
971: memcpy(tun->peer_mac_addr, LLADDR(&hwa), sizeof(tun->peer_mac_addr));
972: };
973:
974: /* Examine all L2TP links. */
975: for (k = 0; k < gNumLinks; k++) {
976: Link l;
977: L2tpInfo pi;
978:
979: if (!gLinks[k] || gLinks[k]->type != &gL2tpPhysType)
980: continue;
981:
982: l = gLinks[k];
983: pi = (L2tpInfo)l->info;
984:
985: if (pi->tun != tun)
986: continue;
987:
988: tun->connected = 1;
989: /* Create number AVPs */
990: avps = ppp_l2tp_avp_list_create();
991: if (pi->conf.callingnum[0]) {
992: if (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_CALLING_NUMBER,
993: pi->conf.callingnum, strlen(pi->conf.callingnum)) == -1) {
994: Perror("[%s] ppp_l2tp_avp_list_append", l->name);
995: }
996: }
997: if (pi->conf.callednum[0]) {
998: if (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_CALLED_NUMBER,
999: pi->conf.callednum, strlen(pi->conf.callednum)) == -1) {
1000: Perror("[%s] ppp_l2tp_avp_list_append", l->name);
1001: }
1002: }
1003: if ((sess = ppp_l2tp_initiate(tun->ctrl,
1004: Enabled(&pi->conf.options, L2TP_CONF_OUTCALL)?1:0,
1005: Enabled(&pi->conf.options, L2TP_CONF_LENGTH)?1:0,
1006: Enabled(&pi->conf.options, L2TP_CONF_DATASEQ)?1:0,
1007: avps)) == NULL) {
1008: Perror("ppp_l2tp_initiate");
1009: pi->sess = NULL;
1010: pi->tun = NULL;
1011: tun->active_sessions--;
1012: l->state = PHYS_STATE_DOWN;
1013: PhysDown(l, STR_ERROR, NULL);
1014: continue;
1015: };
1016: ppp_l2tp_avp_list_destroy(&avps);
1017: pi->sess = sess;
1018: pi->outcall = Enabled(&pi->conf.options, L2TP_CONF_OUTCALL);
1019: Log(LG_PHYS, ("[%s] L2TP: %s call #%u via control connection %p initiated",
1020: l->name, (pi->outcall?"Outgoing":"Incoming"),
1021: ppp_l2tp_sess_get_serial(sess), tun->ctrl));
1022: ppp_l2tp_sess_set_cookie(sess, l);
1023: if (!pi->outcall) {
1024: pi->sync = 1;
1025: if (l->rep) {
1026: uint32_t fr;
1027: avps = ppp_l2tp_avp_list_create();
1028: if (RepIsSync(l)) {
1029: fr = htonl(L2TP_FRAMING_SYNC);
1030: } else {
1031: fr = htonl(L2TP_FRAMING_ASYNC);
1032: pi->sync = 0;
1033: }
1034: if (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_FRAMING_TYPE,
1035: &fr, sizeof(fr)) == -1) {
1036: Perror("[%s] ppp_l2tp_avp_list_append", l->name);
1037: }
1038: } else {
1039: avps = NULL;
1040: }
1041: ppp_l2tp_connected(pi->sess, avps);
1042: if (avps)
1043: ppp_l2tp_avp_list_destroy(&avps);
1044: }
1045: };
1046: }
1047:
1048: /*
1049: * This is called when a control connection is terminated for any reason
1050: * other than a call ppp_l2tp_ctrl_destroy().
1051: */
1052: static void
1053: ppp_l2tp_ctrl_terminated_cb(struct ppp_l2tp_ctrl *ctrl,
1054: u_int16_t result, u_int16_t error, const char *errmsg)
1055: {
1056: struct l2tp_tun *tun = ppp_l2tp_ctrl_get_cookie(ctrl);
1057: int k;
1058:
1.1.1.4 misho 1059: (void)result;
1.1 misho 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;
1.1.1.4 misho 1193: if (ptrs->callingnum)
1.1 misho 1194: strlcpy(pi->callingnum, ptrs->callingnum->number, sizeof(pi->callingnum));
1.1.1.4 misho 1195: if (ptrs->callednum)
1.1 misho 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;
1.1.1.4.2.1! misho 1377: struct u_addr server_addr;
1.1 misho 1378: const size_t bufsize = 8192;
1379: u_int16_t *buf = NULL;
1380: char hook[NG_HOOKSIZ];
1381: char hostname[MAXHOSTNAMELEN];
1382: socklen_t sas_len;
1383: char namebuf[64];
1384: char buf1[32], buf2[32];
1385: ng_ID_t node_id;
1386: int csock = -1;
1387: int dsock = -1;
1388: int len;
1389: u_int32_t cap;
1390: u_int16_t win;
1391: int k;
1392:
1.1.1.4 misho 1393: (void)type;
1.1 misho 1394: /* Allocate buffer */
1395: buf = Malloc(MB_PHYS, bufsize);
1396:
1.1.1.4.2.1! misho 1397: u_addrcopy(&s->self_addr, &server_addr);
! 1398:
1.1 misho 1399: /* Read packet */
1400: sas_len = sizeof(peer_sas);
1.1.1.4.2.1! misho 1401:
! 1402: if (u_addrempty(&s->self_addr)) {
! 1403: if ((len = GetDataAddrs(s->sock, buf, bufsize,
! 1404: &peer_sas, sas_len, &server_addr)) == -1) {
! 1405: Perror("L2TP: GetDataAddrs");
! 1406: goto fail;
! 1407: }
! 1408: } else if ((len = recvfrom(s->sock, buf, bufsize, 0,
1.1 misho 1409: (struct sockaddr *)&peer_sas, &sas_len)) == -1) {
1410: Perror("L2TP: recvfrom");
1411: goto fail;
1412: }
1413:
1414: /* Drop it if it's not an initial L2TP packet */
1415: if (len < 12)
1416: goto fail;
1417: if ((ntohs(buf[0]) & 0xcb0f) != 0xc802 || ntohs(buf[1]) < 12
1418: || buf[2] != 0 || buf[3] != 0 || buf[4] != 0 || buf[5] != 0)
1419: goto fail;
1420:
1421: /* Create a new tun */
1422: tun = Malloc(MB_PHYS, sizeof(*tun));
1423: sockaddrtou_addr(&peer_sas,&tun->peer_addr,&tun->peer_port);
1424: u_addrcopy(&s->self_addr, &tun->self_addr);
1425: tun->self_port = s->self_port;
1426: tun->alive = 1;
1427:
1.1.1.4.2.1! misho 1428: if (u_addrempty(&tun->self_addr))
! 1429: u_addrcopy(&server_addr, &tun->self_addr);
! 1430:
! 1431: if (u_addrempty(&tun->self_addr))
! 1432: Log(LG_PHYS, ("Incoming L2TP packet from %s %d",
! 1433: u_addrtoa(&tun->peer_addr, namebuf, sizeof(namebuf)),
! 1434: tun->peer_port));
! 1435: else {
! 1436: char buf3[INET_ADDRSTRLEN];
! 1437:
! 1438: Log(LG_PHYS, ("Incoming L2TP packet from %s %d to %s %d",
! 1439: u_addrtoa(&tun->peer_addr, namebuf, sizeof(namebuf)),
! 1440: tun->peer_port,
! 1441: u_addrtoa(&tun->self_addr, buf3, sizeof(buf3)),
! 1442: tun->self_port));
! 1443: }
1.1 misho 1444:
1445: /* Examine all L2TP links to get best possible fit tunnel parameters. */
1446: for (k = 0; k < gNumLinks; k++) {
1447: Link l2;
1448: L2tpInfo pi2;
1449:
1450: if (!gLinks[k] || gLinks[k]->type != &gL2tpPhysType)
1451: continue;
1452:
1453: l2 = gLinks[k];
1454: pi2 = (L2tpInfo)l2->info;
1455:
1456: /* Simplified comparation as it is not a final one. */
1457: if ((!PhysIsBusy(l2)) &&
1458: (pi2->server == s) &&
1459: (IpAddrInRange(&pi2->conf.peer_addr, &tun->peer_addr)) &&
1460: (pi2->conf.peer_port == 0 || pi2->conf.peer_port == tun->peer_port)) {
1461:
1462: if (pi == NULL || pi2->conf.peer_addr.width > pi->conf.peer_addr.width) {
1463: pi = pi2;
1464: if (u_rangehost(&pi->conf.peer_addr)) {
1465: break; /* Nothing could be better */
1466: }
1467: }
1468: }
1469: }
1470: if (pi == NULL) {
1471: Log(LG_PHYS, ("L2TP: No link with requested parameters "
1472: "was found"));
1473: goto fail;
1474: }
1475:
1476: /* Create vendor name AVP */
1477: avps = ppp_l2tp_avp_list_create();
1478:
1479: if (pi->conf.hostname[0] != 0) {
1480: strlcpy(hostname, pi->conf.hostname, sizeof(hostname));
1481: } else {
1482: (void)gethostname(hostname, sizeof(hostname) - 1);
1483: hostname[sizeof(hostname) - 1] = '\0';
1484: }
1485: cap = htonl(L2TP_BEARER_DIGITAL|L2TP_BEARER_ANALOG);
1486: win = htons(8); /* XXX: this value is empirical. */
1487: if ((ppp_l2tp_avp_list_append(avps, 1, 0, AVP_HOST_NAME,
1488: hostname, strlen(hostname)) == -1) ||
1489: (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_VENDOR_NAME,
1490: MPD_VENDOR, strlen(MPD_VENDOR)) == -1) ||
1491: (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_BEARER_CAPABILITIES,
1492: &cap, sizeof(cap)) == -1) ||
1493: (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_RECEIVE_WINDOW_SIZE,
1494: &win, sizeof(win)) == -1)) {
1495: Perror("L2TP: ppp_l2tp_avp_list_append");
1496: goto fail;
1497: }
1498:
1499: /* Create a new control connection */
1500: if ((tun->ctrl = ppp_l2tp_ctrl_create(gPeventCtx, &gGiantMutex,
1501: &ppp_l2tp_server_ctrl_cb, u_addrtoid(&tun->peer_addr),
1502: &node_id, hook, avps,
1503: pi->conf.secret, strlen(pi->conf.secret),
1504: Enabled(&pi->conf.options, L2TP_CONF_HIDDEN))) == NULL) {
1505: Perror("L2TP: ppp_l2tp_ctrl_create");
1506: goto fail;
1507: }
1508: ppp_l2tp_ctrl_set_cookie(tun->ctrl, tun);
1509:
1510: /* Get a temporary netgraph socket node */
1511: if (NgMkSockNode(NULL, &csock, &dsock) == -1) {
1512: Perror("L2TP: NgMkSockNode");
1513: goto fail;
1514: }
1515:
1516: /* Connect to l2tp netgraph node "lower" hook */
1517: snprintf(namebuf, sizeof(namebuf), "[%lx]:", (u_long)node_id);
1518: memset(&connect, 0, sizeof(connect));
1519: strlcpy(connect.path, namebuf, sizeof(connect.path));
1520: strlcpy(connect.ourhook, hook, sizeof(connect.ourhook));
1521: strlcpy(connect.peerhook, hook, sizeof(connect.peerhook));
1522: if (NgSendMsg(csock, ".:", NGM_GENERIC_COOKIE,
1523: NGM_CONNECT, &connect, sizeof(connect)) == -1) {
1524: Perror("L2TP: connect");
1525: goto fail;
1526: }
1527:
1528: /* Write the received packet to the node */
1529: if (NgSendData(dsock, hook, (u_char *)buf, len) == -1) {
1530: Perror("L2TP: NgSendData");
1531: goto fail;
1532: }
1533:
1534: /* Disconnect from netgraph node "lower" hook */
1535: memset(&rmhook, 0, sizeof(rmhook));
1536: strlcpy(rmhook.ourhook, hook, sizeof(rmhook.ourhook));
1537: if (NgSendMsg(csock, ".:", NGM_GENERIC_COOKIE,
1538: NGM_RMHOOK, &rmhook, sizeof(rmhook)) == -1) {
1539: Perror("L2TP: rmhook");
1540: goto fail;
1541: }
1542:
1543: /* Attach a new UDP socket to "lower" hook */
1544: memset(&mkpeer, 0, sizeof(mkpeer));
1545: strlcpy(mkpeer.type, NG_KSOCKET_NODE_TYPE, sizeof(mkpeer.type));
1546: strlcpy(mkpeer.ourhook, hook, sizeof(mkpeer.ourhook));
1547: if (s->self_addr.family==AF_INET6) {
1548: snprintf(mkpeer.peerhook, sizeof(mkpeer.peerhook), "%d/%d/%d", PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
1549: } else {
1550: snprintf(mkpeer.peerhook, sizeof(mkpeer.peerhook), "inet/dgram/udp");
1551: }
1552: if (NgSendMsg(csock, namebuf, NGM_GENERIC_COOKIE,
1553: NGM_MKPEER, &mkpeer, sizeof(mkpeer)) == -1) {
1554: Perror("L2TP: mkpeer");
1555: goto fail;
1556: }
1557:
1558: /* Point name at ksocket node */
1559: strlcat(namebuf, hook, sizeof(namebuf));
1560:
1561: /* Make UDP port reusable */
1562: memset(&sockopt_buf, 0, sizeof(sockopt_buf));
1563: sockopt->level = SOL_SOCKET;
1564: sockopt->name = SO_REUSEADDR;
1565: memcpy(sockopt->value, &one, sizeof(int));
1566: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
1567: NGM_KSOCKET_SETOPT, sockopt, sizeof(sockopt_buf)) == -1) {
1568: Perror("L2TP: setsockopt");
1569: goto fail;
1570: }
1571: sockopt->name = SO_REUSEPORT;
1572: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
1573: NGM_KSOCKET_SETOPT, sockopt, sizeof(sockopt_buf)) == -1) {
1574: Perror("L2TP: setsockopt");
1575: goto fail;
1576: }
1577:
1578: /* Bind socket to a new port */
1.1.1.4.2.1! misho 1579: u_addrtosockaddr(&tun->self_addr,tun->self_port,&sas);
1.1 misho 1580: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
1581: NGM_KSOCKET_BIND, &sas, sas.ss_len) == -1) {
1582: Perror("L2TP: bind");
1583: goto fail;
1584: }
1585:
1586: /* Connect socket to remote peer's IP and port */
1587: if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE,
1588: NGM_KSOCKET_CONNECT, &peer_sas, peer_sas.ss_len) == -1
1589: && errno != EINPROGRESS) {
1590: Perror("L2TP: connect");
1591: goto fail;
1592: }
1593:
1594: /* Add peer to our hash table */
1595: if (ghash_put(gL2tpTuns, tun) == -1) {
1596: Perror("L2TP: ghash_put");
1597: goto fail;
1598: }
1599:
1600: Log(LG_PHYS2, ("L2TP: Control connection %p %s %u <-> %s %u accepted",
1601: tun->ctrl, u_addrtoa(&tun->self_addr,buf1,sizeof(buf1)), tun->self_port,
1602: u_addrtoa(&tun->peer_addr,buf2,sizeof(buf2)), tun->peer_port));
1603:
1604: /* Clean up and return */
1605: ppp_l2tp_avp_list_destroy(&avps);
1606: (void)close(csock);
1607: (void)close(dsock);
1608: Freee(buf);
1609: return;
1610:
1611: fail:
1612: /* Clean up after failure */
1613: if (csock != -1)
1614: (void)close(csock);
1615: if (dsock != -1)
1616: (void)close(dsock);
1617: if (tun != NULL) {
1618: ppp_l2tp_ctrl_destroy(&tun->ctrl);
1619: Freee(tun);
1620: }
1621: ppp_l2tp_avp_list_destroy(&avps);
1622: Freee(buf);
1623: }
1624:
1625:
1626: /*
1627: * L2tpListen()
1628: */
1629:
1630: static int
1631: L2tpListen(Link l)
1632: {
1633: L2tpInfo p = (L2tpInfo)l->info;
1634: struct l2tp_server *s;
1635: struct sockaddr_storage sa;
1636: char buf[48];
1637: struct ghash_walk walk;
1638:
1639: if (p->server)
1640: return(1);
1641:
1642: ghash_walk_init(gL2tpServers, &walk);
1643: while ((s = ghash_walk_next(gL2tpServers, &walk)) != NULL) {
1644: if ((u_addrcompare(&s->self_addr, &p->conf.self_addr) == 0) &&
1645: s->self_port == (p->conf.self_port?p->conf.self_port:L2TP_PORT)) {
1646: s->refs++;
1647: p->server = s;
1648: return(1);
1649: }
1650: }
1651:
1652: s = Malloc(MB_PHYS, sizeof(struct l2tp_server));
1653: s->refs = 1;
1654: u_addrcopy(&p->conf.self_addr, &s->self_addr);
1655: s->self_port = p->conf.self_port?p->conf.self_port:L2TP_PORT;
1656:
1657: /* Setup UDP socket that listens for new connections */
1658: if (s->self_addr.family==AF_INET6) {
1.1.1.4.2.1! misho 1659: s->sock = socket(PF_INET6, socktype(SOCK_DGRAM), IPPROTO_UDP);
1.1 misho 1660: } else {
1.1.1.4.2.1! misho 1661: s->sock = socket(PF_INET, socktype(SOCK_DGRAM), IPPROTO_UDP);
1.1 misho 1662: }
1663: if (s->sock == -1) {
1664: Perror("L2TP: socket");
1665: goto fail;
1666: }
1667: if (setsockopt(s->sock, SOL_SOCKET,
1668: SO_REUSEADDR, &one, sizeof(one)) == -1) {
1669: Perror("L2TP: setsockopt");
1670: goto fail;
1671: }
1672: if (setsockopt(s->sock, SOL_SOCKET,
1673: SO_REUSEPORT, &one, sizeof(one)) == -1) {
1674: Perror("L2TP: setsockopt");
1675: goto fail;
1676: }
1.1.1.4.2.1! misho 1677: if (u_addrempty(&s->self_addr)) {
! 1678: int on = 1;
! 1679: setsockopt(s->sock, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on));
! 1680: }
1.1 misho 1681: u_addrtosockaddr(&s->self_addr, s->self_port, &sa);
1682: if (bind(s->sock, (struct sockaddr *)&sa, sa.ss_len) == -1) {
1683: Perror("L2TP: bind");
1684: goto fail;
1685: }
1686:
1687: EventRegister(&s->event, EVENT_READ, s->sock,
1688: EVENT_RECURRING, L2tpServerEvent, s);
1689:
1690: Log(LG_PHYS, ("L2TP: waiting for connection on %s %u",
1691: u_addrtoa(&s->self_addr, buf, sizeof(buf)), s->self_port));
1692:
1693: p->server = s;
1694: ghash_put(gL2tpServers, s);
1695: return (1);
1696: fail:
1697: if (s->sock)
1698: close(s->sock);
1699: Freee(s);
1700: return (0);
1701: }
1702:
1703: /*
1704: * L2tpUnListen()
1705: */
1706:
1707: static void
1708: L2tpUnListen(Link l)
1709: {
1710: L2tpInfo p = (L2tpInfo)l->info;
1711: struct l2tp_server *s = p->server;
1712: char buf[48];
1713:
1714: if (!s)
1715: return;
1716:
1717: s->refs--;
1718: if (s->refs == 0) {
1719: Log(LG_PHYS, ("L2TP: stop waiting for connection on %s %u",
1720: u_addrtoa(&s->self_addr, buf, sizeof(buf)), s->self_port));
1721:
1722: ghash_remove(gL2tpServers, s);
1723: EventUnRegister(&s->event);
1724: if (s->sock)
1725: close(s->sock);
1726: Freee(s);
1727: p->server = NULL;
1728: }
1729: return;
1730: }
1731:
1732: /*
1733: * L2tpNodeUpdate()
1734: */
1735:
1736: static void
1737: L2tpNodeUpdate(Link l)
1738: {
1739: L2tpInfo const pi = (L2tpInfo) l->info;
1740: if (!pi->server) {
1741: if (Enabled(&l->conf.options, LINK_CONF_INCOMING))
1742: L2tpListen(l);
1743: } else {
1744: if (!Enabled(&l->conf.options, LINK_CONF_INCOMING))
1745: L2tpUnListen(l);
1746: }
1747: }
1748:
1749: /*
1750: * L2tpSetCommand()
1751: */
1752:
1753: static int
1.1.1.4 misho 1754: L2tpSetCommand(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 1755: {
1756: L2tpInfo const l2tp = (L2tpInfo) ctx->lnk->info;
1757: char **fqdn_peer_addr = &l2tp->conf.fqdn_peer_addr;
1.1.1.3 misho 1758: char **peer_mask = &l2tp->conf.peer_mask;
1.1 misho 1759: struct u_range rng;
1760: int port;
1761:
1762: switch ((intptr_t)arg) {
1763: case SET_SELFADDR:
1764: case SET_PEERADDR:
1765: if ((ac == 1 || ac == 2) && (intptr_t)arg == SET_PEERADDR) {
1766: if (*fqdn_peer_addr)
1767: Freee(*fqdn_peer_addr);
1768: *fqdn_peer_addr = Mstrdup(MB_PHYS, av[0]);
1769: }
1770: if (ac < 1 || ac > 2 || !ParseRange(av[0], &rng, ALLOW_IPV4|ALLOW_IPV6))
1771: return(-1);
1772: if (ac > 1) {
1773: if ((port = atoi(av[1])) < 0 || port > 0xffff)
1774: return(-1);
1775: } else {
1776: port = 0;
1777: }
1778: if ((intptr_t)arg == SET_SELFADDR) {
1779: l2tp->conf.self_addr = rng.addr;
1780: l2tp->conf.self_port = port;
1781: if (l2tp->server) {
1782: L2tpUnListen(ctx->lnk);
1783: L2tpListen(ctx->lnk);
1784: }
1785: } else {
1786: l2tp->conf.peer_addr = rng;
1787: l2tp->conf.peer_port = port;
1788: }
1789: break;
1790: case SET_CALLINGNUM:
1791: if (ac != 1)
1792: return(-1);
1793: strlcpy(l2tp->conf.callingnum, av[0], sizeof(l2tp->conf.callingnum));
1794: break;
1795: case SET_CALLEDNUM:
1796: if (ac != 1)
1797: return(-1);
1798: strlcpy(l2tp->conf.callednum, av[0], sizeof(l2tp->conf.callednum));
1799: break;
1800: case SET_HOSTNAME:
1801: if (ac != 1)
1802: return(-1);
1803: strlcpy(l2tp->conf.hostname, av[0], sizeof(l2tp->conf.hostname));
1.1.1.3 misho 1804: break;
1805: case SET_PEERMASK:
1806: if (ac != 1)
1807: return(-1);
1808: if (*peer_mask)
1809: Freee(*peer_mask);
1810: *peer_mask = Mstrdup(MB_PHYS, av[0]);
1.1 misho 1811: break;
1812: case SET_SECRET:
1813: if (ac != 1)
1814: return(-1);
1815: strlcpy(l2tp->conf.secret, av[0], sizeof(l2tp->conf.secret));
1816: break;
1817: case SET_ENABLE:
1818: EnableCommand(ac, av, &l2tp->conf.options, gConfList);
1819: break;
1820: case SET_DISABLE:
1821: DisableCommand(ac, av, &l2tp->conf.options, gConfList);
1822: break;
1823: default:
1824: assert(0);
1825: }
1826: return(0);
1827: }
1828:
1829: /*
1830: * L2tpsStat()
1831: */
1832:
1833: int
1.1.1.4 misho 1834: L2tpsStat(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 1835: {
1836: struct l2tp_tun *tun;
1837: struct ghash_walk walk;
1838: char buf1[64], buf2[64], buf3[64];
1839:
1.1.1.4 misho 1840: (void)ac;
1841: (void)av;
1842: (void)arg;
1843:
1.1 misho 1844: Printf("Active L2TP tunnels:\r\n");
1845: ghash_walk_init(gL2tpTuns, &walk);
1846: while ((tun = ghash_walk_next(gL2tpTuns, &walk)) != NULL) {
1847:
1848: u_addrtoa(&tun->self_addr, buf1, sizeof(buf1));
1849: u_addrtoa(&tun->peer_addr, buf2, sizeof(buf2));
1850: ppp_l2tp_ctrl_stats(tun->ctrl, buf3, sizeof(buf3));
1851: Printf("%p\t %s %d <=> %s %d\t%s %d calls\r\n",
1852: tun->ctrl, buf1, tun->self_port, buf2, tun->peer_port,
1853: buf3, tun->active_sessions);
1854: }
1855:
1856: return 0;
1857: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>