]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/plugins/rp-pppoe/plugin.c
Updates and fixes for the rp-pppoe plugin
[ppp.git] / pppd / plugins / rp-pppoe / plugin.c
index a4784107e8755861bafb15a98ad8cd4f34077e97..2968e72e93c2fb8936520888f0697b49f74852ae 100644 (file)
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
+*
 ***********************************************************************/
 
 static char const RCSID[] =
-"$Id: plugin.c,v 1.7 2002/04/02 13:11:00 dfs Exp $";
+"$Id: plugin.c,v 1.16 2008/06/09 08:34:23 paulus Exp $";
 
 #define _GNU_SOURCE 1
 #include "pppoe.h"
@@ -32,10 +33,9 @@ static char const RCSID[] =
 #include "pppd/lcp.h"
 #include "pppd/ipcp.h"
 #include "pppd/ccp.h"
-#include "pppd/pathnames.h"
+/* #include "pppd/pathnames.h" */
 
 #include <linux/types.h>
-#include <syslog.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -48,9 +48,13 @@ static char const RCSID[] =
 #include <signal.h>
 #include <net/ethernet.h>
 #include <net/if_arp.h>
-#include "ppp_defs.h"
-#include "if_ppp.h"
-#include "if_pppox.h"
+#include <linux/ppp_defs.h>
+#include <linux/if_ppp.h>
+#include <linux/if_pppox.h>
+
+#ifndef _ROOT_PATH
+#define _ROOT_PATH ""
+#endif
 
 #define _PATH_ETHOPT         _ROOT_PATH "/etc/ppp/options."
 
@@ -97,20 +101,17 @@ PPPOEInitDevice(void)
 {
     conn = malloc(sizeof(PPPoEConnection));
     if (!conn) {
-       fatal("Could not allocate memory for PPPoE session");
+       novm("PPPoE session data");
     }
     memset(conn, 0, sizeof(PPPoEConnection));
-    if (acName) {
-       SET_STRING(conn->acName, acName);
-    }
-    if (pppd_pppoe_service) {
-       SET_STRING(conn->serviceName, pppd_pppoe_service);
-    }
-    SET_STRING(conn->ifName, devnam);
+    conn->acName = acName;
+    conn->serviceName = pppd_pppoe_service;
+    conn->ifName = devnam;
     conn->discoverySocket = -1;
     conn->sessionSocket = -1;
     conn->useHostUniq = 1;
     conn->printACNames = printACNames;
+    conn->discoveryTimeout = PADI_TIMEOUT;
     return 1;
 }
 
@@ -144,7 +145,8 @@ PPPOEConnectDevice(void)
     } else {
        discovery(conn);
        if (conn->discoveryState != STATE_SESSION) {
-           fatal("Unable to complete PPPoE Discovery");
+           error("Unable to complete PPPoE Discovery");
+           return -1;
        }
     }
 
@@ -154,7 +156,8 @@ PPPOEConnectDevice(void)
     /* Make the session socket */
     conn->sessionSocket = socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_OE);
     if (conn->sessionSocket < 0) {
-       fatal("Failed to create PPPoE socket: %m");
+       error("Failed to create PPPoE socket: %m");
+       goto errout;
     }
     sp.sa_family = AF_PPPOX;
     sp.sa_protocol = PX_PROTO_OE;
@@ -171,50 +174,45 @@ PPPOEConnectDevice(void)
            (unsigned) conn->peerEth[4],
            (unsigned) conn->peerEth[5]);
 
+    warn("Connected to %02X:%02X:%02X:%02X:%02X:%02X via interface %s",
+        (unsigned) conn->peerEth[0],
+        (unsigned) conn->peerEth[1],
+        (unsigned) conn->peerEth[2],
+        (unsigned) conn->peerEth[3],
+        (unsigned) conn->peerEth[4],
+        (unsigned) conn->peerEth[5],
+        conn->ifName);
+
+    script_setenv("MACREMOTE", remote_number, 0);
+
     if (connect(conn->sessionSocket, (struct sockaddr *) &sp,
                sizeof(struct sockaddr_pppox)) < 0) {
-       fatal("Failed to connect PPPoE socket: %d %m", errno);
-       return -1;
+       error("Failed to connect PPPoE socket: %d %m", errno);
+       close(conn->sessionSocket);
+       goto errout;
     }
 
     return conn->sessionSocket;
-}
 
