/*
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 dev