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

📄 miniport.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 "main.h"
#include "debug.h"
#include "adapter.h"
#include "request.h"
#include "oid.h"
#include "pppoe.h"

void MiniReportLineError(PADAPTER a, ULONG err) {
	NDIS_MAC_FRAGMENT f;

	FENTER("MiniReportLineError");

	f.NdisLinkContext = a->miniNdisLinkContext;
	f.Errors = err;

	NdisMIndicateStatus(a->miniAdapterHandle,
						NDIS_STATUS_WAN_FRAGMENT,
						&f, sizeof(f));

	FLEAVE("MiniReportLineError");
}

void MiniReportLineUp(PADAPT a) {
    NDIS_MAC_LINE_UP i;

	FENTER("reportLineUp");

	i.LinkSpeed = a->protoLinkSpeed / 100;
	i.Quality = NdisWanRaw;
	i.SendWindow = 10;
	i.ConnectionWrapperID = (NDIS_HANDLE)a->miniHtCall;
	i.NdisLinkHandle = a;
	i.NdisLinkContext = NULL;//a->miniNdisLinkContext;

    NdisMIndicateStatus(a->miniAdapterHandle, NDIS_STATUS_WAN_LINE_UP,
                        &i, sizeof(i));

	a->miniNdisLinkContext = i.NdisLinkContext;

	FLEAVE("reportLineUp");
}

void MiniReportLineDown(PADAPT a) {
    NDIS_MAC_LINE_DOWN i;

	FENTER("reportLineDown");

	if (a->miniNdisLinkContext) {
		i.NdisLinkContext = a->miniNdisLinkContext;

        NdisMIndicateStatus(a->miniAdapterHandle,
                            NDIS_STATUS_WAN_LINE_DOWN,
                            &i, sizeof(i));

		a->miniNdisLinkContext = NULL;
    }
	else DbgPrint("line already down\n");

	FLEAVE("reportLineDown");
}

void MiniEnterCallState(PADAPT a, ULONG state, ULONG param) {
	FENTER("enterCallState");

	if (a->miniCallState == state) {
		FLEAVE("enterCallState");
		return;
	}
	a->miniCallState = state;

	DbgPrint("enter CALLSTATE 0x%x, reported: 0x%x, together: 0x%x\n",
			 state, a->miniReportedCallStates, a->miniReportedCallStates & state);

	switch (state) {
	case LINECALLSTATE_CONNECTED:
		MiniReportLineUp(a);
		break;

	case LINECALLSTATE_DISCONNECTED:
		MiniReportLineDown(a);
		break;

	default:
		break;
	}

	if ((a->miniReportedCallStates & state) != 0) {
		NDIS_TAPI_EVENT e;

		DbgPrint("report CALLSTATE 0x%x\n", state);

		NdisZeroMemory(&e, sizeof(e));
		e.htLine   = a->miniHtLine;
		e.htCall   = a->miniHtCall;
		e.ulMsg    = LINE_CALLSTATE;
		e.ulParam1 = state;
		e.ulParam2 = param;
		NdisMIndicateStatus(a->miniAdapterHandle, NDIS_STATUS_TAPI_INDICATION,
	                        &e, sizeof(e));
	}

	FLEAVE("enterCallState");
}

void MiniEnterLinedevState(PADAPT a, ULONG state) {
	ULONG callState = 0;
	ULONG param = 0;

	FENTER("MiniEnterLinedevState");

	if (a->miniLinedevState == state) {
		FLEAVE("enterLinedevState");
		return;
	}
	a->miniLinedevState = state;

	DbgPrint("enter LINEDEVSTATE 0x%x\n", state);

	switch(state) {
	case LINEDEVSTATE_CONNECTED:
		callState = LINECALLSTATE_CONNECTED;
		break;

	case LINEDEVSTATE_DISCONNECTED:
		if (a->miniCallState != LINECALLSTATE_IDLE &&
			a->miniCallState != LINECALLSTATE_DISCONNECTED) {
			callState = LINECALLSTATE_DISCONNECTED;
			param = LINEDISCONNECTMODE_NORMAL;
		}
		break;

	case LINEDEVSTATE_OUTOFSERVICE:
		if (a->miniCallState != LINECALLSTATE_IDLE &&
			a->miniCallState != LINECALLSTATE_DISCONNECTED) {
			callState = LINECALLSTATE_DISCONNECTED;
			param = LINEDISCONNECTMODE_NORMAL;
		}
		break;

	case LINEDEVSTATE_OPEN:
		callState = LINECALLSTATE_IDLE;
        break;

	case LINEDEVSTATE_CLOSE:
		callState = LINECALLSTATE_IDLE;
        break;

	default:
		break;
    }

	if ((a->miniReportedLinedevStates & state) != 0) {
		NDIS_TAPI_EVENT e;

		DbgPrint("report LINEDEVSTATE 0x%x\n", state);

		NdisZeroMemory(&e, sizeof(NDIS_TAPI_EVENT));
		e.htLine = a->miniHtLine;
		e.htCall = a->miniHtCall;
		e.ulMsg = LINE_LINEDEVSTATE;
		e.ulParam1 = state;
		NdisMIndicateStatus(a->miniAdapterHandle, NDIS_STATUS_TAPI_INDICATION,
							&e, sizeof(e));
	}

	if (callState != 0) MiniEnterCallState(a, callState, param);

	FLEAVE("enterLinedevState");
}