-static void
-PPPOESendConfig(int mtu,
-               u_int32_t asyncmap,
-               int pcomp,
-               int accomp)
-{
-    int sock;
-    struct ifreq ifr;
-
-    if (mtu > MAX_PPPOE_MTU) {
-       warn("Couldn't increase MTU to %d", mtu);
-       mtu = MAX_PPPOE_MTU;
-    }
-    sock = socket(AF_INET, SOCK_DGRAM, 0);
-    if (sock < 0) {
-       fatal("Couldn't create IP socket: %m");
+ errout:
+    if (conn->discoverySocket >= 0) {
+       sendPADT(conn, NULL);
+       close(conn->discoverySocket);
+       conn->discoverySocket = -1;
     }
-    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
-    ifr.ifr_mtu = mtu;
-    if (ioctl(sock, SIOCSIFMTU, &ifr) < 0) {
-       fatal("ioctl(SIOCSIFMTU): %m");
-    }
-    (void) close (sock);
+    return -1;
 }
 
-
 static void
 PPPOERecvConfig(int mru,
                u_int32_t asyncmap,
                int pcomp,
                int accomp)
 {
-    if (mru > MAX_PPPOE_MTU) {
-       error("Couldn't increase MRU to %d", mru);
-    }
+#if 0 /* broken protocol, but no point harrassing the users I guess... */
+    if (mru > MAX_PPPOE_MTU)
+       warn("Couldn't increase MRU to %d", mru);
+#endif
 }
 
 /**********************************************************************
@@ -237,19 +235,20 @@ PPPOEDisconnectDevice(void)
     memcpy(sp.sa_addr.pppoe.dev, conn->ifName, IFNAMSIZ);
     memcpy(sp.sa_addr.pppoe.remote, conn->peerEth, ETH_ALEN);
     if (connect(conn->sessionSocket, (struct sockaddr *) &sp,
-               sizeof(struct sockaddr_pppox)) < 0) {
-       fatal("Failed to disconnect PPPoE socket: %d %m", errno);
-       return;
-    }
+               sizeof(struct sockaddr_pppox)) < 0)
+       error("Failed to disconnect PPPoE socket: %d %m", errno);
     close(conn->sessionSocket);
+    /* don't send PADT?? */
+    if (conn->discoverySocket >= 0)
+       close(conn->discoverySocket);
 }
 
 static void
 PPPOEDeviceOptions(void)
 {
     char buf[256];
-    snprintf(buf, 256, _PATH_ETHOPT "%s",devnam);
-    if(!options_from_file(buf, 0, 0, 1))
+    snprintf(buf, 256, _PATH_ETHOPT "%s", devnam);
+    if (!options_from_file(buf, 0, 0, 1))
        exit(EXIT_OPTION_ERROR);
 
 }
@@ -275,15 +274,14 @@ PPPoEDevnameHook(char *cmd, char **argv, int doit)
     int fd;
     struct ifreq ifr;
 
-    /* Only do it if name is "ethXXX" or "nic-XXXX.  In latter case,
-       strip off the "nic-" */
-    /* Thanks to Russ Couturier for this fix */
+    /*
+     * Take any otherwise-unrecognized option as a possible device name,
+     * and test if it is the name of a network interface with a
+     * hardware address whose sa_family is ARPHRD_ETHER.
+     */
     if (strlen(cmd) > 4 && !strncmp(cmd, "nic-", 4)) {
        /* Strip off "nic-" */
        cmd += 4;
-    } else if (strlen(cmd) < 4 || strncmp(cmd, "eth", 3)) {
-       if (OldDevnameHook) return OldDevnameHook(cmd, argv, doit);
-       return 0;
     }
 
     /* Open a socket */
@@ -301,8 +299,9 @@ PPPoEDevnameHook(char *cmd, char **argv, int doit)
                r = 0;
            } else {
                if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
-                   error("Interface %s not Ethernet", cmd);
-                   r=0;
+                   if (doit)
+                       error("Interface %s not Ethernet", cmd);
+                   r = 0;
                }
            }
        }
@@ -310,37 +309,18 @@ PPPoEDevnameHook(char *cmd, char **argv, int doit)
 
     /* Close socket */
     close(fd);
