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 --- |