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

📄 discovery.c

📁 NDIS 实现pppoe例子
💻 C
字号:
/*
    MikroTik PPPoE - MikroTik PPP over Ethernet client for Windows
    Copyright (C),  2001  MikroTikls

    The contents of this program are subject to the Mozilla Public License 
    Version 1.1; you may not use this program except in compliance with the 
    License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ 

    
    http://www.mikrotik.com
    mt@mt.lv
*/


#include "discovery.h"
#include "packet.h"
#include "debug.h"
#include "main.h"
#include "pppoe.h"
#include "miniport.h"

void PppoePADI(PADAPTER a) {
	PPPOE_PACKET *p;

	FENTER("PppoePADI");

	p = PacketAllocate(0);
	if (p == NULL) {
		FLEAVE("PppoePADI");
		return;
	}

	PacketReset(p);

	p->code = PPPOE_CODE_PADI;
	p->proto = PPPOE_DISCOVERY_PROTO;
	p->sessionid = 0;
	NdisMoveMemory(p->source, a->protoMacAddr, 6);
	NdisMoveMemory(p->dest, mainEthBcast, 6);

	++a->pppoeHostUniq;
	PacketAddTag(p, PPPOE_TAG_SERVICENAME, (PUCHAR)a->pppoeServiceName,a->pppoeServiceNameLen);
	PacketAddTag(p, PPPOE_TAG_HOSTUNIQ, (PUCHAR)&a->pppoeHostUniq, sizeof(ULONG));

	PppoeSendPacket(a, p, 0);

	FLEAVE("PppoePADI");
}

void PppoePADR(PADAPTER a) {
	PPPOE_PACKET *p;

	FENTER("PppoePADR");

	p = PacketAllocate(0);
	if (p == NULL) {
		FLEAVE("PppoePADR");
		return;
	}

	PacketReset(p);

	p->code = PPPOE_CODE_PADR;
	p->proto = PPPOE_DISCOVERY_PROTO;
	p->sessionid = 0;
	NdisMoveMemory(p->source, a->protoMacAddr, 6);
	NdisMoveMemory(p->dest, a->pppoeServerMacAddr, 6);

	++a->pppoeHostUniq;
	PacketAddTag(p, PPPOE_TAG_SERVICENAME, (PUCHAR)a->pppoeServiceName, a->pppoeServiceNameLen);
	PacketAddTag(p, PPPOE_TAG_HOSTUNIQ, (PUCHAR)&a->pppoeHostUniq, sizeof(ULONG));
	if (a->pppoeACCookieLen > 0) PacketAddTag(p, PPPOE_TAG_ACCOOKIE, a->pppoeACCookie, a->pppoeACCookieLen);

	PppoeSendPacket(a, p, 0);

	FLEAVE("PppoePADR");
}

void PppoePADT(PADAPTER	a) {
	PPPOE_PACKET *p;

	FENTER("PppoePADT");

	p = PacketAllocate(0);
	if (p == NULL) {
		FLEAVE("PppoePADT");
		return;
	}

	PacketReset(p);

	p->code = PPPOE_CODE_PADT;
	p->proto = PPPOE_DISCOVERY_PROTO;
	p->sessionid = a->pppoeSessionId;
	NdisMoveMemory(p->source, a->protoMacAddr, 6);
	NdisMoveMemory(p->dest, a->pppoeServerMacAddr, 6);

	PppoeSendPacket(a, p, 0);

	FLEAVE("PppoePADT");
}

