📄 protocol.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 "my.h"
#include "main.h"
#include "debug.h"
#include "adapter.h"
#include "request.h"
#include "pppoe.h"
#define DIM_MEDIUM_ARRAY 4
static NDIS_MEDIUM MediumArray[DIM_MEDIUM_ARRAY] = {
NdisMediumDix, NdisMedium802_3, NdisMedium802_5, NdisMediumFddi
};
static void ProtoInitAdapter(PADAPTER a) {
FENTER("ProtoInitAdapter");
// this is called to initialize variables in ADAPTER
NdisInitializeReadWriteLock(&a->protoReqLock);
NdisInitializeReadWriteLock(&a->protoSyncReqLock);
NdisInitializeReadWriteLock(&a->protoReceivedPacketsLock);
NdisInitializeNPagedLookasideList(&a->protoReceivedPacketsLookasideList, NULL, NULL, 0, sizeof(RECEIVED_PACKET_LIST),
'ppoe', 0);
a->protoReceivedPackets = NULL;
a->protoReceivedPacketLast = NULL;
FLEAVE("ProtoInitAdapter");
}
static NDIS_STATUS ProtoReadConfig(PADAPT a, NDIS_HANDLE ch, PWCHAR regPath) {
NDIS_STATUS status;
PNDIS_CONFIGURATION_PARAMETER param;
NDIS_CONFIGURATION_PARAMETER writeParam;
NDIS_STRING upperStr = NDIS_STRING_CONST("UpperBindings");
HANDLE keyHandle = NULL;
HANDLE paramHandle = NULL;
WCHAR strBuf[256];
UNICODE_STRING valueName;
UNICODE_STRING blabla;
UNICODE_STRING paramKey;
OBJECT_ATTRIBUTES obj;
PKEY_VALUE_PARTIAL_INFORMATION keyValueInformation;
ULONG keyValueInformationLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 256;
ULONG resultLength;
NTSTATUS ntstatus;
WCHAR upperBindingsBuf[256];
WCHAR parametersKey[512];
static int currentDev = 0;
int tmp;
FENTER("ProtoReadConfig");
NdisReadConfiguration(&status, ¶m, ch, &upperStr, NdisParameterString);
if (status != NDIS_STATUS_SUCCESS) {
DbgPrint("failed to read UpperBindings\n");
tmp = currentDev++;
swprintf(strBuf, L"up%i", tmp);
RtlInitUnicodeString(&blabla, L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\MTPPPOE\\Enum");
NdisZeroMemory(&obj, sizeof(OBJECT_ATTRIBUTES));
obj.ObjectName = &blabla;
obj.Length = sizeof(OBJECT_ATTRIBUTES);
if((ntstatus = ZwOpenKey(&keyHandle, KEY_QUERY_VALUE, &obj)) != STATUS_SUCCESS) {
DbgPrint("Could not open key %i : %ls, error: %x\n", tmp, strBuf, ntstatus);
FLEAVE("ProtoReadConfig");
return status;
} else {
DbgPrint("Key %i opened\n", tmp);
NdisAllocateMemory(&keyValueInformation, keyValueInformationLength, 0, MaxAddress);
RtlInitUnicodeString(&valueName, strBuf);
if((ntstatus = ZwQueryValueKey(keyHandle, &valueName, KeyValuePartialInformation, keyValueInformation, keyValueInformationLength,
&resultLength)) != STATUS_SUCCESS) {
DbgPrint("ERROR- could not query value %i : %ls (%i), error : %x\n", tmp, valueName.Buffer,
valueName.Length, ntstatus);
} else {
DbgPrint("UpperBindings: %ls\n", keyValueInformation->Data);
swprintf(upperBindingsBuf, L"%s", keyValueInformation->Data);
UnicodeFromWideBuffer(&a->protoAdapterName, upperBindingsBuf);
writeParam.ParameterType = NdisParameterString;
writeParam.ParameterData.StringData = a->protoAdapterName;
swprintf(parametersKey, L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\%ls", regPath);
NdisZeroMemory(&obj, sizeof(OBJECT_ATTRIBUTES));
DbgPrint("Full path: %ls\n", parametersKey);
RtlInitUnicodeString(¶mKey, parametersKey);
obj.ObjectName = ¶mKey;
obj.Length = sizeof(OBJECT_ATTRIBUTES);
if((ntstatus = ZwCreateKey(¶mHandle, KEY_ALL_ACCESS, &obj, 0, NULL, REG_OPTION_NON_VOLATILE, NULL))
!= STATUS_SUCCESS) {
DbgPrint("Could not create param key, error : %x\n", ntstatus);
} else {
if((ntstatus = ZwSetValueKey(paramHandle, &upperStr, 0, REG_SZ, a->protoAdapterName.Buffer,
a->protoAdapterName.Length+1)) != STATUS_SUCCESS) {
DbgPrint("Could not set param value, error : %x\n", ntstatus);
}
ZwClose(paramHandle);
}
}
NdisFreeMemory(keyValueInformation, keyValueInformationLength, 0);
ZwClose(keyHandle);
}
} else {
UnicodeFromWideBuffer(&a->protoAdapterName,
param->ParameterData.StringData.Buffer);
}
DbgPrint("adapter name: ");
NdisPrintString(a->protoAdapterName);
DbgPrint("\n");
FLEAVE("ReadConfig");
return NDIS_STATUS_SUCCESS;
}
static void ProtoFinishBind(PADAPT a) {
ULONG hwStatus;
ULONG conStatus;
ULONG linkSpeed;
NDIS_STATUS status;
FENTER("FinishBind");
// link adapter in adapters list
AdapterLink(a);
// ask adapter some stuff
status = ProtoQueryRequestSync(a, OID_GEN_HARDWARE_STATUS, (PVOID)&hwStatus,
sizeof(hwStatus), NULL);
if (status != NDIS_STATUS_SUCCESS) {
DbgPrint("HARDWARE_STATUS request error: %d\n", status);
}
else DbgPrint("HARDWARE_STATUS: 0x%lx\n", hwStatus);
status = ProtoQueryRequestSync(a, OID_GEN_MEDIA_CONNECT_STATUS, (PVOID)&conStatus,
sizeof(conStatus), NULL);
if (status != NDIS_STATUS_SUCCESS) {
DbgPrint("MEDIA_CONNECT_STATUS request error: %d\n", status);
}
else DbgPrint("MEDIA_CONNECT_STATUS: 0x%lx\n", conStatus);
status = ProtoQueryRequestSync(a, OID_GEN_LINK_SPEED, (PVOID)&linkSpeed,
sizeof(linkSpeed), NULL);
if (status != NDIS_STATUS_SUCCESS) {
DbgPrint("LINK_SPEED request error: %d\n", status);
a->protoLinkSpeed = 100000 * 100;
}
else {
DbgPrint("LINK_SPEED: %ld\n", linkSpeed);
a->protoLinkSpeed = linkSpeed * 100;
}
status = ProtoQueryRequestSync(a, OID_802_3_CURRENT_ADDRESS,
a->protoMacAddr, 6, NULL);
if (status != NDIS_STATUS_SUCCESS) {
DbgPrint("802_3_CURRENT_ADDRESS request error: %d\n", status);
}
// perhaps we should tell everybody that we are about to come up
// initialize instance
status = NdisIMInitializeDeviceInstanceEx(mainDriverHandle,
&a->protoAdapterName,
a);
if (status != NDIS_STATUS_SUCCESS) {
DbgPrint("Initialize Device Instance failed\n");
} else {
DbgPrint("Initialize Device Instance successful\n");
}
FLEAVE("ProtoFinishBind");
}
static void ProtoOpenAdapterComplete(NDIS_HANDLE pbc, NDIS_STATUS status,
NDIS_STATUS oes) {
PADAPT a = (PADAPT)pbc;
FENTER("ProtoOpenAdapterComplete");
NdisCompleteBindAdapter(a->protoBindContext, status, oes);
if (status == NDIS_STATUS_SUCCESS) {
ProtoFinishBind(a);
}
else {
DbgPrint("OpenAdapterComplete: open failed, status %d, error_status %d\n",
status, oes);
AdapterFree(a);
}
FLEAVE("ProtoOpenAdapterComplete");
return;
}
static void ProtoResetComplete(NDIS_HANDLE p, NDIS_STATUS status) {
FENTER("ProtoResetComplete");
FLEAVE("ProtoResetComplete");
}
static void ProtoRequestComplete(NDIS_HANDLE p, PNDIS_REQUEST r, NDIS_STATUS s) {
FENTER("ProtoRequestComplete");
ProtoHandleRequestReply((PADAPTER)p, r, s);
FLEAVE("ProtoRequestComplete");
}
static void ProtoStatus(NDIS_HANDLE pbc, NDIS_STATUS status, PVOID buf, UINT size) {
FENTER("ProtoStatus");
FLEAVE("ProtoStatus");
}
static void ProtoStatusComplete(NDIS_HANDLE pbc) {
FENTER("ProtoStatusComplete");
FENTER("ProtoStatusComplete");
}
static void ProtoSendComplete(NDIS_HANDLE pbc,
PNDIS_PACKET packet,
NDIS_STATUS status) {
PADAPT a = (PADAPT)pbc;
PTRANSMIT_PROTOINFO pinfo;
FENTER("ProtoSendComplete");
pinfo = (PTRANSMIT_PROTOINFO)packet->ProtocolReserved;
if (pinfo->wanPacket) {
DbgPrint("Ok, wan packet sent\n");
NdisMWanSendComplete(a->miniAdapterHandle, pinfo->wanPacket, NDIS_STATUS_SUCCESS);
}
if (pinfo->pppoePacket) {
DbgPrint("Ok, our packet sent\n");
PacketFree(pinfo->pppoePacket, pinfo->pppoePacketLen);
}
MyFreeNdisPacket(packet);
FLEAVE("ProtoSendComplete");
}
static void ProtoQueuePacket(PADAPTER a, PPPOE_PACKET *p, UINT len) {
LOCK_STATE lockState;
PRECEIVED_PACKET_LIST recv_packet;
PRECEIVED_PACKET_LIST tmp_packet;
FENTER("ProtoQueuePacket");
recv_packet = NdisAllocateFromNPagedLookasideList(&a->protoReceivedPacketsLookasideList);
if (recv_packet != NULL) {
recv_packet->packet = p;
recv_packet->total_size = len;
recv_packet->next = NULL;
NdisAcquireReadWriteLock(&a->protoReceivedPacketsLock, TRUE, &lockState);
if (a->protoReceivedPacketLast != NULL) a->protoReceivedPacketLast->next = recv_packet;
a->protoReceivedPacketLast = recv_packet;
if (a->protoReceivedPackets == NULL) a->protoReceivedPackets = recv_packet;
NdisReleaseReadWriteLock(&a->protoReceivedPacketsLock, &lockState);
}
else {
DbgPrint("can not allocate from lookaside\n");
PacketFree(p, len);
}
FLEAVE("ProtoQueueuPacket");
}
static void ProtoTransferDataComplete(NDIS_HANDLE pbc, PNDIS_PACKET packet,
NDIS_STATUS status, UINT bytes) {
PRECEIVE_PROTOINFO pinfo;
PADAPTER a = (PADAPTER)pbc;
UINT packetsize;
PPPOE_PACKET *pppoe_packet;
FENTER("ProtoTransferDataComplete");
pinfo = (PRECEIVE_PROTOINFO)packet->ProtocolReserved;
ProtoQueuePacket(a, pinfo->pppoePacket, pinfo->pppoePacketLen);
MyFreeNdisPacket(packet);
FLEAVE("ProtoTransferDataComplete");
}
static NDIS_STATUS ProtoReceive(NDIS_HANDLE pbc, NDIS_HANDLE mrc,
PVOID hbuf, UINT hbufsize,
PVOID lookaheadbuf, UINT lookaheadbufsize,
UINT size) {
PNDIS_PACKET packet;
PNDIS_BUFFER buffer;
PPPOE_PACKET *p;
PPPOE_PACKET *newp;
PADAPTER a = (PADAPTER)pbc;
NDIS_STATUS s;
UINT bTrans = 0;
UINT totalSize = size + 14;
PRECEIVE_PROTOINFO pinfo;
FENTER("ProtoReceive");
DbgPrint("header: %u, lookahead: %u, packet: %u\n", hbufsize, lookaheadbufsize, size);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -