version 1.1.1.1, 2012/02/21 23:32:47
|
version 1.1.1.4, 2021/03/17 00:39:23
|
Line 22
|
Line 22
|
#include <pdel/util/ghash.h> |
#include <pdel/util/ghash.h> |
#endif |
#endif |
|
|
|
#include <net/ethernet.h> |
#include <netgraph/ng_message.h> |
#include <netgraph/ng_message.h> |
#include <netgraph/ng_socket.h> |
#include <netgraph/ng_socket.h> |
#include <netgraph/ng_ksocket.h> |
#include <netgraph/ng_ksocket.h> |
#include <netgraph/ng_l2tp.h> |
#include <netgraph/ng_l2tp.h> |
#include <netgraph.h> |
#include <netgraph.h> |
|
#include <fnmatch.h> |
|
|
/* |
/* |
* DEFINITIONS |
* DEFINITIONS |
Line 73
|
Line 75
|
char hostname[MAXHOSTNAMELEN]; /* L2TP local hostname */ |
char hostname[MAXHOSTNAMELEN]; /* L2TP local hostname */ |
char secret[64]; /* L2TP tunnel secret */ |
char secret[64]; /* L2TP tunnel secret */ |
char *fqdn_peer_addr; /* FQDN Peer address */ |
char *fqdn_peer_addr; /* FQDN Peer address */ |
|
char *peer_mask; /* L2TP peer hostname mask */ |
} conf; |
} conf; |
u_char opened; /* L2TP opened by phys */ |
u_char opened; /* L2TP opened by phys */ |
u_char incoming; /* Call is incoming vs. outgoing */ |
u_char incoming; /* Call is incoming vs. outgoing */ |
Line 93
|
Line 96
|
SET_CALLINGNUM, |
SET_CALLINGNUM, |
SET_CALLEDNUM, |
SET_CALLEDNUM, |
SET_HOSTNAME, |
SET_HOSTNAME, |
|
SET_PEERMASK, |
SET_SECRET, |
SET_SECRET, |
SET_ENABLE, |
SET_ENABLE, |
SET_DISABLE |
SET_DISABLE |
Line 140
|
Line 144
|
static void L2tpNodeUpdate(Link l); |
static void L2tpNodeUpdate(Link l); |
static int L2tpListen(Link l); |
static int L2tpListen(Link l); |
static void L2tpUnListen(Link l); |
static void L2tpUnListen(Link l); |
static int L2tpSetCommand(Context ctx, int ac, char *av[], void *arg); | static int L2tpSetCommand(Context ctx, int ac, const char *const av[], const void *arg); |
|
|
/* L2TP control callbacks */ |
/* L2TP control callbacks */ |
static ppp_l2tp_ctrl_connected_t ppp_l2tp_ctrl_connected_cb; |
static ppp_l2tp_ctrl_connected_t ppp_l2tp_ctrl_connected_cb; |
Line 208
|
Line 212
|
L2tpSetCommand, NULL, 2, (void *) SET_CALLEDNUM }, |
L2tpSetCommand, NULL, 2, (void *) SET_CALLEDNUM }, |
{ "hostname {name}", "Set L2TP local hostname", |
{ "hostname {name}", "Set L2TP local hostname", |
L2tpSetCommand, NULL, 2, (void *) SET_HOSTNAME }, |
L2tpSetCommand, NULL, 2, (void *) SET_HOSTNAME }, |
|
{ "pmask {mask}", "Set L2TP peer hostname mask", |
|
L2tpSetCommand, NULL, 2, (void *) SET_PEERMASK }, |
{ "secret {sec}", "Set L2TP tunnel secret", |
{ "secret {sec}", "Set L2TP tunnel secret", |
L2tpSetCommand, NULL, 2, (void *) SET_SECRET }, |
L2tpSetCommand, NULL, 2, (void *) SET_SECRET }, |
{ "enable [opt ...]", "Enable option", |
{ "enable [opt ...]", "Enable option", |
L2tpSetCommand, NULL, 2, (void *) SET_ENABLE }, |
L2tpSetCommand, NULL, 2, (void *) SET_ENABLE }, |
{ "disable [opt ...]", "Disable option", |
{ "disable [opt ...]", "Disable option", |
L2tpSetCommand, NULL, 2, (void *) SET_DISABLE }, |
L2tpSetCommand, NULL, 2, (void *) SET_DISABLE }, |
{ NULL }, | { NULL, NULL, NULL, NULL, 0, NULL }, |
}; |
}; |
|
|
/* |
/* |
* INTERNAL VARIABLES |
* INTERNAL VARIABLES |
*/ |
*/ |
|
|
static struct confinfo gConfList[] = { | static const struct confinfo gConfList[] = { |
{ 0, L2TP_CONF_OUTCALL, "outcall" }, |
{ 0, L2TP_CONF_OUTCALL, "outcall" }, |
{ 0, L2TP_CONF_HIDDEN, "hidden" }, |
{ 0, L2TP_CONF_HIDDEN, "hidden" }, |
{ 0, L2TP_CONF_LENGTH, "length" }, |
{ 0, L2TP_CONF_LENGTH, "length" }, |
Line 230
|
Line 236
|
{ 0, 0, NULL }, |
{ 0, 0, NULL }, |
}; |
}; |
|
|
int L2tpListenUpdateSheduled = 0; | static struct ghash *gL2tpServers; |
struct pppTimer L2tpListenUpdateTimer; | static struct ghash *gL2tpTuns; |
| static int one = 1; |
|
|
struct ghash *gL2tpServers; |
|
struct ghash *gL2tpTuns; |
|
int one = 1; |
|
|
|
/* |
/* |
* L2tpTInit() |
* L2tpTInit() |
*/ |
*/ |
Line 297 L2tpInit(Link l)
|
Line 300 L2tpInit(Link l)
|
l2tp->conf.peer_addr.width = 0; |
l2tp->conf.peer_addr.width = 0; |
l2tp->conf.peer_port = 0; |
l2tp->conf.peer_port = 0; |
l2tp->conf.fqdn_peer_addr = NULL; |
l2tp->conf.fqdn_peer_addr = NULL; |
|
l2tp->conf.peer_mask = NULL; |
|
|
Enable(&l2tp->conf.options, L2TP_CONF_DATASEQ); |
Enable(&l2tp->conf.options, L2TP_CONF_DATASEQ); |
Enable(&l2tp->conf.options, L2TP_CONF_RESOLVE_ONCE); |
Enable(&l2tp->conf.options, L2TP_CONF_RESOLVE_ONCE); |
Line 319 L2tpInst(Link l, Link lt)
|
Line 323 L2tpInst(Link l, Link lt)
|
if (pit->conf.fqdn_peer_addr != NULL) |
if (pit->conf.fqdn_peer_addr != NULL) |
pi->conf.fqdn_peer_addr = |
pi->conf.fqdn_peer_addr = |
Mstrdup(MB_PHYS, pit->conf.fqdn_peer_addr); |
Mstrdup(MB_PHYS, pit->conf.fqdn_peer_addr); |
|
if (pit->conf.peer_mask != NULL) |
|
pi->conf.peer_mask = Mstrdup(MB_PHYS, pit->conf.peer_mask); |
if (pi->server) |
if (pi->server) |
pi->server->refs++; |
pi->server->refs++; |
|
|
Line 511 L2tpOpen(Link l)
|
Line 517 L2tpOpen(Link l)
|
win = htons(8); /* XXX: this value is empirical. */ |
win = htons(8); /* XXX: this value is empirical. */ |
if ((ppp_l2tp_avp_list_append(avps, 1, 0, AVP_HOST_NAME, |
if ((ppp_l2tp_avp_list_append(avps, 1, 0, AVP_HOST_NAME, |
hostname, strlen(hostname)) == -1) || |
hostname, strlen(hostname)) == -1) || |
(ppp_l2tp_avp_list_append(avps, 1, 0, AVP_VENDOR_NAME, | (ppp_l2tp_avp_list_append(avps, 0, 0, AVP_VENDOR_NAME, |
MPD_VENDOR, strlen(MPD_VENDOR)) == -1) || |
MPD_VENDOR, strlen(MPD_VENDOR)) == -1) || |
(ppp_l2tp_avp_list_append(avps, 1, 0, AVP_BEARER_CAPABILITIES, |
(ppp_l2tp_avp_list_append(avps, 1, 0, AVP_BEARER_CAPABILITIES, |
&cap, sizeof(cap)) == -1) || |
&cap, sizeof(cap)) == -1) || |
Line 578 L2tpOpen(Link l)
|
Line 584 L2tpOpen(Link l)
|
goto fail; |
goto fail; |
} |
} |
|
|
if (!u_addrempty(&tun->self_addr)) { | if (!u_addrempty(&tun->self_addr) || tun->self_port != 0) { |
/* Bind socket to a new port */ |
/* Bind socket to a new port */ |
u_addrtosockaddr(&tun->self_addr,tun->self_port,&sas); |
u_addrtosockaddr(&tun->self_addr,tun->self_port,&sas); |
if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE, |
if (NgSendMsg(csock, namebuf, NGM_KSOCKET_COOKIE, |
Line 679 L2tpShutdown(Link l)
|
Line 685 L2tpShutdown(Link l)
|
|
|
if (pi->conf.fqdn_peer_addr) |
if (pi->conf.fqdn_peer_addr) |
Freee(pi->conf.fqdn_peer_addr); |
Freee(pi->conf.fqdn_peer_addr); |
| if (pi->conf.peer_mask) |
| Freee(pi->conf.peer_mask); |
L2tpUnListen(l); |
L2tpUnListen(l); |
Freee(l->info); |
Freee(l->info); |
} |
} |
Line 850 L2tpPeerMacAddr(Link l, void *buf, size_t buf_len)
|
Line 857 L2tpPeerMacAddr(Link l, void *buf, size_t buf_len)
|
{ |
{ |
L2tpInfo const l2tp = (L2tpInfo) l->info; |
L2tpInfo const l2tp = (L2tpInfo) l->info; |
|
|
|
if (buf_len < 18) |
|
return 1; |
if (l2tp->tun && l2tp->tun->peer_iface[0]) { |
if (l2tp->tun && l2tp->tun->peer_iface[0]) { |
snprintf(buf, buf_len, "%02x:%02x:%02x:%02x:%02x:%02x", | ether_ntoa_r((struct ether_addr *)l2tp->tun->peer_mac_addr, buf); |
l2tp->tun->peer_mac_addr[0], l2tp->tun->peer_mac_addr[1], | |
l2tp->tun->peer_mac_addr[2], l2tp->tun->peer_mac_addr[3], | |
l2tp->tun->peer_mac_addr[4], l2tp->tun->peer_mac_addr[5]); | |
return (0); |
return (0); |
} |
} |
((char*)buf)[0]=0; |
((char*)buf)[0]=0; |
Line 913 L2tpStat(Context ctx)
|
Line 919 L2tpStat(Context ctx)
|
Printf(", port %u", l2tp->conf.peer_port); |
Printf(", port %u", l2tp->conf.peer_port); |
Printf("\r\n"); |
Printf("\r\n"); |
Printf("\tHostname : %s\r\n", l2tp->conf.hostname); |
Printf("\tHostname : %s\r\n", l2tp->conf.hostname); |
|
Printf("\tPeer mask : %s\r\n", l2tp->conf.peer_mask); |
Printf("\tSecret : %s\r\n", (l2tp->conf.callingnum[0])?"******":""); |
Printf("\tSecret : %s\r\n", (l2tp->conf.callingnum[0])?"******":""); |
Printf("\tCalling number: %s\r\n", l2tp->conf.callingnum); |
Printf("\tCalling number: %s\r\n", l2tp->conf.callingnum); |
Printf("\tCalled number: %s\r\n", l2tp->conf.callednum); |
Printf("\tCalled number: %s\r\n", l2tp->conf.callednum); |
Line 931 L2tpStat(Context ctx)
|
Line 938 L2tpStat(Context ctx)
|
L2tpPeerName(ctx->lnk, buf, sizeof(buf)); |
L2tpPeerName(ctx->lnk, buf, sizeof(buf)); |
Printf(" (%s)\r\n", buf); |
Printf(" (%s)\r\n", buf); |
if (l2tp->tun->peer_iface[0]) { |
if (l2tp->tun->peer_iface[0]) { |
Printf("\tCurrent peer : %02x:%02x:%02x:%02x:%02x:%02x at %s\r\n", | ether_ntoa_r((struct ether_addr *)l2tp->tun->peer_mac_addr, buf); |
l2tp->tun->peer_mac_addr[0], l2tp->tun->peer_mac_addr[1], | Printf("\tCurrent peer : %s at %s\r\n", buf, |
l2tp->tun->peer_mac_addr[2], l2tp->tun->peer_mac_addr[3], | |
l2tp->tun->peer_mac_addr[4], l2tp->tun->peer_mac_addr[5], | |
l2tp->tun->peer_iface); |
l2tp->tun->peer_iface); |
} |
} |
|
|
Printf("\tFraming : %s\r\n", (l2tp->sync?"Sync":"Async")); |
Printf("\tFraming : %s\r\n", (l2tp->sync?"Sync":"Async")); |
} |
} |
Printf("\tCalling number: %s\r\n", l2tp->callingnum); |
Printf("\tCalling number: %s\r\n", l2tp->callingnum); |
Line 1052 ppp_l2tp_ctrl_terminated_cb(struct ppp_l2tp_ctrl *ctrl
|
Line 1056 ppp_l2tp_ctrl_terminated_cb(struct ppp_l2tp_ctrl *ctrl
|
struct l2tp_tun *tun = ppp_l2tp_ctrl_get_cookie(ctrl); |
struct l2tp_tun *tun = ppp_l2tp_ctrl_get_cookie(ctrl); |
int k; |
int k; |
|
|
|
(void)result; |
Log(LG_PHYS, ("L2TP: Control connection %p terminated: %d (%s)", |
Log(LG_PHYS, ("L2TP: Control connection %p terminated: %d (%s)", |
ctrl, error, errmsg)); |
ctrl, error, errmsg)); |
|
|
Line 1108 ppp_l2tp_initiated_cb(struct ppp_l2tp_ctrl *ctrl,
|
Line 1113 ppp_l2tp_initiated_cb(struct ppp_l2tp_ctrl *ctrl,
|
u_char *include_length, u_char *enable_dseq) |
u_char *include_length, u_char *enable_dseq) |
{ |
{ |
struct l2tp_tun *const tun = ppp_l2tp_ctrl_get_cookie(ctrl); |
struct l2tp_tun *const tun = ppp_l2tp_ctrl_get_cookie(ctrl); |
|
char *peername = ppp_l2tp_ctrl_get_peer_name_p(ctrl); |
struct ppp_l2tp_avp_ptrs *ptrs = NULL; |
struct ppp_l2tp_avp_ptrs *ptrs = NULL; |
Link l = NULL; |
Link l = NULL; |
L2tpInfo pi = NULL; |
L2tpInfo pi = NULL; |
Line 1151 ppp_l2tp_initiated_cb(struct ppp_l2tp_ctrl *ctrl,
|
Line 1157 ppp_l2tp_initiated_cb(struct ppp_l2tp_ctrl *ctrl,
|
((u_addrempty(&pi2->conf.self_addr)) || (u_addrcompare(&pi2->conf.self_addr, &tun->self_addr) == 0)) && |
((u_addrempty(&pi2->conf.self_addr)) || (u_addrcompare(&pi2->conf.self_addr, &tun->self_addr) == 0)) && |
(pi2->conf.self_port == 0 || pi2->conf.self_port == tun->self_port) && |
(pi2->conf.self_port == 0 || pi2->conf.self_port == tun->self_port) && |
(IpAddrInRange(&pi2->conf.peer_addr, &tun->peer_addr)) && |
(IpAddrInRange(&pi2->conf.peer_addr, &tun->peer_addr)) && |
(pi2->conf.peer_port == 0 || pi2->conf.peer_port == tun->peer_port)) { | (pi2->conf.peer_port == 0 || pi2->conf.peer_port == tun->peer_port) && |
| (peername == NULL || *peername == 0 || pi2->conf.peer_mask == 0 || fnmatch(pi2->conf.peer_mask, peername, 0) == 0)) { |
|
|
if (pi == NULL || pi2->conf.peer_addr.width > pi->conf.peer_addr.width) { |
if (pi == NULL || pi2->conf.peer_addr.width > pi->conf.peer_addr.width) { |
l = l2; |
l = l2; |
Line 1170 ppp_l2tp_initiated_cb(struct ppp_l2tp_ctrl *ctrl,
|
Line 1177 ppp_l2tp_initiated_cb(struct ppp_l2tp_ctrl *ctrl,
|
Log(LG_PHYS, ("[%s] L2TP: %s call #%u via control connection %p accepted", |
Log(LG_PHYS, ("[%s] L2TP: %s call #%u via control connection %p accepted", |
l->name, (out?"Outgoing":"Incoming"), |
l->name, (out?"Outgoing":"Incoming"), |
ppp_l2tp_sess_get_serial(sess), ctrl)); |
ppp_l2tp_sess_get_serial(sess), ctrl)); |
|
if (peername && *peername) |
|
Log(LG_PHYS2, ("[%s] L2TP: Call #%u remote hostname is %s", |
|
l->name, ppp_l2tp_sess_get_serial(sess), peername)); |
|
|
if (out) |
if (out) |
l->state = PHYS_STATE_READY; |
l->state = PHYS_STATE_READY; |
Line 1180 ppp_l2tp_initiated_cb(struct ppp_l2tp_ctrl *ctrl,
|
Line 1190 ppp_l2tp_initiated_cb(struct ppp_l2tp_ctrl *ctrl,
|
pi->tun = tun; |
pi->tun = tun; |
tun->active_sessions++; |
tun->active_sessions++; |
pi->sess = sess; |
pi->sess = sess; |
if (ptrs->callingnum && ptrs->callingnum->number) | if (ptrs->callingnum) |
strlcpy(pi->callingnum, ptrs->callingnum->number, sizeof(pi->callingnum)); |
strlcpy(pi->callingnum, ptrs->callingnum->number, sizeof(pi->callingnum)); |
if (ptrs->callednum && ptrs->callednum->number) | if (ptrs->callednum) |
strlcpy(pi->callednum, ptrs->callednum->number, sizeof(pi->callednum)); |
strlcpy(pi->callednum, ptrs->callednum->number, sizeof(pi->callednum)); |
|
|
*include_length = (Enabled(&pi->conf.options, L2TP_CONF_LENGTH)?1:0); |
*include_length = (Enabled(&pi->conf.options, L2TP_CONF_LENGTH)?1:0); |
Line 1379 L2tpServerEvent(int type, void *arg)
|
Line 1389 L2tpServerEvent(int type, void *arg)
|
u_int16_t win; |
u_int16_t win; |
int k; |
int k; |
|
|
|
(void)type; |
/* Allocate buffer */ |
/* Allocate buffer */ |
buf = Malloc(MB_PHYS, bufsize); |
buf = Malloc(MB_PHYS, bufsize); |
|
|
Line 1712 L2tpNodeUpdate(Link l)
|
Line 1723 L2tpNodeUpdate(Link l)
|
*/ |
*/ |
|
|
static int |
static int |
L2tpSetCommand(Context ctx, int ac, char *av[], void *arg) | L2tpSetCommand(Context ctx, int ac, const char *const av[], const void *arg) |
{ |
{ |
L2tpInfo const l2tp = (L2tpInfo) ctx->lnk->info; |
L2tpInfo const l2tp = (L2tpInfo) ctx->lnk->info; |
char **fqdn_peer_addr = &l2tp->conf.fqdn_peer_addr; |
char **fqdn_peer_addr = &l2tp->conf.fqdn_peer_addr; |
|
char **peer_mask = &l2tp->conf.peer_mask; |
struct u_range rng; |
struct u_range rng; |
int port; |
int port; |
|
|
Line 1762 L2tpSetCommand(Context ctx, int ac, char *av[], void *
|
Line 1774 L2tpSetCommand(Context ctx, int ac, char *av[], void *
|
return(-1); |
return(-1); |
strlcpy(l2tp->conf.hostname, av[0], sizeof(l2tp->conf.hostname)); |
strlcpy(l2tp->conf.hostname, av[0], sizeof(l2tp->conf.hostname)); |
break; |
break; |
|
case SET_PEERMASK: |
|
if (ac != 1) |
|
return(-1); |
|
if (*peer_mask) |
|
Freee(*peer_mask); |
|
*peer_mask = Mstrdup(MB_PHYS, av[0]); |
|
break; |
case SET_SECRET: |
case SET_SECRET: |
if (ac != 1) |
if (ac != 1) |
return(-1); |
return(-1); |
Line 1784 L2tpSetCommand(Context ctx, int ac, char *av[], void *
|
Line 1803 L2tpSetCommand(Context ctx, int ac, char *av[], void *
|
*/ |
*/ |
|
|
int |
int |
L2tpsStat(Context ctx, int ac, char *av[], void *arg) | L2tpsStat(Context ctx, int ac, const char *const av[], const void *arg) |
{ |
{ |
struct l2tp_tun *tun; |
struct l2tp_tun *tun; |
struct ghash_walk walk; |
struct ghash_walk walk; |
char buf1[64], buf2[64], buf3[64]; |
char buf1[64], buf2[64], buf3[64]; |
|
|
|
(void)ac; |
|
(void)av; |
|
(void)arg; |
|
|
Printf("Active L2TP tunnels:\r\n"); |
Printf("Active L2TP tunnels:\r\n"); |
ghash_walk_init(gL2tpTuns, &walk); |
ghash_walk_init(gL2tpTuns, &walk); |