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

📄 common.c

📁 网上的一个开源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************* common.c** Implementation of user-space PPPoE redirector for Linux.** Common functions used by PPPoE client and server** Copyright (C) 2000 by 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.** LIC: GPL************************************************************************/static char const RCSID[] ="$Id: common.c,v 1.19 2004/10/21 16:21:10 dfs Exp $";/* For vsnprintf prototype */#define _ISOC99_SOURCE 1/* For seteuid prototype */#define _BSD_SOURCE 1#include "pppoe.h"#ifdef HAVE_SYSLOG_H#include <syslog.h>#endif#include <string.h>#include <errno.h>#include <stdlib.h>#include <stdarg.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include <sys/types.h>#include <pwd.h>/* Are we running SUID or SGID? */int IsSetID = 0;static uid_t saved_uid = -2;static uid_t saved_gid = -2;/***********************************************************************%FUNCTION: parsePacket*%ARGUMENTS:* packet -- the PPPoE discovery packet to parse* func -- function called for each tag in the packet* extra -- an opaque data pointer supplied to parsing function*%RETURNS:* 0 if everything went well; -1 if there was an error*%DESCRIPTION:* Parses a PPPoE discovery packet, calling "func" for each tag in the packet.* "func" is passed the additional argument "extra".***********************************************************************/intparsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra){    UINT16_t len = ntohs(packet->length);    unsigned char *curTag;    UINT16_t tagType, tagLen;    if (packet->ver != 1) {	syslog(LOG_ERR, "Invalid PPPoE version (%d)", (int) packet->ver);	return -1;    }    if (packet->type != 1) {	syslog(LOG_ERR, "Invalid PPPoE type (%d)", (int) packet->type);	return -1;    }    /* Do some sanity checks on packet */    if (len > ETH_DATA_LEN - 6) { /* 6-byte overhead for PPPoE header */	syslog(LOG_ERR, "Invalid PPPoE packet length (%u)", len);	return -1;    }    /* Step through the tags */    curTag = packet->payload;    while(curTag - packet->payload < len) {	/* Alignment is not guaranteed, so do this by hand... */	tagType = (((UINT16_t) curTag[0]) << 8) +	    (UINT16_t) curTag[1];	tagLen = (((UINT16_t) curTag[2]) << 8) +	    (UINT16_t) curTag[3];	if (tagType == TAG_END_OF_LIST) {	    return 0;	}	if ((curTag - packet->payload) + tagLen + TAG_HDR_SIZE > len) {	    syslog(LOG_ERR, "Invalid PPPoE tag length (%u)", tagLen);	    return -1;	}	func(tagType, tagLen, curTag+TAG_HDR_SIZE, extra);	curTag = curTag + TAG_HDR_SIZE + tagLen;    }    return 0;}/***********************************************************************%FUNCTION: findTag*%ARGUMENTS:* packet -- the PPPoE discovery packet to parse* type -- the type of the tag to look for* tag -- will be filled in with tag contents*%RETURNS:* A pointer to the tag if one of the specified type is found; NULL* otherwise.*%DESCRIPTION:* Looks for a specific tag type.***********************************************************************/unsigned char *findTag(PPPoEPacket *packet, UINT16_t type, PPPoETag *tag){    UINT16_t len = ntohs(packet->length);    unsigned char *curTag;    UINT16_t tagType, tagLen;    if (packet->ver != 1) {	syslog(LOG_ERR, "Invalid PPPoE version (%d)", (int) packet->ver);	return NULL;    }    if (packet->type != 1) {	syslog(LOG_ERR, "Invalid PPPoE type (%d)", (int) packet->type);	return NULL;    }    /* Do some sanity checks on packet */    if (len > ETH_DATA_LEN - 6) { /* 6-byte overhead for PPPoE header */	syslog(LOG_ERR, "Invalid PPPoE packet length (%u)", len);	return NULL;    }    /* Step through the tags */    curTag = packet->payload;    while(curTag - packet->payload < len) {	/* Alignment is not guaranteed, so do this by hand... */	tagType = (((UINT16_t) curTag[0]) << 8) +	    (UINT16_t) curTag[1];	tagLen = (((UINT16_t) curTag[2]) << 8) +	    (UINT16_t) curTag[3];	if (tagType == TAG_END_OF_LIST) {	    return NULL;	}	if ((curTag - packet->payload) + tagLen + TAG_HDR_SIZE > len) {	    syslog(LOG_ERR, "Invalid PPPoE tag length (%u)", tagLen);	    return NULL;	}	if (tagType == type) {	    memcpy(tag, curTag, tagLen + TAG_HDR_SIZE);	    return curTag;	}	curTag = curTag + TAG_HDR_SIZE + tagLen;    }    return NULL;}/***********************************************************************%FUNCTION: switchToRealID*%ARGUMENTS:* None*%RETURNS:* Nothing*%DESCRIPTION:* Sets effective user-ID and group-ID to real ones.  Aborts on failure***********************************************************************/voidswitchToRealID (void) {    if (IsSetID) {	if (saved_uid < 0) saved_uid = geteuid();	if (saved_gid < 0) saved_gid = getegid();	if (setegid(getgid()) < 0) {	    printErr("setgid failed");	    exit(EXIT_FAILURE);	}	if (seteuid(getuid()) < 0) {	    printErr("seteuid failed");	    exit(EXIT_FAILURE);	}    }}/***********************************************************************%FUNCTION: switchToEffectiveID*%ARGUMENTS:* None*%RETURNS:* Nothing*%DESCRIPTION:* Sets effective user-ID and group-ID back to saved gid/uid***********************************************************************/voidswitchToEffectiveID (void) {    if (IsSetID) {	if (setegid(saved_gid) < 0) {	    printErr("setgid failed");	    exit(EXIT_FAILURE);	}	if (seteuid(saved_uid) < 0) {	    printErr("seteuid failed");	    exit(EXIT_FAILURE);	}    }}/***********************************************************************%FUNCTION: dropPrivs*%ARGUMENTS:* None*%RETURNS:* Nothing*%DESCRIPTION:* If effective ID is root, try to become "nobody".  If that fails and* we're SUID, switch to real user-ID***********************************************************************/voiddropPrivs(void){    struct passwd *pw = NULL;    int ok = 0;    if (geteuid() == 0) {	pw = getpwnam("nobody");	if (pw) {	    if (setgid(pw->pw_gid) < 0) ok++;	    if (setuid(pw->pw_uid) < 0) ok++;	}    }    if (ok < 2 && IsSetID) {	setegid(getgid());	seteuid(getuid());    }}/***********************************************************************%FUNCTION: printErr*%ARGUMENTS:* str -- error message*%RETURNS:* Nothing*%DESCRIPTION:* Prints a message to stderr and syslog.***********************************************************************/voidprintErr(char const *str){    fprintf(stderr, "pppoe: %s\n", str);    syslog(LOG_ERR, "%s", str);}/***********************************************************************%FUNCTION: strDup*%ARGUMENTS:* str -- string to copy*%RETURNS:* A malloc'd copy of str.  Exits if malloc fails.***********************************************************************/char *strDup(char const *str){    char *copy = malloc(strlen(str)+1);    if (!copy) {	rp_fatal("strdup failed");    }    strcpy(copy, str);    return copy;}/***********************************************************************%FUNCTION: computeTCPChecksum*%ARGUMENTS:* ipHdr -- pointer to IP header* tcpHdr -- pointer to TCP header*%RETURNS:* The computed TCP checksum***********************************************************************/UINT16_tcomputeTCPChecksum(unsigned char *ipHdr, unsigned char *tcpHdr){    UINT32_t sum = 0;    UINT16_t count = ipHdr[2] * 256 + ipHdr[3];    UINT16_t tmp;    unsigned char *addr = tcpHdr;    unsigned char pseudoHeader[12];    /* Count number of bytes in TCP header and data */    count -= (ipHdr[0] & 0x0F) * 4;    memcpy(pseudoHeader, ipHdr+12, 8);    pseudoHeader[8] = 0;    pseudoHeader[9] = ipHdr[9];    pseudoHeader[10] = (count >> 8) & 0xFF;    pseudoHeader[11] = (count & 0xFF);    /* Checksum the pseudo-header */    sum += * (UINT16_t *) pseudoHeader;    sum += * ((UINT16_t *) (pseudoHeader+2));    sum += * ((UINT16_t *) (pseudoHeader+4));    sum += * ((UINT16_t *) (pseudoHeader+6));    sum += * ((UINT16_t *) (pseudoHeader+8));    sum += * ((UINT16_t *) (pseudoHeader+10));    /* Checksum the TCP header and data */    while (count > 1) {	memcpy(&tmp, addr, sizeof(tmp));

⌨️ 快捷键说明

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