Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Jun 2007 21:41:31 +0200 (CEST)
From:      Frank Behrens <frank@pinky.sax.de>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   bin/114081: ppp(8) should be able to set ethernet address for PPPoE [patch]
Message-ID:  <200706271941.l5RJfVqO041479@moon.behrens>
Resent-Message-ID: <200706271950.l5RJo4RR087087@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         114081
>Category:       bin
>Synopsis:       ppp(8) should be able to set ethernet address for PPPoE [patch]
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jun 27 19:50:03 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Frank Behrens
>Release:        FreeBSD 6.2-STABLE-200705211513 i386
>Organization:
>Environment:
>Description:
ppp(8) should be able to set ethernet address for PPPoE [patch]

In general it is possible to have multiple, concurrent sessions on a
PPPoE connection. So it is possible to connect to different
internet providers simultaneously on a single DSL line. However a big 
german DSL provider requires a different MAC address for each session
to avoid inadvertent double connects.

So it is desired to be able to set the ethernet address for
outgoing PPPoE connections via ppp(8). Fortunately ng_pppoe(4)
has already this possibility: NGM_PPPOE_SETENADDR. The attached
patch adds this functionality to ppp(8).

still todo:
- rename option numbers (meanwhile others were added?)
- Is option name ok?
- bump man page date
- adjust version number for ppp

>How-To-Repeat:
>Fix:

--- pppether.patch begins here ---
--- command.c.orig	Tue Feb  8 11:38:24 2005
+++ command.c	Tue Jun 19 17:37:23 2007
@@ -144,6 +144,7 @@
 #define	VAR_IPV6CPRETRY	37
 #define	VAR_RAD_ALIVE	38
 #define	VAR_PPPOE	39
+#define	VAR_PPPOEENADD	57	/* todo: renumber */
 
 /* ``accept|deny|disable|enable'' masks */
 #define NEG_HISMASK (1)
@@ -168,7 +169,7 @@
 #define NEG_MPPE	55
 #define NEG_CHAP81	56
 
-const char Version[] = "3.4.2";
+const char Version[] = "3.4.2.fb1";
 
 static int ShowCommand(struct cmdargs const *);
 static int TerminalCommand(struct cmdargs const *);
@@ -2312,8 +2313,12 @@
     }
     break;
 
-  }
+  case VAR_PPPOEENADD:
+    res = physical_SetPPPoEEtherAddr(arg->cx->physical, argp);
+    break;
 
+
+  }
   return res;
 }
 
@@ -2444,6 +2449,9 @@
   {"pppoe", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX,
    "Connect using standard/3Com mode", "set pppoe [standard|3Com]",
    (const char *)VAR_PPPOE},
+  {"pppoeethadd", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX,
+   "set pppoe ethernet address", "set pppoeethadd linkaddress",
+   (const char *)VAR_PPPOEENADD},
   {NULL, NULL, NULL, 0, NULL, NULL, NULL},
 };
 
--- ether.c.orig	Mon Sep  6 02:07:58 2004
+++ ether.c	Tue Jun 19 17:45:04 2007
@@ -636,6 +636,16 @@
       }
     }
 
+    /* Set ethernet address for outgoing packets */
+    if (p->cfg.pppoe_addrset) {
+      if (NgSendMsg(dev->cs, connectpath, NGM_PPPOE_COOKIE,
+		NGM_PPPOE_SETENADDR, p->cfg.etheradd, PPP_ETHER_ADDR_LEN) == -1) {
+        log_Printf(LogWARN, "``%s'': Cannot set ethernet address: %s\n",
+                 connectpath, strerror(errno));
+        return ether_Abandon(dev, p);
+      }
+    }
+
     /* And finally, request a connection to the given provider */
 
     data = (struct ngpppoe_init_data *)alloca(sizeof *data + providerlen);
--- physical.c.orig	Sun May 21 17:26:19 2006
+++ physical.c	Tue Jun 19 17:39:32 2007
@@ -24,6 +24,7 @@
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
+#include <net/if_dl.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 
@@ -1147,4 +1148,30 @@
    p->cfg.nonstandard_pppoe = enable ? 1 : 0;
    p->cfg.pppoe_configured = 1;
    return 1;
+}
+
+int
+physical_SetPPPoEEtherAddr(struct physical *p, const char* addrstr)
+{
+
+  char *temp;
+  struct sockaddr_dl sdl;
+
+  if ((temp = malloc(strlen(addrstr) + 2)) == NULL) {
+      log_Printf(LogALERT, "malloc failed");
+      return 1;
+  }
+  temp[0] = ':';
+  strcpy(temp + 1, addrstr);
+  sdl.sdl_len = sizeof(sdl);
+  link_addr(temp, &sdl);
+  free(temp);
+  if (sdl.sdl_alen != PPP_ETHER_ADDR_LEN) {
+      log_Printf(LogERROR, "malformed link-level address: %s", addrstr);
+      return 1;
+  }
+  p->cfg.pppoe_addrset = 1;
+  bcopy(LLADDR(&sdl), p->cfg.etheradd, sdl.sdl_alen);
+
+  return 0;
 }
--- physical.h.orig	Sun Sep  5 03:46:52 2004
+++ physical.h	Tue Jun 19 17:36:41 2007
@@ -49,6 +49,11 @@
 #define CD_NOTREQUIRED	2
 #define CD_DEFAULT	3
 
+/* length of ethernet address. This is already in <net/ethernet.h>, 
+   but avoid to include it in every source. */
+#define PPP_ETHER_ADDR_LEN 6
+
+
 struct cd {
   unsigned necessity : 2;  /* A CD_ value */
   int delay;               /* Wait this many seconds after login script */
@@ -106,12 +111,14 @@
     unsigned rts_cts : 1;      /* Is rts/cts enabled ? */
     unsigned nonstandard_pppoe : 1; /* Is PPPoE mode nonstandard */
     unsigned pppoe_configured : 1; /* temporary hack */
+    unsigned pppoe_addrset : 1; /* Is PPPoE ethernet address set? */
     unsigned parity;           /* What parity is enabled? (tty flags) */
     unsigned speed;            /* tty speed */
 
     char devlist[LINE_LEN];    /* NUL separated list of devices */
     int ndev;                  /* number of devices in list */
     struct cd cd;
+    char etheradd[PPP_ETHER_ADDR_LEN];
   } cfg;
 };
 
@@ -174,3 +181,4 @@
 extern void physical_SetAsyncParams(struct physical *, u_int32_t, u_int32_t);
 extern int physical_Slot(struct physical *);
 extern int physical_SetPPPoEnonstandard(struct physical *, int);
+extern int physical_SetPPPoEEtherAddr(struct physical *, const char* addrstr);
--- ppp.8.m4.orig	Fri May  6 18:13:32 2005
+++ ppp.8.m4	Wed Jun 27 21:28:55 2007
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD: src/usr.sbin/ppp/ppp.8.m4,v 1.322 2005/05/06 16:13:32 brian Exp $
 .\"
-.Dd July 20, 2004
+.Dd June 27, 2007
 .Dt PPP 8
 .Os
 .Sh NAME
@@ -5345,6 +5345,10 @@
 .Xr ng_pppoe 4
 node to either standard RFC2516 PPPoE or proprietary 3Com mode.
 If not set the system default will be used.
+.It set pppoeethadd Ar nn:nn:nn:nn:nn:nn
+This option sets the node Ethernet address for outgoing PPPoE
+sessions.
+If not set the address of interface will be used.
 .It set Op proc Ns Xo
 .No title Op Ar value
 .Xc
--- pppether.patch ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200706271941.l5RJfVqO041479>