-    if (r) {
+    if (r && doit) {
        strncpy(devnam, cmd, sizeof(devnam));
        if (the_channel != &pppoe_channel) {
 
            the_channel = &pppoe_channel;
            modem = 0;
 
-           lcp_allowoptions[0].neg_accompression = 0;
-           lcp_wantoptions[0].neg_accompression = 0;
-
-           lcp_allowoptions[0].neg_asyncmap = 0;
-           lcp_wantoptions[0].neg_asyncmap = 0;
-
-           lcp_allowoptions[0].neg_pcompression = 0;
-           lcp_wantoptions[0].neg_pcompression = 0;
-
-           ccp_allowoptions[0].deflate = 0 ;
-           ccp_wantoptions[0].deflate = 0 ;
-
-           ipcp_allowoptions[0].neg_vj=0;
-           ipcp_wantoptions[0].neg_vj=0;
-
-           ccp_allowoptions[0].bsd_compress = 0;
-           ccp_wantoptions[0].bsd_compress = 0;
-
            PPPOEInitDevice();
        }
        return 1;
     }
 
-    if (OldDevnameHook) r = OldDevnameHook(cmd, argv, doit);
     return r;
 }
 
@@ -366,71 +346,42 @@ plugin_init(void)
         RP_VERSION, VERSION);
 }
 
-/**********************************************************************
-*%FUNCTION: fatalSys
-*%ARGUMENTS:
-* str -- error message
-*%RETURNS:
-* Nothing
-*%DESCRIPTION:
-* Prints a message plus the errno value to stderr and syslog and exits.
-***********************************************************************/
-void
-fatalSys(char const *str)
+void pppoe_check_options(void)
 {
-    char buf[1024];
-    int i = errno;
-    sprintf(buf, "%.256s: %.256s", str, strerror(i));
-    printErr(buf);
-    sprintf(buf, "RP-PPPoE: %.256s: %.256s", str, strerror(i));
-    sendPADT(conn, buf);
-    exit(1);
-}
+    lcp_allowoptions[0].neg_accompression = 0;
+    lcp_wantoptions[0].neg_accompression = 0;
 
-/**********************************************************************
-*%FUNCTION: rp_fatal
-*%ARGUMENTS:
-* str -- error message
-*%RETURNS:
-* Nothing
-*%DESCRIPTION:
-* Prints a message to stderr and syslog and exits.
-***********************************************************************/
-void
-rp_fatal(char const *str)
-{
-    char buf[1024];
-    printErr(str);
-    sprintf(buf, "RP-PPPoE: %.256s", str);
-    sendPADT(conn, buf);
-    exit(1);
-}
-/**********************************************************************
-*%FUNCTION: sysErr
-*%ARGUMENTS:
-* str -- error message
-*%RETURNS:
-* Nothing
-*%DESCRIPTION:
-* Prints a message plus the errno value to syslog.
-***********************************************************************/
-void
-sysErr(char const *str)
-{
-    rp_fatal(str);
-}
+    lcp_allowoptions[0].neg_asyncmap = 0;
+    lcp_wantoptions[0].neg_asyncmap = 0;
 
+    lcp_allowoptions[0].neg_pcompression = 0;
+    lcp_wantoptions[0].neg_pcompression = 0;
+
+    if (lcp_allowoptions[0].mru > MAX_PPPOE_MTU)
+       lcp_allowoptions[0].mru = MAX_PPPOE_MTU;
+    if (lcp_wantoptions[0].mru > MAX_PPPOE_MTU)
+       lcp_wantoptions[0].mru = MAX_PPPOE_MTU;
+
+    ccp_allowoptions[0].deflate = 0;
+    ccp_wantoptions[0].deflate = 0;
+
+    ipcp_allowoptions[0].neg_vj = 0;
+    ipcp_wantoptions[0].neg_vj = 0;
+
+    ccp_allowoptions[0].bsd_compress = 0;
+    ccp_wantoptions[0].bsd_compress = 0;
+}
 
 struct channel pppoe_channel = {
-    options: Options,
-    process_extra_options: &PPPOEDeviceOptions,
-    check_options: NULL,
-    connect: &PPPOEConnectDevice,
-    disconnect: &PPPOEDisconnectDevice,
-    establish_ppp: &generic_establish_ppp,
-    disestablish_ppp: &generic_disestablish_ppp,
-    send_config: &PPPOESendConfig,
-    recv_config: &PPPOERecvConfig,
-    close: NULL,
-    cleanup: NULL
+    .options = Options,
+    .process_extra_options = &PPPOEDeviceOptions,
+    .check_options = pppoe_check_options,
+    .connect = &PPPOEConnectDevice,
+    .disconnect = &PPPOEDisconnectDevice,
+    .establish_ppp = &generic_establish_ppp,
+    .disestablish_ppp = &generic_disestablish_ppp,
+    .send_config = NULL,
+    .recv_config = &PPPOERecvConfig,
+    .close = NULL,
+    .cleanup = NULL
 };