📄 control.c
字号:
t->hostname); set_error (c, VENDOR_ERROR, "No secret on our side"); toss (buf); return -EINVAL; }; add_challenge_avp (buf, t->chal_them.challenge, MD_SIG_SIZE); } add_control_hdr (t, c, buf); if (packet_dump) do_packet_dump (buf); c->cnu = 0; if (debug_state) log (LOG_DEBUG, "%s: sending SCCRP\n", __FUNCTION__); control_xmit (buf); break; case SCCRP: /* * We have a reply. If everything is okay, send * a connected message */ if (t->fc < 0) { if (DEBUG) log (LOG_DEBUG, "%s: Peer did not specify framing capability. Closing.\n", __FUNCTION__); set_error (c, VENDOR_ERROR, "Specify framing capability"); c->needclose = -1; return -EINVAL; } /* FIXME: Do we need to be sure they specified a version number? * Theoretically, yes, but we don't have anything in the code * to actually *do* anything with it, so...why check at this point? * We shouldn't be requiring a bearer capabilities avp to be present in * SCCRQ and SCCRP as they aren't required if (t->bc < 0 ) { if (DEBUG) log(LOG_DEBUG, "%s: Peer did not specify bearer capability. Closing.\n",__FUNCTION__); set_error(c, VENDOR_ERROR, "Specify bearer capability"); c->needclose = -1; return -EINVAL; } */ if (!strlen (t->hostname)) { if (DEBUG) log (LOG_DEBUG, "%s: Peer did not specify hostname. Closing.\n", __FUNCTION__); set_error (c, VENDOR_ERROR, "Specify your hostname"); c->needclose = -1; return -EINVAL; } if (t->tid <= 0) { if (DEBUG) log (LOG_DEBUG, "%s: Peer did not specify assigned tunnel ID. Closing.\n", __FUNCTION__); set_error (c, VENDOR_ERROR, "Specify your assigned tunnel ID"); c->needclose = -1; return -EINVAL; } if (t->chal_them.state) { t->chal_them.ss = SCCRP; if (handle_challenge (t, &t->chal_them)) { set_error (c, VENDOR_ERROR, "No secret key on our side"); log (LOG_WARN, "%s: No secret key for authenticating '%s'\n", __FUNCTION__, t->hostname); c->needclose = -1; return -EINVAL; } if (memcmp (t->chal_them.reply, t->chal_them.response, MD_SIG_SIZE)) { set_error (c, VENDOR_ERROR, "Invalid challenge authentication"); log (LOG_DEBUG, "%s: Invalid authentication for host '%s'\n", __FUNCTION__, t->hostname); c->needclose = -1; return -EINVAL; } } if (t->chal_us.state) { t->chal_us.ss = SCCCN; if (handle_challenge (t, &t->chal_us)) { log (LOG_WARN, "%s: No secret for authenticating to '%s'\n", __FUNCTION__, t->hostname); set_error (c, VENDOR_ERROR, "No secret key on our end"); c->needclose = -1; return -EINVAL; }; }#ifdef USE_KERNEL if (kernel_support) { struct l2tp_tunnel_opts to; to.ourtid = t->ourtid; ioctl (server_socket, L2TPIOCGETTUNOPTS, &to); to.tid = t->tid; ioctl (server_socket, L2TPIOCSETTUNOPTS, &to); }#endif t->state = SCCCN; buf = new_outgoing (t); add_message_type_avp (buf, SCCCN); if (t->hbit) { mk_challenge (t->chal_them.vector, VECTOR_SIZE); add_randvect_avp (buf, t->chal_them.vector, VECTOR_SIZE); } if (t->chal_us.state) add_chalresp_avp (buf, t->chal_us.response, MD_SIG_SIZE); add_control_hdr (t, c, buf); if (packet_dump) do_packet_dump (buf); c->cnu = 0; if (debug_state) log (LOG_DEBUG, "%s: sending SCCCN\n", __FUNCTION__); control_xmit (buf); /* Schedule a HELLO */ tv.tv_sec = HELLO_DELAY; tv.tv_usec = 0;#ifdef DEBUG_HELLO log (LOG_DEBUG, "%s: scheduling initial HELLO on %d\n", __FUNCTION__, t->ourtid);#endif t->hello = schedule (tv, hello, (void *) t); log (LOG_LOG, "%s: Connection established to %s, %d. Local: %d, Remote: %d.\n", __FUNCTION__, IPADDY (t->peer.sin_addr), ntohs (t->peer.sin_port), t->ourtid, t->tid); if (t->lac) { /* This is part of a LAC, so we want to go ahead and start an ICRQ now */ magic_lac_dial (t->lac); } break; case SCCCN: if (t->chal_them.state) { if (memcmp (t->chal_them.reply, t->chal_them.response, MD_SIG_SIZE)) { set_error (c, VENDOR_ERROR, "Invalid challenge authentication"); log (LOG_DEBUG, "%s: Invalid authentication for host '%s'\n", __FUNCTION__, t->hostname); c->needclose = -1; return -EINVAL; } }#ifdef USE_KERNEL if (kernel_support) { struct l2tp_tunnel_opts to; to.ourtid = t->ourtid; ioctl (server_socket, L2TPIOCGETTUNOPTS, &to); to.tid = t->tid; ioctl (server_socket, L2TPIOCSETTUNOPTS, &to); }#endif t->state = SCCCN; log (LOG_LOG, "%s: Connection established to %s, %d. Local: %d, Remote: %d. LNS session is '%s'\n", __FUNCTION__, IPADDY (t->peer.sin_addr), ntohs (t->peer.sin_port), t->ourtid, t->tid, t->lns->entname); /* Schedule a HELLO */ tv.tv_sec = HELLO_DELAY; tv.tv_usec = 0;#ifdef DEBUG_HELLO log (LOG_DEBUG, "%s: scheduling initial HELLO on %d\n", __FUNCTION__, t->ourtid);#endif t->hello = schedule (tv, hello, (void *) t); break; case StopCCN: if (t->qtid < 0) { if (DEBUG) log (LOG_DEBUG, "%s: Peer tried to disconnect without specifying tunnel ID\n", __FUNCTION__); return -EINVAL; } if ((t->qtid != t->tid) && (t->tid > 0)) { if (DEBUG) log (LOG_DEBUG, "%s: Peer tried to disconnect with invalid TID (%d != %d)\n", __FUNCTION__, t->qtid, t->tid); return -EINVAL; } /* In case they're disconnecting immediately after SCCN */ if (!t->tid) t->tid = t->qtid; if (t->self->result < 0) { if (DEBUG) log (LOG_DEBUG, "%s: Peer tried to disconnect without specifying result code.\n", __FUNCTION__); return -EINVAL; } log (LOG_LOG, "%s: Connection closed to %s, port %d (%s), Local: %d, Remote: %d\n", __FUNCTION__, IPADDY (t->peer.sin_addr), ntohs (t->peer.sin_port), t->self->errormsg, t->ourtid, t->tid); c->needclose = 0; c->closing = -1; break; case ICRQ: p = t->call_head; if (!p->lns) { set_error (p, ERROR_INVALID, "This tunnel cannot accept calls\n"); call_close (p); return -EINVAL; } p->lbit = p->lns->lbit ? LBIT : 0;/* p->ourrws = p->lns->call_rws; if (p->ourrws > -1) p->ourfbit = FBIT; else p->ourfbit = 0; */ if (p->cid < 0) { if (DEBUG) log (LOG_DEBUG, "%s: Peer tried to initiate call without call ID\n", __FUNCTION__); /* Here it doesn't make sense to use the needclose flag because the call p did not receive any packets */ call_close (p); return -EINVAL; } z = p->next; while (z) { if (z->cid == p->cid) { /* This can happen if we get a duplicate ICRQ or if they don't get our ack packet */ log (LOG_DEBUG, "%s: Peer requested call %d twice, ignoring second one.\n", __FUNCTION__, p->cid); p->needclose = 0; p->closing = -1; return 0; } z = z->next; } p = t->call_head; /* FIXME: by commenting this out, we're not checking whether the serial * number avp is included in the ICRQ at all which its required to be. * Since the serial number is only used for human debugging aid, this * isn't a big deal, but it would be nice to have *some* sort of check * for it and perhaps just log it and go on. *//* JLM if (p->serno<1) { if (DEBUG) log(LOG_DEBUG, "%s: Peer did not specify serial number when initiating call\n", __FUNCTION__); call_close(p); return -EINVAL; } */#ifdef IP_ALLOCATION p->addr = get_addr (t->lns->range); if (!p->addr) { set_error (p, ERROR_NORES, "No available IP address"); call_close (p); log (LOG_DEBUG, "%s: Out of IP addresses on tunnel %d!\n", __FUNCTION__, t->tid); return -EINVAL; }#endif reserve_addr (p->addr); p->state = ICRP; buf = new_outgoing (t); add_message_type_avp (buf, ICRP); if (t->hbit) { mk_challenge (t->chal_them.vector, VECTOR_SIZE); add_randvect_avp (buf, t->chal_them.vector, VECTOR_SIZE); }#ifdef TEST_HIDDEN add_callid_avp (buf, p->ourcid, t);#else add_callid_avp (buf, p->ourcid);#endif/* if (p->ourrws >=0) add_avp_rws(buf, p->ourrws); */ /* * FIXME: I should really calculate * Packet Processing Delay */ /* add_ppd_avp(buf,ppd); */ add_control_hdr (t, p, buf); if (packet_dump) do_packet_dump (buf); p->cnu = 0; if (debug_state) log (LOG_DEBUG, "%s: Sending ICRP\n", __FUNCTION__); control_xmit (buf); break; case ICRP: if (c->cid < 0) { if (DEBUG) log (LOG_DEBUG, "%s: Peer tried to negotiate ICRP without specifying call ID\n", __FUNCTION__); c->needclose = -1; return -EINVAL; } c->state = ICCN; if (t->fc & SYNC_FRAMING) c->frame = SYNC_FRAMING; else c->frame = ASYNC_FRAMING; buf = new_outgoing (t); add_message_type_avp (buf, ICCN); if (t->hbit) { mk_challenge (t->chal_them.vector, VECTOR_SIZE); add_randvect_avp (buf, t->chal_them.vector, VECTOR_SIZE); } add_txspeed_avp (buf, DEFAULT_TX_BPS); add_frame_avp (buf, c->frame);/* if (c->ourrws >= 0) add_avp_rws(buf, c->ourrws); */ /* FIXME: Packet Processing Delay */ /* We don't need any kind of proxy PPP stuff */ /* Can we proxy authenticate ourselves??? */ add_rxspeed_avp (buf, DEFAULT_RX_BPS);/* add_seqreqd_avp (buf); *//* We don't have sequencing code, so * don't ask for sequencing */ add_control_hdr (t, c, buf); if (packet_dump) do_packet_dump (buf); c->cnu = 0;#ifdef USE_KERNEL if (kernel_support) { co.ourtid = c->container->ourtid; co.ourcid = c->ourcid; ioctl (server_socket, L2TPIOCGETCALLOPTS, &co); co.cid = c->cid; co.flags = co.flags | L2TP_FLAG_CALL_UP; co.rws = c->rws; co.ourrws = c->ourrws; co.flags |= c->lbit; ioctl (server_socket, L2TPIOCSETCALLOPTS, &co); }#endif if (debug_state) log (LOG_DEBUG, "%s: Sending ICCN\n", __FUNCTION__); log (LOG_LOG, "%s: Call established with %s, Local: %d, Remote: %d, Serial: %d\n", __FUNCTION__, IPADDY (t->peer.sin_addr), c->ourcid, c->cid, c->serno); control_xmit (buf); po = NULL; po = add_opt (po, "passive"); po = add_opt (po, "-detach"); if (c->lac) { if (c->lac->defaultroute) po = add_opt (po, "defaultroute"); strncpy (ip1, IPADDY (c->lac->localaddr), sizeof (ip1)); strncpy (ip2, IPADDY (c->lac->remoteaddr), sizeof (ip2));#ifdef IP_ALLOCATION po = add_opt (po, "%s:%s", c->lac->localaddr ? ip1 : "", c->lac->remoteaddr ? ip2 : "");#endif if (c->lac->authself) { if (c->lac->pap_refuse) po = add_opt (po, "refuse-pap"); if (c->lac->chap_refuse) po = add_opt (po, "refuse-chap"); } else { po = add_opt (po, "refuse-pap"); po = add_opt (po, "refuse-chap"); } if (c->lac->authpeer) { po = add_opt (po, "auth"); if (c->lac->pap_require) po = add_opt (po, "require-pap"); if (c->lac->chap_require) po = add_opt (po, "require-chap"); } if (c->lac->authname[0]) { po = add_opt (po, "name"); po = add_opt (po, c->lac->authname); } if (c->lac->debug) po = add_opt (po, "debug"); if (c->lac->pppoptfile[0]) { po = add_opt (po, "file"); po = add_opt (po, c->lac->pppoptfile); } }; start_pppd (c, po); opt_destroy (po); if (c->lac) c->lac->rtries = 0; break; case ICCN: if (c == t->self) { log (LOG_DEBUG, "%s: Peer attempted ICCN on the actual tunnel, not the call", __FUNCTION__); return -EINVAL; } if (c->txspeed < 1) { log (LOG_DEBUG, "%s: Peer did not specify transmit speed\n", __FUNCTION__); c->needclose = -1; return -EINVAL; }; if (c->frame < 1) { log (LOG_DEBUG, "%s: Peer did not specify framing type\n", __FUNCTION__); c->needclose = -1; return -EINVAL; } c->state = ICCN;#ifdef USE_KERNEL if (kernel_support) { co.ourtid = c->container->ourtid; co.ourcid = c->ourcid; if (ioctl (server_socket, L2TPIOCGETCALLOPTS, &co)) perror ("ioctl(get)"); co.cid = c->cid; co.flags = co.flags | L2TP_FLAG_CALL_UP; co.rws = c->rws; co.ourrws = c->ourrws; co.flags |= c->lbit; if (ioctl (server_socket, L2TPIOCSETCALLOPTS, &co)) perror ("ioctl(set)"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -