* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <limits.h>
#include <stdio.h>
#include <stddef.h>
#include <sys/ethernet.h>
#endif
-#include "pppd.h"
+#ifdef PPP_WITH_FILTER
+#include <pcap.h>
+#endif
+
+#include "pppd-private.h"
#include "fsm.h"
#include "lcp.h"
#include "ipcp.h"
#include "ccp.h"
+#ifdef PPP_WITH_IPV6CP
+#include "eui64.h"
+#endif
+
#if !defined(PPP_DRV_NAME)
#define PPP_DRV_NAME "ppp"
#endif /* !defined(PPP_DRV_NAME) */
static int ipfd;
static int ipmuxid = -1;
-#if defined(INET6) && defined(SOL2)
+#if defined(PPP_WITH_IPV6CP) && defined(SOL2)
static int ip6fd; /* IP file descriptor */
static int ip6muxid = -1; /* Multiplexer file descriptor */
static int if6_is_up = 0; /* IPv6 interface has been marked up */
#define IN6A_LLADDR_FROM_EUI64(s, eui64) \
_IN6A_LLX_FROM_EUI64(s, eui64, 0xfe800000)
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
-#if defined(INET6) && defined(SOL2)
-static char first_ether_name[LIFNAMSIZ]; /* Solaris 8 and above */
-#else
-static char first_ether_name[IFNAMSIZ]; /* Before Solaris 8 */
+#if !defined(PPP_WITH_IPV6CP) || !defined(SOL2)
#define MAXIFS 256 /* Max # of interfaces */
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
static int restore_term;
static struct termios inittermios;
static int get_hw_addr_dlpi(char *, struct sockaddr *);
static int dlpi_attach(int, int);
static int dlpi_info_req(int);
-static int dlpi_get_reply(int, union DL_primitives *, int, int);
+static int dlpi_get_reply(int, union DL_primitives *, int, size_t);
static int strioctl(int, int, void *, int, int);
#ifdef SOL2
}
#endif /* SOL2 */
-#if defined(SOL2) && defined(INET6)
+#if defined(SOL2) && defined(PPP_WITH_IPV6CP)
/*
- * get_first_ethernet - returns the first Ethernet interface name found in
- * the system, or NULL if none is found
+ * get_first_ether_hwaddr - get the hardware address for the first
+ * ethernet-style interface on this system.
*
* NOTE: This is the lifreq version (Solaris 8 and above)
*/
-char *
-get_first_ethernet(void)
+int
+get_first_ether_hwaddr(u_char *addr)
{
struct lifnum lifn;
struct lifconf lifc;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
- return 0;
+ return -1;
}
/*
if (ioctl(fd, SIOCGLIFNUM, &lifn) < 0) {
close(fd);
error("could not determine number of interfaces: %m");
- return 0;
+ return -1;
}
num_ifs = lifn.lifn_count;
if (req == NULL) {
close(fd);
error("out of memory");
- return 0;
+ return -1;
}
/*
close(fd);
free(req);
error("SIOCGLIFCONF: %m");
- return 0;
+ return -1;
}
/*
memset(&lifr, 0, sizeof(lifr));
strncpy(lifr.lifr_name, plifreq->lifr_name, sizeof(lifr.lifr_name));
if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) {
- close(fd);
- free(req);
error("SIOCGLIFFLAGS: %m");
- return 0;
+ break;
}
fl = lifr.lifr_flags;
!= (IFF_UP | IFF_BROADCAST))
continue;
+ if (get_if_hwaddr(addr, lifr.lifr_name) < 0)
+ continue;
+
found = 1;
break;
}
free(req);
close(fd);
- if (found) {
- strncpy(first_ether_name, lifr.lifr_name, sizeof(first_ether_name));
- return (char *)first_ether_name;
- } else
- return NULL;
+ if (found)
+ return 0;
+ else
+ return -1;
}
#else
/*
- * get_first_ethernet - returns the first Ethernet interface name found in
- * the system, or NULL if none is found
+ * get_first_ether_hwaddr - get the hardware address for the first
+ * ethernet-style interface on this system.
*
* NOTE: This is the ifreq version (before Solaris 8).
*/
-char *
-get_first_ethernet(void)
+int
+get_first_ether_hwaddr(u_char *addr)
{
struct ifconf ifc;
struct ifreq *pifreq;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
- return 0;
+ return -1;
}
/*
if (req == NULL) {
close(fd);
error("out of memory");
- return 0;
+ return -1;
}
/*
close(fd);
free(req);
error("SIOCGIFCONF: %m");
- return 0;
+ return -1;
}
/*
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, pifreq->ifr_name, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
- close(fd);
- free(req);
error("SIOCGIFFLAGS: %m");
- return 0;
+ break;
}
fl = ifr.ifr_flags;
!= (IFF_UP | IFF_BROADCAST))
continue;
+ if (get_if_hwaddr(addr, ifr.ifr_name) < 0)
+ continue;
+
found = 1;
break;
}
free(req);
close(fd);
- if (found) {
- strncpy(first_ether_name, ifr.ifr_name, sizeof(first_ether_name));
- return (char *)first_ether_name;
- } else
- return NULL;
+ if (found)
+ return 0;
+ else
+ return -1;
}
-#endif /* defined(SOL2) && defined(INET6) */
+#endif /* defined(SOL2) && defined(PPP_WITH_IPV6CP) */
#if defined(SOL2)
/*
}
#endif /* SOL2 */
-#if defined(SOL2) && defined(INET6)
+#if defined(SOL2) && defined(PPP_WITH_IPV6CP)
/*
* slifname - Sets interface ppa and flags
*
}
-#endif /* defined(SOL2) && defined(INET6) */
+#endif /* defined(SOL2) && defined(PPP_WITH_IPV6CP) */
/*
* sys_init - System-dependent initialization.
{
int ifd, x;
struct ifreq ifr;
-#if defined(INET6) && defined(SOL2)
+#if defined(PPP_WITH_IPV6CP) && defined(SOL2)
int i6fd;
struct lifreq lifr;
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
#if !defined(SOL2)
struct {
union DL_primitives prim;
if (ipfd < 0)
fatal("Couldn't open IP device: %m");
-#if defined(INET6) && defined(SOL2)
+#if defined(PPP_WITH_IPV6CP) && defined(SOL2)
ip6fd = open(UDP6_DEV_NAME, O_RDWR, 0);
if (ip6fd < 0)
fatal("Couldn't open IP device (2): %m");
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
if (default_device && !notty)
tty_sid = getsid((pid_t)0);
strioctl(ifd, PPPIO_DEBUG, &x, sizeof(int), 0);
}
-#if defined(INET6) && defined(SOL2)
+#if defined(PPP_WITH_IPV6CP) && defined(SOL2)
i6fd = open(PPP_DEV_NAME, O_RDWR, 0);
if (i6fd < 0) {
close(ifd);
x = PPPDBG_LOG + PPPDBG_DRIVER;
strioctl(i6fd, PPPIO_DEBUG, &x, sizeof(int), 0);
}
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
#if defined(SOL2)
if (ioctl(ifd, I_PUSH, IP_MOD_NAME) < 0) {
close(ifd);
-#if defined(INET6)
+#if defined(PPP_WITH_IPV6CP)
close(i6fd);
-#endif /* defined(INET6) */
+#endif /* defined(PPP_WITH_IPV6CP) */
fatal("Can't push IP module: %m");
}
*/
if (sifppa(ifd, ifunit) < 0) {
close (ifd);
-#if defined(INET6)
+#if defined(PPP_WITH_IPV6CP)
close(i6fd);
-#endif /* defined(INET6) */
+#endif /* defined(PPP_WITH_IPV6CP) */
fatal("Can't set ppa for unit %d: %m", ifunit);
}
-#if defined(INET6)
+#if defined(PPP_WITH_IPV6CP)
/*
* An IPv6 interface is created anyway, even when the user does not
* explicitly enable it. Note that the interface will be marked
close(i6fd);
fatal("Can't set ifname for unit %d: %m", ifunit);
}
-#endif /* defined(INET6) */
+#endif /* defined(PPP_WITH_IPV6CP) */
ipmuxid = ioctl(ipfd, I_PLINK, ifd);
close(ifd);
if (ipmuxid < 0) {
-#if defined(INET6)
+#if defined(PPP_WITH_IPV6CP)
close(i6fd);
-#endif /* defined(INET6) */
+#endif /* defined(PPP_WITH_IPV6CP) */
fatal("Can't I_PLINK PPP device to IP: %m");
}
*/
if (ioctl(ipfd, SIOCSIFMUXID, &ifr) < 0) {
ioctl(ipfd, I_PUNLINK, ipmuxid);
-#if defined(INET6)
+#if defined(PPP_WITH_IPV6CP)
close(i6fd);
-#endif /* defined(INET6) */
+#endif /* defined(PPP_WITH_IPV6CP) */
fatal("SIOCSIFMUXID: %m");
}
fatal("Can't link PPP device to IP: %m");
#endif /* defined(SOL2) */
-#if defined(INET6) && defined(SOL2)
+#if defined(PPP_WITH_IPV6CP) && defined(SOL2)
ip6muxid = ioctl(ip6fd, I_PLINK, i6fd);
close(i6fd);
if (ip6muxid < 0) {
ioctl(ip6fd, I_PUNLINK, ip6muxid);
fatal("Can't link PPP device to IP (2): %m");
}
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
#if !defined(SOL2)
/* Set the interface name for the link. */
{
#if defined(SOL2)
struct ifreq ifr;
-#if defined(INET6)
+#if defined(PPP_WITH_IPV6CP)
struct lifreq lifr;
-#endif /* defined(INET6) */
+#endif /* defined(PPP_WITH_IPV6CP) */
#endif /* defined(SOL2) */
-#if defined(SOL2) && defined(INET6)
+#if defined(SOL2) && defined(PPP_WITH_IPV6CP)
if (if6_is_up)
sif6down(0);
-#endif /* defined(SOL2) && defined(INET6) */
+#endif /* defined(SOL2) && defined(PPP_WITH_IPV6CP) */
if (if_is_up)
sifdown(0);
if (default_route_gateway)
error("Can't I_PUNLINK PPP from IP: %m");
return;
}
-#if defined(INET6)
+#if defined(PPP_WITH_IPV6CP)
/*
* Make sure we ask ip what the muxid, because 'ifconfig modlist' will
* unlink and re-link the modules, causing the muxid to change.
if (ioctl(ip6fd, I_PUNLINK, ip6muxid) < 0) {
error("Can't I_PUNLINK PPP from IP (2): %m");
}
-#endif /* defined(INET6) */
+#endif /* defined(PPP_WITH_IPV6CP) */
#endif /* defined(SOL2) */
}
* sys_close - Clean up in a child process before execing.
*/
void
-sys_close(void)
+ppp_sys_close(void)
{
close(ipfd);
-#if defined(INET6) && defined(SOL2)
+#if defined(PPP_WITH_IPV6CP) && defined(SOL2)
close(ip6fd);
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
if (pppfd >= 0)
close(pppfd);
}
#endif
/*
- * ppp_available - check whether the system has any ppp interfaces
+ * ppp_check_kernel_support - check whether the system has any ppp interfaces
*/
int
-ppp_available(void)
+ppp_check_kernel_support(void)
{
struct stat buf;
/* Push the async hdlc module and the compressor module. */
tty_npushed = 0;
- if(!sync_serial) {
+ if(!ppp_sync_serial()) {
if (ioctl(fd, I_PUSH, AHDLC_MOD_NAME) < 0) {
error("Couldn't push PPP Async HDLC module: %m");
return -1;
struct termiox tiox;
#endif
- if (!sync_serial && tcgetattr(fd, &tios) < 0)
+ if (!ppp_sync_serial() && tcgetattr(fd, &tios) < 0)
fatal("tcgetattr: %m");
#ifndef CRTSCTS
termiox_ok = 1;
- if (!sync_serial && ioctl (fd, TCGETX, &tiox) < 0) {
+ if (!ppp_sync_serial() && ioctl (fd, TCGETX, &tiox) < 0) {
termiox_ok = 0;
if (errno != ENOTTY)
error("TCGETX: %m");
#ifndef CRTSCTS
inittermiox = tiox;
#endif
- if (!sync_serial)
+ if (!ppp_sync_serial())
ioctl(fd, TIOCGWINSZ, &wsinfo);
}
* We can't proceed if the serial port speed is 0,
* since that implies that the serial port is disabled.
*/
- if ((speed == B0) && !sync_serial)
+ if ((speed == B0) && !ppp_sync_serial())
fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
}
- if (!sync_serial && tcsetattr(fd, TCSAFLUSH, &tios) < 0)
+ if (!ppp_sync_serial() && tcsetattr(fd, TCSAFLUSH, &tios) < 0)
fatal("tcsetattr: %m");
#ifndef CRTSCTS
- if (!sync_serial && termiox_ok && ioctl (fd, TCSETXF, &tiox) < 0){
+ if (!ppp_sync_serial() && termiox_ok && ioctl (fd, TCSETXF, &tiox) < 0){
error("TCSETXF: %m");
}
#endif
baud_rate = inspeed = baud_rate_of(speed);
- if (!sync_serial)
+ if (!ppp_sync_serial())
restore_term = 1;
}
*/
inittermios.c_lflag &= ~(ECHO | ECHONL);
}
- if (!sync_serial && tcsetattr(fd, TCSAFLUSH, &inittermios) < 0)
+ if (!ppp_sync_serial() && tcsetattr(fd, TCSAFLUSH, &inittermios) < 0)
if (!hungup && errno != ENXIO)
warn("tcsetattr: %m");
#ifndef CRTSCTS
- if (!sync_serial && ioctl (fd, TCSETXF, &inittermiox) < 0){
+ if (!ppp_sync_serial() && ioctl (fd, TCSETXF, &inittermiox) < 0){
if (!hungup && errno != ENXIO)
error("TCSETXF: %m");
}
#endif
- if (!sync_serial)
+ if (!ppp_sync_serial())
ioctl(fd, TIOCSWINSZ, &wsinfo);
restore_term = 0;
}
}
/*
- * netif_set_mtu - set the MTU on the PPP network interface.
+ * ppp_set_mtu - set the MTU on the PPP network interface.
*/
void
-netif_set_mtu(int unit, int mtu)
+ppp_set_mtu(int unit, int mtu)
{
struct ifreq ifr;
-#if defined(INET6) && defined(SOL2)
+#if defined(PPP_WITH_IPV6CP) && defined(SOL2)
struct lifreq lifr;
int fd;
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
error("Couldn't set IP MTU (%s): %m", ifr.ifr_name);
}
-#if defined(INET6) && defined(SOL2)
+#if defined(PPP_WITH_IPV6CP) && defined(SOL2)
fd = socket(AF_INET6, SOCK_DGRAM, 0);
if (fd < 0)
error("Couldn't open IPv6 socket: %m");
error("Couldn't set IPv6 MTU (%s): %m", ifr.ifr_name);
}
close(fd);
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
}
/*
- * netif_get_mtu - get the MTU on the PPP network interface.
+ * ppp_get_mtu - get the MTU on the PPP network interface.
*/
int
-netif_get_mtu(int unit)
+ppp_get_mtu(int unit)
{
struct ifreq ifr;
error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
return 0;
}
- return ifr.ifr_mtu;
+ return ifr.ifr_metric;
}
/*
error("Couldn't set MTU: %m");
}
if (fdmuxid >= 0) {
- if (!sync_serial) {
+ if (!ppp_sync_serial()) {
if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0)
error("Couldn't set transmit ACCM: %m");
}
void
tty_set_xaccm(ext_accm accm)
{
- if (sync_serial)
+ if (ppp_sync_serial())
return;
if (fdmuxid >= 0
error("Couldn't set MRU: %m");
}
if (fdmuxid >= 0) {
- if (!sync_serial) {
+ if (!ppp_sync_serial()) {
if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0)
error("Couldn't set receive ACCM: %m");
}
{
struct ppp_stats s;
- if (!sync_serial &&
+ if (!ppp_sync_serial() &&
strioctl(pppfd, PPPIO_GETSTAT, &s, 0, sizeof(s)) < 0) {
error("Couldn't get link statistics: %m");
return 0;
return 1;
}
-#if 0
-/*
- * set_filters - transfer the pass and active filters to the kernel.
- */
-int
-set_filters(struct bpf_program *pass, struct bpf_program *active)
-{
- int ret = 1;
-
- if (pass->bf_len > 0) {
- if (strioctl(pppfd, PPPIO_PASSFILT, pass,
- sizeof(struct bpf_program), 0) < 0) {
- error("Couldn't set pass-filter in kernel: %m");
- ret = 0;
- }
- }
- if (active->bf_len > 0) {
- if (strioctl(pppfd, PPPIO_ACTIVEFILT, active,
- sizeof(struct bpf_program), 0) < 0) {
- error("Couldn't set active-filter in kernel: %m");
- ret = 0;
- }
- }
- return ret;
-}
-#endif
-
/*
* ccp_fatal_error - returns 1 if decompression was disabled as a
* result of an error detected after decompression of a packet,
return 1;
}
-#if defined(SOL2) && defined(INET6)
+#if defined(SOL2) && defined(PPP_WITH_IPV6CP)
/*
* sif6up - Config the IPv6 interface up and enable IPv6 packets to pass.
*/
return 1;
}
-#endif /* defined(SOL2) && defined(INET6) */
+#endif /* defined(SOL2) && defined(PPP_WITH_IPV6CP) */
#define INET_ADDR(x) (((struct sockaddr_in *) &(x))->sin_addr.s_addr)
}
static int
-dlpi_get_reply(int fd, union DL_primitives *reply, int expected_prim, maxlen)
+dlpi_get_reply(int fd, union DL_primitives *reply, int expected_prim, size_t maxlen)
{
struct strbuf buf;
int flags, n;
pfd.events = POLLIN | POLLPRI;
do {
n = poll(&pfd, 1, 1000);
- } while (n == -1 && errno == EINTR && !got_sigterm);
+ } while (n == -1 && errno == EINTR && !ppp_signaled(SIGTERM));
if (n <= 0)
return -1;
* get_time - Get current time, monotonic if possible.
*/
int
-get_time(struct timeval *tv)
+ppp_get_time(struct timeval *tv)
{
return gettimeofday(tv, NULL);
}