📄 discovery.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 + -