Fix service_name management and add pppoe_only_equal_svc_name parameter
authorfendo <fendo@bi12info.com>
Tue, 9 Apr 2013 15:03:00 +0000 (17:03 +0200)
committerfendo <fendo@bi12info.com>
Tue, 9 Apr 2013 15:03:00 +0000 (17:03 +0200)
Docs/manual.html
l2tpns.c
l2tpns.h
pppoe.c

index 384fe9a..95e3afe 100644 (file)
@@ -466,6 +466,11 @@ PPPOE service name (default: NULL).
 PPPOE  access concentrator name (default: "l2tpns-pppoe").
 </LI>
 
+<LI><B>pppoe_only_equal_svc_name</B> (boolean)<BR>
+If set to yes, the PPPOE server only accepts clients with a "service-name"
+different from NULL and a "service-name" equal to server "service-name" (default: no).
+</LI>
+
 </UL>
 
 <P><U><B>BGP configuration</B></U></P>
index 4545d6c..8f1ace5 100644 (file)
--- a/l2tpns.c
+++ b/l2tpns.c
@@ -185,6 +185,7 @@ config_descriptt config_values[] = {
        CONFIG("disable_sending_hello", disable_sending_hello, BOOL),
        CONFIG("disable_no_spoof", disable_no_spoof, BOOL),
        CONFIG("bind_multi_address", bind_multi_address, STRING),
+       CONFIG("pppoe_only_equal_svc_name", pppoe_only_equal_svc_name, BOOL),
        { NULL, 0, 0, 0 }
 };
 
index e962256..89f49dd 100644 (file)
--- a/l2tpns.h
+++ b/l2tpns.h
@@ -773,6 +773,7 @@ typedef struct
        char pppoe_service_name[64];    // pppoe service name
        char pppoe_ac_name[64];
        uint8_t pppoe_hwaddr[ETH_ALEN]; // MAC addr of interface pppoe to bind
+       int pppoe_only_equal_svc_name; // Accept only PADI with service-name equal to server
        int disable_sending_hello; // Disable l2tp sending HELLO message for Apple compatibility.
        int disable_no_spoof; // Disable no spoof (permit load balancing client --> internet)
        int nbudpfd; // number UDP file handle
diff --git a/pppoe.c b/pppoe.c
index 01cc153..4d442cc 100644 (file)
--- a/pppoe.c
+++ b/pppoe.c
@@ -502,20 +502,27 @@ static void pppoe_recv_PADI(uint8_t *pack, int size)
                return;
 
        len = ntohs(hdr->length);
-       for (n = 0; n < len; n += sizeof(*tag) + ntohs(tag->tag_len)) {
+       for (n = 0; n < len; n += sizeof(*tag) + ntohs(tag->tag_len))
+       {
                tag = (struct pppoe_tag *)(pack + ETH_HLEN + sizeof(*hdr) + n);
                if (n + sizeof(*tag) + ntohs(tag->tag_len) > len)
                        return;
-               switch (ntohs(tag->tag_type)) {
+               switch (ntohs(tag->tag_type))
+               {
                        case TAG_END_OF_LIST:
                                break;
                        case TAG_SERVICE_NAME:
-                               if (*config->pppoe_service_name && tag->tag_len)
+                               if (config->pppoe_only_equal_svc_name && *config->pppoe_service_name && !tag->tag_len)
+                               {
+                                       break;
+                               }
+                               else if (*config->pppoe_service_name && tag->tag_len)
                                {
                                        if (ntohs(tag->tag_len) != strlen(config->pppoe_service_name))
                                                break;
                                        if (memcmp(tag->tag_data, config->pppoe_service_name, ntohs(tag->tag_len)))
                                                break;
+                                       service_name_tag = tag;
                                        service_match = 1;
                                }
                                else