summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel-pppd/CMakeLists.txt1
-rw-r--r--accel-pppd/accel-ppp.conf4
-rw-r--r--accel-pppd/accel-ppp.conf.58
-rw-r--r--accel-pppd/include/events.h8
-rw-r--r--accel-pppd/ppp/CMakeLists.txt1
-rw-r--r--accel-pppd/ppp/ipcp_opt_wins.c203
-rw-r--r--accel-pppd/ppp/ppp_ipcp.h2
-rw-r--r--accel-pppd/radius/radius.c12
8 files changed, 238 insertions, 1 deletions
diff --git a/accel-pppd/CMakeLists.txt b/accel-pppd/CMakeLists.txt
index 11df04fc..0f7ab089 100644
--- a/accel-pppd/CMakeLists.txt
+++ b/accel-pppd/CMakeLists.txt
@@ -54,6 +54,7 @@ ADD_EXECUTABLE(accel-pppd
ppp/ppp_ipcp.c
ppp/ipcp_opt_ipaddr.c
ppp/ipcp_opt_dns.c
+ ppp/ipcp_opt_wins.c
ppp/ipv6cp_opt_intfid.c
ppp/ppp_ipv6cp.c
ppp/ppp_ccp.c
diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf
index 28e8ed0c..8487ce9f 100644
--- a/accel-pppd/accel-ppp.conf
+++ b/accel-pppd/accel-ppp.conf
@@ -95,6 +95,10 @@ verbose=1
#dns1=172.16.0.1
#dns2=172.16.1.1
+[wins]
+#wins1=172.16.0.1
+#wins2=172.16.1.1
+
[radius]
#dictionary=/usr/local/share/accel-ppp/radius/dictionary
nas-identifier=accel-ppp
diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5
index b3e72653..69b27a5d 100644
--- a/accel-pppd/accel-ppp.conf.5
+++ b/accel-pppd/accel-ppp.conf.5
@@ -206,6 +206,14 @@ You have to explicitly specify range of ip address from which clients can connec
.B x.x.x.x-y
(for example 10.0.0.1-254)
.TP
+.SH [wins]
+.TP
+.BI "wins1=" x.x.x.x
+Specifies primary NBNS to be sent to peer.
+.TP
+.BI "wins2=" x.x.x.x
+Specifies secondary NBNS to be sent to peer.
+.TP
.SH [pptp]
.br
Configuration of PPTP module.
diff --git a/accel-pppd/include/events.h b/accel-pppd/include/events.h
index 5d6fea7e..0d8f1fc3 100644
--- a/accel-pppd/include/events.h
+++ b/accel-pppd/include/events.h
@@ -21,6 +21,7 @@
#define EV_SHAPER 101
#define EV_MPPE_KEYS 102
#define EV_DNS 103
+#define EV_WINS 104
#define EV_RADIUS_ACCESS_ACCEPT 200
#define EV_RADIUS_COA 201
@@ -56,5 +57,10 @@ struct ev_dns_t
in_addr_t dns2;
};
+struct ev_wins_t
+{
+ struct ppp_t *ppp;
+ in_addr_t wins1;
+ in_addr_t wins2;
+};
#endif
-
diff --git a/accel-pppd/ppp/CMakeLists.txt b/accel-pppd/ppp/CMakeLists.txt
index f4c0f04a..560f7759 100644
--- a/accel-pppd/ppp/CMakeLists.txt
+++ b/accel-pppd/ppp/CMakeLists.txt
@@ -11,6 +11,7 @@ SET(sources_c
ppp_ipcp.c
ipcp_opt_ipaddr.c
ipcp_opt_dns.c
+ ipcp_opt_wins.c
ppp_ccp.c
)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/accel-pppd/ppp/ipcp_opt_wins.c b/accel-pppd/ppp/ipcp_opt_wins.c
new file mode 100644
index 00000000..d549722a
--- /dev/null
+++ b/accel-pppd/ppp/ipcp_opt_wins.c
@@ -0,0 +1,203 @@
+#include <stdlib.h>
+#include <string.h>
+#include <arpa/inet.h>
+
+#include "ppp.h"
+#include "ppp_ipcp.h"
+#include "log.h"
+#include "ipdb.h"
+#include "events.h"
+
+#include "memdebug.h"
+
+static in_addr_t conf_wins1;
+static in_addr_t conf_wins2;
+
+static struct ipcp_option_t *wins1_init(struct ppp_ipcp_t *ipcp);
+static struct ipcp_option_t *wins2_init(struct ppp_ipcp_t *ipcp);
+static void wins_free(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt);
+static int wins_send_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr);
+static int wins_send_conf_nak(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr);
+static int wins_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr);
+static int wins_recv_conf_rej(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr);
+static void wins1_print(void (*print)(const char *fmt,...), struct ipcp_option_t*, uint8_t *ptr);
+static void wins2_print(void (*print)(const char *fmt,...), struct ipcp_option_t*, uint8_t *ptr);
+
+struct wins_option_t
+{
+ struct ipcp_option_t opt;
+ in_addr_t addr;
+ int rejected;
+};
+
+static struct ipcp_option_handler_t wins1_opt_hnd = {
+ .init = wins1_init,
+ .send_conf_req = wins_send_conf_req,
+ .send_conf_nak = wins_send_conf_nak,
+ .recv_conf_req = wins_recv_conf_req,
+ .recv_conf_rej = wins_recv_conf_rej,
+ .free = wins_free,
+ .print = wins1_print,
+};
+
+static struct ipcp_option_handler_t wins2_opt_hnd = {
+ .init = wins2_init,
+ .send_conf_req = wins_send_conf_req,
+ .send_conf_nak = wins_send_conf_nak,
+ .recv_conf_req = wins_recv_conf_req,
+ .recv_conf_rej = wins_recv_conf_rej,
+ .free = wins_free,
+ .print = wins2_print,
+};
+
+static struct ipcp_option_t *wins1_init(struct ppp_ipcp_t *ipcp)
+{
+ struct wins_option_t *wins_opt = _malloc(sizeof(*wins_opt));
+ memset(wins_opt, 0, sizeof(*wins_opt));
+ wins_opt->opt.id = CI_WINS1;
+ wins_opt->opt.len = 6;
+
+ return &wins_opt->opt;
+}
+
+static struct ipcp_option_t *wins2_init(struct ppp_ipcp_t *ipcp)
+{
+ struct wins_option_t *wins_opt = _malloc(sizeof(*wins_opt));
+ memset(wins_opt, 0, sizeof(*wins_opt));
+ wins_opt->opt.id = CI_WINS2;
+ wins_opt->opt.len = 6;
+
+ return &wins_opt->opt;
+}
+
+static void wins_free(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt)
+{
+ struct wins_option_t *wins_opt=container_of(opt,typeof(*wins_opt),opt);
+
+ _free(wins_opt);
+}
+
+static int wins_send_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr)
+{
+ struct wins_option_t *wins_opt = container_of(opt, typeof(*wins_opt), opt);
+ struct ipcp_opt32_t *opt32 = (struct ipcp_opt32_t *)ptr;
+
+ if (!wins_opt->addr || wins_opt->rejected)
+ return 0;
+
+ opt32->hdr.id = wins_opt->opt.id;
+ opt32->hdr.len = 6;
+ opt32->val = 0;
+
+ return 6;
+}
+
+static int wins_send_conf_nak(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr)
+{
+ struct wins_option_t *wins_opt = container_of(opt, typeof(*wins_opt), opt);
+ struct ipcp_opt32_t *opt32 = (struct ipcp_opt32_t *)ptr;
+ opt32->hdr.id = wins_opt->opt.id;
+ opt32->hdr.len = 6;
+ opt32->val = wins_opt->addr;
+ return 6;
+}
+
+static int wins_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr)
+{
+ struct wins_option_t *wins_opt = container_of(opt, typeof(*wins_opt), opt);
+ struct ipcp_opt32_t *opt32 = (struct ipcp_opt32_t*)ptr;
+
+ if (opt32->hdr.len != 6)
+ return IPCP_OPT_REJ;
+
+ if (!wins_opt->addr) {
+ if (wins_opt->opt.id == CI_WINS1 && conf_wins1)
+ wins_opt->addr=conf_wins1;
+ else if (wins_opt->opt.id == CI_WINS2 && conf_wins2)
+ wins_opt->addr=conf_wins2;
+
+ if (!wins_opt->addr) {
+ wins_opt->addr = opt32->val;
+ return IPCP_OPT_ACK;
+ }
+ }
+
+ if (wins_opt->addr == opt32->val)
+ return IPCP_OPT_ACK;
+
+ return IPCP_OPT_NAK;
+}
+
+static int wins_recv_conf_rej(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr)
+{
+ struct wins_option_t *wins_opt = container_of(opt, typeof(*wins_opt), opt);
+
+ wins_opt->rejected = 1;
+
+ return 0;
+}
+
+static void wins1_print(void (*print)(const char *fmt,...), struct ipcp_option_t *opt, uint8_t *ptr)
+{
+ struct wins_option_t *wins_opt = container_of(opt, typeof(*wins_opt), opt);
+ struct ipcp_opt32_t *opt32 = (struct ipcp_opt32_t *)ptr;
+ struct in_addr in;
+
+ if (ptr)
+ in.s_addr = opt32->val;
+ else
+ in.s_addr = wins_opt->addr;
+
+ print("<wins1 %s>", inet_ntoa(in));
+}
+
+static void wins2_print(void (*print)(const char *fmt,...), struct ipcp_option_t *opt, uint8_t *ptr)
+{
+ struct wins_option_t *wins_opt = container_of(opt, typeof(*wins_opt), opt);
+ struct ipcp_opt32_t *opt32 = (struct ipcp_opt32_t *)ptr;
+ struct in_addr in;
+
+ if (ptr)
+ in.s_addr = opt32->val;
+ else
+ in.s_addr = wins_opt->addr;
+
+ print("<wins2 %s>", inet_ntoa(in));
+}
+
+static void ev_wins(struct ev_wins_t *ev)
+{
+ struct wins_option_t *wins_opt;
+
+ wins_opt = container_of(ipcp_find_option(ev->ppp, &wins1_opt_hnd), typeof(*wins_opt), opt);
+ wins_opt->addr = ev->wins1;
+
+ wins_opt = container_of(ipcp_find_option(ev->ppp, &wins2_opt_hnd), typeof(*wins_opt), opt);
+ wins_opt->addr = ev->wins2;
+}
+
+static void load_config(void)
+{
+ char *opt;
+
+ opt = conf_get_opt("wins", "wins1");
+ if (opt)
+ conf_wins1 = inet_addr(opt);
+
+ opt = conf_get_opt("wins", "wins2");
+ if (opt)
+ conf_wins2 = inet_addr(opt);
+}
+
+static void wins_opt_init()
+{
+ ipcp_option_register(&wins1_opt_hnd);
+ ipcp_option_register(&wins2_opt_hnd);
+
+ load_config();
+ triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
+
+ triton_event_register_handler(EV_WINS, (triton_event_func)ev_wins);
+}
+
+DEFINE_INIT(4, wins_opt_init);
diff --git a/accel-pppd/ppp/ppp_ipcp.h b/accel-pppd/ppp/ppp_ipcp.h
index 301bdcec..74127020 100644
--- a/accel-pppd/ppp/ppp_ipcp.h
+++ b/accel-pppd/ppp/ppp_ipcp.h
@@ -12,6 +12,8 @@
#define CI_ADDR 3 /* IP-Address */
#define CI_DNS1 129 /* Primary-DNS-Address */
#define CI_DNS2 131 /* Secondary-DNS-Address */
+#define CI_WINS1 130 /* Primary-NBNS-Address */
+#define CI_WINS2 132 /* Secondary-NBNS-Address */
struct ipcp_hdr_t
{
diff --git a/accel-pppd/radius/radius.c b/accel-pppd/radius/radius.c
index 8f17fcc9..b6a0b5f5 100644
--- a/accel-pppd/radius/radius.c
+++ b/accel-pppd/radius/radius.c
@@ -58,9 +58,11 @@ int rad_proc_attrs(struct rad_req_t *req)
struct rad_attr_t *attr;
struct ipv6db_addr_t *a;
struct ev_dns_t dns;
+ struct ev_wins_t wins;
int res = 0;
dns.ppp = NULL;
+ wins.ppp = NULL;
req->rpd->acct_interim_interval = conf_acct_interim_interval;
list_for_each_entry(attr, &req->reply->attrs, entry) {
@@ -74,6 +76,14 @@ int rad_proc_attrs(struct rad_req_t *req)
dns.ppp = req->rpd->ppp;
dns.dns2 = attr->val.ipaddr;
break;
+ case MS_Primary_NBNS_Server:
+ wins.ppp = req->rpd->ppp;
+ wins.wins1 = attr->val.ipaddr;
+ break;
+ case MS_Secondary_NBNS_Server:
+ wins.ppp = req->rpd->ppp;
+ wins.wins2 = attr->val.ipaddr;
+ break;
}
continue;
} else if (attr->vendor)
@@ -134,6 +144,8 @@ int rad_proc_attrs(struct rad_req_t *req)
if (dns.ppp)
triton_event_fire(EV_DNS, &dns);
+ if (wins.ppp)
+ triton_event_fire(EV_WINS, &wins);
return res;
}