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

📄 protocol.c

📁 pppoe在windows实现的miniport驱动源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
    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,  &param,  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(&paramKey, parametersKey);
				obj.ObjectName = &paramKey;
				obj.Length = sizeof(OBJECT_ATTRIBUTES);
				if((ntstatus = ZwCreateKey(&paramHandle, 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 + -