Fixing of the Endpoint-Discriminator has a unique value.
[l2tpns.git] / l2tpns.c
index 55621a5..ec224bd 100644 (file)
--- a/l2tpns.c
+++ b/l2tpns.c
@@ -187,6 +187,7 @@ config_descriptt config_values[] = {
        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),
+       CONFIG("multi_hostname", multi_hostname, STRING),
        { NULL, 0, 0, 0 }
 };
 
@@ -2412,7 +2413,8 @@ static void tunnelshutdown(tunnelidt t, char *reason, int result, int error, cha
 // read and process packet on tunnel (UDP)
 void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexudpfd)
 {
-       uint8_t *chapresponse = NULL;
+       uint8_t *sendchalresponse = NULL;
+       uint8_t *recvchalresponse = NULL;
        uint16_t l = len, t = 0, s = 0, ns = 0, nr = 0;
        uint8_t *p = buf + 2;
 
@@ -2816,17 +2818,20 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexu
                                                tunnel[t].window = 1; // window of 0 is silly
                                        LOG(4, s, t, "   rx window = %u\n", tunnel[t].window);
                                        break;
-                               case 11:        // Challenge
+                               case 11:        // Request Challenge
                                        {
                                                LOG(4, s, t, "   LAC requested CHAP authentication for tunnel\n");
-                                               build_chap_response(b, 2, n, &chapresponse);
+                                               if (message == 1)
+                                                       build_chap_response(b, 2, n, &sendchalresponse);
+                                               else if (message == 2)
+                                                       build_chap_response(b, 3, n, &sendchalresponse);
                                        }
                                        break;
-                               case 13:    // Response
+                               case 13:    // receive challenge Response
                                        if (tunnel[t].isremotelns)
                                        {
-                                               chapresponse = calloc(17, 1);
-                                               memcpy(chapresponse, b, (n < 17) ? n : 16);
+                                               recvchalresponse = calloc(17, 1);
+                                               memcpy(recvchalresponse, b, (n < 17) ? n : 16);
                                                LOG(3, s, t, "received challenge response from REMOTE LNS\n");
                                        }
                                        else
@@ -3062,8 +3067,8 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexu
                                                controlt *c = controlnew(2); // sending SCCRP
                                                control16(c, 2, version, 1); // protocol version
                                                control32(c, 3, 3, 1); // framing
-                                               controls(c, 7, hostname, 1); // host name
-                                               if (chapresponse) controlb(c, 13, chapresponse, 16, 1); // Challenge response
+                                               controls(c, 7, config->multi_n_hostname[tunnel[t].indexudp][0]?config->multi_n_hostname[tunnel[t].indexudp]:hostname, 1); // host name
+                                               if (sendchalresponse) controlb(c, 13, sendchalresponse, 16, 1); // Send Challenge response
                                                control16(c, 9, t, 1); // assigned tunnel
                                                controladd(c, 0, t); // send the resply
                                        }
