⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pppoe-server.c

📁 网上的一个开源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* Ignore PADO and PADS totally */	break;    default:	/* Syslog an error */	break;    }}/***********************************************************************%FUNCTION: sendErrorPADS*%ARGUMENTS:* sock -- socket to write to* source -- source Ethernet address* dest -- destination Ethernet address* errorTag -- error tag* errorMsg -- error message*%RETURNS:* Nothing*%DESCRIPTION:* Sends a PADS packet with an error message***********************************************************************/voidsendErrorPADS(int sock,	      unsigned char *source,	      unsigned char *dest,	      int errorTag,	      char *errorMsg){    PPPoEPacket pads;    unsigned char *cursor = pads.payload;    UINT16_t plen;    PPPoETag err;    int elen = strlen(errorMsg);    memcpy(pads.ethHdr.h_dest, dest, ETH_ALEN);    memcpy(pads.ethHdr.h_source, source, ETH_ALEN);    pads.ethHdr.h_proto = htons(Eth_PPPOE_Discovery);    pads.ver = 1;    pads.type = 1;    pads.code = CODE_PADS;    pads.session = htons(0);    plen = 0;    err.type = htons(errorTag);    err.length = htons(elen);    memcpy(err.payload, errorMsg, elen);    memcpy(cursor, &err, TAG_HDR_SIZE+elen);    cursor += TAG_HDR_SIZE + elen;    plen += TAG_HDR_SIZE + elen;    if (relayId.type) {	memcpy(cursor, &relayId, ntohs(relayId.length) + TAG_HDR_SIZE);	cursor += ntohs(relayId.length) + TAG_HDR_SIZE;	plen += ntohs(relayId.length) + TAG_HDR_SIZE;    }    if (hostUniq.type) {	memcpy(cursor, &hostUniq, ntohs(hostUniq.length) + TAG_HDR_SIZE);	cursor += ntohs(hostUniq.length) + TAG_HDR_SIZE;	plen += ntohs(hostUniq.length) + TAG_HDR_SIZE;    }    pads.length = htons(plen);    sendPacket(NULL, sock, &pads, (int) (plen + HDR_SIZE));}/***********************************************************************%FUNCTION: startPPPDUserMode*%ARGUMENTS:* session -- client session record*%RETURNS:* Nothing*%DESCRIPTION:* Starts PPPD for user-mode PPPoE***********************************************************************/voidstartPPPDUserMode(ClientSession *session){    /* Leave some room */    char *argv[32];    char buffer[SMALLBUF];    int c = 0;    argv[c++] = "pppd";    argv[c++] = "pty";    /* Let's hope service-name does not have ' in it... */    snprintf(buffer, SMALLBUF, "%s -n -I %s -e %d:%02x:%02x:%02x:%02x:%02x:%02x%s -S '%s'",	     PPPOE_PATH, session->ethif->name,	     ntohs(session->sess),	     session->eth[0], session->eth[1], session->eth[2],	     session->eth[3], session->eth[4], session->eth[5],	     PppoeOptions, session->serviceName);    argv[c++] = strdup(buffer);    if (!argv[c-1]) {	/* TODO: Send a PADT */	exit(EXIT_FAILURE);    }    argv[c++] = "file";    argv[c++] = PPPOE_SERVER_OPTIONS;    snprintf(buffer, SMALLBUF, "%d.%d.%d.%d:%d.%d.%d.%d",	    (int) session->myip[0], (int) session->myip[1],	    (int) session->myip[2], (int) session->myip[3],	    (int) session->peerip[0], (int) session->peerip[1],	    (int) session->peerip[2], (int) session->peerip[3]);    syslog(LOG_INFO,	   "Session %d created for client %02x:%02x:%02x:%02x:%02x:%02x (%d.%d.%d.%d) on %s using Service-Name '%s'",	   ntohs(session->sess),	   session->eth[0], session->eth[1], session->eth[2],	   session->eth[3], session->eth[4], session->eth[5],	   (int) session->peerip[0], (int) session->peerip[1],	   (int) session->peerip[2], (int) session->peerip[3],	   session->ethif->name,	   session->serviceName);    argv[c++] = strdup(buffer);    if (!argv[c-1]) {	/* TODO: Send a PADT */	exit(EXIT_FAILURE);    }    argv[c++] = "nodetach";    argv[c++] = "noaccomp";    argv[c++] = "nobsdcomp";    argv[c++] = "nodeflate";    argv[c++] = "nopcomp";    argv[c++] = "novj";    argv[c++] = "novjccomp";    argv[c++] = "default-asyncmap";    if (Synchronous) {	argv[c++] = "sync";    }    if (PassUnitOptionToPPPD) {	argv[c++] = "unit";	sprintf(buffer, "%d", ntohs(session->sess) - 1 - SessOffset);	argv[c++] = buffer;    }    argv[c++] = NULL;    execv(PPPD_PATH, argv);    exit(EXIT_FAILURE);}/***********************************************************************%FUNCTION: startPPPDLinuxKernelMode*%ARGUMENTS:* session -- client session record*%RETURNS:* Nothing*%DESCRIPTION:* Starts PPPD for kernel-mode PPPoE on Linux***********************************************************************/voidstartPPPDLinuxKernelMode(ClientSession *session){    /* Leave some room */    char *argv[32];    int c = 0;    char buffer[SMALLBUF];    argv[c++] = "pppd";    argv[c++] = "plugin";    argv[c++] = PLUGIN_PATH;    argv[c++] = session->ethif->name;    snprintf(buffer, SMALLBUF, "%d:%02x:%02x:%02x:%02x:%02x:%02x",	     ntohs(session->sess),	     session->eth[0], session->eth[1], session->eth[2],	     session->eth[3], session->eth[4], session->eth[5]);    argv[c++] = "rp_pppoe_sess";    argv[c++] = strdup(buffer);    if (!argv[c-1]) {	/* TODO: Send a PADT */	exit(EXIT_FAILURE);    }    argv[c++] = "rp_pppoe_service";    argv[c++] = (char *) session->serviceName;    argv[c++] = "file";    argv[c++] = PPPOE_SERVER_OPTIONS;    snprintf(buffer, SMALLBUF, "%d.%d.%d.%d:%d.%d.%d.%d",	    (int) session->myip[0], (int) session->myip[1],	    (int) session->myip[2], (int) session->myip[3],	    (int) session->peerip[0], (int) session->peerip[1],	    (int) session->peerip[2], (int) session->peerip[3]);    syslog(LOG_INFO,	   "Session %d created for client %02x:%02x:%02x:%02x:%02x:%02x (%d.%d.%d.%d) on %s using Service-Name '%s'",	   ntohs(session->sess),	   session->eth[0], session->eth[1], session->eth[2],	   session->eth[3], session->eth[4], session->eth[5],	   (int) session->peerip[0], (int) session->peerip[1],	   (int) session->peerip[2], (int) session->peerip[3],	   session->ethif->name,	   session->serviceName);    argv[c++] = strdup(buffer);    if (!argv[c-1]) {	/* TODO: Send a PADT */	exit(EXIT_FAILURE);    }    argv[c++] = "nodetach";    argv[c++] = "noaccomp";    argv[c++] = "nobsdcomp";    argv[c++] = "nodeflate";    argv[c++] = "nopcomp";    argv[c++] = "novj";    argv[c++] = "novjccomp";    argv[c++] = "default-asyncmap";    if (PassUnitOptionToPPPD) {	argv[c++] = "unit";	sprintf(buffer, "%d", ntohs(session->sess) - 1 - SessOffset);	argv[c++] = buffer;    }    argv[c++] = NULL;    execv(PPPD_PATH, argv);    exit(EXIT_FAILURE);}/***********************************************************************%FUNCTION: startPPPD*%ARGUMENTS:* session -- client session record*%RETURNS:* Nothing*%DESCRIPTION:* Starts PPPD***********************************************************************/voidstartPPPD(ClientSession *session){    if (UseLinuxKernelModePPPoE) startPPPDLinuxKernelMode(session);    else startPPPDUserMode(session);}/*********************************************************************** %FUNCTION: InterfaceHandler* %ARGUMENTS:*  es -- event selector (ignored)*  fd -- file descriptor which is readable*  flags -- ignored*  data -- Pointer to the Interface structure* %RETURNS:*  Nothing* %DESCRIPTION:*  Handles a packet ready at an interface***********************************************************************/voidInterfaceHandler(EventSelector *es,		 int fd,		 unsigned int flags,		 void *data){    serverProcessPacket((Interface *) data);}/*********************************************************************** %FUNCTION: PppoeStopSession* %ARGUMENTS:*  ses -- the session*  reason -- reason session is being stopped.* %RETURNS:*  Nothing* %DESCRIPTION:*  Kills pppd.***********************************************************************/static voidPppoeStopSession(ClientSession *ses,		 char const *reason){    /* Temporary structure for sending PADT's. */    PPPoEConnection conn;    memset(&conn, 0, sizeof(conn));    conn.useHostUniq = 0;    memcpy(conn.myEth, ses->ethif->mac, ETH_ALEN);    conn.discoverySocket = ses->ethif->sock;    conn.session = ses->sess;    memcpy(conn.peerEth, ses->eth, ETH_ALEN);    sendPADT(&conn, reason);    ses->flags |= FLAG_SENT_PADT;    if (ses->pid) {	kill(ses->pid, SIGTERM);    }    ses->funcs = &DefaultSessionFunctionTable;}/*********************************************************************** %FUNCTION: PppoeSessionIsActive* %ARGUMENTS:*  ses -- the session* %RETURNS:*  True if session is active, false if not.***********************************************************************/static intPppoeSessionIsActive(ClientSession *ses){    return (ses->pid != 0);}#ifdef HAVE_LICENSE/*********************************************************************** %FUNCTION: getFreeMem* %ARGUMENTS:*  None* %RETURNS:*  The amount of free RAM in kilobytes, or -1 if it could not be*  determined* %DESCRIPTION:*  Reads Linux-specific /proc/meminfo file and extracts free RAM***********************************************************************/intgetFreeMem(void){    char buf[512];    int memfree=0, buffers=0, cached=0;    FILE *fp = fopen("/proc/meminfo", "r");    if (!fp) return -1;    while (fgets(buf, sizeof(buf), fp)) {	if (!strncmp(buf, "MemFree:", 8)) {	    if (sscanf(buf, "MemFree: %d", &memfree) != 1) {		fclose(fp);		return -1;	    }	} else if (!strncmp(buf, "Buffers:", 8)) {	    if (sscanf(buf, "Buffers: %d", &buffers) != 1) {		fclose(fp);		return -1;	    }	} else if (!strncmp(buf, "Cached:", 7)) {	    if (sscanf(buf, "Cached: %d", &cached) != 1) {		fclose(fp);		return -1;	    }	}    }    fclose(fp);    /* return memfree + buffers + cached; */    return memfree;}#endif/*********************************************************************** %FUNCTION: pppoe_alloc_session* %ARGUMENTS:*  None* %RETURNS:*  NULL if no session is available, otherwise a ClientSession structure.* %DESCRIPTION:*  Allocates a ClientSession structure and removes from free list, puts*  on busy list***********************************************************************/ClientSession *pppoe_alloc_session(void){    ClientSession *ses = FreeSessions;    if (!ses) return NULL;    /* Remove from free sessions list */    if (ses == LastFreeSession) {	LastFreeSession = NULL;    }    FreeSessions = ses->next;    /* Put on busy sessions list */    ses->next = BusySessions;    BusySessions = ses;    /* Initialize fields to sane values */    ses->funcs = &DefaultSessionFunctionTable;    ses->pid = 0;    ses->ethif = NULL;    memset(ses->eth, 0, ETH_ALEN);    ses->flags = 0;    ses->startTime = time(NULL);    ses->serviceName = "";#ifdef HAVE_LICENSE    memset(ses->user, 0, MAX_USERNAME_LEN+1);    memset(ses->realm, 0, MAX_USERNAME_LEN+1);    memset(ses->realpeerip, 0, IPV4ALEN);#endif#ifdef HAVE_L2TP    ses->l2tp_ses = NULL;#endif    NumActiveSessions++;    return ses;}/*********************************************************************** %FUNCTION: pppoe_free_session* %ARGUMENTS:*  ses -- session to free* %RETURNS:*  0 if OK, -1 if error* %DESCRIPTION:*  Places a ClientSession on the free list.***********************************************************************/intpppoe_free_session(ClientSession *ses){    ClientSession *cur, *prev;    cur = BusySessions;    prev = NULL;    while (cur) {	if (ses == cur) break;	prev = cur;	cur = cur->next;    }    if (!cur) {	syslog(LOG_ERR, "pppoe_free_session: Could not find session %p on busy list", (void *) ses);	return -1;    }    /* Remove from busy sessions list */    if (prev) {	prev->next = ses->next;    } else {	BusySessions = ses->next;    }    /* Add to end of free sessions */    ses->next = NULL;    if (LastFreeSession) {	LastFreeSession->next = ses;	LastFreeSession = ses;    } else {	FreeSessions = ses;	LastFreeSession = ses;    }    /* Initialize fields to sane values */    ses->funcs = &DefaultSessionFunctionTable;    ses->pid = 0;    ses->flags = 0;#ifdef HAVE_L2TP    ses->l2tp_ses = NULL;#endif    NumActiveSessions--;    return 0;}/*********************************************************************** %FUNCTION: sendHURLorMOTM* %ARGUMENTS:*  conn -- PPPoE connection*  url -- a URL, which *MUST* begin with "http://" or it won't be sent, or*         a message.*  tag -- one of TAG_HURL or TAG_MOTM* %RETURNS:*  Nothing* %DESCRIPTION:*  Sends a PADM packet contaning a HURL or MOTM tag to the victim...er, peer.***********************************************************************/voidsendHURLorMOTM(PPPoEConnection *conn, char const *url, UINT16_t tag){    PPPoEPacket packet;    PPPoETag hurl;    size_t elen;    unsigned char *cursor = packet.payload;    UINT16_t plen = 0;    if (!conn->session) return;    if (conn->discoverySocket < 0) return;    if (tag == TAG_HURL) {	if (strncmp(url, "http://", 7)) {	    syslog(LOG_WARNING, "sendHURL(%s): URL must begin with http://", url);	    return;	}    } else {	tag = TAG_MOTM;    }    memcpy(packet.ethHdr.h_dest, conn->peerEth, ETH_ALEN);    memcpy(packet.ethHdr.h_source, conn->myEth, ETH_ALEN);    packet.ethHdr.h_proto = htons(Eth_PPPOE_Discovery);    packet.ver = 1;    packet.type = 1;    packet.code = CODE_PADM;    packet.session = conn->session;    elen = strlen(url);    if (elen > 256) {	syslog(LOG_WARNING, "MOTM or HURL too long: %d", (int) elen);	return;    }    hurl.type = htons(tag);    hurl.length = htons(elen);    strcpy((char *) hurl.payload, url);    memcpy(cursor, &hurl, elen + TAG_HDR_SIZE);    cursor += elen + TAG_HDR_SIZE;    plen += elen + TAG_HDR_SIZE;    packet.length = htons(plen);    sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE));    if (conn->debugFile) {	dumpPacket(conn->debugFile, &packet, "SENT");	fprintf(conn->debugFile, "\n");	fflush(conn->debugFile);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -