📄 protocol.c
字号:
p = (PPPOE_PACKET *)hbuf;
// check if we can accept this packet
if((p->proto != 0x6388) && (p->proto != 0x6488)) {
FLEAVE("ProtoReceive");
return NDIS_STATUS_NOT_ACCEPTED;
}
switch(a->pppoeState) {
case PPPOE_STATE_SESSION:
break;
case PPPOE_STATE_PADI:
case PPPOE_STATE_PADR:
if (p->proto != 0x6388) {
FLEAVE("ProtoReceive");
return NDIS_STATUS_NOT_ACCEPTED;
}
break;
default:
FLEAVE("ProtoReceive");
return NDIS_STATUS_NOT_ACCEPTED;
}
// allocate new buffer
newp = PacketAllocate(totalSize);
if (!newp) {
DbgPrint("can not allocate new packet\n");
FLEAVE("ProtoReceive");
return NDIS_STATUS_FAILURE;
}
// copy information that we already have
NdisMoveMemory(newp, hbuf, 14);
NdisMoveMemory((PVOID)((ULONG)newp + 14), lookaheadbuf, lookaheadbufsize);
// see if we have all packet
if (size <= lookaheadbufsize) {
ProtoQueuePacket(a, newp, totalSize);
FLEAVE("ProtoReceive");
return NDIS_STATUS_SUCCESS;
}
NdisAllocatePacket(&s, &packet, a->pppoePacketPoolHandle);
if (s != NDIS_STATUS_SUCCESS) {
DbgPrint("can not allocate packet\n");
goto packet_failed;
}
NdisAllocateBuffer(&s, &buffer, a->pppoeBufferPoolHandle, (PVOID)((ULONG)newp + 14 + lookaheadbufsize),
size - lookaheadbufsize);
if (s != NDIS_STATUS_SUCCESS) {
DbgPrint("can not allocate buffer\n");
goto buffer_failed;
}
NdisChainBufferAtFront(packet, buffer);
pinfo = (PRECEIVE_PROTOINFO)packet->ProtocolReserved;
pinfo->pppoePacket = newp;
pinfo->pppoePacketLen = totalSize;
NdisTransferData(&s, a->protoBindingHandle, mrc, lookaheadbufsize, size - lookaheadbufsize, packet, &bTrans);
switch(s) {
case NDIS_STATUS_SUCCESS:
ProtoTransferDataComplete(a, packet, NDIS_STATUS_SUCCESS, bTrans);
// fall through
case NDIS_STATUS_PENDING:
FLEAVE("ProtoReceive");
return NDIS_STATUS_SUCCESS;
}
NdisFreeBuffer(buffer);
buffer_failed:
NdisFreePacket(packet);
packet_failed:
PacketFree(newp, totalSize);
FLEAVE("ProtoReceive");
return NDIS_STATUS_FAILURE;
}
static void ProtoReceiveComplete(NDIS_HANDLE pbc) {
PADAPT a = (PADAPT)pbc;
LOCK_STATE lockState;
int tmp;
PRECEIVED_PACKET_LIST b;
FENTER("ProtoReceiveComplete");
NdisAcquireReadWriteLock(&a->protoReceivedPacketsLock, TRUE, &lockState);
while (a->protoReceivedPackets != NULL) {
// unlink
b = a->protoReceivedPackets;
a->protoReceivedPackets = b->next;
for(tmp = 0; tmp < (b->packet->len > 64 ? 64 : b->packet->len); tmp++) {
DbgPrint("%2.2X ", (unsigned)b->packet->data[tmp]);
if((tmp % 16) == 15) DbgPrint("\n");
}
DbgPrint("\n");
// handle and free
if (b->packet->proto == 0x6388) {
PppoeReceiveDiscovery(a, b->packet, b->total_size);
}
else {
PppoeReceiveSession(a, b->packet, b->total_size);
}
PacketFree(b->packet, b->total_size);
}
a->protoReceivedPacketLast = NULL;
NdisReleaseReadWriteLock(&a->protoReceivedPacketsLock, &lockState);
FLEAVE("ProtoReceiveComplete");
}
static void ProtoBindAdapter(PNDIS_STATUS binds, NDIS_HANDLE bindc, PNDIS_STRING devname,
PVOID sys1, PVOID sys2) {
NDIS_STATUS status;
NDIS_HANDLE configHandle;
PADAPTER a;
UINT medium;
WCHAR regPath[256];
PNDIS_STRING regStr = (PNDIS_STRING)sys1;
FENTER("ProtoBindAdapter");
DbgPrint("device name: ");
PrintUnicodeStr(devname);
DbgPrint("\n");
// allocate ADAPTER
a = AdapterCreate();
if (a == NULL) {
DbgPrint("can not allocate adapter structure\n");
*binds = NDIS_STATUS_FAILURE;
FLEAVE("ProtoBindAdapter");
return;
}
// ask everybody to set up fields in ADAPTER
ProtoInitAdapter(a);
MiniInitAdapter(a);
PppoeInitAdapter(a);
// open configuration in registry
NdisMoveMemory(regPath, regStr->Buffer, regStr->Length * sizeof(WCHAR));
NdisOpenProtocolConfiguration(binds, &configHandle, sys1);
if (*binds != NDIS_STATUS_SUCCESS) {
DbgPrint("failed to open config\n");
goto err_out;
}
PrintUnicodeStr((PNDIS_STRING)sys1);
DbgPrint("\n");
// ask everyone to read in their configuration
*binds = ProtoReadConfig(a, configHandle, regPath);
if (*binds != NDIS_STATUS_SUCCESS) goto config_read_err;
// close config
NdisCloseConfiguration(configHandle);
// save bind context as we will need it in OpenAdapterComplete and OpenAdapter
a->protoBindContext = bindc;
NdisOpenAdapter(binds, &status, &a->protoBindingHandle, &medium,
MediumArray, DIM_MEDIUM_ARRAY,
mainProtocolHandle, (NDIS_HANDLE)a,
devname, 0, NULL);
DbgPrint("NdisOpenAdapter over, status: %d\n", *binds);
if (*binds != NDIS_STATUS_SUCCESS && *binds != NDIS_STATUS_PENDING) {
DbgPrint("NdisOpenAdapter failed\n");
AdapterFree(a);
FLEAVE("ProtoBindAdapter");
return;
}
if (*binds == NDIS_STATUS_SUCCESS) {
DbgPrint("NdisOpenAdapter == NDIS_STATUS_SUCCESS\n");
ProtoFinishBind(a);
}
else DbgPrint("NdisOpenAdapter == NDIS_STATUS_PENDING\n");
FLEAVE("ProtoBindAdapter");
return;
config_read_err:
NdisCloseConfiguration(configHandle);
err_out:
AdapterFree(a);
FLEAVE("ProtoBindAdapter");
return;
}
static VOID protoFinishUnbind(PADAPT a) {
FENTER("protoFinishUnbind");
if(a->protoReceivedPackets || a->protoReceivedPacketLast) {
DbgPrint("ERROR- received packets list is not empty\n");
}
NdisDeleteNPagedLookasideList(&a->protoReceivedPacketsLookasideList);
NdisFreeBufferPool(a->pppoeBufferPoolHandle);
NdisFreePacketPool(a->pppoePacketPoolHandle);
FLEAVE("protoFinishUnbind");
}
static void ProtoCloseAdapterComplete(NDIS_HANDLE pbc, NDIS_STATUS status) {
FENTER("ProtoCloseAdapterComplete");
if(status != NDIS_STATUS_SUCCESS) {
DbgPrint("Could not complete close adapter\n");
} else {
protoFinishUnbind((PADAPT)pbc);
}
FLEAVE("ProtoCloseAdapterComplete");
}
static VOID ProtoUnbindAdapter(PNDIS_STATUS status,
NDIS_HANDLE pbc, NDIS_HANDLE unbindc) {
NDIS_STATUS s;
PADAPT a = (PADAPT)pbc;
FENTER("ProtoUnbindAdapter");
if(NdisIMDeInitializeDeviceInstance(a->miniAdapterHandle) != NDIS_STATUS_SUCCESS) {
DbgPrint("Could not deinitialize miniport\n");
}
NdisCloseAdapter(&s, a->protoBindingHandle);
*status = s;
if(s == NDIS_STATUS_SUCCESS) {
protoFinishUnbind(a);
} else if(s == NDIS_STATUS_PENDING) {
} else {
DbgPrint("Could not close adapter\n");
}
FLEAVE("ProtoUnbindAdapter");
}
static NDIS_STATUS ProtoPNPEvent(NDIS_HANDLE pbc, PNET_PNP_EVENT e) {
FENTER("ProtoPNPEvent");
switch(e->NetEvent) {
case NetEventSetPower:
DbgPrint("NetEventSetPower\n");
break;
case NetEventQueryPower:
DbgPrint("NetEventQueryPower\n");
break;
case NetEventQueryRemoveDevice:
DbgPrint("NetEventQueryRemoveDevice\n");
FLEAVE("ProtoPNPEvent");
return NDIS_STATUS_FAILURE;
case NetEventCancelRemoveDevice:
DbgPrint("NetEventCancelRemoveDevice\n");
break;
case NetEventReconfigure:
DbgPrint("NetEventReconfigure\n");
break;
case NetEventBindList:
DbgPrint("NetEventBindList\n");
break;
case NetEventBindsComplete:
DbgPrint("NetEventBindsComplete\n");
break;
case NetEventPnPCapabilities:
DbgPrint("NetEventPnPCapabilities\n");
break;
case NetEventMaximum:
DbgPrint("NetEventMaximum\n");
break;
default:
DbgPrint("Unknown NetEvent\n");
break;
}
FLEAVE("ProtoPNPEvent");
return NDIS_STATUS_SUCCESS;
}
void SetupProtocolCfg(PNDIS_PROTOCOL_CHARACTERISTICS cfg) {
FENTER("SetupProtocolCfg");
cfg->MajorNdisVersion = 4;
cfg->MinorNdisVersion = 0;
cfg->BindAdapterHandler = ProtoBindAdapter;
cfg->UnbindAdapterHandler = ProtoUnbindAdapter;
cfg->OpenAdapterCompleteHandler = ProtoOpenAdapterComplete;
cfg->CloseAdapterCompleteHandler = ProtoCloseAdapterComplete;
cfg->ReceiveHandler = ProtoReceive;
cfg->ReceiveCompleteHandler = ProtoReceiveComplete;
cfg->TransferDataCompleteHandler = ProtoTransferDataComplete;
cfg->ResetCompleteHandler = ProtoResetComplete;
cfg->RequestCompleteHandler = ProtoRequestComplete;
cfg->SendCompleteHandler = ProtoSendComplete;
cfg->StatusHandler = ProtoStatus;
cfg->StatusCompleteHandler = ProtoStatusComplete;
cfg->PnPEventHandler = ProtoPNPEvent;
FLEAVE("SetupProtocolCfg");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -