diff options
author | brian <brian@FreeBSD.org> | 2001-07-25 03:34:07 +0000 |
---|---|---|
committer | brian <brian@FreeBSD.org> | 2001-07-25 03:34:07 +0000 |
commit | aa2caf2f5e3989d1b1ef326a4fbb8cd2fd4f9faf (patch) | |
tree | 2fcf4b2e1988ab52ce700a74dddc51bab9ee95d7 /sys | |
parent | 28c44c45cbe37e450773f5aacb8d8219d2d415b6 (diff) | |
download | FreeBSD-src-aa2caf2f5e3989d1b1ef326a4fbb8cd2fd4f9faf.zip FreeBSD-src-aa2caf2f5e3989d1b1ef326a4fbb8cd2fd4f9faf.tar.gz |
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
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netgraph/ng_pppoe.c | 42 |
1 files changed, 28 insertions, 14 deletions
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; |