/***********************************************************************
*
* pppoe-server.c
*
* Implementation of a user-space PPPoE server
*
* Copyright (C) 2000-2012 Roaring Penguin Software Inc.
*
* This program may be distributed according to the terms of the GNU
* General Public License, version 2 or (at your option) any later version.
*
* $Id$
*
* LIC: GPL
*
***********************************************************************/
#include "config.h"
#include <sys/socket.h>
#if defined(HAVE_LINUX_IF_H)
#include <linux/if.h>
#elif defined(HAVE_NET_IF_H)
#include <net/if.h>
#endif
#if defined(HAVE_NETPACKET_PACKET_H) || defined(HAVE_LINUX_IF_PACKET_H)
#define _POSIX_SOURCE 1 /* For sigaction defines */
#endif
#include "pppoe-server.h"
#include "md5.h"
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#endif
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/file.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <time.h>
#include <signal.h>
#ifdef HAVE_LICENSE
#include "license.h"
#include "licensed-only/servfuncs.h"
static struct License const *ServerLicense;
static struct License const *ClusterLicense;
#else
#define control_session_started(x) (void) 0
#define control_session_terminated(x) (void) 0
#define control_exit() (void) 0
#define realpeerip peerip
#endif
#ifdef HAVE_L2TP
extern PppoeSessionFunctionTable L2TPSessionFunctionTable;
extern void pppoe_to_l2tp_add_interface(EventSelector *es,
Interface *interface);
#endif
static void InterfaceHandler(EventSelector *es,
int fd, unsigned int flags, void *data);
static void startPPPD(ClientSession *sess);
static void sendErrorPADS(int sock, unsigned char *source, unsigned char *dest,
int errorTag, char *errorMsg);
#define CHECK_ROOM(cursor, start, len) \
do {\
if (((cursor)-(start))+(len) > MAX_PPPOE_PAYLOAD) { \
syslog(LOG_ERR, "Would create too-long packet"); \
return; \
} \
} while(0)
static void PppoeStopSession(ClientSession *ses, char const *reason);
static int PppoeSessionIsActive(ClientSession *ses);
/* Service-Names we advertise */
#define MAX_SERVICE_NAMES 64
static int NumServiceNames = 0;
static char const *ServiceNames[MAX_SERVICE_NAMES];
PppoeSessionFunctionTable DefaultSessionFunctionTable = {
PppoeStopSession,
PppoeSessionIsActive,
NULL
};
/* An array of client sessions */
ClientSession *Sessions = NULL;
ClientSession *FreeSessions = NULL;
ClientSession *LastFreeSession = NULL;
ClientSession *BusySessions = NULL;
/* Interfaces we're listening on */
Interface interfaces[MAX_INTERFACES];
int NumInterfaces = 0;
/* The number of session slots */
size_t NumSessionSlots;
/* Maximum number of sessions per MAC address */
int MaxSessionsPerMac;
/* Number of active sessions */
size_t NumActiveSessions = 0;
/* Offset of first session */
size_t SessOffset = 0;
/* Event Selector */
EventSelector *event_selector;
/* Use Linux kernel-mode PPPoE? */
static int UseLinuxKernelModePPPoE = 0;
/* Requested max_ppp_payload */
static UINT16_t max_ppp_payload = 0;
/* File with PPPD options */
static char *pppoptfile = NULL;
static char *pppd_path = PPPD_PATH;
static char *pppoe_path = PPPOE_PATH;
static int Debug = 0;
static int CheckPoolSyntax = 0;
/* Synchronous mode */
static int Synchronous = 0;
/* Ignore PADI if no free sessions */
static int IgnorePADIIfNoFreeSessions = 0;
static int KidPipe[2] = {-1, -1};
static int LockFD = -1;
/* Random seed for cookie generation */
#define SEED_LEN 16
#define MD5_LEN 16
#define COOKIE_LEN (MD5_LEN + sizeof(pid_t)) /* Cookie is 16-byte MD5 + PID of server */
static unsigned char CookieSeed[SEED_LEN];
#define MAXLINE 512
/* Default interface if no -I option given */
#define DEFAULT_IF "eth0"
/* Access concentrator name */
char *ACName = NULL;
/* Options to pass to pppoe process */
char PppoeOptions[SMALLBUF] = "";
/* Our local IP address */
unsigned char LocalIP[IPV4ALEN] = {10, 0, 0, 1}; /* Counter optionally STARTS here */
unsigned char RemoteIP[IPV4ALEN] = {10, 67, 15, 1}; /* Counter STARTS here */
/* Do we increment local IP for each connection? */
int IncrLocalIP = 0;
/* Do we randomize session numbers? */
int RandomizeSessionNumbers = 0;
/* Do we pass the "unit" option to pppd? (2.4 or greater) */
int PassUnitOptionToPPPD = 0;
static PPPoETag hostUniq;
static PPPoETag relayId;
static PPPoETag receivedCookie;
static PPPoETag requestedService;
#define HOSTNAMELEN 256
static int
count_sessions_from_mac(unsigned char *eth)
{
int n=0;
ClientSession *s = BusySessions;
while(s) {
if (!memcmp(eth, s->eth, ETH_ALEN)) n++;
s = s->next;
}
return n;
}
/**********************************************************************
*%FUNCTION: childHandler
*%ARGUMENTS:
* pid -- pid of child
* status -- exit status
* ses -- which session terminated
*%RETURNS:
* Nothing
*%DESCRIPTION:
* Called synchronously when a child dies. Remove from busy list.
***********************************************************************/
static void
childHandler(pid_t pid, int status, void *s)
{
ClientSession *session = s;
/* Temporary structure for sending PADT's. */
PPPoEConnection conn;
#ifdef HAVE_L2TP
/* We're acting as LAC, so when child exits, become a PPPoE <-> L2TP
relay */
if (session->flags & FLAG_ACT_AS_LAC) {
syslog(LOG_INFO, "Session %u for client "
"%02x:%02x:%02x:%02x:%02x:%02x handed off to LNS %s",
(unsigned int) ntohs(session->sess),
session->eth[0], session->eth[1], session->eth[2],
session->eth[3], session->eth[4], session->eth[5],
inet_ntoa(session->tunnel_endpoint.sin_addr));
session->pid = 0;
session->funcs = &L2TPSessionFunctionTable;
return;
}
#endif
memset(&conn, 0, sizeof(conn));
conn.hostUniq = NULL;
syslog(LOG_INFO,
"Session %u closed for client "
"%02x:%02x:%02x:%02x:%02x:%02x (%d.%d.%d.%d) on %s",
(unsigned int) ntohs(session->sess),
session->eth[0], session->eth[1], session->eth[2],
session->eth[3], session->eth[4], session->eth[5],
(int) session->realpeerip[0], (int) session->realpeerip[1],
(int) session->realpeerip[2], (int) session->realpeerip[3],
session->ethif->name);
memcpy(conn.myEth, session->ethif->mac, ETH_ALEN);
conn.discoverySocket = session->ethif->sock;
conn.session = session->sess;
memcpy(conn.peerEth, session->eth, ETH_ALEN);
if (!(session->flags & FLAG_SENT_PADT)) {
if (session->flags & FLAG_RECVD_PADT) {
sendPADT(&conn, "RP-PPPoE: Received PADT from peer");
} else {
sendPADT(&conn, "RP-PPPoE: Child pppd process terminated");
}
session->flags |= FLAG_SENT_PADT;
}
session->serviceName = "";
control_session_terminated(session);
if (pppoe_free_session(session) < 0) {
return;
}
}
/**********************************************************************
*%FUNCTION: incrementIPAddress (static)
*%ARGUMENTS:
* addr -- a 4-byte array representing IP address
*%RETURNS:
* Nothing
*%DESCRIPTION:
* Increments addr in-place
***********************************************************************/
static void
incrementIPAddress(unsigned char ip[IPV4ALEN])
{
ip[3]++;
if (!ip[3]) {
ip[2]++;
if (!ip[2]) {
ip[1]++;
if (!ip[1]) {
ip[0]++;
}
}
}
}
/**********************************************************************
*%FUNCTION: killAllSessions
*%ARGUMENTS:
* None
*%RETURNS:
* Nothing
*%DESCRIPTION:
* Kills all pppd processes (and hence all PPPoE sessions)
***********************************************************************/
void
killAllSessions(void)
{
ClientSession *sess = BusySessions;
while(sess) {
sess->funcs->stop(sess, "Shutting Down");
sess = sess->next;
}
#ifdef HAVE_L2TP
pppoe_close_l2tp_tunnels();
#endif
}
/****************************
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
rp-pppoe-3.13.tar.gz (77个子文件)
rp-pppoe-3.13
rp-pppoe.spec 4KB
src
debug.c 4KB
pppoe-server.h 5KB
Makefile.in 13KB
configure 172KB
ppp.c 9KB
config.h.in 4KB
pppoe-sniff.c 7KB
if.c 29KB
configure.in 10KB
discovery.c 22KB
pppoe.h 11KB
relay.c 44KB
install-sh 5KB
md5.h 715B
plugin
relay.h 4KB
pppoe-server.c 64KB
plugin.c 16KB
common.c 16KB
pppoe.c 26KB
libevent
Makefile.in 848B
hash.c 7KB
event.c 16KB
event.h 3KB
event_sig.c 8KB
hash.h 1KB
eventpriv.h 2KB
event_tcp.c 14KB
event_tcp.h 2KB
md5.c 8KB
doc
CHANGES 12KB
HOW-TO-CONNECT 10KB
LICENSE 18KB
PROBLEMS 63B
KERNEL-MODE-PPPOE 3KB
man
pppoe-sniff.8 3KB
pppoe-relay.8 4KB
pppoe.8 9KB
pppoe.conf.5 6KB
pppoe-setup.8 722B
pppoe-stop.8 681B
pppoe-start.8 886B
pppoe-status.8 739B
pppoe-connect.8 2KB
pppoe-server.8 7KB
scripts
pppoe-init-suse.in 1KB
pppoe-init-turbolinux.in 1KB
pppoe-init.in 1KB
pppoe-setup.in 9KB
pppoe-stop.in 2KB
pppoe-connect.in 9KB
pppoe-start.in 5KB
pppoe-status 2KB
configs
pap-secrets 278B
pppoe.conf 4KB
firewall-standalone 978B
pppoe-server-options 104B
firewall-masq 2KB
gui
Makefile.in 2KB
en.msg 8KB
html
mainwin.png 2KB
mainwin-busy.png 2KB
props-nic.png 4KB
props-basic.png 4KB
props-options.png 4KB
mainwin-nonroot.png 2KB
props-advanced.png 3KB
tkpppoe.html 7KB
pppoe-wrapper.1 1KB
tkpppoe.in 106KB
ja.msg 9KB
wrapper.c 6KB
tkpppoe.1 944B
go 845B
SERVPOET 559B
go-gui 2KB
README 2KB
共 77 条
- 1
资源评论
gcoollinux
- 粉丝: 2
- 资源: 12
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功