/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* pppoe.c - pppd plugin to handle PPPoE operation.
*/
#include <unistd.h>
#include <stddef.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <strings.h>
#include "pppd.h"
#include "pathnames.h"
/* Saved hook pointers */
/* Room for 3 IPv4 addresses and metric */
/* Environment string for routes */
/*
* strioctl()
*
* wrapper for STREAMS I_STR ioctl.
*/
static int
{
return (-1);
}
return (-1);
}
return (0);
}
/*
* If the user named the tunneling device, check that it is
* reasonable; otherwise check that standard input is the tunnel.
*/
static int
{
if (devnam[0] != '\0') {
/*
* Open as real user so that modes on device can be
* used to limit access.
*/
if (!devnam_info.priv)
if (!devnam_info.priv)
(void) seteuid(0);
if (tstfd == -1) {
return (-1);
}
if (retv == -1) {
option_error("device %s is not a PPP tunneling device",
devnam);
return (-1);
}
} else {
if (retv == -1) {
option_error("standard input is not a PPP device");
return (-1);
}
if (retv == -1) {
option_error("standard input is not a PPP tunnel");
return (-1);
}
":pppoe") != 0) {
option_error("standard input not connected to PPPoE");
return (-1);
}
}
if (old_check_options != NULL &&
return ((*old_check_options)(uid));
return (0);
}
/*
* When we're about to call one of the up or down scripts, change the
* second argument to contain the interface name and selected PPPoE
* service.
*/
static int
{
const char *cp;
if (old_updown_script != NULL &&
return ((*old_updown_script)(argsp));
return (0);
}
/*
* Concatenate and save strings from command line into environment
* variable.
*/
static void
{
char **argp;
int totlen;
char *str;
char *cp;
totlen = 0;
return;
}
*cp++ = '\n';
}
*cp = '\0';
}
/*
* Convert Message Of The Moment (MOTM) and Host Uniform Resource
* Locator (HURL) strings into environment variables and command-line
* arguments for script.
*/
static void
{
int ttype;
int tlen;
char *str;
/* Must have room for two strings and NULL terminator. */
while (argc >= 3) {
while (pktlen >= POET_HDRLEN) {
break;
break;
error("cannot malloc PPPoE message");
break;
}
}
break;
}
break;
argc -= 2;
}
}
/*
* Convert IP Route Add structures into environment variables and
* command-line arguments for script.
*/
static void
{
int ttype;
int tlen;
char *str;
int idx;
idx = 0;
/* Must have room for four strings and NULL terminator. */
while (argc >= 5) {
while (pktlen >= POET_HDRLEN) {
break;
break;
error("cannot malloc PPPoE route");
break;
}
break;
}
break;
/* No alignment restrictions on source; copy to local. */
/* Save off the environment variable version of this. */
*str++ = '\0';
*str++ = '\0';
*str++ = '\0';
argc -= 4;
}
}
/*
* If we get here, then the driver has already validated the sender,
* the PPPoE version, the message length, and session ID. The code
* number is known not to be zero.
*/
static int
{
const char *mname;
const char *cstr;
char *str;
char *cp;
char **argp;
int idx;
int pktlen;
/*
* Warning: the data->buf pointer here is not necessarily properly
* aligned for access to the poep_session_id or poep_length members.
*/
/* LINTED: alignment */
case POECODE_PADT:
dbglog("received PPPoE PADT; connection has been closed");
/* LINTED: alignment */
return (0);
/* Active Discovery Message and Network extensions */
case POECODE_PADM:
case POECODE_PADN:
mname = "PADM";
} else {
mname = "PADN";
pktlen);
}
/* Note: strdup doesn't handle NULL input. */
} else {
else
*cp++ = '\0';
}
argv[0]);
/* Free storage allocated by handle_{motm_hurl,ip_route_add} */
idx = 0;
argp += 2;
} else {
argp += 4;
}
}
script_unsetenv("HURL");
script_unsetenv("MOTM");
}
break;
default:
break;
}
return (-1);
}
/*
* Handle an action code passed up from the driver.
*/
static int
{
switch (ptc->ptc_action) {
case PTCA_CONTROL:
case PTCA_BADCTRL:
return (0);
}
return (-1);
}
/*
* sys-solaris has just read in a packet; grovel through it and see if
* it's something we need to handle ourselves.
*/
static int
int flags)
{
/* LINTED: alignment */
/* ptc_discrim is the first uint32_t of the structure. */
retv = -1;
if (retv < 0)
return (retv);
}
}
/* Forward along to other plug-ins */
if (old_sys_read_packet != NULL &&
return (retv);
}
/*
* Get an environment variable from the chat script.
*/
static int
{
int len;
return (-1);
if (len <= 1)
return (0);
return (1);
}
/*
* Read environment variables exported by chat script.
*/
static void
{
int i;
fatal("unable to open environment file: %m");
for (i = 1; ; i++) {
"VENDOR_SPECIFIC_%d", i);
break;
}
}
void
plugin_init(void)
{
if (absmax_mtu > 1492)
absmax_mtu = 1492;
if (absmax_mru > 1492)
absmax_mru = 1492;
already_ppp = 1;
}