📄 network.c
字号:
/* * Layer Two Tunnelling Protocol Daemon * Copyright (C) 1998 Adtran, Inc. * Copyright (C) 2002 Jeff McAdams * * Mark Spencer * * This software is distributed under the terms * of the GPL, which you should have received * along with this source. * * Network routines for UDP handling */#include <stdio.h>#include <errno.h>#include <string.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <sys/ioctl.h>#include "l2tp.h"char hostname[256];unsigned int listen_addy = INADDR_ANY; /* Address to listen on */struct sockaddr_in server, from; /* Server and transmitter structs */int server_socket; /* Server socket */#ifdef USE_KERNELint kernel_support; /* Kernel Support there or not? */#endif/* * Debugging info */int debug_tunnel = 0;int debug_network = 0; /* Debug networking? */int packet_dump = 0; /* Dump packets? */int debug_avp = 1; /* Debug AVP negotiations? */int debug_state = 0; /* Debug state machine? */int init_network (void){ long arg; int length = sizeof (server); gethostname (hostname, sizeof (hostname)); server.sin_family = AF_INET; server.sin_addr.s_addr = htonl (listen_addy); server.sin_port = htons (gconfig.port); if ((server_socket = socket (PF_INET, SOCK_DGRAM, 0)) < 0) { log (LOG_CRIT, "%s: Unable to allocate socket. Terminating.\n", __FUNCTION__); return -EINVAL; }; /* L2TP/IPSec: Set up SA for listening port here? NTB 20011015 */ if (bind (server_socket, (struct sockaddr *) &server, sizeof (server))) { close (server_socket); log (LOG_CRIT, "%s: Unable to bind socket. Terminating.\n", __FUNCTION__); return -EINVAL; }; if (getsockname (server_socket, (struct sockaddr *) &server, &length)) { log (LOG_CRIT, "%s: Unable to read socket name.Terminating.\n", __FUNCTION__); return -EINVAL; }#ifdef USE_KERNEL if (gconfig.forceuserspace) { log (LOG_LOG, "Not looking for kernel support.\n"); kernel_support = 0; } else { if (ioctl (server_socket, SIOCSETL2TP, NULL) < 0) { log (LOG_LOG, "L2TP kernel support not detected.\n"); kernel_support = 0; } else { log (LOG_LOG, "Using l2tp kernel support.\n"); kernel_support = -1; } }#else log (LOG_LOG, "This binary does not support kernel L2TP.\n");#endif arg = fcntl (server_socket, F_GETFL); arg |= O_NONBLOCK; fcntl (server_socket, F_SETFL, arg); gconfig.port = ntohs (server.sin_port); return 0;}inline void extract (void *buf, int *tunnel, int *call){ /* * Extract the tunnel and call #'s, and fix the order of the * version */ struct payload_hdr *p = (struct payload_hdr *) buf; if (PLBIT (p->ver)) { *tunnel = p->tid; *call = p->cid; } else { *tunnel = p->length; *call = p->tid; }}inline void fix_hdr (void *buf){ /* * Fix the byte order of the header */ struct payload_hdr *p = (struct payload_hdr *) buf; _u16 ver = ntohs (p->ver); if (CTBIT (p->ver)) { /* * Control headers are always * exactly 12 bytes big. */ swaps (buf, 12); } else { int len = 6; if (PSBIT (ver)) len += 4; if (PLBIT (ver)) len += 2; if (PFBIT (ver)) len += 4; swaps (buf, len); }}void dethrottle (void *call){/* struct call *c = (struct call *)call; *//* if (c->throttle) {#ifdef DEBUG_FLOW log(LOG_DEBUG, "%s: dethrottling call %d, and setting R-bit\n",__FUNCTION__,c->ourcid); #endif c->rbit = RBIT; c->throttle = 0; } else { log(LOG_DEBUG, "%s: call %d already dethrottled?\n",__FUNCTION__,c->ourcid); } */}void control_xmit (void *b){ struct buffer *buf = (struct buffer *) b; struct tunnel *t; struct timeval tv; int ns; if (!buf) { log (LOG_WARN, "%s: called on NULL buffer!\n", __FUNCTION__); return; } buf->retries++; t = buf->tunnel; ns = ntohs (((struct control_hdr *) (buf->start))->Ns); if (t) { if (ns < t->cLr) {#ifdef DEBUG_CONTROL_XMIT log (LOG_DEBUG, "%s: Tossing packet %d\n", __FUNCTION__, ns);#endif /* Okay, it's been received. Let's toss it now */ toss (buf); return; } } if (buf->retries > DEFAULT_MAX_RETRIES) { /* * Too many retries. Either kill the tunnel, or * if there is no tunnel, just stop retransmitting. */ if (t) { if (t->self->needclose) { log (LOG_DEBUG, "%s: Unable to deliver closing message for tunnel %d. Destroying anyway.\n", __FUNCTION__, t->ourtid); t->self->needclose = 0; t->self->closing = -1; } else { log (LOG_DEBUG, "%s: Maximum retries exceeded for tunnel %d. Closing.\n", __FUNCTION__, t->ourtid); strcpy (t->self->errormsg, "Timeout"); t->self->needclose = -1; } } } else { /* * FIXME: How about adaptive timeouts? */ tv.tv_sec = 1; tv.tv_usec = 0; schedule (tv, control_xmit, buf);#ifdef DEBUG_CONTROL_XMIT log (LOG_DEBUG, "%s: Scheduling and transmitting packet %d\n", __FUNCTION__, ns);#endif udp_xmit (buf); }}void udp_xmit (struct buffer *buf){ /* * Just send it all out. */#if 0 struct sockaddr_in to; to.sin_family = AF_INET; to.sin_port = buf->port; /* if (buf->retry>-1) buf->retry++; */ bcopy (&buf->addr, &to.sin_addr, sizeof (buf->addr));#endif sendto (server_socket, buf->start, buf->len, 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -