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

📄 oid.c

📁 NDIS 实现pppoe例子
💻 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 "oid.h"
#include "debug.h"
#include "adapter.h"
#include "request.h"
#include "pppoe.h"

// OID_WAN_SET_LINK_INFO
static NDIS_STATUS setWanSetLinkInfo(PADAPT a, PDATABUF_DESCR buf) {
	NDIS_WAN_SET_LINK_INFO *i;

	FENTER("setWanSetLinkInfo");

	i = (NDIS_WAN_SET_LINK_INFO *)buf->data;
	DbgPrint("MTU: %d, MRU: %d, headerpad: %d, tailpad: %d\n",
			 i->MaxSendFrameSize, i->MaxRecvFrameSize,
			 i->HeaderPadding, i->TailPadding);	
	FLEAVE("setWanSetLinkInfo");
	return NDIS_STATUS_SUCCESS;
}

// OID_TAPI_CLOSE_CALL
static NDIS_STATUS setTapiCloseCall(PADAPT a, PDATABUF_DESCR buf) {
	FENTER("setTapiCloseCall");

	MiniEnterCallState(a, LINECALLSTATE_IDLE, 0);
	MiniReportLineDown(a);

	PppoeTerminate(a);

	FLEAVE("setTapiCloseCall");
	return NDIS_STATUS_SUCCESS;
}

// OID_TAPI_CLOSE
static NDIS_STATUS setTapiClose(PADAPT a, PDATABUF_DESCR buf) {
	NDIS_STATUS status;
	ULONG packetFilter = 0;

	FENTER("setTapiClose");

	MiniEnterLinedevState(a, LINEDEVSTATE_CLOSE);

	// make sure line is down
	MiniReportLineDown(a);

	PppoeTerminate(a);

	FLEAVE("setTapiClose");
	return NDIS_STATUS_SUCCESS;
}

// OID_TAPI_DROP
static NDIS_STATUS setTapiDrop(PADAPT a, PDATABUF_DESCR buf) {
	FENTER("setTapiDrop");

    MiniEnterCallState(a, LINECALLSTATE_DISCONNECTED, LINEDISCONNECTMODE_NORMAL);

	PppoeTerminate(a);

	FLEAVE("setTapiDrop");
	return NDIS_STATUS_SUCCESS;
}

// OID_TAPI_SET_STATUS_MESSAGES
static NDIS_STATUS setTapiSetStatusMessages(PADAPT a, PDATABUF_DESCR buf) {
	NDIS_TAPI_SET_STATUS_MESSAGES *i;
	FENTER("setTapiSetStatusMessages");

	i = (NDIS_TAPI_SET_STATUS_MESSAGES *)buf->data;
	DbgPrint("Supported line messages: 0x%x\n", i->ulLineStates);
	DbgPrint("Supported address messages: 0x%x\n", i->ulAddressStates);

	a->miniReportedLinedevStates = i->ulLineStates & a->miniSupportedLinedevStates;

	FLEAVE("setTapiSetStatusMessages");
	return NDIS_STATUS_SUCCESS;
}

// OID_TAPI_SET_DEFAULT_MEDIA_DETECTION
static NDIS_STATUS setTapiSetDefaultMediaDetection(PADAPT a, PDATABUF_DESCR buf) {
	NDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION *i;
	FENTER("setTapiSetDefaultMediaDetection");

	i = (NDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION *)buf->data;
	DbgPrint("Supported media: 0x%x\n", i->ulMediaModes);

	FLEAVE("setTapiSetDefaultMediaDetection");
	return NDIS_STATUS_SUCCESS;
}

