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

📄 discovery.c

📁 实现点到点的以太网协议,用于拨号上网,是拨号上网的基础部分软件模块.
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************* discovery.c** Perform PPPoE discovery** Copyright (C) 1999 by Roaring Penguin Software Inc.************************************************************************/static char const RCSID[] ="$Id: discovery.c,v 1.4 2005/03/22 10:22:32 paulus Exp $";#include "pppoe.h"#ifdef HAVE_SYSLOG_H#include <syslog.h>#endif#include <string.h>#include <stdlib.h>#include <errno.h>#ifdef HAVE_SYS_TIME_H#include <sys/time.h>#endif#ifdef HAVE_SYS_UIO_H#include <sys/uio.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef USE_LINUX_PACKET#include <sys/ioctl.h>#include <fcntl.h>#endif#include <signal.h>/***********************************************************************%FUNCTION: parseForHostUniq*%ARGUMENTS:* type -- tag type* len -- tag length* data -- tag data.* extra -- user-supplied pointer.  This is assumed to be a pointer to int.*%RETURNS:* Nothing*%DESCRIPTION:* If a HostUnique tag is found which matches our PID, sets *extra to 1.***********************************************************************/voidparseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data,		 void *extra){    int *val = (int *) extra;    if (type == TAG_HOST_UNIQ && len == sizeof(pid_t)) {	pid_t tmp;	memcpy(&tmp, data, len);	if (tmp == getpid()) {	    *val = 1;	}    }}/***********************************************************************%FUNCTION: packetIsForMe*%ARGUMENTS:* conn -- PPPoE connection info* packet -- a received PPPoE packet*%RETURNS:* 1 if packet is for this PPPoE daemon; 0 otherwise.*%DESCRIPTION:* If we are using the Host-Unique tag, verifies that packet contains* our unique identifier.***********************************************************************/intpacketIsForMe(PPPoEConnection *conn, PPPoEPacket *packet){    int forMe = 0;    /* If packet is not directed to our MAC address, forget it */    if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0;    /* If we're not using the Host-Unique tag, then accept the packet */    if (!conn->useHostUniq) return 1;    parsePacket(packet, parseForHostUniq, &forMe);    return forMe;}/***********************************************************************%FUNCTION: parsePADOTags*%ARGUMENTS:* type -- tag type* len -- tag length* data -- tag data* extra -- extra user data.  Should point to a PacketCriteria structure*          which gets filled in according to selected AC name and service*          name.*%RETURNS:* Nothing*%DESCRIPTION:* Picks interesting tags out of a PADO packet***********************************************************************/voidparsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data,	      void *extra){    struct PacketCriteria *pc = (struct PacketCriteria *) extra;    PPPoEConnection *conn = pc->conn;    int i;    switch(type) {    case TAG_AC_NAME:	pc->seenACName = 1;	if (conn->printACNames) {	    printf("Access-Concentrator: %.*s\n", (int) len, data);	}	if (conn->acName && len == strlen(conn->acName) &&	    !strncmp((char *) data, conn->acName, len)) {	    pc->acNameOK = 1;	}	break;    case TAG_SERVICE_NAME:	pc->seenServiceName = 1;	if (conn->printACNames && len > 0) {	    printf("       Service-Name: %.*s\n", (int) len, data);	}	if (conn->serviceName && len == strlen(conn->serviceName) &&	    !strncmp((char *) data, conn->serviceName, len)) {	    pc->serviceNameOK = 1;	}	break;    case TAG_AC_COOKIE:	if (conn->printACNames) {	    printf("Got a cookie:");	    /* Print first 20 bytes of cookie */	    for (i=0; i<len && i < 20; i++) {		printf(" %02x", (unsigned) data[i]);	    }	    if (i < len) printf("...");	    printf("\n");	}	conn->cookie.type = htons(type);	conn->cookie.length = htons(len);	memcpy(conn->cookie.payload, data, len);	break;    case TAG_RELAY_SESSION_ID:	if (conn->printACNames) {	    printf("Got a Relay-ID:");	    /* Print first 20 bytes of relay ID */	    for (i=0; i<len && i < 20; i++) {		printf(" %02x", (unsigned) data[i]);	    }	    if (i < len) printf("...");	    printf("\n");	}	conn->relayId.type = htons(type);	conn->relayId.length = htons(len);	memcpy(conn->relayId.payload, data, len);	break;    case TAG_SERVICE_NAME_ERROR:	if (conn->printACNames) {	    printf("Got a Service-Name-Error tag: %.*s\n", (int) len, data);	} else {	    syslog(LOG_ERR, "PADO: Service-Name-Error: %.*s", (int) len, data);	    exit(1);	}	break;    case TAG_AC_SYSTEM_ERROR:	if (conn->printACNames) {	    printf("Got a System-Error tag: %.*s\n", (int) len, data);	} else {	    syslog(LOG_ERR, "PADO: System-Error: %.*s", (int) len, data);	    exit(1);	}	break;    case TAG_GENERIC_ERROR:	if (conn->printACNames) {	    printf("Got a Generic-Error tag: %.*s\n", (int) len, data);	} else {	    syslog(LOG_ERR, "PADO: Generic-Error: %.*s", (int) len, data);	    exit(1);	}	break;    }}/***********************************************************************%FUNCTION: parsePADSTags*%ARGUMENTS:* type -- tag type* len -- tag length* data -- tag data* extra -- extra user data (pointer to PPPoEConnection structure)*%RETURNS:* Nothing*%DESCRIPTION:* Picks interesting tags out of a PADS packet***********************************************************************/voidparsePADSTags(UINT16_t type, UINT16_t len, unsigned char *data,	      void *extra){    PPPoEConnection *conn = (PPPoEConnection *) extra;    switch(type) {    case TAG_SERVICE_NAME:	syslog(LOG_DEBUG, "PADS: Service-Name: '%.*s'", (int) len, data);	break;    case TAG_SERVICE_NAME_ERROR:	syslog(LOG_ERR, "PADS: Service-Name-Error: %.*s", (int) len, data);	fprintf(stderr, "PADS: Service-Name-Error: %.*s\n", (int) len, data);	exit(1);    case TAG_AC_SYSTEM_ERROR:	syslog(LOG_ERR, "PADS: System-Error: %.*s", (int) len, data);	fprintf(stderr, "PADS: System-Error: %.*s\n", (int) len, data);	exit(1);    case TAG_GENERIC_ERROR:	syslog(LOG_ERR, "PADS: Generic-Error: %.*s", (int) len, data);	fprintf(stderr, "PADS: Generic-Error: %.*s\n", (int) len, data);	exit(1);    case TAG_RELAY_SESSION_ID:	conn->relayId.type = htons(type);	conn->relayId.length = htons(len);	memcpy(conn->relayId.payload, data, len);	break;    }}/************************************************************************%FUNCTION: sendPADI*%ARGUMENTS:* conn -- PPPoEConnection structure*%RETURNS:* Nothing*%DESCRIPTION:* Sends a PADI packet***********************************************************************/voidsendPADI(PPPoEConnection *conn){    PPPoEPacket packet;    unsigned char *cursor = packet.payload;    PPPoETag *svc = (PPPoETag *) (&packet.payload);    UINT16_t namelen = 0;    UINT16_t plen;    if (conn->serviceName) {	namelen = (UINT16_t) strlen(conn->serviceName);    }    plen = TAG_HDR_SIZE + namelen;    CHECK_ROOM(cursor, packet.payload, plen);    /* Set destination to Ethernet broadcast address */    memset(packet.ethHdr.h_dest, 0xFF, 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_PADI;    packet.session = 0;    svc->type = TAG_SERVICE_NAME;    svc->length = htons(namelen);    CHECK_ROOM(cursor, packet.payload, namelen+TAG_HDR_SIZE);    if (conn->serviceName) {	memcpy(svc->payload, conn->serviceName, strlen(conn->serviceName));    }    cursor += namelen + TAG_HDR_SIZE;    /* If we're using Host-Uniq, copy it over */    if (conn->useHostUniq) {	PPPoETag hostUniq;	pid_t pid = getpid();	hostUniq.type = htons(TAG_HOST_UNIQ);	hostUniq.length = htons(sizeof(pid));	memcpy(hostUniq.payload, &pid, sizeof(pid));	CHECK_ROOM(cursor, packet.payload, sizeof(pid) + TAG_HDR_SIZE);	memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);	cursor += sizeof(pid) + TAG_HDR_SIZE;	plen += sizeof(pid) + 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);    }}/***********************************************************************%FUNCTION: waitForPADO*%ARGUMENTS:* conn -- PPPoEConnection structure* timeout -- how long to wait (in seconds)*%RETURNS:* Nothing*%DESCRIPTION:* Waits for a PADO packet and copies useful information***********************************************************************/voidwaitForPADO(PPPoEConnection *conn, int timeout){    fd_set readable;    int r;    struct timeval tv;    PPPoEPacket packet;    int len;    struct PacketCriteria pc;    pc.conn          = conn;    pc.acNameOK      = (conn->acName)      ? 0 : 1;    pc.serviceNameOK = (conn->serviceName) ? 0 : 1;    pc.seenACName    = 0;

⌨️ 快捷键说明

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