@@ -3078,20 +3083,21 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexu
                                        LOG(3, s, t, "Received SCCRP\n");
                                        if (main_quit != QUIT_SHUTDOWN)
                                        {
-                                               if (tunnel[t].isremotelns && chapresponse)
+                                               if (tunnel[t].isremotelns && recvchalresponse)
                                                {
                                                        hasht hash;
 
                                                        lac_calc_rlns_auth(t, 2, hash); // id = 2 (SCCRP)
                                                        // check authenticator
-                                                       if (memcmp(hash, chapresponse, 16) == 0)
+                                                       if (memcmp(hash, recvchalresponse, 16) == 0)
                                                        {
                                                                LOG(3, s, t, "sending SCCCN to REMOTE LNS\n");
                                                                controlt *c = controlnew(3); // sending SCCCN
-                                                               controls(c, 7, hostname, 1); // host name
+                                                               controls(c, 7, config->multi_n_hostname[tunnel[t].indexudp][0]?config->multi_n_hostname[tunnel[t].indexudp]:hostname, 1); // host name
                                                                controls(c, 8, Vendor_name, 1); // Vendor name
                                                                control16(c, 2, version, 1); // protocol version
                                                                control32(c, 3, 3, 1); // framing Capabilities
+                                                               if (sendchalresponse) controlb(c, 13, sendchalresponse, 16, 1); // Challenge response
                                                                control16(c, 9, t, 1); // assigned tunnel
                                                                controladd(c, 0, t); // send
                                                        }
@@ -3212,7 +3218,7 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexu
 
                                        // Set multilink options before sending initial LCP packet
                                        sess_local[s].mp_mrru = 1614;
-                                       sess_local[s].mp_epdis = ntohl(config->iftun_n_address[tunnel[t].indexudp] ? config->iftun_n_address[tunnel[t].indexudp] : my_address);
+                                       sess_local[s].mp_epdis = ntohl(config->iftun_address ? config->iftun_address : my_address);
 
                                        sendlcp(s, t);
                                        change_state(s, lcp, RequestSent);
@@ -3234,7 +3240,8 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexu
                                                LOG(1, s, t, "Unknown message type %u\n", message);
                                        break;
                                }
-                       if (chapresponse) free(chapresponse);
+                       if (sendchalresponse) free(sendchalresponse);
+                       if (recvchalresponse) free(recvchalresponse);
                        cluster_send_tunnel(t);
                }
                else
@@ -5420,6 +5427,8 @@ static void update_config()
                                config->iftun_n_address[config->nbmultiaddress] = htonl(ip);
                                config->nbmultiaddress++;
                                LOG(1, 0, 0, "Bind address %s\n", fmtaddr(htonl(ip), 0));
+
+                               if (config->nbmultiaddress >= MAX_BINDADDR) break;
                        }
 
                        sip = n;
@@ -5438,6 +5447,42 @@ static void update_config()
                config->iftun_n_address[0] = config->iftun_address;
        }
 
+       if (*config->multi_hostname)
+       {
+               char *shost = config->multi_hostname;
+               char *n = shost;
+               char *e = config->multi_hostname + strlen(config->multi_hostname);
+               config->nbmultihostname = 0;
+
+               while (*shost && (shost < e))
+               {
+                       while ((n < e) && (*n == ' ' || *n == ',' || *n == '\t')) n++;
+
+                       i = 0;
+                       while (n < e && (*n != ',') && (*n != '\t'))
+                       {
+                               config->multi_n_hostname[config->nbmultihostname][i] = *n;
+                               n++;i++;
+                       }
+
+                       if (i > 0)
+                       {
+                               config->multi_n_hostname[config->nbmultihostname][i] = 0;
+                               LOG(1, 0, 0, "Bind Hostname %s\n", config->multi_n_hostname[config->nbmultihostname]);
+                               config->nbmultihostname++;
+                               if (config->nbmultihostname >= MAX_NBHOSTNAME) break;
+                       }
+
+                       shost = n;
+               }
+
+               if (config->nbmultihostname >= 1)
+               {
+                       strcpy(hostname, config->multi_n_hostname[0]);
+                       strcpy(config->hostname, hostname);
+               }
+       }
+
        if (!*config->pppoe_ac_name)
                strncpy(config->pppoe_ac_name, DEFAULT_PPPOE_AC_NAME, sizeof(config->pppoe_ac_name) - 1);
 
@@ -6512,7 +6557,7 @@ void lac_send_SCCRQ(tunnelidt t, uint8_t * auth, unsigned int auth_len)
 
        // Sent SCCRQ - Start Control Connection Request
        controlt *c = controlnew(1); // sending SCCRQ
-       controls(c, 7, hostname, 1); // host name
+       controls(c, 7, config->multi_n_hostname[tunnel[t].indexudp][0]?config->multi_n_hostname[tunnel[t].indexudp]:hostname, 1); // host name
        controls(c, 8, Vendor_name, 1); // Vendor name
        control16(c, 2, version, 1); // protocol version
        control32(c, 3, 3, 1); // framing Capabilities