ref: 1be331f2084e094f6322744083012b4e394f39fd
parent: cbf5d3dc340da5b96cd1282e622a3f862c5b103e
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun May 21 13:53:00 EDT 2023
ip/ppp, ip/pppoe: handle ipv6 address auto-configuration, call ip/ipconfig Change ip/ppp to call ip/ipconfig to add and remove addresses to avoid duplicating code for removing ndb entries and handling default routes as well as allow ipv6 address auto-configuration.
--- a/sys/man/8/ppp
+++ b/sys/man/8/ppp
@@ -20,6 +20,9 @@
] [
.B -p
.I dev
+|
+.B -e
+.I dev
] [
.B -x
.I netmntpt
@@ -27,6 +30,9 @@
.B -t
.I modemcmd
] [
+.B -U
+.I duid
+] [
.I local
[
.I remote
@@ -35,32 +41,28 @@
.B ip/pppoe
[
.B -PdcCr
-]
-[
+] [
.B -A
.I acname
-]
-[
+] [
.B -S
.I srvname
-]
-[
+] [
+.B -U
+.I duid
+] [
.B -k
.I keyspec
-]
-[
+] [
.B -m
.I mtu
-]
-[
+] [
.B -b
.I baud
-]
-[
+] [
.B -x
.I pppnetmntpt
-]
-[
+] [
.I ether
]
.PP
@@ -67,16 +69,13 @@
.B ip/pptp
[
.B -dP
-]
-[
+] [
.B -k
.I keyspec
-]
-[
+] [
.B -w
.I window
-]
-[
+] [
.B -x
.I pppnetmntpt
]
@@ -98,7 +97,6 @@
.I tcp-dir
.SH DESCRIPTION
The Point-to-Point Protocol is used to encapsulate Internet Protocol packets
-in IPv4 packets
for transfer over serial lines or other protocol connections.
.I Ppp
can run either as a client or, with the
@@ -130,6 +128,12 @@
.B C
disallow IP header compression
.TP
+.B e
+assigns
+.I dev
+to the packet interface device (for identification only),
+but otherwise communicates over standard I/O.
+.TP
.B f
make PPP add HDLC framing. This is necessary when using
PPP over a serial line or a TCP connection
@@ -169,6 +173,20 @@
.I modemcmd
to the device
.TP
+.B U
+use
+.I duid
+as the DHCPv6 client identier.
+.I Pppoe
+creates the
+.I duid
+from the ethernet address (DUID-LL) of
+.I dev
+when not specified and passes it on to
+.IR ppp .
+See also
+.IR ipconfig (8)).
+.TP
.B u
before starting the PPP protocol with the remote end, shuttle
bytes between the device and standard I/O until an EOF on standard
@@ -291,6 +309,8 @@
.br
.B /sys/src/cmd/ip/pppoe.c
.SH SEE ALSO
+.IR ipconfig (8),
.I gre
in
.IR ip (3)
+
--- a/sys/src/cmd/ip/ppp/ppp.c
+++ b/sys/src/cmd/ip/ppp/ppp.c
@@ -17,9 +17,9 @@
static int pppframing = 1;
static int noipcompress;
static int server;
-static int noauth;
+static int noauth;
static int dying; /* flag to signal to all threads its time to go */
-static int primary; /* this is the primary IP interface */
+static int primary;
static char *chatfile;
int debug;
@@ -98,8 +98,6 @@
static void ptimer(PPP*, Pstate*);
static int putframe(PPP*, int, Block*);
static void putlqm(PPP*);
-static void putndb(PPP*);
-static void refresh(char*);
static void putpaprequest(PPP*);
static void rcv(PPP*, Pstate*, Block*);
static void rejopts(PPP*, Pstate*, Block*, int);
@@ -112,14 +110,14 @@
static void dmppkt(char *s, uchar *a, int na);
void
-pppopen(PPP *ppp, int mediain, int mediaout, char *net,
+pppopen(PPP *ppp, int mediain, int mediaout, int shellin, char *net, char *dev,
Ipaddr ipaddr[2], Ipaddr remip[2],
- int mtu, int framing)
+ int mtu, int framing, char *duid)
{
int i;
ppp->ipfd = -1;
- ppp->ipcfd = -1;
+
invalidate(ppp->remote);
invalidate(ppp->local);
invalidate(ppp->curremote);
@@ -134,9 +132,14 @@
invalidate(ppp->curremote6);
invalidate(ppp->curlocal6);
+ ppp->dev = dev;
+ ppp->duid = duid;
+
ppp->mediain = mediain;
ppp->mediaout = mediaout;
+ ppp->shellin = shellin;
+
for(i=0; i<2; i++){
if(validv4(ipaddr[i])){
ipmove(ppp->local, ipaddr[i]);
@@ -160,14 +163,8 @@
ppp->net = net;
init(ppp);
- switch(rfork(RFPROC|RFMEM|RFNOWAIT)){
- case -1:
- terminate(ppp, "forking mediainproc", 1);
- case 0:
- mediainproc(ppp);
- terminate(ppp, "mediainproc", 0);
- exits(nil);
- }
+ mediainproc(ppp);
+ terminate(ppp, "mediainproc", 0);
}
static void
@@ -781,10 +778,11 @@
static void
getipinfo(PPP *ppp)
{
+ char buf[32];
char *av[3];
int ndns, nwins;
- char ip[64];
Ndbtuple *t, *nt;
+ Ipaddr ip;
if(!validv4(ppp->local))
return;
@@ -791,16 +789,18 @@
av[0] = "dns";
av[1] = "wins";
- sprint(ip, "%I", ppp->local);
- t = csipinfo(ppp->net, "ip", ip, av, 2);
+ snprint(buf, sizeof buf, "%I", ppp->local);
+ t = csipinfo(ppp->net, "ip", buf, av, 2);
ndns = nwins = 0;
for(nt = t; nt != nil; nt = nt->entry){
+ if (parseip(ip, nt->val) == -1 || !validv4(ip))
+ continue;
if(strcmp(nt->attr, "dns") == 0){
if(ndns < 2)
- parseip(ppp->dns[ndns++], nt->val);
+ ipmove(ppp->dns[ndns++], ip);
} else if(strcmp(nt->attr, "wins") == 0){
if(nwins < 2)
- parseip(ppp->wins[nwins++], nt->val);
+ ipmove(ppp->wins[nwins++], ip);
}
}
if(t != nil)
@@ -1611,54 +1611,67 @@
}
static void
-defroute(char *net, char *verb, Ipaddr gate, Ipaddr local)
+ipconfig(int shell, char *net, char *dev, int mtu, Ipaddr gate, Ipaddr dns[2], char *duid)
{
- char path[128];
- int fd;
+ fprint(shell, "ip/ipconfig -x %q ", net);
+ if(!primary){
+ /* don't write /net/ndb */
+ fprint(shell, "-P ");
+ } else {
+ /* write dns servers in /net/ndb */
+ if(dns != nil){
+ int i;
- snprint(path, sizeof path, "%s/iproute", net);
- fd = open(path, ORDWR);
- if(fd < 0)
- return;
- fprint(fd, "tag ppp\n");
- fprint(fd, "%s 0.0.0.0 0.0.0.0 %I %I 255.255.255.255\n", verb, gate, local);
- close(fd);
+ for(i = 0; i < 2; i++){
+ if(validv4(dns[i]))
+ fprint(shell, "-s %I ", dns[i]);
+ }
+ }
+ /* set default gateway */
+ if(gate != nil)
+ fprint(shell, "-g %I ", gate);
+ }
+ /* allow dhcpv6 */
+ if(duid != nil)
+ fprint(shell, "-dU %q ", duid);
+ if(mtu > 0)
+ fprint(shell, "-m %d ", mtu);
+ fprint(shell, "pkt %q ", dev);
}
-static int
-addip(int cfd, char *net, Ipaddr local, Ipaddr remote, int mtu)
+static void
+addip(int shell, char *net, char *dev, Ipaddr local, Ipaddr remote, int mtu, Ipaddr *dns)
{
if(validv4(local) && validv4(remote)){
- netlog("ppp: setting up IPv4 interface local %I remote %I\n", local, remote);
-
- if(fprint(cfd, "add %I 255.255.255.255 %I %d proxy", local, remote, mtu-10) < 0)
- return -1;
-
- defroute(net, "add", remote, local);
- } else if(validv6(local) && validv6(remote)){
- netlog("ppp: setting up IPv6 interface local %I remote %I\n", local, remote);
-
- if(fprint(cfd, "add %I /64 %I %d", local, remote, mtu-10) < 0)
- return -1;
+ ipconfig(shell, net, dev, mtu, remote, dns, nil);
+ fprint(shell, "add %I 255.255.255.255 %I\n", local, remote);
+ } else if(validv6(local)){
+ ipconfig(shell, net, dev, mtu, nil, nil, nil);
+ fprint(shell, "add %I /64\n", local);
}
- return 0;
}
-static int
-removeip(int cfd, char *net, Ipaddr local, Ipaddr remote)
+static void
+removeip(int shell, char *net, char *dev, Ipaddr local, Ipaddr remote)
{
if(validv4(local) && validv4(remote)){
- defroute(net, "remove", remote, local);
-
- if(fprint(cfd, "remove %I 255.255.255.255 %I", local, remote) < 0)
- return -1;
- } else if(validv6(local) && validv6(remote)){
- if(fprint(cfd, "remove %I /64 %I", local, remote) < 0)
- return -1;
+ ipconfig(shell, net, dev, 0, remote, nil, nil);
+ fprint(shell, "remove %I 255.255.255.255\n", local);
+ } else if(validv6(local)){
+ ipconfig(shell, net, dev, 0, nil, nil, nil);
+ fprint(shell, "remove %I /64\n", local);
}
- return 0;
}
+static void
+v6autoconfig(int shell, char *net, char *dev, Ipaddr remote, char *duid)
+{
+ if(server || !validv6(remote))
+ return;
+ ipconfig(shell, net, dev, 0, remote, nil, duid);
+ fprint(shell, "ra6 recvra 1\n");
+}
+
static char*
ipopen(PPP *ppp)
{
@@ -1685,39 +1698,20 @@
close(cfd);
return "can't open ip interface";
}
- if(fprint(cfd, "bind pkt") < 0){
+
+ if(ppp->dev == nil)
+ ppp->dev = smprint("%s/ipifc/%s", ppp->net, buf);
+
+ if(fprint(cfd, "bind pkt %s", ppp->dev) < 0){
close(fd);
close(cfd);
return "binding pkt to ip interface";
}
- if(validv4(ppp->local)){
- if(!validv4(ppp->remote))
- ipmove(ppp->remote, ppp->local);
- if(addip(cfd, ppp->net, ppp->local, ppp->remote, ppp->mtu) < 0){
- close(fd);
- close(cfd);
- return "can't set addresses";
- }
- syslog(0, LOG, "%I/%I", ppp->local, ppp->remote);
- }
- if(validv6(ppp->local6) && validv6(ppp->remote6)){
- if(addip(cfd, ppp->net, ppp->local6, ppp->remote6, ppp->mtu) < 0){
- close(fd);
- close(cfd);
- return "can't set addresses";
- }
- syslog(0, LOG, "%I/%I", ppp->local6, ppp->remote6);
- }
if(baud)
fprint(cfd, "speed %d", baud);
- ppp->ipfd = fd;
- ppp->ipcfd = cfd;
- putndb(ppp);
- refresh(ppp->net);
+ close(cfd);
- /* signal main() that ip is configured */
- rendezvous(ppp, 0);
-
+ ppp->ipfd = fd;
switch(ipinprocpid = rfork(RFPROC|RFMEM|RFNOWAIT)){
case -1:
terminate(ppp, "forking ipinproc", 1);
@@ -1726,24 +1720,38 @@
terminate(ppp, "ipinproc", 0);
exits(nil);
}
+
+ if(validv4(ppp->local)){
+ if(!validv4(ppp->remote))
+ ipmove(ppp->remote, ppp->local);
+ syslog(0, LOG, "%I/%I", ppp->local, ppp->remote);
+ addip(ppp->shellin, ppp->net, ppp->dev, ppp->local, ppp->remote, ppp->mtu, ppp->dns);
+ }
+ if(validv6(ppp->local6) && validv6(ppp->remote6)){
+ syslog(0, LOG, "%I/%I", ppp->local6, ppp->remote6);
+ addip(ppp->shellin, ppp->net, ppp->dev, ppp->local6, ppp->remote6, ppp->mtu, nil);
+ v6autoconfig(ppp->shellin, ppp->net, ppp->dev, ppp->remote6, ppp->duid);
+ }
+
+ /* fork in background, main returns */
+ fprint(ppp->shellin, "rc </fd/0 &; exit ''\n");
} else {
/* we may have changed addresses */
if(ipcmp(ppp->local, ppp->curlocal) != 0 || ipcmp(ppp->remote, ppp->curremote) != 0){
- removeip(ppp->ipcfd, ppp->net, ppp->curlocal, ppp->curremote);
- addip(ppp->ipcfd, ppp->net, ppp->local, ppp->remote, ppp->mtu);
-
+ if(!validv4(ppp->remote))
+ ipmove(ppp->remote, ppp->local);
syslog(0, LOG, "%I/%I -> %I/%I", ppp->curlocal, ppp->curremote,
ppp->local, ppp->remote);
+ removeip(ppp->shellin, ppp->net, ppp->dev, ppp->curlocal, ppp->curremote);
+ addip(ppp->shellin, ppp->net, ppp->dev, ppp->local, ppp->remote, ppp->mtu, ppp->dns);
}
if(ipcmp(ppp->local6, ppp->curlocal6) != 0 || ipcmp(ppp->remote6, ppp->curremote6) != 0){
- removeip(ppp->ipcfd, ppp->net, ppp->curlocal6, ppp->curremote6);
- addip(ppp->ipcfd, ppp->net, ppp->local6, ppp->remote6, ppp->mtu);
-
syslog(0, LOG, "%I/%I -> %I/%I", ppp->curlocal6, ppp->curremote6,
ppp->local6, ppp->remote6);
+ removeip(ppp->shellin, ppp->net, ppp->dev, ppp->curlocal6, ppp->curremote6);
+ addip(ppp->shellin, ppp->net, ppp->dev, ppp->local6, ppp->remote6, ppp->mtu, nil);
+ v6autoconfig(ppp->shellin, ppp->net, ppp->dev, ppp->remote6, ppp->duid);
}
- putndb(ppp);
- refresh(ppp->net);
}
ipmove(ppp->curlocal, ppp->local);
@@ -1956,26 +1964,23 @@
syslog(0, LOG, "ppp: terminated: %s", why);
- if(validv4(ppp->curremote) && validv4(ppp->curlocal)){
- defroute(ppp->net, "remove", ppp->curremote, ppp->curlocal);
- invalidate(ppp->remote);
- invalidate(ppp->local);
- putndb(ppp);
+ if(ppp->dev != nil){
+ removeip(ppp->shellin, ppp->net, ppp->dev, ppp->curlocal, ppp->curremote);
+ removeip(ppp->shellin, ppp->net, ppp->dev, ppp->curlocal6, ppp->curremote6);
}
+ fprint(ppp->shellin, "exit %q\n", why);
+ close(ppp->shellin);
+ ppp->shellin = -1;
close(ppp->ipfd);
ppp->ipfd = -1;
- close(ppp->ipcfd);
- ppp->ipcfd = -1;
close(ppp->mediain);
close(ppp->mediaout);
ppp->mediain = -1;
ppp->mediaout = -1;
+
postnote(PNGROUP, getpid(), "die");
- /* interface gone, notify cs */
- refresh(ppp->net);
-
if(fatal)
sysfatal("%s", why);
}
@@ -2840,7 +2845,7 @@
usage(void)
{
fprint(2, "usage: ppp [-CPSacdfu] [-b baud] [-k keyspec] [-m mtu] "
- "[-M chatfile] [-p dev] [-x netmntpt] [-t modemcmd] "
+ "[-M chatfile] [-p dev | -e etherdev] [-x netmntpt] [-t modemcmd] [-U duid] "
"[local-addr [remote-addr]]\n");
exits("usage");
}
@@ -2848,29 +2853,30 @@
void
main(int argc, char **argv)
{
+ static PPP ppp[1];
int mtu, framing, user, mediain, mediaout, cfd;
Ipaddr ipaddr[2], remip[2];
- char *dev, *modemcmd;
+ char *dev, *ether, *duid, *modemcmd;
char net[128];
- PPP *ppp;
+ int pfd[2];
char buf[128];
- rfork(RFREND|RFNOTEG|RFNAMEG);
-
+ quotefmtinstall();
fmtinstall('I', eipfmt);
fmtinstall('V', eipfmt);
fmtinstall('E', eipfmt);
fmtinstall('H', encodefmt);
- dev = nil;
-
invalidate(ipaddr[0]);
invalidate(ipaddr[1]);
invalidate(remip[0]);
invalidate(remip[1]);
+ dev = nil;
+ ether = nil;
mtu = Defmtu;
framing = 0;
+ duid = nil;
setnetmtpt(net, sizeof(net), nil);
user = 0;
modemcmd = nil;
@@ -2893,6 +2899,9 @@
case 'd':
debug++;
break;
+ case 'e':
+ ether = EARGF(usage());
+ break;
case 'f':
framing = 1;
break;
@@ -2915,7 +2924,7 @@
case 'p':
dev = EARGF(usage());
break;
- case 'P':
+ case 'P': /* this seems reversed compared to ipconfig */
primary = 1;
break;
case 'S':
@@ -2924,6 +2933,9 @@
case 't':
modemcmd = EARGF(usage());
break;
+ case 'U':
+ duid = EARGF(usage());
+ break;
case 'u':
user = 1;
break;
@@ -2970,11 +2982,11 @@
if(mediain < 0){
if(strchr(dev, '!')){
if((mediain = dial(dev, 0, 0, &cfd)) == -1){
- fprint(2, "ppp: couldn't dial %s: %r\n", dev);
+ fprint(2, "%s: couldn't dial %s: %r\n", argv0, dev);
exits(dev);
}
} else {
- fprint(2, "ppp: couldn't open %s\n", dev);
+ fprint(2, "%s: couldn't open %s\n", argv0, dev);
exits(dev);
}
} else {
@@ -2997,30 +3009,52 @@
if(user || chatfile)
connect(mediain, -1);
}
- mediaout = mediain;
+ mediaout = dup(mediain, -1);
} else {
mediain = open("/fd/0", OREAD);
if(mediain < 0){
- fprint(2, "ppp: couldn't open /fd/0\n");
+ fprint(2, "%s: couldn't open /fd/0\n", argv0);
exits("/fd/0");
}
mediaout = open("/fd/1", OWRITE);
if(mediaout < 0){
- fprint(2, "ppp: couldn't open /fd/0\n");
+ fprint(2, "%s: couldn't open /fd/0\n", argv0);
exits("/fd/1");
}
+ /* use the ethernet from pppoe to identify the interface */
+ dev = ether;
}
-
if(modemcmd != nil && mediaout >= 0)
fprint(mediaout, "%s\r", modemcmd);
- ppp = mallocz(sizeof(*ppp), 1);
- pppopen(ppp, mediain, mediaout, net, ipaddr, remip, mtu, framing);
+ if(pipe(pfd) < 0){
+ fprint(2, "%s: can't create pipe\n", argv0);
+ exits("pipe");
+ }
+ switch(rfork(RFFDG|RFREND|RFPROC|RFNOTEG|RFNOWAIT)){
+ case -1:
+ fprint(2, "%s: can't fork\n", argv0);
+ exits("fork");
+ case 0:
+ close(pfd[0]);
+ pppopen(ppp, mediain, mediaout, pfd[1], net, dev, ipaddr, remip, mtu, framing, duid);
+ exits(nil);
+ default:
+ /* read commands from pipe */
+ dup(pfd[0], 0);
- /* wait until ip is configured */
- rendezvous(ppp, 0);
+ close(pfd[0]);
+ close(pfd[1]);
+ close(mediain);
+ close(mediaout);
- exits(nil);
+ /* stdout to stderr */
+ dup(2, 1);
+ }
+
+ /* become a shell, reading commands from pipe */
+ execl("/bin/rc", "rc", nil);
+ exits("exec");
}
void
@@ -3094,79 +3128,4 @@
ipmove(addr, v6llprefix);
memmove(&addr[IPaddrlen-len], data, len);
return memcmp(addr, v6llprefix, IPaddrlen) != 0;
-}
-
-/*
- * make an ndb entry and put it into /net/ndb for the servers to see
- */
-static void
-putndb(PPP *ppp)
-{
- static char buf[16*1024];
- char file[128], *p, *e;
- Ndbtuple *t, *nt;
- Ndb *db;
- int fd;
-
- if(!primary)
- return;
-
- e = buf + sizeof(buf);
- p = buf;
-
- if(validv4(ppp->local) && validv4(ppp->remote)){
- p = seprint(p, e, "ip=%I ipmask=255.255.255.255 ipgw=%I\n",
- ppp->local, ppp->remote);
- if(validv4(ppp->dns[0]))
- p = seprint(p, e, "\tdns=%I\n", ppp->dns[0]);
- if(validv4(ppp->dns[1]))
- p = seprint(p, e, "\tdns=%I\n", ppp->dns[1]);
- if(validv4(ppp->wins[0]))
- p = seprint(p, e, "\twins=%I\n", ppp->wins[0]);
- if(validv4(ppp->wins[1]))
- p = seprint(p, e, "\twins=%I\n", ppp->wins[1]);
- }
-
- /* append preexisting entries not matching our old or new ip */
- snprint(file, sizeof file, "%s/ndb", ppp->net);
- db = ndbopen(file);
- if(db != nil ){
- while((t = ndbparse(db)) != nil){
- uchar ip[IPaddrlen];
-
- if((nt = ndbfindattr(t, t, "ip")) == nil
- || parseip(ip, nt->val) == -1
- || (ipcmp(ip, ppp->local) != 0 && ipcmp(ip, ppp->curlocal) != 0)){
- p = seprint(p, e, "\n");
- for(nt = t; nt != nil; nt = nt->entry)
- p = seprint(p, e, "%s=%s%s", nt->attr, nt->val,
- nt->entry==nil? "\n": nt->line!=nt->entry? "\n\t": " ");
- }
- ndbfree(t);
- }
- ndbclose(db);
- }
-
- if((fd = open(file, OWRITE|OTRUNC)) < 0)
- return;
- write(fd, buf, p-buf);
- close(fd);
-}
-
-static void
-refresh(char *net)
-{
- char file[128];
- int fd;
-
- snprint(file, sizeof file, "%s/cs", net);
- if((fd = open(file, OWRITE)) >= 0){
- write(fd, "refresh", 7);
- close(fd);
- }
- snprint(file, sizeof file, "%s/dns", net);
- if((fd = open(file, OWRITE)) >= 0){
- write(fd, "refresh", 7);
- close(fd);
- }
}
--- a/sys/src/cmd/ip/ppp/ppp.h
+++ b/sys/src/cmd/ip/ppp/ppp.h
@@ -262,15 +262,20 @@
QLock;
int ipfd; /* fd to ip stack */
- int ipcfd; /* fd to control channel of ip stack */
int mediain; /* fd to media */
int mediaout; /* fd to media */
+ int shellin; /* fd to rc shell for running ipconfig */
+
char *net; /* ip stack to use */
+ char *dev; /* the device */
+ char *duid; /* dhcpv6 uid */
+
int framing; /* non-zero to use framing characters */
Ipaddr local;
Ipaddr curlocal;
Ipaddr remote;
Ipaddr curremote;
+
Ipaddr local6;
Ipaddr curlocal6;
Ipaddr remote6;
@@ -345,7 +350,7 @@
extern Block* pppread(PPP*);
extern int pppwrite(PPP*, Block*);
-extern void pppopen(PPP*, int, int, char*, Ipaddr[2], Ipaddr[2], int, int);
+extern void pppopen(PPP*, int, int, int, char*, char *dev, Ipaddr[2], Ipaddr[2], int, int, char*);
struct Lcpmsg
{
--- a/sys/src/cmd/ip/pppoe.c
+++ b/sys/src/cmd/ip/pppoe.c
@@ -12,15 +12,16 @@
void hexdump(uchar*, int);
int malformed(uchar*, int, int);
int pppoe(char*);
-void execppp(int);
+void execppp(char*, int);
+int primary;
int forked;
int alarmed;
int debug;
int rflag;
int sessid;
+char *duid;
char *keyspec;
-int primary;
char *pppnetmtpt;
char *acname;
char *pppname = "/bin/ip/ppp";
@@ -29,6 +30,7 @@
uchar *cookie;
int cookielen;
uchar etherdst[6];
+uchar ethersrc[6];
int mtu = 1492;
int pktcompress, hdrcompress;
char *baud;
@@ -36,7 +38,7 @@
void
usage(void)
{
- fprint(2, "usage: %s [-rPdcC] [-A acname] [-S srvname] [-k keyspec] [-m mtu] [-b baud] [-x pppnet] [ether0]\n", argv0);
+ fprint(2, "usage: %s [-rPdcC] [-A acname] [-S srvname] [-U duid] [-k keyspec] [-m mtu] [-b baud] [-x pppnet] [/net/ether0]\n", argv0);
exits("usage");
}
@@ -110,6 +112,9 @@
case 'x':
pppnetmtpt = EARGF(usage());
break;
+ case 'U':
+ duid = EARGF(usage());
+ break;
default:
usage();
}ARGEND
@@ -118,7 +123,7 @@
default:
usage();
case 0:
- dev = "ether0";
+ dev = "/net/ether0";
break;
case 1:
dev = argv[0];
@@ -127,8 +132,15 @@
fmtinstall('E', eipfmt);
+ /* generate DUID-LL when not specified */
+ if(myetheraddr(ethersrc, dev) != -1 && duid == nil){
+ static char buf[32];
+ snprint(buf, sizeof buf, "00030001%E", ethersrc);
+ duid = buf;
+ }
+
atnotify(catchalarm, 1);
- execppp(pppoe(dev));
+ execppp(dev, pppoe(dev));
}
typedef struct Etherhdr Etherhdr;
@@ -604,11 +616,11 @@
}
void
-execppp(int fd)
+execppp(char *dev, int fd)
{
- char *argv[16];
- int argc;
char smtu[10];
+ char *argv[20];
+ int argc;
argc = 0;
argv[argc++] = pppname;
@@ -617,6 +629,10 @@
argv[argc++] = "-F";
if(debug)
argv[argc++] = "-d";
+ if(dev){
+ argv[argc++] = "-e";
+ argv[argc++] = dev;
+ }
if(primary)
argv[argc++] = "-P";
if(baud){
@@ -634,6 +650,10 @@
if(keyspec){
argv[argc++] = "-k";
argv[argc++] = keyspec;
+ }
+ if(duid){
+ argv[argc++] = "-U";
+ argv[argc++] = duid;
}
argv[argc] = nil;