void PppoeReceivePADO(PADAPTER a, PPPOE_PACKET *p) {
	BOOLEAN tc;
	int serviceOk = 0;

	PCHAR errType = NULL;
	PCHAR errStr = NULL;
	UINT errStrLen;

	PCHAR acStr = NULL;
	UINT acStrLen;

	PCHAR cookieStr = NULL;
	UINT cookieStrLen;

	int haveHostUniq;
	ULONG hostUniq;

	PPPOE_TAG tag;

	FENTER("PppoeReceivePADO");

	if (PacketGetFirstTag(p, &tag) == 0) {
		while (1) {
DbgPrint("tag: 0x%x, len: %d\n", tag.type, tag.len);

			switch(tag.type) {
			case PPPOE_TAG_SERVICENAME:
				if (serviceOk == 0) {
					if (a->pppoeServiceNameLen != tag.len) break;
					if (tag.len != 0 && MyMemCmp(tag.data, a->pppoeServiceName, tag.len) != 0) break;
					serviceOk = 1;
				}
				break;

			case PPPOE_TAG_ACNAME:
				acStr = tag.data;
				acStrLen = tag.len;
				break;

			case PPPOE_TAG_SERVICENAMEERR:
				errType = "Service-Name-Error";
				errStr = tag.data;
				errStrLen = tag.len;
				break;

			case PPPOE_TAG_ACSYSERR:
				errType = "AC-System-Error";
				errStr = tag.data;
				errStrLen = tag.len;
				break;

			case PPPOE_TAG_GENERICERR:
				errType = "Generic-Error";
				errStr = tag.data;
				errStrLen = tag.len;
				break;

			case PPPOE_TAG_ACCOOKIE:
				cookieStr = tag.data;
				cookieStrLen = tag.len;
				break;

			case PPPOE_TAG_HOSTUNIQ:
				if (tag.len != sizeof(ULONG)) {
					DbgPrint("Host-Uniq tag has wrong length: %d\n", tag.len);

					FLEAVE("PppoeReceivePADO");
					return;
				}
				haveHostUniq = 1;
				NdisMoveMemory(&hostUniq, tag.data, tag.len);
				break;

			default:
				break;
			}
			if (PacketGetNextTag(p, &tag) != 0) break;
		}
	}

	if (haveHostUniq == 0) {
		DbgPrint("no Host-Uniq tag\n");
		FLEAVE("PppoeReceivePADO");
		return;
	}
	if (acStr == NULL) {
		DbgPrint("no AC-Name tag\n");
		FLEAVE("PppoeReceivePADO");
		return;
	}
	if (errType) {
		DbgPrint("error: %s\n", errType);
		FLEAVE("PppoeReceivePADO");
		return;
	}
	if (hostUniq != a->pppoeHostUniq) {
		DbgPrint("wrong Host-Uniq: 0x%x\n", hostUniq);
		FLEAVE("PppoeReceivePADO");
		return;
	}

	// see if offer is good
	if (serviceOk == 0) {
		DbgPrint("service not OK\n");
		FLEAVE("PppoeReceicePADO");
		return;
	}
	if (a->pppoeACNameLen > 0) {
		if (a->pppoeACNameLen != acStrLen || MyMemCmp(a->pppoeACName, acStr, acStrLen) != 0) {
			DbgPrint("AC name does not match requested\n");
			FLEAVE("PppoeReceicePADO");
			return;
		}
	}

	// ok PADO is good for us
	NdisCancelTimer(&a->pppoeTimer, &tc);

	NdisMoveMemory(a->pppoeServerMacAddr, p->source, 6);
	a->pppoeState = PPPOE_STATE_PADR;
	a->pppoeRetries = 0;
	NdisSetTimer(&a->pppoeTimer, 3000);

	PppoePADR(a);

	FLEAVE("PppoeReceivePADO");
}

void PppoeReceivePADS(PADAPTER a, PPPOE_PACKET *p) {
	BOOLEAN tc;

	PCHAR errType = NULL;
	PCHAR errStr = NULL;
	UINT errStrLen;

	ULONG hostUniq;
	int haveHostUniq = 0;

	PCHAR servStr = NULL;
	UINT servStrLen;

	PPPOE_TAG tag;

	FENTER("PppoeReceivePADS");

	if (PacketGetFirstTag(p, &tag) == 0) {
		while (1) {
			switch(tag.type) {
			case PPPOE_TAG_SERVICENAME:
				if (servStr != NULL) {
					DbgPrint("more than one service name\n");
					FLEAVE("PppoeReceivePADS");
					return;
				}
				servStr = tag.data;
				servStrLen = tag.len;
				break;

			case PPPOE_TAG_SERVICENAMEERR:
				errType = "Service-Name-Error";
				errStr = tag.data;
				errStrLen = tag.len;
				break;

			case PPPOE_TAG_ACSYSERR:
				errType = "AC-System-Error";
				errStr = tag.data;
				errStrLen = tag.len;
				break;

			case PPPOE_TAG_GENERICERR:
				errType = "Generic-Error";
				errStr = tag.data;
				errStrLen = tag.len;
				break;

			case PPPOE_TAG_HOSTUNIQ:
				if (tag.len != sizeof(ULONG)) {
					DbgPrint("Host-Uniq tag has wrong length: %d\n", tag.len);

					FLEAVE("PppoeReceivePADO");
					return;
				}
				haveHostUniq = 1;
				NdisMoveMemory(&hostUniq, tag.data, tag.len);
				break;

			default:
				break;
			}
			if (PacketGetNextTag(p, &tag) != 0) break;
		}
	}

	if (haveHostUniq == 0) {
		DbgPrint("no Host-Uniq tag\n");
		FLEAVE("PppoeReceivePADS");
		return;
	}
	if (servStr == NULL) {
		DbgPrint("no Service-Name tag\n");
		FLEAVE("PppoeReceivePADS");
		return;
	}
	if (errType != NULL && p->sessionid != 0) {
		DbgPrint("PADS with error, but session id non-zero, error: %s\n", errType);
		FLEAVE("PppoeReceivePADS");
		return;
	}

	if (hostUniq != a->pppoeHostUniq) {
		DbgPrint("wrong Host-Uniq: 0x%x\n", hostUniq);
		FLEAVE("PppoeReceivePADS");
		return;
	}

	if (errType != NULL) {
		DbgPrint("error: %s\n", errType);
		FLEAVE("PppoeReceivePADS");
		return;
	}


	NdisCancelTimer(&a->pppoeTimer, &tc);

	if (a->pppoeServiceName != 0) {
		if (a->pppoeServiceNameLen != servStrLen || MyMemCmp(a->pppoeServiceName, servStr, servStrLen) != 0) {
			DbgPrint("accepted under wrong service name\n");

			PppoePADT(a);
			PppoeTerminate(a);
			MiniEnterCallState(a, LINECALLSTATE_DISCONNECTED, LINEDISCONNECTMODE_UNKNOWN);

			FLEAVE("PppoeReceivePADS");
			return;
		}
	}

	a->pppoeSessionId = p->sessionid;
	a->pppoeState = PPPOE_STATE_SESSION;

	MiniEnterLinedevState(a, LINEDEVSTATE_CONNECTED);

	NdisSetTimer(&a->pppoeTimer, 10000);

	
	FLEAVE("PppoeReceivePADS");
}

void PppoeReceivePADT(PADAPTER a, PPPOE_PACKET *p) {

	BOOLEAN b;
	FENTER("PppoeReceivePADT");

	if (a->pppoeState != PPPOE_STATE_SESSION) {
		DbgPrint("PADT in non-SESSION state %d\n", a->pppoeState);
		FLEAVE("PppoeReceivePADT");
		return;
	}

	if (a->pppoeSessionId != p->sessionid) {
		DbgPrint("PADT in for wrong session: 0x%x\n", a->pppoeSessionId);
		FLEAVE("PppoeReceivePADT");
		return;
	}

	NdisCancelTimer(&a->pppoeTimer, &b);

	a->pppoeState = PPPOE_STATE_PADT;

	MiniEnterLinedevState(a, LINEDEVSTATE_DISCONNECTED);

	FLEAVE("PppoeReceivePADT");
}

⌨️ 快捷键说明

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