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

📄 protocol.c

📁 pppoe在windows实现的miniport驱动源代码
💻 C
📖 第 1 页 / 共 2 页
字号:

	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 + -