// OID_TAPI_GET_DEV_CAPS:
static NDIS_STATUS queryTapiGetDevCaps(PADAPT a, PDATABUF_DESCR buf) {
	PLINE_DEV_CAPS caps;
	PNDIS_TAPI_GET_DEV_CAPS req;
//	Todo: Uncomment for Windows2000
//	char ProviderInfo[19] = "ISDN\0RMSPPPOE";

	FENTER("queryTapiGetDevCaps");

	req = (PNDIS_TAPI_GET_DEV_CAPS)buf->data;
	caps = &(req->LineDevCaps);

	DbgPrint("ulDeviceId: 0x%x, ulExtVersion: 0x%x\n", req->ulDeviceID, req->ulExtVersion);
	DbgPrint("buf->len=%d, sizeof(CAPS)=%d, TotalSize=%d, NeededSize=%d\n",
			 buf->len, sizeof(LINE_DEV_CAPS), caps->ulTotalSize, caps->ulNeededSize);

	if (req->ulDeviceID != a->miniUlDeviceID) {
		DbgPrint("wrong ulDeviceID\n");

		FLEAVE("queryTapiGetDevCaps");
		return NDIS_STATUS_TAPI_NODRIVER;
	}

	// this should not hurt:
	caps->ulUsedSize = sizeof(*caps);
	caps->ulNeededSize = sizeof(*caps);

    caps->ulPermanentLineID = 1;

    // RASTAPI requires the "MediaType\0DeviceName" be placed in the
    // ProviderInfo field at the end of this structure.

	//	Todo: Uncomment for Windows2000

//	caps->ulNeededSize += 14;
//	caps->ulUsedSize += 14;
//	caps->ulProviderInfoSize = 14;
//	caps->ulProviderInfoOffset = sizeof(*caps);
//	NdisMoveMemory((PUCHAR)caps + caps->ulProviderInfoOffset, ProviderInfo, 14);
    caps->ulStringFormat = STRINGFORMAT_ASCII;

	caps->ulAddressModes = LINEADDRESSMODE_ADDRESSID |
                           LINEADDRESSMODE_DIALABLEADDR;
    caps->ulNumAddresses = 1;
    caps->ulBearerModes  = LINEBEARERMODE_DATA;
    caps->ulMaxRate      = a->protoLinkSpeed;
    caps->ulMediaModes   = LINEMEDIAMODE_DIGITALDATA;

    // Each line on the DSU only supports a single call.
    caps->ulDevCapFlags = LINEDEVCAPFLAGS_CLOSEDROP;
    caps->ulMaxNumActiveCalls = 1;
    caps->ulAnswerMode = LINEANSWERMODE_DROP;
    caps->ulRingModes  = 1;
    caps->ulLineStates = a->miniSupportedLinedevStates;

	FLEAVE("queryTapiGetDevCaps");
	return NDIS_STATUS_SUCCESS;
}

// OID_TAPI_SECURE_CALL
static NDIS_STATUS queryTapiSecureCall(PADAPT a, PDATABUF_DESCR buf) {
	FENTER("queryTapiSecureCall");
	FLEAVE("queryTapiSecureCall");
	return NDIS_STATUS_SUCCESS;
}

// OID_TAPI_OPEN
static NDIS_STATUS queryTapiOpen(PADAPT a, PDATABUF_DESCR buf) {
	NDIS_TAPI_OPEN *i;
	ULONG packetFilter = NDIS_PACKET_TYPE_DIRECTED /*| NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_MULTICAST*/;
	NDIS_STATUS status;

	FENTER("queryTapiOpen");

	i = (NDIS_TAPI_OPEN *)buf->data;

	if (i->ulDeviceID != a->miniUlDeviceID) {
		DbgPrint("wrong ulDeviceID\n");

		FLEAVE("queryTapiOpen");
		return NDIS_STATUS_FAILURE;
	}

	a->miniHtLine = i->htLine;
	i->hdLine = (ULONG)a;

	MiniEnterLinedevState(a, LINEDEVSTATE_OPEN);	

	FLEAVE("queryTapiOpen");
	return NDIS_STATUS_SUCCESS;
}


// OID_TAPI_MAKE_CALL
static NDIS_STATUS queryTapiMakeCall(PADAPT a, PDATABUF_DESCR buf) {
	NDIS_TAPI_MAKE_CALL *i;
	NDIS_STATUS s;

	FENTER("queryTapiMakeCall");

	i = (NDIS_TAPI_MAKE_CALL *)buf->data;

	if (i->hdLine != (ULONG)a) {
		DbgPrint("wrong hdLine\n");

		FLEAVE("queryTapiMakeCall");
		return NDIS_STATUS_TAPI_INVALLINEHANDLE;
	}

	if (a->miniCallState != LINECALLSTATE_IDLE) {
		DbgPrint("line used\n");

		FLEAVE("queryTapiMakeCall");
		return NDIS_STATUS_TAPI_INUSE;
	}

	a->miniHtCall = i->htCall;
	i->hdCall = (ULONG)a;

	DbgPrint("dest address size: %d\n", i->ulDestAddressSize);
	if (i->ulDestAddressSize > 0) {
		char buf[100];
		NdisMoveMemory(buf, (PCHAR)i + i->ulDestAddressOffset,
					   i->ulDestAddressSize > 100 ? 100 : i->ulDestAddressSize);
		buf[i->ulDestAddressSize > 100 ? 100 : i->ulDestAddressSize] = 0;
		DbgPrint("address: %s\n", buf);
	}

	MiniEnterCallState(a, LINECALLSTATE_DIALING, 0);

	s = PppoeConnect(a, (PCHAR)i + i->ulDestAddressOffset, i->ulDestAddressSize);
	if (s != NDIS_STATUS_SUCCESS) {
		DbgPrint("pppoe connect failed: 0x%x\n", s);
		MiniEnterCallState(a, LINECALLSTATE_IDLE, 0); // God knows what this will give us
	}

	FLEAVE("queryTapiMakeCall");
	return s;
}

// OID_TAPI_GET_ID
static NDIS_STATUS queryTapiGetId(PADAPT a, PDATABUF_DESCR buf) {
	NDIS_STATUS ret = NDIS_STATUS_TAPI_INVALDEVICECLASS;
	ULONG deviceId;

	NDIS_TAPI_GET_ID *i;

	FENTER("queryTapiGetId");

	i = (NDIS_TAPI_GET_ID *)buf->data;

	DbgPrint("device class: %s, ulSelect: 0x%x\n", (PCHAR)i + i->ulDeviceClassOffset,
			 i->ulSelect);

    if (_strnicmp((PCHAR)i + i->ulDeviceClassOffset, "ndis", i->ulDeviceClassSize) == 0) {
		if (i->ulSelect == LINECALLSELECT_CALL) {
            // This must match ConnectionWrapperID used in LINE_UP event!
			DbgPrint("DeviceId: %u\n", a->miniNdisLinkContext);
			deviceId = (ULONG)a->miniNdisLinkContext;
			ret = NDIS_STATUS_SUCCESS;
		}
		else DbgPrint("ulSelect != LINECALLSELECT_CALL\n");
    }
    else if (_strnicmp((PCHAR)i + i->ulDeviceClassOffset, "tapi/line",
			 i->ulDeviceClassSize) == 0) {
		if (i->ulSelect == LINECALLSELECT_LINE) {
            // TAPI just wants the ulDeviceID for this line.
			deviceId = (ULONG)a->miniUlDeviceID;
			ret = NDIS_STATUS_SUCCESS;
		}
		else DbgPrint("ulSelect != LINECALLSELECT_LINE\n");
	}
	else DbgPrint("unknown device class\n");

	if (ret == NDIS_STATUS_SUCCESS) {
		i->DeviceID.ulNeededSize = sizeof(VAR_STRING) + sizeof(deviceId);
		if (i->DeviceID.ulTotalSize >= i->DeviceID.ulNeededSize) {
			i->DeviceID.ulUsedSize = i->DeviceID.ulNeededSize;
			i->DeviceID.ulStringFormat = STRINGFORMAT_BINARY;
			i->DeviceID.ulStringSize = sizeof(deviceId);
			i->DeviceID.ulStringOffset = sizeof(VAR_STRING);

			NdisMoveMemory((PCHAR)&i->DeviceID + sizeof(VAR_STRING),
						   (PCHAR)&deviceId, sizeof(deviceId));
		}
	}

	FLEAVE("queryTapiGetId");
	return ret;
}

// OID_TAPI_GET_CALL_STATUS
static NDIS_STATUS queryTapiGetCallStatus(PADAPT a, PDATABUF_DESCR buf) {
	NDIS_TAPI_GET_CALL_STATUS *i;

	FENTER("queryTapiGetCallStatus");

	i = (NDIS_TAPI_GET_CALL_STATUS *)buf->data;

	if (i->hdCall != (ULONG)a) {
		DbgPrint("wrong hdCall\n");

		FLEAVE("queryTapiGetCallStatus");
		return NDIS_STATUS_TAPI_INVALCALLHANDLE;
	}

    i->LineCallStatus.ulNeededSize = sizeof(i->LineCallStatus);
    i->LineCallStatus.ulUsedSize = sizeof(i->LineCallStatus);

    // The link has all the call information.
    i->LineCallStatus.ulCallPrivilege = LINECALLPRIVILEGE_OWNER;
    i->LineCallStatus.ulCallState = a->miniCallState;

    // Tag CallStateMode with appropriate value for the current CallState.
    if (a->miniCallState == LINECALLSTATE_BUSY) {
        i->LineCallStatus.ulCallStateMode = LINEBUSYMODE_STATION;
    }
    else if (a->miniCallState == LINECALLSTATE_DISCONNECTED) {
        i->LineCallStatus.ulCallStateMode = LINEDISCONNECTMODE_UNKNOWN;
    }
    
	FLEAVE("queryTapiGetCallStatus");
	return NDIS_STATUS_SUCCESS;
}

// OID_TAPI_GET_CALL_INFO
static NDIS_STATUS queryTapiGetCallInfo(PADAPT a, PDATABUF_DESCR buf) {
	NDIS_TAPI_GET_CALL_INFO *i;

	FENTER("queryTapiGetCallInfo");

	i = (NDIS_TAPI_GET_CALL_INFO *)buf->data;

	if (i->hdCall != (ULONG)a) {
		DbgPrint("wrong hdCall\n");

		FLEAVE("queryTapiGetCallInfo");
		return NDIS_STATUS_TAPI_INVALCALLHANDLE;
	}

    i->LineCallInfo.ulNeededSize = sizeof(i->LineCallInfo);
    i->LineCallInfo.ulUsedSize = sizeof(i->LineCallInfo);

    // The link has all the call information we need to return.

⌨️ 快捷键说明

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