Teach an IPV6CP to pppd(8).

The eui64.[ch] and ipv6cp.[ch] were taken from ppp-2.3.11.
However, our stock pppd(8) doesn't provide option_t nor some
utility functions.  So, I made some hacks to adjust to our
stock pppd(8).
The sys_bsd.c part was taken from NetBSD with some
modifications to adjust to our stock pppd(8).

MFC after:	1 week
This commit is contained in:
Hajimu UMEMOTO 2006-11-12 17:36:58 +00:00
parent 39383a88d2
commit da525eb2e7
10 changed files with 351 additions and 81 deletions

View File

@ -39,6 +39,11 @@ LDADD+= -lcrypto
DPADD+= ${LIBCRYPTO}
.endif
.if ${MK_INET6_SUPPORT} != "no"
CFLAGS+=-DINET6
SRCS+= eui64.c ipv6cp.c
.endif
.if defined(RELEASE_CRUNCH)
# We must create these objects because crunchgen will link them,
# and we don't want any unused symbols to spoil the final link.

View File

@ -18,11 +18,17 @@
$Id: eui64.c,v 1.3 1999/08/25 04:15:51 paulus Exp $
*/
#ifndef lint
#define RCSID "$Id: eui64.c,v 1.3 1999/08/25 04:15:51 paulus Exp $"
#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "pppd.h"
#ifdef RCSID
static const char rcsid[] = RCSID;
#endif
/*
* eui64_ntoa - Make an ascii representation of an interface identifier

View File

@ -93,7 +93,11 @@
* $Id: ipv6cp.c,v 1.7 1999/10/08 01:08:18 masputra Exp $
*/
#ifndef lint
#define RCSID "$Id: ipv6cp.c,v 1.7 1999/10/08 01:08:18 masputra Exp $"
#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* TODO:
@ -107,6 +111,7 @@
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/param.h>
@ -122,7 +127,11 @@
#include "magic.h"
#include "pathnames.h"
#define s6_addr32 __u6_addr.__u6_addr32
#ifdef RCSID
static const char rcsid[] = RCSID;
#endif
/* global vars */
ipv6cp_options ipv6cp_wantoptions[NUM_PPP]; /* Options that we want to request */
@ -168,41 +177,6 @@ static fsm_callbacks ipv6cp_callbacks = { /* IPV6CP callback routines */
"IPV6CP" /* String name of protocol */
};
/*
* Command-line options.
*/
static int setifaceid __P((char **arg));
static option_t ipv6cp_option_list[] = {
{ "ipv6", o_special, setifaceid,
"Set interface identifiers for IPV6" },
{ "noipv6", o_bool, &ipv6cp_protent.enabled_flag,
"Disable IPv6 and IPv6CP" },
{ "-ipv6", o_bool, &ipv6cp_protent.enabled_flag,
"Disable IPv6 and IPv6CP" },
{ "+ipv6", o_bool, &ipv6cp_protent.enabled_flag,
"Enable IPv6 and IPv6CP", 1 },
{ "ipv6cp-accept-local", o_bool, &ipv6cp_allowoptions[0].accept_local,
"Accept peer's interface identifier for us", 1 },
{ "ipv6cp-use-ipaddr", o_bool, &ipv6cp_allowoptions[0].use_ip,
"Use (default) IPv4 address as interface identifier", 0 },
#if defined(SOL2)
{ "ipv6cp-use-persistent", o_bool, &ipv6cp_wantoptions[0].use_persistent,
"Use uniquely-available persistent value for link local address", 1 },
#endif /* defined(SOL2) */
{ "ipv6cp-restart", o_int, &ipv6cp_fsm[0].timeouttime,
"Set timeout for IPv6CP" },
{ "ipv6cp-max-terminate", o_int, &ipv6cp_fsm[0].maxtermtransmits,
"Set max #xmits for term-reqs" },
{ "ipv6cp-max-configure", o_int, &ipv6cp_fsm[0].maxconfreqtransmits,
"Set max #xmits for conf-reqs" },
{ "ipv6cp-max-failure", o_int, &ipv6cp_fsm[0].maxnakloops,
"Set max #conf-naks for IPv6CP" },
{ NULL }
};
/*
* Protocol entry points from main code.
@ -233,8 +207,6 @@ struct protent ipv6cp_protent = {
NULL,
0,
"IPV6CP",
"IPV6",
ipv6cp_option_list,
ipv6_check_options,
ipv6_demand_conf,
ipv6_active_pkt
@ -242,7 +214,6 @@ struct protent ipv6cp_protent = {
static void ipv6cp_clear_addrs __P((int, eui64_t, eui64_t));
static void ipv6cp_script __P((char *));
static void ipv6cp_script_done __P((void *));
/*
* Lengths of configuration options.
@ -262,12 +233,11 @@ static enum script_state {
s_down,
s_up,
} ipv6cp_script_state;
static pid_t ipv6cp_script_pid;
/*
* setifaceid - set the interface identifiers manually
*/
static int
int
setifaceid(argv)
char **argv;
{
@ -1069,9 +1039,9 @@ ipv6_demand_conf(u)
if (!sifnpmode(u, PPP_IPV6, NPMODE_QUEUE))
return 0;
notice("ipv6_demand_conf");
notice("local LL address %s", llv6_ntoa(wo->ourid));
notice("remote LL address %s", llv6_ntoa(wo->hisid));
syslog(LOG_NOTICE, "ipv6_demand_conf");
syslog(LOG_NOTICE, "local LL address %s", llv6_ntoa(wo->ourid));
syslog(LOG_NOTICE, "remote LL address %s", llv6_ntoa(wo->hisid));
return 1;
}
@ -1100,17 +1070,17 @@ ipv6cp_up(f)
if(!no_ifaceid_neg) {
if (eui64_iszero(ho->hisid)) {
error("Could not determine remote LL address");
syslog(LOG_ERR, "Could not determine remote LL address");
ipv6cp_close(f->unit, "Could not determine remote LL address");
return;
}
if (eui64_iszero(go->ourid)) {
error("Could not determine local LL address");
syslog(LOG_ERR, "Could not determine local LL address");
ipv6cp_close(f->unit, "Could not determine local LL address");
return;
}
if (eui64_equals(go->ourid, ho->hisid)) {
error("local and remote LL addresses are equal");
syslog(LOG_ERR, "local and remote LL addresses are equal");
ipv6cp_close(f->unit, "local and remote LL addresses are equal");
return;
}
@ -1191,8 +1161,8 @@ ipv6cp_up(f)
#endif
sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS);
notice("local LL address %s", llv6_ntoa(go->ourid));
notice("remote LL address %s", llv6_ntoa(ho->hisid));
syslog(LOG_NOTICE, "local LL address %s", llv6_ntoa(go->ourid));
syslog(LOG_NOTICE, "remote LL address %s", llv6_ntoa(ho->hisid));
}
np_up(f->unit, PPP_IPV6);
@ -1202,7 +1172,7 @@ ipv6cp_up(f)
* Execute the ipv6-up script, like this:
* /etc/ppp/ipv6-up interface tty speed local-LL remote-LL
*/
if (ipv6cp_script_state == s_down && ipv6cp_script_pid == 0) {
if (ipv6cp_script_state == s_down) {
ipv6cp_script_state = s_up;
ipv6cp_script(_PATH_IPV6UP);
}
@ -1220,7 +1190,6 @@ ipv6cp_down(f)
fsm *f;
{
IPV6CPDEBUG(("ipv6cp: down"));
update_link_stats(f->unit);
if (ipv6cp_is_up) {
ipv6cp_is_up = 0;
np_down(f->unit, PPP_IPV6);
@ -1253,7 +1222,7 @@ ipv6cp_down(f)
}
/* Execute the ipv6-down script */
if (ipv6cp_script_state == s_up && ipv6cp_script_pid == 0) {
if (ipv6cp_script_state == s_up) {
ipv6cp_script_state = s_down;
ipv6cp_script(_PATH_IPV6DOWN);
}
@ -1285,32 +1254,6 @@ ipv6cp_finished(f)
}
/*
* ipv6cp_script_done - called when the ipv6-up or ipv6-down script
* has finished.
*/
static void
ipv6cp_script_done(arg)
void *arg;
{
ipv6cp_script_pid = 0;
switch (ipv6cp_script_state) {
case s_up:
if (ipv6cp_fsm[0].state != OPENED) {
ipv6cp_script_state = s_down;
ipv6cp_script(_PATH_IPV6DOWN);
}
break;
case s_down:
if (ipv6cp_fsm[0].state == OPENED) {
ipv6cp_script_state = s_up;
ipv6cp_script(_PATH_IPV6UP);
}
break;
}
}
/*
* ipv6cp_script - Execute a script with arguments
* interface-name tty-name speed local-LL remote-LL.
@ -1335,7 +1278,7 @@ ipv6cp_script(script)
argv[6] = ipparam;
argv[7] = NULL;
ipv6cp_script_pid = run_program(script, argv, 0, ipv6cp_script_done, NULL);
run_program(script, argv, 0);
}
/*

View File

@ -91,6 +91,7 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: ipv6cp.h,v 1.3 1999/09/30 19:57:45 masputra Exp $
* $FreeBSD$
*/
/*
@ -124,3 +125,5 @@ extern ipv6cp_options ipv6cp_allowoptions[];
extern ipv6cp_options ipv6cp_hisoptions[];
extern struct protent ipv6cp_protent;
extern int setifaceid __P((char **arg));

View File

@ -46,6 +46,9 @@ static char rcsid[] = "$FreeBSD$";
#include "fsm.h"
#include "lcp.h"
#include "ipcp.h"
#ifdef INET6
#include "ipv6cp.h"
#endif
#include "upap.h"
#include "chap.h"
#include "ccp.h"
@ -152,6 +155,9 @@ struct protent *protocols[] = {
&cbcp_protent,
#endif
&ipcp_protent,
#ifdef INET6
&ipv6cp_protent,
#endif
&ccp_protent,
#ifdef IPX_CHANGE
&ipxcp_protent,

View File

@ -55,6 +55,10 @@ static char rcsid[] = "$FreeBSD$";
#include "cbcp.h"
#endif
#ifdef INET6
#include "ipv6cp.h"
#endif
#ifdef IPX_CHANGE
#include "ipxcp.h"
#endif /* IPX_CHANGE */
@ -227,6 +231,7 @@ static int setpapcrypt __P((char **));
static int setidle __P((char **));
static int setholdoff __P((char **));
static int setdnsaddr __P((char **));
static int resetipv6proto __P((char **));
static int resetipxproto __P((char **));
static int setwinsaddr __P((char **));
static int showversion __P((char **));
@ -238,6 +243,19 @@ static int setpassfilter __P((char **));
static int setactivefilter __P((char **));
#endif
#ifdef INET6
static int setipv6cp_accept_local __P((char **));
static int setipv6cp_use_ip __P((char **));
#if defined(SOL2)
static int setipv6cp_use_persistent __P((char **));
#endif
static int setipv6cptimeout __P((char **));
static int setipv6cpterm __P((char **));
static int setipv6cpconf __P((char **));
static int setipv6cpfails __P((char **));
static int setipv6proto __P((char **));
#endif /* INET6 */
#ifdef IPX_CHANGE
static int setipxproto __P((char **));
static int setipxanet __P((char **));
@ -388,6 +406,8 @@ static struct cmd {
/* end compat hack */
{"ms-dns", 1, setdnsaddr}, /* DNS address for the peer's use */
{"ms-wins", 1, setwinsaddr}, /* Nameserver for SMB over TCP/IP for peer */
{"noipv6", 0, resetipv6proto}, /* Disable IPv6 and IPv6CP */
{"-ipv6", 0, resetipv6proto}, /* Disable IPv6 and IPv6CP */
{"noipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */
{"-ipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */
{"--version", 0, showversion}, /* Show version number */
@ -400,6 +420,20 @@ static struct cmd {
{"active-filter", 1, setactivefilter}, /* set filter for active pkts */
#endif
#ifdef INET6
{"ipv6", 1, setifaceid}, /* Set interface id for IPV6" */
{"+ipv6", 0, setipv6proto}, /* Enable IPv6 and IPv6CP */
{"ipv6cp-accept-local", 0, setipv6cp_accept_local}, /* Accept peer's iface id for us */
{"ipv6cp-use-ipaddr", 0, setipv6cp_use_ip}, /* Use IPv4 addr as iface id */
#if defined(SOL2)
{"ipv6cp-use-persistent", 0, setipv6cp_use_persistent}, /* Use uniquely-available persistent value for link local addr */
#endif
{"ipv6cp-restart", 1, setipv6cptimeout}, /* Set timeout for IPv6CP */
{"ipv6cp-max-terminate", 1, setipv6cpterm}, /* max #xmits for term-reqs */
{"ipv6cp-max-configure", 1, setipv6cpconf}, /* max #xmits for conf-reqs */
{"ipv6cp-max-failure", 1, setipv6cpfails}, /* max #conf-naks for IPv6CP */
#endif
#ifdef IPX_CHANGE
{"ipx-network", 1, setipxnetwork}, /* IPX network number */
{"ipxcp-accept-network", 0, setipxanet}, /* Accept peer netowrk */
@ -2374,6 +2408,85 @@ setwinsaddr(argv)
return (1);
}
#ifdef INET6
static int
setipv6cp_accept_local(argv)
char **argv;
{
ipv6cp_allowoptions[0].accept_local = 1;
return 1;
}
static int
setipv6cp_use_ip(argv)
char **argv;
{
ipv6cp_allowoptions[0].use_ip = 1;
return 1;
}
#if defined(SOL2)
static int
setipv6cp_use_persistent(argv)
char **argv;
{
ipv6cp_wantoptions[0].use_persistent = 1;
return 1;
}
#endif
static int
setipv6cptimeout(argv)
char **argv;
{
return int_option(*argv, &ipv6cp_fsm[0].timeouttime);
}
static int
setipv6cpterm(argv)
char **argv;
{
return int_option(*argv, &ipv6cp_fsm[0].maxtermtransmits);
}
static int
setipv6cpconf(argv)
char **argv;
{
return int_option(*argv, &ipv6cp_fsm[0].maxconfreqtransmits);
}
static int
setipv6cpfails(argv)
char **argv;
{
return int_option(*argv, &ipv6cp_fsm[0].maxnakloops);
}
static int
setipv6proto(argv)
char **argv;
{
ipv6cp_protent.enabled_flag = 1;
return 1;
}
static int
resetipv6proto(argv)
char **argv;
{
ipv6cp_protent.enabled_flag = 0;
return 1;
}
#else
static int
resetipv6proto(argv)
char **argv;
{
return 1;
}
#endif /* INET6 */
#ifdef IPX_CHANGE
static int
setipxrouter (argv)

View File

@ -26,6 +26,11 @@
#define _PATH_PPPDENY "/etc/ppp/ppp.deny"
#define _PATH_PPPSHELLS "/etc/ppp/ppp.shells"
#ifdef INET6
#define _PATH_IPV6UP "/etc/ppp/ipv6-up"
#define _PATH_IPV6DOWN "/etc/ppp/ipv6-down"
#endif
#ifdef IPX_CHANGE
#define _PATH_IPXUP "/etc/ppp/ipx-up"
#define _PATH_IPXDOWN "/etc/ppp/ipx-down"

View File

@ -142,13 +142,14 @@ Pppd
will ask the peer to send packets of no more than \fIn\fR bytes. The
minimum MRU value is 128. The default MRU value is 1500. A value of
296 is recommended for slow links (40 bytes for TCP/IP header + 256
bytes of data).
bytes of data). (Note that for IPv6 MRU must be at least 1280)
.TP
.B mtu \fIn
Set the MTU [Maximum Transmit Unit] value to \fIn\fR. Unless the
peer requests a smaller value via MRU negotiation, pppd will
request that the kernel networking code send data packets of no more
than \fIn\fR bytes through the PPP network interface.
than \fIn\fR bytes through the PPP network interface. (Note that for
IPv6 MTU must be at least 1280)
.TP
.B passive
Enables the "passive" option in the LCP. With this option, pppd will
@ -171,6 +172,17 @@ will not accept a different value from the peer in the IPCP
negotiation, unless the \fIipcp-accept-local\fR and/or
\fIipcp-accept-remote\fR options are given, respectively.
.TP
.B ipv6 \fI<local_interface_identifier>\fR,\fI<remote_interface_identifier>
Set the local and/or remote 64-bit interface identifier. Either one may be
omitted. The identifier must be specified in standard ascii notation of
IPv6 addresses (e.g. ::dead:beef). If the
\fIipv6cp-use-ipaddr\fR
option is given, the local identifier is the local IPv4 address (see above).
On systems which supports a unique persistent id, such as EUI-48 derived
from the Ethernet MAC address, \fIipv6cp-use-persistent\fR option can be
used to replace the \fIipv6 <local>,<remote>\fR option. Otherwise the
identifier is randomized.
.TP
.B bsdcomp \fInr,nt
Request that the peer compress packets that it sends, using the
BSD-Compress scheme, with a maximum code size of \fInr\fR bits, and
@ -300,6 +312,22 @@ Provides an extra parameter to the ip-up and ip-down scripts. If this
option is given, the \fIstring\fR supplied is given as the 6th
parameter to those scripts.
.TP
.B ipv6cp-max-configure \fIn
Set the maximum number of IPv6CP configure-request transmissions to
\fIn\fR (default 10).
.TP
.B ipv6cp-max-failure \fIn
Set the maximum number of IPv6CP configure-NAKs returned before starting
to send configure-Rejects instead to \fIn\fR (default 10).
.TP
.B ipv6cp-max-terminate \fIn
Set the maximum number of IPv6CP terminate-request transmissions to
\fIn\fR (default 3).
.TP
.B ipv6cp-restart \fIn
Set the IPv6CP restart interval (retransmission timeout) to \fIn\fR
seconds (default 3).
.TP
.B ipx
Enable the IPXCP and IPX protocols. This option is presently only
supported under Linux, and only if your kernel has been configured to
@ -526,6 +554,11 @@ Disable IPCP negotiation and IP communication. This option should
only be required if the peer is buggy and gets confused by requests
from pppd for IPCP negotiation.
.TP
.B noipv6
Disable IPv6CP negotiation and IPv6 communication. This option should
only be required if the peer is buggy and gets confused by requests
from pppd for IPv6CP negotiation.
.TP
.B noipdefault
Disables the default behaviour when no local IP address is specified,
which is to determine (if possible) the local IP address from the
@ -1063,6 +1096,18 @@ used for undoing the effects of the /etc/ppp/ip-up script. It is
invoked in the same manner and with the same parameters as the ip-up
script.
.TP
.B /etc/ppp/ipv6-up
Like /etc/ppp/ip-up, except that it is executed when the link is available
for sending and receiving IPv6 packets. It is executed with the parameters
.IP
\fIinterface-name tty-device speed local-link-local-address
remote-link-local-address ipparam\fR
.TP
.B /etc/ppp/ipv6-down
Similar to /etc/ppp/ip-down, but it is executed when IPv6 packets can no
longer be transmitted on the link. It is executed with the same parameters
as the ipv6-up script.
.TP
.B /etc/ppp/ipx-up
A program or script which is executed when the link is available for
sending and receiving IPX packets (that is, IPXCP has come up). It is

View File

@ -41,6 +41,10 @@
#define const
#endif
#ifdef INET6
#include "eui64.h"
#endif
/*
* Limits.
*/
@ -285,6 +289,12 @@ int sifaddr __P((int, u_int32_t, u_int32_t, u_int32_t));
/* Configure IP addresses for i/f */
int cifaddr __P((int, u_int32_t, u_int32_t));
/* Reset i/f IP addresses */
#ifdef INET6
int sif6addr __P((int, eui64_t, eui64_t));
/* Configure IPv6 addresses for i/f */
int cif6addr __P((int, eui64_t, eui64_t));
/* Remove an IPv6 address from i/f */
#endif
int sifdefaultroute __P((int, u_int32_t, u_int32_t));
/* Create default route through i/f */
int cifdefaultroute __P((int, u_int32_t, u_int32_t));
@ -457,6 +467,12 @@ extern struct option_info devnam_info;
#define IPCPDEBUG(x)
#endif
#ifdef DEBUGIPV6CP
#define IPV6CPDEBUG(x) if (debug) syslog x
#else
#define IPV6CPDEBUG(x)
#endif
#ifdef DEBUGUPAP
#define UPAPDEBUG(x) if (debug) syslog x
#else

View File

@ -58,6 +58,10 @@ static char rcsid[] = "$FreeBSD$";
#include <net/route.h>
#include <net/if_dl.h>
#include <netinet/in.h>
#include <net/if_var.h>
#include <netinet6/in6_var.h>
#include <netinet6/nd6.h>
#include <ifaddrs.h>
#ifdef IPX_CHANGE
#include <netipx/ipx.h>
@ -100,6 +104,9 @@ static char loop_name[20];
static unsigned char inbuf[512]; /* buffer for chars read from loopback */
static int sockfd; /* socket for doing interface ioctls */
#ifdef INET6
static int sock6_fd = -1; /* socket for doing ipv6 interface ioctls */
#endif /* INET6 */
static int if_is_up; /* the interface is currently up */
static u_int32_t ifaddrs[2]; /* local and remote addresses we set */
@ -122,6 +129,13 @@ sys_init()
syslog(LOG_ERR, "Couldn't create IP socket: %m");
die(1);
}
#ifdef INET6
if ((sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
/* check it at runtime */
sock6_fd = -1;
}
#endif
}
/*
@ -156,7 +170,12 @@ sys_cleanup()
void
sys_close()
{
close(sockfd);
if (sockfd >= 0)
close(sockfd);
#ifdef INET6
if (sock6_fd >= 0)
close(sock6_fd);
#endif
if (loop_slave >= 0) {
close(loop_slave);
close(loop_master);
@ -476,6 +495,115 @@ int fd, on;
ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
}
#ifdef INET6
/*
* sif6addr - Config the interface with an IPv6 link-local address
*/
int
sif6addr(int unit, eui64_t our_eui64, eui64_t his_eui64)
{
int ifindex;
struct in6_aliasreq addreq6;
if (sock6_fd < 0) {
syslog(LOG_ERR, "No IPv6 socket available");
die(1);
/*NOTREACHED*/
}
/* actually, this part is not kame local - RFC2553 conformant */
ifindex = if_nametoindex(ifname);
if (ifindex == 0) {
syslog(LOG_ERR, "sifaddr6: no interface %s", ifname);
return 0;
}
memset(&addreq6, 0, sizeof(addreq6));
strlcpy(addreq6.ifra_name, ifname, sizeof(addreq6.ifra_name));
/* my addr */
addreq6.ifra_addr.sin6_family = AF_INET6;
addreq6.ifra_addr.sin6_len = sizeof(struct sockaddr_in6);
addreq6.ifra_addr.sin6_addr.s6_addr[0] = 0xfe;
addreq6.ifra_addr.sin6_addr.s6_addr[1] = 0x80;
memcpy(&addreq6.ifra_addr.sin6_addr.s6_addr[8], &our_eui64,
sizeof(our_eui64));
/* KAME ifindex hack */
*(u_int16_t *)&addreq6.ifra_addr.sin6_addr.s6_addr[2] = htons(ifindex);
/* his addr */
addreq6.ifra_dstaddr.sin6_family = AF_INET6;
addreq6.ifra_dstaddr.sin6_len = sizeof(struct sockaddr_in6);
addreq6.ifra_dstaddr.sin6_addr.s6_addr[0] = 0xfe;
addreq6.ifra_dstaddr.sin6_addr.s6_addr[1] = 0x80;
memcpy(&addreq6.ifra_dstaddr.sin6_addr.s6_addr[8], &his_eui64,
sizeof(our_eui64));
/* KAME ifindex hack */
*(u_int16_t *)&addreq6.ifra_dstaddr.sin6_addr.s6_addr[2] = htons(ifindex);
/* prefix mask: 128bit */
addreq6.ifra_prefixmask.sin6_family = AF_INET6;
addreq6.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
memset(&addreq6.ifra_prefixmask.sin6_addr, 0xff,
sizeof(addreq6.ifra_prefixmask.sin6_addr));
/* address lifetime (infty) */
addreq6.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
addreq6.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
if (ioctl(sock6_fd, SIOCAIFADDR_IN6, &addreq6) < 0) {
syslog(LOG_ERR, "sif6addr: ioctl(SIOCAIFADDR_IN6): %m");
return 0;
}
return 1;
}
/*
* cif6addr - Remove IPv6 address from interface
*/
int
cif6addr(int unit, eui64_t our_eui64, eui64_t his_eui64)
{
int ifindex;
struct in6_ifreq delreq6;
if (sock6_fd < 0) {
syslog(LOG_ERR, "No IPv6 socket available");
die(1);
/*NOTREACHED*/
}
/* actually, this part is not kame local - RFC2553 conformant */
ifindex = if_nametoindex(ifname);
if (ifindex == 0) {
syslog(LOG_ERR, "cifaddr6: no interface %s", ifname);
return 0;
}
memset(&delreq6, 0, sizeof(delreq6));
strlcpy(delreq6.ifr_name, ifname, sizeof(delreq6.ifr_name));
/* my addr */
delreq6.ifr_ifru.ifru_addr.sin6_family = AF_INET6;
delreq6.ifr_ifru.ifru_addr.sin6_len = sizeof(struct sockaddr_in6);
delreq6.ifr_ifru.ifru_addr.sin6_addr.s6_addr[0] = 0xfe;
delreq6.ifr_ifru.ifru_addr.sin6_addr.s6_addr[1] = 0x80;
memcpy(&delreq6.ifr_ifru.ifru_addr.sin6_addr.s6_addr[8], &our_eui64,
sizeof(our_eui64));
/* KAME ifindex hack */
*(u_int16_t *)&delreq6.ifr_ifru.ifru_addr.sin6_addr.s6_addr[2] =
htons(ifindex);
if (ioctl(sock6_fd, SIOCDIFADDR_IN6, &delreq6) < 0) {
syslog(LOG_ERR, "cif6addr: ioctl(SIOCDIFADDR_IN6): %m");
return 0;
}
return 1;
}
#endif /* INET6 */
/*
* open_ppp_loopback - open the device we use for getting