diff options
Diffstat (limited to 'share/man/man4/ng_pppoe.4')
-rw-r--r-- | share/man/man4/ng_pppoe.4 | 507 |
1 files changed, 507 insertions, 0 deletions
diff --git a/share/man/man4/ng_pppoe.4 b/share/man/man4/ng_pppoe.4 new file mode 100644 index 0000000..a124d67 --- /dev/null +++ b/share/man/man4/ng_pppoe.4 @@ -0,0 +1,507 @@ +.\" Copyright (c) 1996-1999 Whistle Communications, Inc. +.\" All rights reserved. +.\" +.\" Subject to the following obligations and disclaimer of warranty, use and +.\" redistribution of this software, in source or object code forms, with or +.\" without modifications are expressly permitted by Whistle Communications; +.\" provided, however, that: +.\" 1. Any and all reproductions of the source or object code must include the +.\" copyright notice above and the following disclaimer of warranties; and +.\" 2. No rights are granted, in any manner or form, to use Whistle +.\" Communications, Inc. trademarks, including the mark "WHISTLE +.\" COMMUNICATIONS" on advertising, endorsements, or otherwise except as +.\" such appears in the above copyright notice or in the software. +.\" +.\" THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND +.\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO +.\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, +.\" INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. +.\" WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY +.\" REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS +.\" SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. +.\" IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES +.\" RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING +.\" WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +.\" PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR +.\" SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY +.\" OF SUCH DAMAGE. +.\" +.\" Author: Archie Cobbs <archie@FreeBSD.org> +.\" +.\" $FreeBSD$ +.\" $Whistle: ng_pppoe.8,v 1.1 1999/01/25 23:46:27 archie Exp $ +.\" +.Dd November 13, 2012 +.Dt NG_PPPOE 4 +.Os +.Sh NAME +.Nm ng_pppoe +.Nd RFC 2516 PPPoE protocol netgraph node type +.Sh SYNOPSIS +.In sys/types.h +.In net/ethernet.h +.In netgraph.h +.In netgraph/ng_pppoe.h +.Sh DESCRIPTION +The +.Nm pppoe +node type performs the PPPoE protocol. +It is used in conjunction with the +.Xr netgraph 4 +extensions to the Ethernet framework to divert and inject Ethernet packets +to and from a PPP agent (which is not specified). +.Pp +The +.Dv NGM_PPPOE_GET_STATUS +control message can be used at any time to query the current status +of the PPPoE module. +The only statistics presently available are the +total packet counts for input and output. +This node does not yet support +the +.Dv NGM_TEXT_STATUS +control message. +.Sh HOOKS +This node type supports the following hooks: +.Bl -tag -width ".Va [unspecified]" +.It Va ethernet +The hook that should normally be connected to an +.Xr ng_ether 4 +node. +Once connected, +.Nm +will send a message down this hook to determine Ethernet address of +the underlying node. +Obtained address will be stored and then used for outgoing datagrams. +.It Va debug +Presently no use. +.It Va [unspecified] +Any other name is assumed to be a session hook that will be connected to +a PPP client agent, or a PPP server agent. +.El +.Sh CONTROL MESSAGES +This node type supports the generic control messages, plus the following: +.Bl -tag -width 3n +.It Dv NGM_PPPOE_GET_STATUS +This command returns status information in a +.Dv "struct ngpppoestat" : +.Bd -literal -offset 4n +struct ngpppoestat { + u_int packets_in; /* packets in from Ethernet */ + u_int packets_out; /* packets out towards Ethernet */ +}; +.Ed +.It Dv NGM_TEXT_STATUS +This generic message returns a human-readable version of the node status. +(not yet) +.It Dv NGM_PPPOE_CONNECT Pq Ic pppoe_connect +Tell a nominated newly created hook that its session should enter +the state machine as a client. +It must be newly created and a service name can be given as an argument. +It is legal to specify a zero-length service name, this is common +on some DSL setups. +It is possible to request a connection to a specific +access concentrator by its name using the "AC-Name\\Service-Name" syntax. +A session request packet will be broadcasted on the Ethernet. +This command uses the +.Dv ngpppoe_init_data +structure shown below. +.It Dv NGM_PPPOE_LISTEN Pq Ic pppoe_listen +Tell a nominated newly created hook that its session should enter +the state machine as a server listener. +The argument +given is the name of the service to listen for. +A zero-length service name will match all requests for service. +A matching service request +packet will be passed unmodified back to the process responsible +for starting the service. +It can then examine it and pass it on to +the session that is started to answer the request. +This command uses the +.Dv ngpppoe_init_data +structure shown below. +.It Dv NGM_PPPOE_OFFER Pq Ic pppoe_offer +Tell a nominated newly created hook that its session should enter +the state machine as a server. +The argument given is the name of the service to offer. +A zero-length service +is legal. +The State machine will progress to a state where it will await +a request packet to be forwarded to it from the startup server, +which in turn probably received it from a LISTEN mode hook (see above). +This is so +that information that is required for the session that is embedded in +the original session request packet, is made available to the state machine +that eventually answers the request. +When the Session request packet is +received, the session negotiation will proceed. +This command uses the +.Dv ngpppoe_init_data +structure shown below. +.El +.Pp +The three commands above use a common data structure: +.Bd -literal -offset 4n +struct ngpppoe_init_data { + char hook[NG_HOOKSIZ]; /* hook to monitor on */ + uint16_t data_len; /* length of the service name */ + char data[0]; /* init data goes here */ +}; +.Ed +.Bl -tag -width 3n +.It Dv NGM_PPPOE_SUCCESS Pq Ic pppoe_success +This command is sent to the node that started this session with one of the +above messages, and reports a state change. +This message reports successful Session negotiation. +It uses the structure shown below, and +reports back the hook name corresponding to the successful session. +.It Dv NGM_PPPOE_FAIL Pq Ic pppoe_fail +This command is sent to the node that started this session with one of the +above messages, and reports a state change. +This message reports failed Session negotiation. +It uses the structure shown below, and +reports back the hook name corresponding to the failed session. +The hook will probably have been removed immediately after sending this +message. +.It Dv NGM_PPPOE_CLOSE Pq Ic pppoe_close +This command is sent to the node that started this session with one of the +above messages, and reports a state change. +This message reports a request to close a session. +It uses the structure shown below, and +reports back the hook name corresponding to the closed session. +The hook will probably have been removed immediately after sending this +message. +At present this message is not yet used and a +.Dv NGM_PPPOE_FAIL +message +will be received at closure instead. +.It Dv NGM_PPPOE_ACNAME +This command is sent to the node that started this session with one of the +above messages, and reports the Access Concentrator Name. +.El +.Pp +The four commands above use a common data structure: +.Bd -literal -offset 4n +struct ngpppoe_sts { + char hook[NG_HOOKSIZ]; /* hook associated with event session */ +}; +.Ed +.Bl -tag -width 3n +.It Dv NGM_PPPOE_GETMODE Pq Ic pppoe_getmode +This command returns the current compatibility mode of the node +as a string. +.Tn ASCII +form of this message is +.Qq Li pppoe_getmode . +The following keywords can be returned: +.Bl -tag -width 3n +.It Qq standard +The node operates according to RFC 2516. +.It Qq 3Com +When +.Nm +is a PPPoE client, it initiates a session encapsulating packets into +incorrect 3Com ethertypes. +This compatibility option does not affect server mode. +In server mode +.Nm +supports both modes simultaneously, depending on the ethertype, the +client used when connecting. +.It Qq D-Link +When +.Nm +is a PPPoE server serving only specific Service-Name(s), it will respond +to a PADI requests with empty Service-Name tag, returning all available +Service-Name(s) on node. +This option is necessary for compatibility with D-Link DI-614+ and DI-624+ +SOHO routers as clients, when serving only specific Service-Name. +This compatibility option does not affect client mode. +.El +.It Dv NGM_PPPOE_SETMODE Pq Ic pppoe_setmode +Configure node to the specified mode. +The string argument is required. +This command understands the same keywords that are returned by the +.Dv NGM_PPPOE_GETMODE +command. +.Tn ASCII +form of this message is +.Qq Li pppoe_setmode . +For example, the following command will configure the node to initiate +the next session in the proprietary 3Com mode: +.Bd -literal -offset indent +ngctl msg fxp0:orphans pppoe_setmode '"3Com"' +.Ed +.It Dv NGM_PPPOE_SETENADDR Pq Ic setenaddr +Set the node Ethernet address for outgoing datagrams. +This message is important when a node has failed to obtain an Ethernet +address from its peer on the +.Dv ethernet +hook, or when user wants to override this address with another one. +.Tn ASCII +form of this message is +.Qq Li setenaddr . +.El +.Sh SHUTDOWN +This node shuts down upon receipt of a +.Dv NGM_SHUTDOWN +control message, when all session have been disconnected or when the +.Dv ethernet +hook is disconnected. +.Sh EXAMPLES +The following code uses +.Dv libnetgraph +to set up a +.Nm +node and connect it to both a socket node and an Ethernet node. +It can handle the case of when a +.Nm +node is already attached to the Ethernet. +It then starts a client session. +.Bd -literal +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <unistd.h> +#include <sysexits.h> +#include <errno.h> +#include <err.h> + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/select.h> +#include <net/ethernet.h> + +#include <netgraph.h> +#include <netgraph/ng_ether.h> +#include <netgraph/ng_pppoe.h> +#include <netgraph/ng_socket.h> +static int setup(char *ethername, char *service, char *sessname, + int *dfd, int *cfd); + +int +main() +{ + int fd1, fd2; + setup("xl0", NULL, "fred", &fd1, &fd2); + sleep (30); +} + +static int +setup(char *ethername, char *service, char *sessname, + int *dfd, int *cfd) +{ + struct ngm_connect ngc; /* connect */ + struct ngm_mkpeer mkp; /* mkpeer */ + /******** nodeinfo stuff **********/ + u_char rbuf[2 * 1024]; + struct ng_mesg *const resp = (struct ng_mesg *) rbuf; + struct hooklist *const hlist + = (struct hooklist *) resp->data; + struct nodeinfo *const ninfo = &hlist->nodeinfo; + int ch, no_hooks = 0; + struct linkinfo *link; + struct nodeinfo *peer; + /****message to connect PPPoE session*****/ + struct { + struct ngpppoe_init_data idata; + char service[100]; + } message; + /********tracking our little graph ********/ + char path[100]; + char source_ID[NG_NODESIZ]; + char pppoe_node_name[100]; + int k; + + /* + * Create the data and control sockets + */ + if (NgMkSockNode(NULL, cfd, dfd) < 0) { + return (errno); + } + /* + * find the ether node of the name requested by asking it for + * it's inquiry information. + */ + if (strlen(ethername) > 16) + return (EINVAL); + sprintf(path, "%s:", ethername); + if (NgSendMsg(*cfd, path, NGM_GENERIC_COOKIE, + NGM_LISTHOOKS, NULL, 0) < 0) { + return (errno); + } + /* + * the command was accepted so it exists. Await the reply (It's + * almost certainly already waiting). + */ + if (NgRecvMsg(*cfd, resp, sizeof(rbuf), NULL) < 0) { + return (errno); + } + /** + * The following is available about the node: + * ninfo->name (string) + * ninfo->type (string) + * ninfo->id (uint32_t) + * ninfo->hooks (uint32_t) (count of hooks) + * check it is the correct type. and get it's ID for use + * with mkpeer later. + */ + if (strncmp(ninfo->type, NG_ETHER_NODE_TYPE, + strlen(NG_ETHER_NODE_TYPE)) != 0) { + return (EPROTOTYPE); + } + sprintf(source_ID, "[%08x]:", ninfo->id); + + /* + * look for a hook already attached. + */ + for (k = 0; k < ninfo->hooks; k++) { + /** + * The following are available about each hook. + * link->ourhook (string) + * link->peerhook (string) + * peer->name (string) + * peer->type (string) + * peer->id (uint32_t) + * peer->hooks (uint32_t) + */ + link = &hlist->link[k]; + peer = &hlist->link[k].nodeinfo; + + /* Ignore debug hooks */ + if (strcmp("debug", link->ourhook) == 0) + continue; + + /* If the orphans hook is attached, use that */ + if (strcmp(NG_ETHER_HOOK_ORPHAN, + link->ourhook) == 0) { + break; + } + /* the other option is the 'divert' hook */ + if (strcmp("NG_ETHER_HOOK_DIVERT", + link->ourhook) == 0) { + break; + } + } + + /* + * See if we found a hook there. + */ + if (k < ninfo->hooks) { + if (strcmp(peer->type, NG_PPPOE_NODE_TYPE) == 0) { + /* + * If it's a type PPPoE, we skip making one + * ourself, but we continue, using + * the existing one. + */ + sprintf(pppoe_node_name, "[%08x]:", peer->id); + } else { + /* + * There is already someone hogging the data, + * return an error. Some day we'll try + * daisy-chaining.. + */ + return (EBUSY); + } + } else { + + /* + * Try make a node of type PPPoE against node "ID" + * On hook NG_ETHER_HOOK_ORPHAN. + */ + snprintf(mkp.type, sizeof(mkp.type), + "%s", NG_PPPOE_NODE_TYPE); + snprintf(mkp.ourhook, sizeof(mkp.ourhook), + "%s", NG_ETHER_HOOK_ORPHAN); + snprintf(mkp.peerhook, sizeof(mkp.peerhook), + "%s", NG_PPPOE_HOOK_ETHERNET); + /* Send message */ + if (NgSendMsg(*cfd, source_ID, NGM_GENERIC_COOKIE, + NGM_MKPEER, &mkp, sizeof(mkp)) < 0) { + return (errno); + } + /* + * Work out a name for the new node. + */ + sprintf(pppoe_node_name, "%s:%s", + source_ID, NG_ETHER_HOOK_ORPHAN); + } + /* + * We now have a PPPoE node attached to the Ethernet + * card. The Ethernet is addressed as ethername: The PPPoE + * node is addressed as pppoe_node_name: attach to it. + * Connect socket node to specified node Use the same hook + * name on both ends of the link. + */ + snprintf(ngc.path, sizeof(ngc.path), "%s", pppoe_node_name); + snprintf(ngc.ourhook, sizeof(ngc.ourhook), "%s", sessname); + snprintf(ngc.peerhook, sizeof(ngc.peerhook), "%s", sessname); + + if (NgSendMsg(*cfd, ".:", NGM_GENERIC_COOKIE, + NGM_CONNECT, &ngc, sizeof(ngc)) < 0) { + return (errno); + } + +#ifdef NONSTANDARD + /* + * In some cases we are speaking to 3Com hardware, so + * configure node to non-standard mode. + */ + if (NgSendMsg(*cfd, ngc.path, NGM_PPPOE_COOKIE, + NGM_PPPOE_SETMODE, NG_PPPOE_NONSTANDARD, + strlen(NG_PPPOE_NONSTANDARD) + 1) == -1) { + return (errno); + } +#endif + + /* + * Send it a message telling it to start up. + */ + bzero(&message, sizeof(message)); + snprintf(message.idata.hook, sizeof(message.idata.hook), + "%s", sessname); + if (service == NULL) { + message.idata.data_len = 0; + } else { + snprintf(message.idata.data, + sizeof(message.idata.data), "%s", service); + message.idata.data_len = strlen(service); + } + /* Tell session/hook to start up as a client */ + if (NgSendMsg(*cfd, ngc.path, + NGM_PPPOE_COOKIE, NGM_PPPOE_CONNECT, &message.idata, + sizeof(message.idata) + message.idata.data_len) < 0) { + return (errno); + } + return (0); +} +.Ed +.Sh SEE ALSO +.Xr netgraph 3 , +.Xr netgraph 4 , +.Xr ng_ether 4 , +.Xr ng_ppp 4 , +.Xr ng_socket 4 , +.Xr ngctl 8 , +.Xr ppp 8 +.Rs +.%A L. Mamakos +.%A K. Lidl +.%A J. Evarts +.%A D. Carrel +.%A D. Simone +.%A R. Wheeler +.%T "A Method for transmitting PPP over Ethernet (PPPoE)" +.%O RFC 2516 +.Re +.Sh HISTORY +The +.Nm +node type was implemented in +.Fx 4.0 . +.Sh AUTHORS +.An Julian Elischer Aq julian@FreeBSD.org |