Deleted Added
full compact
ng_pppoe.c (154604) ng_pppoe.c (154862)
1/*
2 * ng_pppoe.c
3 */
4
5/*-
6 * Copyright (c) 1996-1999 Whistle Communications, Inc.
7 * All rights reserved.
8 *

--- 23 unchanged lines hidden (view full) ---

32 * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
36 * OF SUCH DAMAGE.
37 *
38 * Author: Julian Elischer <julian@freebsd.org>
39 *
1/*
2 * ng_pppoe.c
3 */
4
5/*-
6 * Copyright (c) 1996-1999 Whistle Communications, Inc.
7 * All rights reserved.
8 *

--- 23 unchanged lines hidden (view full) ---

32 * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
36 * OF SUCH DAMAGE.
37 *
38 * Author: Julian Elischer <julian@freebsd.org>
39 *
40 * $FreeBSD: head/sys/netgraph/ng_pppoe.c 154604 2006-01-21 08:13:19Z glebius $
40 * $FreeBSD: head/sys/netgraph/ng_pppoe.c 154862 2006-01-26 13:06:49Z glebius $
41 * $Whistle: ng_pppoe.c,v 1.10 1999/11/01 09:24:52 julian Exp $
42 */
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/kernel.h>
47#include <sys/ktr.h>
48#include <sys/mbuf.h>

--- 390 unchanged lines hidden (view full) ---

439 dp += tlen;
440 }
441 wh->ph.length = htons(length);
442 sp->neg->m->m_len = length + sizeof(*wh);
443 sp->neg->m->m_pkthdr.len = length + sizeof(*wh);
444}
445
446/**************************************************************************
41 * $Whistle: ng_pppoe.c,v 1.10 1999/11/01 09:24:52 julian Exp $
42 */
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/kernel.h>
47#include <sys/ktr.h>
48#include <sys/mbuf.h>

--- 390 unchanged lines hidden (view full) ---

