From aa2caf2f5e3989d1b1ef326a4fbb8cd2fd4f9faf Mon Sep 17 00:00:00 2001 From: brian Date: Wed, 25 Jul 2001 03:34:07 +0000 Subject: If an attempt is made to LISTEN for a service tag that's already being LISTENed for, return EEXISTS. Only match the magic "*" service tag if no other LISTEN service tags match. Require an explicit LISTEN for an empty service tag in order to match empty service requests. Approved by: julian MFC after: 3 days --- sys/netgraph/ng_pppoe.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) (limited to 'sys/netgraph/ng_pppoe.c') diff --git a/sys/netgraph/ng_pppoe.c b/sys/netgraph/ng_pppoe.c index faa323c..2378e7a 100644 --- a/sys/netgraph/ng_pppoe.c +++ b/sys/netgraph/ng_pppoe.c @@ -451,13 +451,18 @@ AAA * for testing allow a null string to match 1st found and a null service * to match all requests. Also make '*' do the same. */ + +#define NG_MATCH_EXACT 1 +#define NG_MATCH_ANY 2 + static hook_p -pppoe_match_svc(node_p node, char *svc_name, int svc_len) +pppoe_match_svc(node_p node, char *svc_name, int svc_len, int match) { sessp sp = NULL; negp neg = NULL; priv_p privp = NG_NODE_PRIVATE(node); - hook_p hook; + hook_p allhook = NULL; + hook_p hook; AAA LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) { @@ -473,17 +478,12 @@ AAA continue; neg = sp->neg; - /* XXX check validity of this */ - /* special case, NULL request. match 1st found. */ - if (svc_len == 0) - break; - /* XXX check validity of this */ /* Special case for a blank or "*" service name (wildcard) */ - if ((neg->service_len == 0) - || ((neg->service_len == 1) - && (neg->service.data[0] == '*'))) { - break; + if (match == NG_MATCH_ANY && neg->service_len == 1 && + neg->service.data[0] == '*') { + allhook = hook; + continue; } /* If the lengths don't match, that aint it. */ @@ -491,10 +491,13 @@ AAA continue; /* An exact match? */ + if (svc_len == 0) + break; + if (strncmp(svc_name, neg->service.data, svc_len) == 0) break; } - return (hook); + return (hook ? hook : allhook); } /************************************************************************** * Routine to find a particular session that matches an incoming packet * @@ -685,6 +688,17 @@ AAA } sp = NG_HOOK_PRIVATE(hook); + if (msg->header.cmd == NGM_PPPOE_LISTEN) { + /* + * Ensure we aren't already listening for this + * service. + */ + if (pppoe_match_svc(node, ourmsg->data, + ourmsg->data_len, NG_MATCH_EXACT) != NULL) { + LEAVE(EEXIST); + } + } + /* * PPPOE_SERVICE advertisments are set up * on sessions that are in PRIMED state. @@ -991,12 +1005,12 @@ AAA LEAVE(ENETUNREACH); } sendhook = pppoe_match_svc(NG_HOOK_NODE(hook), - tag->tag_data, ntohs(tag->tag_len)); + tag->tag_data, ntohs(tag->tag_len), + NG_MATCH_ANY); if (sendhook) { NG_FWD_NEW_DATA(error, item, sendhook, m); } else { - printf("no such service\n"); LEAVE(ENETUNREACH); } break; -- cgit v1.1