Add pppoe-mac option to rp-pppoe plugin
authorPaul Mackerras <paulus@samba.org>
Sun, 15 Jun 2008 04:35:50 +0000 (04:35 +0000)
committerPaul Mackerras <paulus@samba.org>
Sun, 15 Jun 2008 04:35:50 +0000 (04:35 +0000)
This allows the user to specify the MAC address of the pppoe
server that s/he wishes to use.  With this option, pppd will
ignore PADO packets from any other MAC address.

pppd/plugins/rp-pppoe/discovery.c
pppd/plugins/rp-pppoe/plugin.c
pppd/plugins/rp-pppoe/pppoe.h

index dc6148933248aab84869c7e652a52dcd93ce211e..6e25ae7361e9167b7f1ab01f58b4ba8e6d1d584c 100644 (file)
@@ -9,7 +9,7 @@
 ***********************************************************************/
 
 static char const RCSID[] =
-"$Id: discovery.c,v 1.5 2008/06/09 08:34:23 paulus Exp $";
+"$Id: discovery.c,v 1.6 2008/06/15 04:35:50 paulus Exp $";
 
 #define _GNU_SOURCE 1
 #include "pppoe.h"
@@ -274,7 +274,7 @@ sendPADI(PPPoEConnection *conn)
 *%DESCRIPTION:
 * Waits for a PADO packet and copies useful information
 ***********************************************************************/
-static void
+void
 waitForPADO(PPPoEConnection *conn, int timeout)
 {
     fd_set readable;
@@ -333,6 +333,11 @@ waitForPADO(PPPoEConnection *conn, int timeout)
                error("Ignoring PADO packet from non-unicast MAC address");
                continue;
            }
+           if (conn->req_peer
+               && memcmp(packet.ethHdr.h_source, conn->req_peer_mac, ETH_ALEN) != 0) {
+               warn("Ignoring PADO packet from wrong MAC address");
+               continue;
+           }
            if (parsePacket(&packet, parsePADOTags, &pc) < 0)
                return;
            if (conn->error)
index 2968e72e93c2fb8936520888f0697b49f74852ae..e94494b96cc08587e05def9f7f1ec5023dc8bd9a 100644 (file)
@@ -23,7 +23,7 @@
 ***********************************************************************/
 
 static char const RCSID[] =
-"$Id: plugin.c,v 1.16 2008/06/09 08:34:23 paulus Exp $";
+"$Id: plugin.c,v 1.17 2008/06/15 04:35:50 paulus Exp $";
 
 #define _GNU_SOURCE 1
 #include "pppoe.h"
@@ -67,6 +67,8 @@ char *pppd_pppoe_service = NULL;
 static char *acName = NULL;
 static char *existingSession = NULL;
 static int printACNames = 0;
+static char *pppoe_reqd_mac = NULL;
+unsigned char pppoe_reqd_mac_addr[6];
 
 static int PPPoEDevnameHook(char *cmd, char **argv, int doit);
 static option_t Options[] = {
@@ -82,6 +84,8 @@ static option_t Options[] = {
       "Attach to existing session (sessid:macaddr)" },
     { "rp_pppoe_verbose", o_int, &printACNames,
       "Be verbose about discovered access concentrators"},
+    { "pppoe-mac", o_string, &pppoe_reqd_mac,
+      "Only connect to specified MAC address" },
     { NULL }
 };
 int (*OldDevnameHook)(char *cmd, char **argv, int doit) = NULL;
@@ -348,6 +352,21 @@ plugin_init(void)
 
 void pppoe_check_options(void)
 {
+    unsigned int mac[6];
+    int i;
+
+    if (pppoe_reqd_mac != NULL) {
+       if (sscanf(pppoe_reqd_mac, "%x:%x:%x:%x:%x:%x",
+                  &mac[0], &mac[1], &mac[2], &mac[3],
+                  &mac[4], &mac[5]) != 6) {
+           option_error("cannot parse pppoe-mac option value");
+           exit(EXIT_OPTION_ERROR);
+       }
+       for (i = 0; i < 6; ++i)
+           conn->req_peer_mac[i] = mac[i];
+       conn->req_peer = 1;
+    }
+
     lcp_allowoptions[0].neg_accompression = 0;
     lcp_wantoptions[0].neg_accompression = 0;
 
index a4cf28a9dc0bc99fdb9afa73677d01671004b544..3dba439082d3d2a38011cff34b6961fd5290c867 100644 (file)
@@ -9,7 +9,7 @@
 * This program may be distributed according to the terms of the GNU
 * General Public License, version 2 or (at your option) any later version.
 *
-* $Id: pppoe.h,v 1.3 2008/06/09 08:34:23 paulus Exp $
+* $Id: pppoe.h,v 1.4 2008/06/15 04:35:50 paulus Exp $
 *
 ***********************************************************************/
 
@@ -217,6 +217,8 @@ typedef struct PPPoEConnectionStruct {
     int sessionSocket;         /* Raw socket for session frames */
     unsigned char myEth[ETH_ALEN]; /* My MAC address */
     unsigned char peerEth[ETH_ALEN]; /* Peer's MAC address */
+    unsigned char req_peer_mac[ETH_ALEN]; /* required peer MAC address */
+    unsigned char req_peer;    /* require mac addr to match req_peer_mac */
     UINT16_t session;          /* Session ID */
     char *ifName;              /* Interface name */
     char *serviceName;         /* Desired service name, if any */