439 dp += tlen;
440 }
441 wh->ph.length = htons(length);
442 sp->neg->m->m_len = length + sizeof(*wh);
443 sp->neg->m->m_pkthdr.len = length + sizeof(*wh);
444}
445
446/**************************************************************************
447 * Routine to match a service offered *
447 * Routines to match a service. *
448 **************************************************************************/
448 **************************************************************************/
449
449/*
450 * Find a hook that has a service string that matches that
450/*
451 * Find a hook that has a service string that matches that
451 * we are seeking. for now use a simple string.
452 * we are seeking. For now use a simple string.
452 * In the future we may need something like regexp().
453 * In the future we may need something like regexp().
453 * for testing allow a null string to match 1st found and a null service
454 * to match all requests. Also make '*' do the same.
454 *
455 * Null string is a wildcard (ANY service), according to RFC2516.
456 * And historical FreeBSD wildcard is also "*".
455 */
456
457 */
458
457#define NG_MATCH_EXACT 1
458#define NG_MATCH_ANY 2
459
460static hook_p
459static hook_p
461pppoe_match_svc(node_p node, const char *svc_name, int svc_len, int match)
460pppoe_match_svc(node_p node, const struct pppoe_tag *tag)
462{
461{
463 sessp sp = NULL;
464 negp neg = NULL;
465 priv_p privp = NG_NODE_PRIVATE(node);
466 hook_p allhook = NULL;
467 hook_p hook;
462 priv_p privp = NG_NODE_PRIVATE(node);
463 hook_p hook;
468
469 LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) {
464
465 LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) {
466 sessp sp = NG_HOOK_PRIVATE(hook);
467 negp neg;
470
468
471 /* skip any hook that is debug or ethernet */
472 if ((NG_HOOK_PRIVATE(hook) == &privp->debug_hook)
473 || (NG_HOOK_PRIVATE(hook) == &privp->ethernet_hook))
469 /* Skip any hook that is debug or ethernet. */
470 if ((NG_HOOK_PRIVATE(hook) == &privp->debug_hook) ||
471 (NG_HOOK_PRIVATE(hook) == &privp->ethernet_hook))
474 continue;
472 continue;
475 sp = NG_HOOK_PRIVATE(hook);
476
477 /* Skip any sessions which are not in LISTEN mode. */
473
474 /* Skip any sessions which are not in LISTEN mode. */
478 if ( sp->state != PPPOE_LISTENING)
475 if (sp->state != PPPOE_LISTENING)
479 continue;
480
481 neg = sp->neg;
482
476 continue;
477
478 neg = sp->neg;
479
483 /* Special case for a blank or "*" service name (wildcard) */
484 if (match == NG_MATCH_ANY && neg->service_len == 1 &&
485 neg->service.data[0] == '*') {
486 allhook = hook;
487 continue;
488 }
480 /* Empty Service-Name matches any service. */
481 if (neg->service_len == 0)
482 break;
489
483
484 /* Special case for a blank or "*" service name (wildcard). */
485 if (neg->service_len == 1 && neg->service.data[0] == '*')
486 break;
487
490 /* If the lengths don't match, that aint it. */
488 /* If the lengths don't match, that aint it. */
491 if (neg->service_len != svc_len)
489 if (neg->service_len != ntohs(tag->tag_len))
492 continue;
493
490 continue;
491
494 /* An exact match? */
495 if (svc_len == 0)
492 if (strncmp(tag->tag_data, neg->service.data,
493 ntohs(tag->tag_len)) == 0)
496 break;
494 break;
495 }
496 CTR3(KTR_NET, "%20s: matched %p for %s", __func__, hook, tag->tag_data);
497
497
498 if (strncmp(svc_name, neg->service.data, svc_len) == 0)
499 break;
498 return (hook);
499}
500
501/*
502 * Broadcast the PADI packet in m0 to all listening hooks.
503 * This routine is called when a PADI with empty Service-Name
504 * tag is received. Client should receive PADOs with all
505 * available services.
506 */
507static int
508pppoe_broadcast_padi(node_p node, struct mbuf *m0)
509{
510 priv_p privp = NG_NODE_PRIVATE(node);
511 hook_p hook;
512 int error = 0;
513
514 LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) {
515 sessp sp = NG_HOOK_PRIVATE(hook);
516 struct mbuf *m;
517
518 /*
519 * Go through all listening hooks and
520 * broadcast the PADI packet up there
521 */
522 if ((NG_HOOK_PRIVATE(hook) == &privp->debug_hook) ||
523 (NG_HOOK_PRIVATE(hook) == &privp->ethernet_hook))
524 continue;
525
526 if (sp->state != PPPOE_LISTENING)
527 continue;
528
529 m = m_dup(m0, M_DONTWAIT);
530 if (m == NULL)
531 return (ENOMEM);
532 NG_SEND_DATA_ONLY(error, hook, m);
533 if (error)
534 return (error);
500 }
535 }
501 CTR3(KTR_NET, "%20s: matched %p for %s", __func__, hook, svc_name);
502
536
503 return (hook ? hook : allhook);
537 return (0);
504}
505
538}
539
540/*
541 * Find a hook, which name equals to given service.
542 */
543static hook_p
544pppoe_find_svc(node_p node, const char *svc_name, int svc_len)
545{
546 priv_p privp = NG_NODE_PRIVATE(node);
547 hook_p hook;
548
549 LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) {
550 sessp sp = NG_HOOK_PRIVATE(hook);
551 negp neg;
552
553 /* Skip any hook that is debug or ethernet. */
554 if ((NG_HOOK_PRIVATE(hook) == &privp->debug_hook) ||
555 (NG_HOOK_PRIVATE(hook) == &privp->ethernet_hook))
556 continue;
557
558 /* Skip any sessions which are not in LISTEN mode. */
559 if (sp->state != PPPOE_LISTENING)
560 continue;
561
562 neg = sp->neg;
563
564 if (neg->service_len == svc_len &&
565 strncmp(svc_name, neg->service.data, svc_len == 0))
566 return (hook);
567 }
568
569 return (NULL);
570}
571
506/**************************************************************************
507 * Routine to find a particular session that matches an incoming packet. *
508 **************************************************************************/
509static hook_p
510pppoe_findsession(node_p node, const struct pppoe_full_hdr *wh)
511{
512 priv_p privp = NG_NODE_PRIVATE(node);
513 sessp sp = NULL;

--- 184 unchanged lines hidden (view full) ---

698
699 sp = NG_HOOK_PRIVATE(hook);
700
701 if (msg->header.cmd == NGM_PPPOE_LISTEN) {
702 /*
703 * Ensure we aren't already listening for this
704 * service.
705 */
572/**************************************************************************
573 * Routine to find a particular session that matches an incoming packet. *
574 **************************************************************************/
575static hook_p
576pppoe_findsession(node_p node, const struct pppoe_full_hdr *wh)
577{
578 priv_p privp = NG_NODE_PRIVATE(node);
579 sessp sp = NULL;

--- 184 unchanged lines hidden (view full) ---

764
765 sp = NG_HOOK_PRIVATE(hook);
766
767 if (msg->header.cmd == NGM_PPPOE_LISTEN) {
768 /*
769 * Ensure we aren't already listening for this
770 * service.
771 */
706 if (pppoe_match_svc(node, ourmsg->data,
707 ourmsg->data_len, NG_MATCH_EXACT) != NULL)
772 if (pppoe_find_svc(node, ourmsg->data,
773 ourmsg->data_len) != NULL)
708 LEAVE(EEXIST);
709 }
710
711 /*
712 * PPPOE_SERVICE advertisments are set up
713 * on sessions that are in PRIMED state.
714 */
715 if (msg->header.cmd == NGM_PPPOE_SERVICE)

--- 364 unchanged lines hidden (view full) ---

1080 * Look for a hook with the required service
1081 * and send the ENTIRE packet up there.
1082 * It should come back to a new hook in
1083 * PRIMED state. Look there for further
1084 * processing.
1085 */
1086 tag = get_tag(ph, PTT_SRV_NAME);
1087 if (tag == NULL) {
774 LEAVE(EEXIST);
775 }
776
777 /*
778 * PPPOE_SERVICE advertisments are set up
779 * on sessions that are in PRIMED state.
780 */
781 if (msg->header.cmd == NGM_PPPOE_SERVICE)

--- 364 unchanged lines hidden (view full) ---

1146 * Look for a hook with the required service
1147 * and send the ENTIRE packet up there.
1148 * It should come back to a new hook in
1149 * PRIMED state. Look there for further
1150 * processing.
1151 */
1152 tag = get_tag(ph, PTT_SRV_NAME);
1153 if (tag == NULL) {
1088 printf("no service tag\n");
1154 CTR1(KTR_NET,
1155 "%20s: PADI w/o Service-Name",
1156 __func__);
1089 LEAVE(ENETUNREACH);
1090 }
1157 LEAVE(ENETUNREACH);
1158 }
1091 sendhook = pppoe_match_svc(NG_HOOK_NODE(hook),
1092 tag->tag_data, ntohs(tag->tag_len),
1093 NG_MATCH_ANY);
1094 if (sendhook) {
1095 NG_FWD_NEW_DATA(error, item,
1096 sendhook, m);
1097 } else {
1098 LEAVE(ENETUNREACH);
1099 }
1159
1160 /*
1161 * If Service-Name is NULL, we broadcast
1162 * the PADI to all listening hooks, otherwise
1163 * we seek for a matching one.
1164 */
1165 if (ntohs(tag->tag_len) != 0) {
1166 sendhook = pppoe_match_svc(node, tag);
1167 if (sendhook != NULL)
1168 NG_FWD_NEW_DATA(error, item,
1169 sendhook, m);
1170 else
1171 error = ENETUNREACH;
1172 } else
1173 error = pppoe_broadcast_padi(node, m);
1100 break;
1101 case PADO_CODE:
1102 /*
1103 * We are a client:
1104 * Use the host_uniq tag to find the
1105 * hook this is in response to.
1106 * Received #2, now send #3
1107 * For now simply accept the first we receive.

--- 675 unchanged lines hidden ---
1174 break;
1175 case PADO_CODE:
1176 /*
1177 * We are a client:
1178 * Use the host_uniq tag to find the
1179 * hook this is in response to.
1180 * Received #2, now send #3
1181 * For now simply accept the first we receive.

--- 675 unchanged lines hidden ---