/*
 * Query Information Handler
 */
NDIS_STATUS MiniQueryInformation(NDIS_HANDLE ac, NDIS_OID oid, PVOID buf,
									ULONG len, PULONG bwritten, PULONG bneeded) {
	NDIS_STATUS ret = NDIS_STATUS_SUCCESS;
	PADAPT a = (PADAPT)ac;
	POID_HANDLER h = queryOids;

	FENTER("MiniQueryInformation");

	DbgPrint("OID: 0x%x\n", oid);

	while (h->handler != NULL) {
		if (h->oid == oid) break;
		h++;
	}

	if (h->handler) {
		if (h->requestedLen != 0 && len < h->requestedLen) {
			DbgPrint("too short buffer: %d, needed: %d, oid 0x%x\n",
					 len, h->requestedLen, oid);
			*bneeded = h->requestedLen;
			ret = NDIS_STATUS_INVALID_LENGTH;
		}
		else {
			DATABUF_DESCR d = {buf, len, bwritten, bneeded};
			*bneeded = h->requestedLen;
			*bwritten = h->requestedLen;
			ret = (h->handler)(a, &d);
		}
	}
	else {
		DbgPrint("unknown oid: 0x%x\n", oid);
//		Todo: Uncomment this
//		ret = NDIS_STATUS_INVALID_OID;
// Todo: Delete this
		ret = NDIS_STATUS_SUCCESS;
	}

	FLEAVE("MiniQueryInformation");
	return ret;
}


NDIS_STATUS MiniSetInformation(NDIS_HANDLE ac, NDIS_OID oid, PVOID buf,
							   ULONG len, PULONG bread, PULONG bneeded) {
	NDIS_STATUS ret = NDIS_STATUS_SUCCESS;
	PADAPT a = (PADAPT)ac;
	POID_HANDLER h = setOids;

	FENTER("MiniSetInformation");

	DbgPrint("OID: 0x%x\n", oid);

	while (h->handler != NULL) {
		if (h->oid == oid) break;
		h++;
	}

	if (h->handler) {
		if (h->requestedLen != 0 && len < h->requestedLen) {
			DbgPrint("too short buffer: %d, needed: %d, oid 0x%x\n",
					 len, h->requestedLen, oid);
			*bneeded = h->requestedLen;
			ret = NDIS_STATUS_INVALID_LENGTH;
		}
		else {
			DATABUF_DESCR d = {buf, len, bread, bneeded};
			*bneeded = h->requestedLen;
			*bread = h->requestedLen;
			ret = (h->handler)(a, &d);
		}
	}
	else {
		DbgPrint("unknown oid: 0x%x\n", oid);
		ret = NDIS_STATUS_INVALID_OID;
	}

	FLEAVE("MiniSetInformation");
	return ret;
}

void MiniInitAdapter(PADAPTER a) {
	a->miniSupportedCallStates = LINECALLSTATE_IDLE |
								 LINECALLSTATE_DIALING |
                                 LINECALLSTATE_BUSY |
                                 LINECALLSTATE_CONNECTED |
                                 LINECALLSTATE_DISCONNECTED;
	
	a->miniSupportedLinedevStates = LINEDEVSTATE_CONNECTED |
						            LINEDEVSTATE_DISCONNECTED |
									LINEDEVSTATE_OPEN |
			                        LINEDEVSTATE_CLOSE;

	a->miniReportedCallStates = a->miniSupportedCallStates;
	a->miniReportedLinedevStates = 0;
	a->miniCallState = 0;
	a->miniLinedevState = 0;
}

NDIS_STATUS MiniInitialize(PNDIS_STATUS error, PUINT mediumidx,
                              PNDIS_MEDIUM mediumarray, UINT mediumarraysize, 
                              NDIS_HANDLE mah,
                              NDIS_HANDLE wrapper_config_context) {
	UINT idx = 0;
	PADAPTER a;

	FENTER("InitalizeHandler");

	a = (PADAPTER)NdisIMGetDeviceContext(mah);
	a->miniAdapterHandle = mah;
	
	// select medium
	for(idx = 0; idx < mediumarraysize; idx++) {
		if(mediumarray[idx] == NdisMediumWan) {
			*mediumidx = idx;
			DbgPrint("Wan medium selected\n");
			break;
		}
	}
	if(idx == mediumarraysize) {
		DbgPrint("no supported media\n");
		*error = NDIS_STATUS_UNSUPPORTED_MEDIA;
		FLEAVE("MiniInitialize");
		return NDIS_STATUS_FAILURE;
	}

	// configure 
	NdisMSetAttributesEx(mah, a, 10, NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER
	    | NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND | NDIS_ATTRIBUTE_DESERIALIZE
	    | NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT, 0);

	PppoeInitialize(a);
	    
	FLEAVE("MiniInitialize");
	return NDIS_STATUS_SUCCESS;
}

/*
 Wan miniport send function.
*/
NDIS_STATUS MiniWanSend(NDIS_HANDLE c, 
                           NDIS_HANDLE linkHandle,
                           PNDIS_WAN_PACKET packet) {
	PADAPT a = (PADAPT)c;
	NDIS_STATUS s;

	FENTER("MiniWanSend");
	s = PppoeTransmit(a, packet);
/*
	DbgPrint("len: %d, headpad: %d, tailpad: %d\n", packet->CurrentLength,
			 packet->CurrentBuffer - packet->StartBuffer,
			 packet->EndBuffer - (packet->CurrentBuffer + packet->CurrentLength));

	DbgPrint("first bytes: %02x %02x %02x %02x %02x %02x %02x %02x\n",
		packet->CurrentBuffer[0],
		packet->CurrentBuffer[1],
		packet->CurrentBuffer[2],
		packet->CurrentBuffer[3],
		packet->CurrentBuffer[4],
		packet->CurrentBuffer[5],
		packet->CurrentBuffer[6],
		packet->CurrentBuffer[7]);
*/
	FLEAVE("MiniWanSend");
	return s;
}


static VOID MiniReturnPacket(NDIS_HANDLE miniport_adapter_context, 
                         PNDIS_PACKET packet) {
	FENTER("MiniReturnPacket");
	FLEAVE("MiniReturnPacket");
	return;
}

static VOID MiniHalt(NDIS_HANDLE miniport_adapter_context) {
	FENTER("MiniHalt");
	FLEAVE("MiniHalt");
	return;
}

static NDIS_STATUS MiniReset(OUT PBOOLEAN addressing_reset, 
                         NDIS_HANDLE miniport_adapter_context) {
	FENTER("MiniReset");
	FLEAVE("MiniReset");
	return NDIS_STATUS_SUCCESS;
}

void SetupMiniportCfg(PNDIS_MINIPORT_CHARACTERISTICS cfg) {
	FENTER("SetupMiniportCfg");
	
	cfg->MajorNdisVersion = 4;
	cfg->MinorNdisVersion = 0;

	cfg->Reserved = NDIS_USE_WAN_WRAPPER;
 
	cfg->HaltHandler = MiniHalt;
	cfg->InitializeHandler = MiniInitialize;
	cfg->QueryInformationHandler = MiniQueryInformation;
	cfg->ResetHandler = MiniReset;
	cfg->WanSendHandler = MiniWanSend;
	cfg->SetInformationHandler = MiniSetInformation;
	cfg->TransferDataHandler = NULL;
	cfg->ReturnPacketHandler = MiniReturnPacket;
	
	FLEAVE("SetupMiniportCfg");
}

⌨️ 快捷键说明

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