📄 ubd_sys.c
字号:
);
}
}
__except (EXCEPTION_EXECUTE_HANDLER){
DbgPrint("SentToNet error\n");
}
//kAo 这里不再负责回收pSendList! bug fixed
//ExFreePool(pSendList);
IoQueueWorkItem(g_pSendIoWorkItem,
SendIoWorkItemRoutine,
DelayedWorkQueue,
NULL
);
}
//--------------------------------------------------------------------
//存入列表时,AddSendDAtAToList负责分配buffer,释放buffer由RemoveSendDAtAFromList 完成,在收到ACK的时候调用
NTSTATUS
AddSendDAtAToList(PSENDLISTHEAD pSendListHeAd,char* dAtA,ULONG SendDAtALength,PTCPS_Connection pConnection)
{
NTSTATUS dwStAtus = STATUS_UNSUCCESSFUL;
KIRQL kOldIrql;
PSENDLIST pSendList;
PETHHDR pEthHdr = NULL;
PIPHDR pIpHdr = NULL;
PTCPHDR pTcpHdr = NULL;
pEthHdr = (PVOID)dAtA;
pIpHdr = (PIPHDR)((UCHAR*)pEthHdr + sizeof(ETHHDR));//heAder
pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4);//heAder
//这里要用不分页内存
pSendList = (PSENDLIST)ExAllocatePool(NonPagedPool,sizeof(SENDLIST));
if(pSendList){
//DbgPrint("AddSendDAtAToList AllocAte Memory = 0x0%x\n",pSendList); //debug
pSendList->pNext = NULL;
pSendList->pBuffer = ExAllocatePool(NonPagedPool,SendDAtALength);
RtlCopyMemory(pSendList->pBuffer,dAtA,SendDAtALength);
pSendList->ulBufferLength = SendDAtALength;
pSendList->pConnection = pConnection;
//rst包发过来算消息,不记数,因为他不会被发送,记数也就不会减少
//if(!pTcpHdr->rst){
pSendList->pConnection->m_PAcketsLeftToBeSend++;
//}
KeAcquireSpinLock(&pSendListHeAd->kspSendListLock,&kOldIrql);
if(pSendListHeAd->pListBAck){
pSendListHeAd->pListBAck->pNext = pSendList;
pSendListHeAd->pListBAck = pSendList;
}
else{
pSendListHeAd->pListFront = pSendListHeAd->pListBAck = pSendList;
}
KeReleaseSemaphore(&(g_SendListHeAd.ksemSendListSemAphore),0,1,FALSE);
KeReleaseSpinLock(&pSendListHeAd->kspSendListLock,kOldIrql);//////////
dwStAtus = STATUS_SUCCESS;
}
return dwStAtus;
}
//--------------------------------------------------------------------
//存入列表时,AddSendDAtAToList负责分配buffer,释放buffer由RemoveSendDAtAFromList 完成,在收到ACK的时候调用
NTSTATUS
AddSendDAtAToListAtFront(PSENDLISTHEAD pSendListHeAd,char* dAtA,ULONG SendDAtALength,PTCPS_Connection pConnection)
{
NTSTATUS dwStAtus = STATUS_UNSUCCESSFUL;
KIRQL kOldIrql;
PSENDLIST pSendList;
PETHHDR pEthHdr = NULL;
PIPHDR pIpHdr = NULL;
PTCPHDR pTcpHdr = NULL;
pEthHdr = (PVOID)dAtA;
pIpHdr = (PIPHDR)((UCHAR*)pEthHdr + sizeof(ETHHDR));//heAder
pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4);//heAder
//这里要用不分页内存
pSendList = (PSENDLIST)ExAllocatePool(NonPagedPool,sizeof(SENDLIST));
if(pSendList){
//DbgPrint("AddSendDAtAToList AllocAte Memory = 0x0%x\n",pSendList); //debug
pSendList->pNext = NULL;
pSendList->pBuffer = ExAllocatePool(NonPagedPool,SendDAtALength);
RtlCopyMemory(pSendList->pBuffer,dAtA,SendDAtALength);
pSendList->ulBufferLength = SendDAtALength;
pSendList->pConnection = pConnection;
//rst包发过来算消息,不记数,因为他不会被发送,记数也就不会减少
//if(!pTcpHdr->rst){
pSendList->pConnection->m_PAcketsLeftToBeSend++;
//}
KeAcquireSpinLock(&pSendListHeAd->kspSendListLock,&kOldIrql);
if(pSendListHeAd->pListFront){
pSendList->pNext = pSendListHeAd->pListFront;
pSendListHeAd->pListFront = pSendList;
}
else{
pSendListHeAd->pListFront = pSendListHeAd->pListBAck = pSendList;
}
KeReleaseSemaphore(&(g_SendListHeAd.ksemSendListSemAphore),0,1,FALSE);
KeReleaseSpinLock(&pSendListHeAd->kspSendListLock,kOldIrql);//////////
dwStAtus = STATUS_SUCCESS;
}
return dwStAtus;
}
//--------------------------------------------------------------------
PSENDLIST
ReAdSendDAtAFromList(PSENDLISTHEAD pSendListHeAd)
{
PSENDLIST pSendListCurrent;
pSendListCurrent = pSendListHeAd->pListFront;
return pSendListCurrent;
}
//--------------------------------------------------------------------
VOID
RemoveSendDAtAFromList(PSENDLISTHEAD pSendListHeAd)
{
KIRQL kOldIrql;
PSENDLIST pSendListCurrent;
KeAcquireSpinLock(&pSendListHeAd->kspSendListLock,&kOldIrql);
pSendListCurrent = pSendListHeAd->pListFront;
if(pSendListCurrent){
pSendListHeAd->pListFront = pSendListCurrent->pNext;
if(pSendListCurrent->pConnection->m_PAcketsLeftToBeSend > 0){
pSendListCurrent->pConnection->m_PAcketsLeftToBeSend--;
}else{
DbgPrint("!!error m_PAcketsLeftToBeSend < 0:%d\n",(LONG)pSendListCurrent->pConnection->m_PAcketsLeftToBeSend);
}
if(pSendListHeAd->pListFront == NULL){
pSendListHeAd->pListBAck = NULL;
}
ExFreePool(pSendListCurrent->pBuffer);
ExFreePool(pSendListCurrent);
KeReleaseSpinLock(&(pSendListHeAd->kspSendListLock),kOldIrql);
return;
}
KeReleaseSpinLock(&(pSendListHeAd->kspSendListLock),kOldIrql);
return;
}
//--------------------------------------------------------------------
//uSend把要发送的包全部加到send链表里
NTSTATUS
uSend(
PTCPS_Connection pConnection,
char *pSendBuffer,
ULONG ulSendBufferSize
)
{
PVOID VirtuAlAddress = NULL;
PETHHDR pEthHdrSend = NULL;
PIPHDR pIpHdrSend = NULL;
PTCPHDR pTcpHdrSend = NULL;
PVOID pDAtA = NULL;
ULONG ulTotAlLength = 0;
NTSTATUS stAtus;
ULONG SendCount = 0;
//这里不用计算效验和,,SendToNet会重新算
//SendToNet will recount the checksum
ulTotAlLength = sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR)+ulSendBufferSize;
NdisAllocateMemoryWithTag(
&VirtuAlAddress,
ulTotAlLength,
'ytuU'
);
NdisZeroMemory(
VirtuAlAddress,
sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR)+ulSendBufferSize
);
//填包
pEthHdrSend = VirtuAlAddress;
pIpHdrSend = (PIPHDR)((UCHAR*)pEthHdrSend + sizeof(ETHHDR));//heAder
NdisMoveMemory(&pEthHdrSend->h_dest,&pConnection->m_SourceMAc,6);
NdisMoveMemory(&pEthHdrSend->h_source,&pConnection->m_OurMAc,6);
pEthHdrSend->h_proto = HTONS(ETH_P_IP);
pIpHdrSend->ihl = sizeof(IPHDR)/4;
pIpHdrSend->version = 4;
pIpHdrSend->tos = 0;
pIpHdrSend->tot_len = HTONS(sizeof(IPHDR)+sizeof(TCPHDR)+(USHORT)ulSendBufferSize);
pIpHdrSend->id = 0;
pIpHdrSend->frag_off = 0;
pIpHdrSend->ttl = 255;
pIpHdrSend->protocol = IPPROTO_TCP;
pIpHdrSend->check = 0;//whAt
pIpHdrSend->saddr = pConnection->m_OurIp;
pIpHdrSend->daddr = pConnection->m_SourceIp;
pIpHdrSend->check = checksum((USHORT*)pIpHdrSend,sizeof(IPHDR));
pTcpHdrSend = (PTCPHDR)((UCHAR*)pIpHdrSend + pIpHdrSend->ihl * 4);//heAder
pDAtA = (PVOID)((UCHAR*)pTcpHdrSend + sizeof(TCPHDR));//heAder
pTcpHdrSend->source = pConnection->m_OurPort;
pTcpHdrSend->dest = pConnection->m_SourcePort;
pTcpHdrSend->seq = pConnection->m_Ack_seq;
pTcpHdrSend->ack_seq = pConnection->m_Seq;//seq
pTcpHdrSend->doff = sizeof(TCPHDR)/4;
pTcpHdrSend->syn = 0;
pTcpHdrSend->ack = 1;
pTcpHdrSend->psh = 1;
pTcpHdrSend->window = pConnection->m_Window;
pTcpHdrSend->check = 0;
pTcpHdrSend->urg_ptr = 0;
//填发送的数据
NdisMoveMemory(pDAtA,pSendBuffer,ulSendBufferSize);
//把数据加入到链表
DbgPrint("AddSendDAtAToList\n");
AddSendDAtAToList(
&g_SendListHeAd,
VirtuAlAddress,
ulTotAlLength,
pConnection
);
//释放空间
NdisFreeMemory(
VirtuAlAddress,
0,
0
);
return NDIS_STATUS_SUCCESS;
}
//--------------------------------------------------------------------
VOID EchoPrompt(PTCPS_Connection pConnection)
{
uSend(pConnection,"u>",strlen("u>"));
}
//--------------------------------------------------------------------
//reAlly send
NTSTATUS
SendToNet(
PSENDLIST pSendList
)
{
PNDIS_BUFFER pNdisBuffer = NULL;
PNDIS_PACKET pNdisPAcket = NULL;
NTSTATUS stAtus;
PSDHDR PsdHdrSend;
PVOID ChecksumTempBuff = NULL;
PETHHDR pEthHdrSend = NULL;
PIPHDR pIpHdrSend = NULL;
PTCPHDR pTcpHdrSend = NULL;
PVOID pDAtA = NULL;
ULONG ulDAtALength = 0;
//bug fix 修改seq Ack
pEthHdrSend = pSendList->pBuffer;
pIpHdrSend = (PIPHDR)((UCHAR*)pEthHdrSend + sizeof(ETHHDR));//heAder
pTcpHdrSend = (PTCPHDR)((UCHAR*)pIpHdrSend + pIpHdrSend->ihl * 4);//heAder
pDAtA = (PVOID)((UCHAR*)pTcpHdrSend + sizeof(TCPHDR));//heAder
DbgPrint("send SYN ACK,dest port is %d\n",HTONS(pTcpHdrSend->dest));
ulDAtALength = NTOHS(pIpHdrSend->tot_len) - pIpHdrSend->ihl*4 - sizeof(TCPHDR);
//发包的时候,seq等于上个对方发过来的包的Ack, Ack等于上一个发过来的包的seq加上包中数据的长度,如果没数据就加0了,
//但如果上一个包是syn包,要加1,syn包占一个序列
pTcpHdrSend->check = 0;//注意这里
pTcpHdrSend->seq = pSendList->pConnection->m_Ack_seq;//任意
//回复syn 的Ack包中也有syn标志,所以可以直接检查有tcp头中有没有syn
//if(pSendList->pConnection->m_IsSyn){
if(pTcpHdrSend->syn){
pTcpHdrSend->ack_seq = HTONL(NTOHL(pSendList->pConnection->m_Seq)+1);//seq //debug 这里不确定,需要实验
}else{
pTcpHdrSend->ack_seq = HTONL(NTOHL(pSendList->pConnection->m_Seq)+pSendList->pConnection->m_DAtALength);//seq //debug 这里不确定,需要实验
}
//预期的返回的Ack的seq和Ack
pSendList->pConnection->m_ExpectedSeq = pTcpHdrSend->ack_seq;//////////
DbgPrint("set m_ExpectedSeq in SendToNet: %d\n",pTcpHdrSend->ack_seq);
//if(pSendList->pConnection->m_IsSyn){
if(pTcpHdrSend->syn){
pSendList->pConnection->m_ExpectedAck_seq = HTONL(NTOHL(pTcpHdrSend->seq) + 1);////////////
DbgPrint("set m_ExpectedAck_seq in SendToNet: %d\n",HTONL(NTOHL(pTcpHdrSend->seq) + 1));
}else{
pSendList->pConnection->m_ExpectedAck_seq = HTONL(NTOHL(pTcpHdrSend->seq) + ulDAtALength);////////////
DbgPrint("set m_ExpectedAck_seq in SendToNet: %d\n",HTONL(NTOHL(pTcpHdrSend->seq) + 1));
}
//PsdHdrSend用来计算tcp效验和
PsdHdrSend.saddr = pIpHdrSend->saddr;
PsdHdrSend.daddr = pIpHdrSend->daddr;
PsdHdrSend.mbz = 0;
PsdHdrSend.ptcl = IPPROTO_TCP;
PsdHdrSend.tcpl = HTONS(sizeof(TCPHDR)+(USHORT)ulDAtALength);
//ChecksumTempBuff 为了计算效验和
NdisAllocateMemoryWithTag(
&ChecksumTempBuff,
MAX_PACKET_SIZE,
'pmtU'
);
NdisMoveMemory(ChecksumTempBuff,&PsdHdrSend,sizeof(PSDHDR));
NdisMoveMemory((UCHAR*)ChecksumTempBuff + sizeof(PSDHDR),pTcpHdrSend,sizeof(TCPHDR));
NdisMoveMemory((UCHAR*)ChecksumTempBuff + sizeof(PSDHDR) + sizeof(TCPHDR),pDAtA,ulDAtALength);
pTcpHdrSend->check = checksum((USHORT*)ChecksumTempBuff,sizeof(PSDHDR)+sizeof(TCPHDR)+ulDAtALength);
//释放ChecksumTempBuff
NdisFreeMemory(
ChecksumTempBuff,
0,
0
);
//准备发送
NdisAllocateBuffer(
&stAtus,
&pNdisBuffer,
m_ourBufferPoolHAndle,
pSendList->pBuffer,
pSendList->ulBufferLength
);
if(stAtus != NDIS_STATUS_SUCCESS){
//DbgPrint("NdisAllocAteBuffer fAiled\n");
return TRUE;
}
NdisAllocatePacket(
&stAtus,
&pNdisPAcket,
m_ourPAcketPoolHAndle
);
if(stAtus != NDIS_STATUS_SUCCESS){
//DbgPrint("NdisAllocAtePAcket fAiled\n");
return TRUE;
}
NdisChainBufferAtFront(
pNdisPAcket,
pNdisBuffer
);
NdisSendPackets(
pSendList->pConnection->m_pBindAdaptHandle,
&pNdisPAcket,
1
);
return NDIS_STATUS_SUCCESS;
}
//--------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -