1/* 2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25#include <sys/systm.h> 26#include <sys/malloc.h> 27#include <sys/kpi_mbuf.h> 28#include <sys/socket.h> 29#include <sys/syslog.h> 30#include <sys/protosw.h> 31#include <kern/locks.h> 32 33#include <net/if_types.h> 34#include <net/if.h> 35 36#include "../../../Family/ppp_defs.h" 37#include "../../../Family/if_ppplink.h" 38#include "../../../Family/if_ppp.h" 39#include "../../../Family/ppp_domain.h" 40 41 42#include "PPPoE.h" 43#include "pppoe_proto.h" 44#include "pppoe_rfc.h" 45#include "pppoe_wan.h" 46 47 48/* ----------------------------------------------------------------------------- 49Definitions 50----------------------------------------------------------------------------- */ 51 52 53/* ----------------------------------------------------------------------------- 54Declarations 55----------------------------------------------------------------------------- */ 56 57void pppoe_init(); 58int pppoe_ctloutput(struct socket *so, struct sockopt *sopt); 59int pppoe_usrreq(); 60void pppoe_slowtimo(); 61 62int pppoe_attach(struct socket *, int, struct proc *); 63int pppoe_detach(struct socket *); 64int pppoe_shutdown(struct socket *); 65int pppoe_control(struct socket *so, u_long cmd, caddr_t data, 66 struct ifnet *ifp, struct proc *p); 67int pppoe_connect(struct socket *so, struct sockaddr *nam, struct proc *p); 68int pppoe_disconnect(struct socket *so); 69int pppoe_send(struct socket *so, int flags, struct mbuf *m, 70 struct sockaddr *nam, struct mbuf *control, struct proc *p); 71int pppoe_bind(struct socket *so, struct sockaddr *nam, struct proc *p); 72int pppoe_accept(struct socket *so, struct sockaddr **nam); 73int pppoe_listen(struct socket *so, struct proc *p); 74 75// callback from rfc layer 76void pppoe_event(void *data, u_int32_t event, u_int32_t msg); 77int pppoe_input(void *data, mbuf_t m); 78 79/* ----------------------------------------------------------------------------- 80Globals 81----------------------------------------------------------------------------- */ 82struct pr_usrreqs pppoe_usr; /* pr_usrreqs extension to the protosw */ 83struct protosw pppoe; /* describe the protocol switch */ 84 85extern lck_mtx_t *ppp_domain_mutex; 86 87/* ----------------------------------------------------------------------------- 88-------------------------------------------------------------------------------- 89-------------------------------------------------------------------------------- 90----------- Admistrative functions, called by ppp_domain ----------------------- 91-------------------------------------------------------------------------------- 92-------------------------------------------------------------------------------- 93----------------------------------------------------------------------------- */ 94 95/* ----------------------------------------------------------------------------- 96 PPPOE Timer, at 100 ms. Replaces pppoe_slowtimo, which is deprecated. 97 ----------------------------------------------------------------------------- */ 98static uint8_t pppoe_timer_thread_is_dying = 0; /* > 0 if dying */ 99static uint8_t pppoe_timer_thread_is_dead = 0; /* > 0 if dead */ 100 101static void pppoe_timer() 102{ 103 struct timespec ts = {0}; 104 105 /* timeout of 1000 ms */ 106 ts.tv_nsec = 1000 * 1000 * 1000; 107 ts.tv_sec = 0; 108 109 lck_mtx_lock(ppp_domain_mutex); 110 while (TRUE) { 111 if (pppoe_timer_thread_is_dying > 0) { 112 break; 113 } 114 115 pppoe_rfc_timer(); 116 117 msleep(&pppoe_timer_thread_is_dying, ppp_domain_mutex, PSOCK, "pppoe_timer_sleep", &ts); 118 } 119 120 pppoe_timer_thread_is_dead++; 121 wakeup(&pppoe_timer_thread_is_dead); 122 lck_mtx_unlock(ppp_domain_mutex); 123 124 thread_terminate(current_thread()); 125} 126 127/* ----------------------------------------------------------------------------- 128Called when we need to add the PPPoE protocol to the domain 129Typically, ppp_add is called by ppp_domain when we add the domain, 130but we can add the protocol anytime later, if the domain is present 131----------------------------------------------------------------------------- */ 132int pppoe_add(struct domain *domain) 133{ 134 int err; 135 thread_t pppoe_timer_thread = NULL; 136 137 bzero(&pppoe_usr, sizeof(struct pr_usrreqs)); 138 pppoe_usr.pru_abort = pru_abort_notsupp; 139 pppoe_usr.pru_accept = pppoe_accept; 140 pppoe_usr.pru_attach = pppoe_attach; 141 pppoe_usr.pru_bind = pppoe_bind; 142 pppoe_usr.pru_connect = pppoe_connect; 143 pppoe_usr.pru_connect2 = pru_connect2_notsupp; 144 pppoe_usr.pru_control = pppoe_control; 145 pppoe_usr.pru_detach = pppoe_detach; 146 pppoe_usr.pru_disconnect = pppoe_disconnect; 147 pppoe_usr.pru_listen = pppoe_listen; 148 pppoe_usr.pru_peeraddr = pru_peeraddr_notsupp; 149 pppoe_usr.pru_rcvd = pru_rcvd_notsupp; 150 pppoe_usr.pru_rcvoob = pru_rcvoob_notsupp; 151 pppoe_usr.pru_send = pppoe_send; 152 pppoe_usr.pru_sense = pru_sense_null; 153 pppoe_usr.pru_shutdown = pppoe_shutdown; 154 pppoe_usr.pru_sockaddr = pru_sockaddr_notsupp; 155 pppoe_usr.pru_sosend = sosend; 156 pppoe_usr.pru_soreceive = soreceive; 157 pppoe_usr.pru_sopoll = pru_sopoll_notsupp; 158 159 160 bzero(&pppoe, sizeof(struct protosw)); 161 pppoe.pr_type = SOCK_DGRAM; 162 pppoe.pr_domain = domain; 163 pppoe.pr_protocol = PPPPROTO_PPPOE; 164 pppoe.pr_flags = PR_ATOMIC|PR_CONNREQUIRED|PR_PROTOLOCK; 165 pppoe.pr_ctloutput = pppoe_ctloutput; 166 pppoe.pr_init = pppoe_init; 167 pppoe.pr_usrreqs = &pppoe_usr; 168 169 pppoe_timer_thread_is_dying = 0; 170 if (kernel_thread_start((thread_continue_t)pppoe_timer, NULL, &pppoe_timer_thread) == KERN_SUCCESS) { 171 thread_deallocate(pppoe_timer_thread); 172 } 173 174 err = net_add_proto(&pppoe, domain); 175 if (err) 176 return err; 177 178 return KERN_SUCCESS; 179} 180 181/* ----------------------------------------------------------------------------- 182Called when we need to remove the PPPoE protocol from the domain 183----------------------------------------------------------------------------- */ 184int pppoe_remove(struct domain *domain) 185{ 186 int err; 187 188 lck_mtx_assert(ppp_domain_mutex, LCK_MTX_ASSERT_OWNED); 189 190 /* Cleanup timer thread */ 191 if (pppoe_timer_thread_is_dead == 0) { 192 pppoe_timer_thread_is_dying++; /* Tell thread to die */ 193 wakeup(&pppoe_timer_thread_is_dying); /* Wake thread */ 194 msleep(&pppoe_timer_thread_is_dying, ppp_domain_mutex, PSOCK, "pppoe_timer_sleep", 0); 195 } 196 197 err = net_del_proto(pppoe.pr_type, pppoe.pr_protocol, domain); 198 if (err) 199 return err; 200 201 // shall we test that all the pcbs have been freed ? 202 203 return KERN_SUCCESS; 204} 205 206/* ----------------------------------------------------------------------------- 207-------------------------------------------------------------------------------- 208-------------------------------------------------------------------------------- 209--------------------------- protosw functions ---------------------------------- 210-------------------------------------------------------------------------------- 211-------------------------------------------------------------------------------- 212----------------------------------------------------------------------------- */ 213 214/* ----------------------------------------------------------------------------- 215This function is called by socket layer when the protocol is added 216----------------------------------------------------------------------------- */ 217void pppoe_init() 218{ 219 //IOLog("pppoe_init\n"); 220} 221 222/* ----------------------------------------------------------------------------- 223This function is called by socket layer to handle get/set-socketoption 224----------------------------------------------------------------------------- */ 225int pppoe_ctloutput(struct socket *so, struct sockopt *sopt) 226{ 227 int error, optval, i, mult; 228 u_int16_t val; 229 u_int32_t lval; 230 u_char str[IFNAMSIZ]; 231 232 lck_mtx_assert(ppp_domain_mutex, LCK_MTX_ASSERT_OWNED); 233 234 //IOLog("pppoe_ctloutput, so = %p\n", so); 235 236 error = optval = 0; 237 if (sopt->sopt_level != PPPPROTO_PPPOE) { 238 return EINVAL; 239 } 240 241 switch (sopt->sopt_dir) { 242 case SOPT_SET: 243 switch (sopt->sopt_name) { 244 case PPPOE_OPT_FLAGS: 245 if (sopt->sopt_valsize != 4) 246 error = EMSGSIZE; 247 else if ((error = sooptcopyin(sopt, &lval, 4, 4)) == 0) 248 pppoe_rfc_command(so->so_pcb, PPPOE_CMD_SETFLAGS, &lval); 249 break; 250 case PPPOE_OPT_INTERFACE: 251 if (sopt->sopt_valsize > IFNAMSIZ) { 252 error = EMSGSIZE; 253 break; 254 } 255 bzero(str, sizeof(str)); 256 if ((error = sooptcopyin(sopt, str, sopt->sopt_valsize, 0))) 257 break; 258 val = 0; 259 for (i = IFNAMSIZ - 1; i && !str[i]; i--); 260 for (mult = 1; i && (str[i] >= '0' && str[i] <= '9'); i--) { 261 val += (str[i] - '0') * mult; 262 mult *= 10; 263 } 264 //IOLog("pppoe_ctloutput (set) : PPPOE_OPT_INTERFACE = %s, %d\n", ifname, val); 265 pppoe_rfc_command(so->so_pcb, PPPOE_CMD_SETUNIT, &val); 266 break; 267 case PPPOE_OPT_CONNECT_TIMER: 268 if (sopt->sopt_valsize != 2) 269 error = EMSGSIZE; 270 else if ((error = sooptcopyin(sopt, &val, 2, 2)) == 0) 271 pppoe_rfc_command(so->so_pcb, PPPOE_CMD_SETCONNECTTIMER , &val); 272 break; 273 case PPPOE_OPT_RING_TIMER: 274 if (sopt->sopt_valsize != 2) 275 error = EMSGSIZE; 276 else if ((error = sooptcopyin(sopt, &val, 2, 2)) == 0) 277 pppoe_rfc_command(so->so_pcb, PPPOE_CMD_SETRINGTIMER , &val); 278 break; 279 case PPPOE_OPT_RETRY_TIMER: 280 if (sopt->sopt_valsize != 2) 281 error = EMSGSIZE; 282 else if ((error = sooptcopyin(sopt, &val, 2, 2)) == 0) 283 pppoe_rfc_command(so->so_pcb, PPPOE_CMD_SETRETRYTIMER , &val); 284 break; 285 case PPPOE_OPT_PEER_ENETADDR: 286 if (sopt->sopt_valsize != 6) 287 error = EMSGSIZE; 288 else if ((error = sooptcopyin(sopt, &str, 2, 2)) == 0) 289 pppoe_rfc_command(so->so_pcb, PPPOE_CMD_SETPEERADDR , &str); 290 break; 291 default: 292 error = ENOPROTOOPT; 293 } 294 break; 295 296 case SOPT_GET: 297 switch (sopt->sopt_name) { 298 case PPPOE_OPT_FLAGS: 299 if (sopt->sopt_valsize != 4) 300 error = EMSGSIZE; 301 else { 302 pppoe_rfc_command(so->so_pcb, PPPOE_CMD_GETFLAGS, &lval); 303 error = sooptcopyout(sopt, &lval, 4); 304 } 305 break; 306 case PPPOE_OPT_INTERFACE: 307 if (sopt->sopt_valsize < IFNAMSIZ) 308 error = EMSGSIZE; 309 else { 310 pppoe_rfc_command(so->so_pcb, PPPOE_CMD_GETUNIT, &val); 311 // Fix Me : should get the name from ifnet 312 snprintf((char*)str, sizeof(str), "en%d", val); 313 error = sooptcopyout(sopt, str, strlen((char*)str)); 314 } 315 break; 316 case PPPOE_OPT_CONNECT_TIMER: 317 if (sopt->sopt_valsize != 2) 318 error = EMSGSIZE; 319 else { 320 pppoe_rfc_command(so->so_pcb, PPPOE_CMD_GETCONNECTTIMER, &val); 321 error = sooptcopyout(sopt, &val, 2); 322 } 323 break; 324 case PPPOE_OPT_RING_TIMER: 325 if (sopt->sopt_valsize != 2) 326 error = EMSGSIZE; 327 else { 328 pppoe_rfc_command(so->so_pcb, PPPOE_CMD_GETRINGTIMER, &val); 329 error = sooptcopyout(sopt, &val, 2); 330 } 331 break; 332 case PPPOE_OPT_RETRY_TIMER: 333 if (sopt->sopt_valsize != 2) 334 error = EMSGSIZE; 335 else { 336 pppoe_rfc_command(so->so_pcb, PPPOE_CMD_GETRETRYTIMER, &val); 337 error = sooptcopyout(sopt, &val, 2); 338 } 339 break; 340 case PPPOE_OPT_PEER_ENETADDR: 341 if (sopt->sopt_valsize != 6) 342 error = EMSGSIZE; 343 else { 344 pppoe_rfc_command(so->so_pcb, PPPOE_CMD_GETPEERADDR, &str); 345 error = sooptcopyout(sopt, &str, 6); 346 } 347 break; 348 default: 349 error = ENOPROTOOPT; 350 } 351 break; 352 353 } 354 return error; 355} 356 357/* ----------------------------------------------------------------------------- 358-------------------------------------------------------------------------------- 359-------------------------------------------------------------------------------- 360------------------------- pr_usrreqs functions --------------------------------- 361-------------------------------------------------------------------------------- 362-------------------------------------------------------------------------------- 363----------------------------------------------------------------------------- */ 364 365/* ----------------------------------------------------------------------------- 366Called by socket layer when a new socket is created 367Should create all the structures and prepare for pppoe dialog 368----------------------------------------------------------------------------- */ 369int pppoe_attach (struct socket *so, int proto, struct proc *p) 370{ 371 int error; 372 u_short unit; 373 374 //IOLog("pppoe_attach, so = %p, dom_ref = %d\n", so, so->so_proto->pr_domain->dom_refs); 375 if (so->so_pcb) 376 return EINVAL; 377 378 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 379 error = soreserve(so, 8192, 8192); 380 if (error) 381 return error; 382 } 383 384 // fix me : change association between socket and dltag to support multiple interface 385 //pcb->dl_tag = pppoe_domain_find_dl_tag(); 386 unit = 0; 387 388 // call pppoe init with the rfc specific structure 389 lck_mtx_lock(ppp_domain_mutex); 390 if (pppoe_rfc_new_client(so, (void**)&(so->so_pcb), pppoe_input, pppoe_event)) { 391 lck_mtx_unlock(ppp_domain_mutex); 392 return ENOMEM; 393 } 394 lck_mtx_unlock(ppp_domain_mutex); 395 396 return 0; 397} 398 399/* ----------------------------------------------------------------------------- 400Called by socket layer when the socket is closed 401Should free all the pppoe structures 402----------------------------------------------------------------------------- */ 403int pppoe_detach(struct socket *so) 404{ 405 406 //IOLog("pppoe_detach, so = %p, dom_ref = %d\n", so, so->so_proto->pr_domain->dom_refs); 407 408 lck_mtx_assert(ppp_domain_mutex, LCK_MTX_ASSERT_OWNED); 409 410 if (so->so_tpcb) { 411 pppoe_wan_detach((struct ppp_link *)so->so_tpcb); 412 so->so_tpcb = 0; 413 } 414 if (so->so_pcb) { 415 pppoe_rfc_free_client(so->so_pcb); 416 so->so_pcb = 0; 417 } 418 so->so_flags |= SOF_PCBCLEARING; 419 return 0; 420} 421 422/* ----------------------------------------------------------------------------- 423this function is not yet complete 424----------------------------------------------------------------------------- */ 425int pppoe_shutdown(struct socket *so) 426{ 427 int error = 0; 428 429 lck_mtx_assert(ppp_domain_mutex, LCK_MTX_ASSERT_OWNED); 430 431 //IOLog("pppoe_shutdown, so = %p\n", so); 432 433 socantsendmore(so); 434 pppoe_disconnect(so); 435 return error; 436} 437 438/* ----------------------------------------------------------------------------- 439Called by socket layer to bind to the protocol 440----------------------------------------------------------------------------- */ 441int pppoe_bind(struct socket *so, struct sockaddr *nam, struct proc *p) 442{ 443 int error = 0; 444 struct sockaddr_pppoe *adr = (struct sockaddr_pppoe *)nam; 445 446 lck_mtx_assert(ppp_domain_mutex, LCK_MTX_ASSERT_OWNED); 447 448 //IOLog("pppoe_bind, so = %p\n", so); 449 450 // bind pppoe protocol 451 if (pppoe_rfc_bind(so->so_pcb, (u_char*)&adr->pppoe_ac_name[0], (u_char*)&adr->pppoe_service[0])) 452 error = EINVAL; /* XXX ??? */ 453 454 return error; 455} 456 457/* ----------------------------------------------------------------------------- 458Called by socket layer to connect the protocol (PR_CONNREQUIRED) 459----------------------------------------------------------------------------- */ 460int pppoe_connect(struct socket *so, struct sockaddr *nam, struct proc *p) 461{ 462 int error = 0; 463 struct sockaddr_pppoe *adr = (struct sockaddr_pppoe *)nam; 464 465 lck_mtx_assert(ppp_domain_mutex, LCK_MTX_ASSERT_OWNED); 466 467 //IOLog("pppoe_connect, so = %p\n", so); 468 469 // connect pppoe protocol 470 if (pppoe_rfc_connect(so->so_pcb, (u_char*)adr->pppoe_ac_name, (u_char*)adr->pppoe_service)) 471 error = EINVAL; /* XXX ??? */ 472 else { 473 soisconnecting(so); 474 } 475 476 return error; 477} 478 479/* ----------------------------------------------------------------------------- 480Called by socket layer to disconnect the protocol (PR_CONNREQUIRED) 481----------------------------------------------------------------------------- */ 482int pppoe_disconnect(struct socket *so) 483{ 484 485 //IOLog("pppoe_disconnect, so = %p\n", so); 486 487 lck_mtx_assert(ppp_domain_mutex, LCK_MTX_ASSERT_OWNED); 488 489 // disconnect pppoe protocol 490 if (pppoe_rfc_disconnect(so->so_pcb)) { 491 // ??? 492 } 493 494 soisdisconnected(so); // let's say we are disconnected anyway... 495 return 0; 496} 497 498/* ----------------------------------------------------------------------------- 499Prepare to accept connections 500----------------------------------------------------------------------------- */ 501int pppoe_listen(struct socket *so, struct proc *p) 502{ 503 int error = 0; 504 505 lck_mtx_assert(ppp_domain_mutex, LCK_MTX_ASSERT_OWNED); 506 507 //IOLog("pppoe_listen, so = %p\n", so); 508 509 if (pppoe_rfc_listen(so->so_pcb)) 510 error = EINVAL; // XXX ??? 511 512 return error; 513} 514 515/* ----------------------------------------------------------------------------- 516Accept connection 517----------------------------------------------------------------------------- */ 518int pppoe_accept(struct socket *so, struct sockaddr **nam) 519{ 520 int error = 0; 521 struct sockaddr_pppoe *addr; 522 523 //IOLog("pppoe_accept, so = %p\n", so); 524 525 lck_mtx_assert(ppp_domain_mutex, LCK_MTX_ASSERT_OWNED); 526 527 *nam = 0; 528 if (pppoe_rfc_accept(so->so_pcb)) 529 error = EINVAL; // XXX ??? 530 else { 531 // pppoe_rfc_getboundaddr(pcb->rfc, addr.ac_name, addr.service); 532 addr = (struct sockaddr_pppoe *)_MALLOC(sizeof (struct sockaddr_pppoe), M_SONAME, M_WAITOK); 533 if (addr) { 534 addr->ppp.ppp_len = sizeof(struct sockaddr_pppoe); 535 addr->ppp.ppp_family = AF_PPP; 536 addr->ppp.ppp_proto = PPPPROTO_PPPOE; 537 addr->ppp.ppp_cookie = 0; 538 addr->pppoe_ac_name[0] = 0; 539 addr->pppoe_service[0] = 0; 540 *nam = (struct sockaddr *)addr; 541 } 542 } 543 544 return error; 545} 546 547/* ----------------------------------------------------------------------------- 548Called by socket layer to abort call 549----------------------------------------------------------------------------- */ 550int pppoe_abort(struct socket *so) 551{ 552 int error = 0; 553 554 lck_mtx_assert(ppp_domain_mutex, LCK_MTX_ASSERT_OWNED); 555 556 //IOLog("pppoe_abort, so = %p\n", so); 557 558 if (pppoe_rfc_abort(so->so_pcb, 1)) 559 error = EINVAL; // XXX ??? 560 561 soisdisconnected(so); // let's say we are disconnected anyway... 562 return error; 563} 564 565/* ----------------------------------------------------------------------------- 566Called by socket layer to handle ioctl 567----------------------------------------------------------------------------- */ 568int pppoe_control(struct socket *so, u_long cmd, caddr_t data, 569 struct ifnet *ifp, struct proc *p) 570{ 571 int error = 0; 572 573 lck_mtx_assert(ppp_domain_mutex, LCK_MTX_ASSERT_OWNED); 574 575 //IOLog("pppoe_control : so = %p, cmd = %d\n", so, cmd); 576 577 switch (cmd) { 578 case PPPIOCGCHAN: 579 //IOLog("pppoe_control : PPPIOCGCHAN\n"); 580 if (!so->so_tpcb) 581 return EINVAL;// not attached 582 *(u_int32_t *)data = ((struct ppp_link *)so->so_tpcb)->lk_index; 583 break; 584 case PPPIOCATTACH: 585 //IOLog("pppoe_control : PPPIOCATTACH\n"); 586 if (so->so_tpcb) 587 return EINVAL;// already attached 588 sbflush(&so->so_rcv); // flush all data received 589 error = pppoe_wan_attach(so->so_pcb, (struct ppp_link **)&so->so_tpcb); 590 break; 591 case PPPIOCDETACH: 592 //IOLog("pppoe_control : PPPIOCDETACH\n"); 593 if (!so->so_tpcb) 594 return EINVAL;// already detached 595 pppoe_wan_detach((struct ppp_link *)so->so_tpcb); 596 so->so_tpcb = 0; 597 break; 598 default: 599 ; 600 } 601 602 return error; 603} 604 605/* ----------------------------------------------------------------------------- 606Called by socket layer to send data out 607----------------------------------------------------------------------------- */ 608int pppoe_send(struct socket *so, int flags, struct mbuf *m, 609 struct sockaddr *nam, struct mbuf *control, struct proc *p) 610{ 611 612 int error = 0; 613 614 lck_mtx_assert(ppp_domain_mutex, LCK_MTX_ASSERT_OWNED); 615 616 //IOLog("pppoe_send, so = %p\n", so); 617 618 if ((error = pppoe_rfc_output(so->so_pcb, (mbuf_t)m))) { 619 mbuf_freem((mbuf_t)m); 620 } 621 622 return error; 623} 624 625/* ----------------------------------------------------------------------------- 626-------------------------------------------------------------------------------- 627-------------------------------------------------------------------------------- 628------------------------- callbacks from pppoe rfc or from dlil ---------------- 629-------------------------------------------------------------------------------- 630-------------------------------------------------------------------------------- 631----------------------------------------------------------------------------- */ 632 633/* ----------------------------------------------------------------------------- 634called from pppoe_rfc when change state occurs 635----------------------------------------------------------------------------- */ 636void pppoe_event(void *data, u_int32_t event, u_int32_t msg) 637{ 638 struct socket *so = (struct socket *)data, *so2; 639 struct sockaddr_pppoe addr; 640 641 lck_mtx_assert(ppp_domain_mutex, LCK_MTX_ASSERT_OWNED); 642 643 switch (event) { 644 case PPPOE_EVT_RINGING: 645 /* 646 at this point, we need to introduce our semantic about how ring/accept will work. 647 when there is an incoming call, we create a new socket with sonewconn, so socket layer is happy. 648 the sonewconn will wake up the original listening app with the ogirinal socket. 649 the app will decide wether it wants to accept or refuse the call. 650 if the app decides to accept it, il will call accept with the original listening socket, 651 which will be turned by the socket layer into a call to the accept function to our protocol 652 with the second socket (created with sonewconn). [the socket layer knows that 653 those two sockets are related, because sonewconn had linked them together] 654 when we enter into our accept function, we will then physically answer the call. 655 (that's a difference with tcp, where the call has already be answer at ring time) 656 the original listening socket will still be listening (probably for nothing if the protocol 657 can only accept one call) 658 then, when later the app close the socket (the one returned by accept) the protocol can listen again 659 it's up to this protocol to know what's really happening here, and to do the correct work, 660 wether we have only one active listening socket, or whatever makes sense. 661 in case of PPPoE, let's say we can continue listening.... 662 */ 663 664 addr.ppp.ppp_len = sizeof(struct sockaddr_pppoe); 665 addr.ppp.ppp_family = AF_PPP; 666 addr.ppp.ppp_proto = PPPPROTO_PPPOE; 667 addr.ppp.ppp_cookie = 0; 668 addr.pppoe_ac_name[0] = 0; 669 addr.pppoe_service[0] = 0; 670 671 so2 = sonewconn(so, SS_ISCONFIRMING, (struct sockaddr*)(&addr)); // create the accepting connection 672 //IOLog("pppoe_event, so = %p, so2 = %p, evt = PPPOE_EVT_RINGING\n", so, so2); 673 674 if (so2) 675 pppoe_rfc_clone(so->so_pcb, so2->so_pcb); // transfer all the RFC info to the new connection, including ringing state 676 677 pppoe_rfc_abort(so->so_pcb, 0); // abort the ring on the listening connection 678 pppoe_rfc_listen(so->so_pcb); // relisten again, because pppoe can handle multiple connections 679 break; 680 681 case PPPOE_EVT_CONNECTED: 682 //IOLog("pppoe_event, so = %p, evt = PPPOE_EVT_CONNECTED\n", so); 683 soisconnected(so); 684 break; 685 686 case PPPOE_EVT_DISCONNECTED: 687 //IOLog("pppoe_event, so = %p, evt = PPPOE_EVT_DISCONNECTED\n", so); 688 so->so_error = msg; 689 690 //if (so->so_tpcb) { 691 // pppoe_wan_detach((struct ppp_link *)so->so_tpcb); 692 // so->so_tpcb = 0; 693 //} 694 soisdisconnected(so); 695 break; 696 } 697} 698 699/* ----------------------------------------------------------------------------- 700called from pppoe_rfc when data are present 701----------------------------------------------------------------------------- */ 702int pppoe_input(void *data, mbuf_t m) 703{ 704 struct socket *so = (struct socket *)data; 705 706 lck_mtx_assert(ppp_domain_mutex, LCK_MTX_ASSERT_OWNED); 707 708 if (so->so_tpcb) { 709 // we are hooked to ppp 710 return pppoe_wan_input((struct ppp_link *)so->so_tpcb, m); 711 } 712 713 //IOLog("pppoe_input, so = %p, len = %d\n", so, m_pkthdr.len); 714 715 if (sbspace(&so->so_rcv) < mbuf_pkthdr_len(m)) { 716 mbuf_freem(m); 717 IOLog("pppoe_input no space, so = %p, len = %d\n", so, mbuf_pkthdr_len(m)); 718 return 0; 719 } 720 721 sbappendrecord(&so->so_rcv, (struct mbuf*)m); 722 sorwakeup(so); 723 return 0; 724} 725 726 727