Reply To: Изменение пакета

Home Forums Discussions Support Изменение пакета Reply To: Изменение пакета

#9600
Vadim Smirnov
Keymaster

    Примера для C#, к сожалению нет, в следующих версиях соответствующие функции будут добавлены к ndisapi.dll, но ничего не мешает сделать сейчас:

    //
    // Function recalculates IP checksum
    //
    void
    CNdisApi::RecalculateIPChecksum(
    	PINTERMEDIATE_BUFFER pPacket
    )
    {
    	unsigned short word16;
    	unsigned int sum = 0;
    	unsigned int i = 0;
    	PUCHAR buff;
    
    	iphdr_ptr pIpHeader = (iphdr_ptr)&pPacket->m_IBuffer[sizeof(ether_header)];
    
    	// Initialize checksum to zero
    	pIpHeader->ip_sum = 0;
    	buff = (PUCHAR)pIpHeader;
    
    	// Calculate IP header checksum
    	for (i = 0; i < pIpHeader->ip_hl * sizeof(DWORD); i = i + 2)
    	{
    		word16 = ((buff[i] << 8) & 0xFF00) + (buff[i + 1] & 0xFF);
    		sum = sum + word16;
    	}
    
    	// keep only the last 16 bits of the 32 bit calculated sum and add the carries
    	while (sum >> 16)
    		sum = (sum & 0xFFFF) + (sum >> 16);
    
    	// Take the one's complement of sum
    	sum = ~sum;
    
    	pIpHeader->ip_sum = htons((unsigned short)sum);
    }
    
    //
    // Function recalculates ICMP checksum
    //
    void
    CNdisApi::RecalculateICMPChecksum(
    	PINTERMEDIATE_BUFFER pPacket
    )
    {
    	unsigned short word16, padd = 0;
    	unsigned int i, sum = 0;
    	PUCHAR buff;
    	DWORD dwIcmpLen;
    	icmphdr_ptr pIcmpHeader = NULL;
    	iphdr_ptr pIpHeader = (iphdr_ptr)&pPacket->m_IBuffer[sizeof(ether_header)];
    
    	// Sanity check
    	if (pIpHeader->ip_p == IPPROTO_ICMP)
    	{
    		pIcmpHeader = (icmphdr_ptr)(((PUCHAR)pIpHeader) + sizeof(DWORD)*pIpHeader->ip_hl);
    	}
    	else
    		return;
    
    	dwIcmpLen = ntohs(pIpHeader->ip_len) - pIpHeader->ip_hl * 4;
    
    	if ((dwIcmpLen / 2) * 2 != dwIcmpLen)
    	{
    		padd = 1;
    		pPacket->m_IBuffer[dwIcmpLen + pIpHeader->ip_hl * 4 + sizeof(ether_header)] = 0;
    	}
    
    	buff = (PUCHAR)pIcmpHeader;
    	pIcmpHeader->checksum = 0;
    
    	// make 16 bit words out of every two adjacent 8 bit words and 
    	// calculate the sum of all 16 bit words
    	for (i = 0; i< dwIcmpLen + padd; i = i + 2) {
    		word16 = ((buff[i] << 8) & 0xFF00) + (buff[i + 1] & 0xFF);
    		sum = sum + (unsigned long)word16;
    	}
    
    	// keep only the last 16 bits of the 32 bit calculated sum and add the carries
    	while (sum >> 16)
    		sum = (sum & 0xFFFF) + (sum >> 16);
    
    	// Take the one's complement of sum
    	sum = ~sum;
    
    	pIcmpHeader->checksum = ntohs((unsigned short)sum);
    }
    
    //
    // Function recalculates TCP checksum
    //
    void
    CNdisApi::RecalculateTCPChecksum(
    	PINTERMEDIATE_BUFFER pPacket
    )
    {
    	tcphdr_ptr pTcpHeader = NULL;
    	unsigned short word16, padd = 0;
    	unsigned int i, sum = 0;
    	PUCHAR buff;
    	DWORD dwTcpLen;
    
    	iphdr_ptr pIpHeader = (iphdr_ptr)&pPacket->m_IBuffer[sizeof(ether_header)];
    
    	// Sanity check
    	if (pIpHeader->ip_p == IPPROTO_TCP)
    	{
    		pTcpHeader = (tcphdr_ptr)(((PUCHAR)pIpHeader) + sizeof(DWORD)*pIpHeader->ip_hl);
    	}
    	else
    		return;
    
    	dwTcpLen = ntohs(pIpHeader->ip_len) - pIpHeader->ip_hl * 4;//pPacket->m_Length - ((PUCHAR)(pTcpHeader) - pPacket->m_IBuffer);
    
    	if ((dwTcpLen / 2) * 2 != dwTcpLen)
    	{
    		padd = 1;
    		pPacket->m_IBuffer[dwTcpLen + pIpHeader->ip_hl * 4 + sizeof(ether_header)] = 0;
    	}
    
    	buff = (PUCHAR)pTcpHeader;
    	pTcpHeader->th_sum = 0;
    
    	// make 16 bit words out of every two adjacent 8 bit words and 
    	// calculate the sum of all 16 vit words
    	for (i = 0; i< dwTcpLen + padd; i = i + 2) {
    		word16 = ((buff[i] << 8) & 0xFF00) + (buff[i + 1] & 0xFF);
    		sum = sum + (unsigned long)word16;
    	}
    
    	// add the TCP pseudo header which contains:
    	// the IP source and destination addresses,
    
    	sum = sum + ntohs(pIpHeader->ip_src.S_un.S_un_w.s_w1) + ntohs(pIpHeader->ip_src.S_un.S_un_w.s_w2);
    	sum = sum + ntohs(pIpHeader->ip_dst.S_un.S_un_w.s_w1) + ntohs(pIpHeader->ip_dst.S_un.S_un_w.s_w2);
    
    	// the protocol number and the length of the TCP packet
    	sum = sum + IPPROTO_TCP + (unsigned short)dwTcpLen;
    
    	// keep only the last 16 bits of the 32 bit calculated sum and add the carries
    	while (sum >> 16)
    		sum = (sum & 0xFFFF) + (sum >> 16);
    
    	// Take the one's complement of sum
    	sum = ~sum;
    
    	pTcpHeader->th_sum = htons((unsigned short)sum);
    }
    
    //
    // Function recalculates UDP checksum
    //
    void
    CNdisApi::RecalculateUDPChecksum(
    	PINTERMEDIATE_BUFFER pPacket
    )
    {
    	udphdr_ptr pUdpHeader = NULL;
    	unsigned short word16, padd = 0;
    	unsigned int i, sum = 0;
    	PUCHAR buff;
    	DWORD dwUdpLen;
    
    	iphdr_ptr pIpHeader = (iphdr_ptr)&pPacket->m_IBuffer[sizeof(ether_header)];
    
    	// Sanity check
    	if (pIpHeader->ip_p == IPPROTO_UDP)
    	{
    		pUdpHeader = (udphdr_ptr)(((PUCHAR)pIpHeader) + sizeof(DWORD)*pIpHeader->ip_hl);
    	}
    	else
    		return;
    
    	dwUdpLen = ntohs(pIpHeader->ip_len) - pIpHeader->ip_hl * 4;//pPacket->m_Length - ((PUCHAR)(pTcpHeader) - pPacket->m_IBuffer);
    
    	if ((dwUdpLen / 2) * 2 != dwUdpLen)
    	{
    		padd = 1;
    		pPacket->m_IBuffer[dwUdpLen + pIpHeader->ip_hl * 4 + sizeof(ether_header)] = 0;
    	}
    
    	buff = (PUCHAR)pUdpHeader;
    	pUdpHeader->th_sum = 0;
    
    	// make 16 bit words out of every two adjacent 8 bit words and 
    	// calculate the sum of all 16 vit words
    	for (i = 0; i< dwUdpLen + padd; i = i + 2) {
    		word16 = ((buff[i] << 8) & 0xFF00) + (buff[i + 1] & 0xFF);
    		sum = sum + (unsigned long)word16;
    	}
    
    	// add the UDP pseudo header which contains:
    	// the IP source and destination addresses,
    
    	sum = sum + ntohs(pIpHeader->ip_src.S_un.S_un_w.s_w1) + ntohs(pIpHeader->ip_src.S_un.S_un_w.s_w2);
    	sum = sum + ntohs(pIpHeader->ip_dst.S_un.S_un_w.s_w1) + ntohs(pIpHeader->ip_dst.S_un.S_un_w.s_w2);
    
    	// the protocol number and the length of the UDP packet
    	sum = sum + IPPROTO_UDP + (unsigned short)dwUdpLen;
    
    	// keep only the last 16 bits of the 32 bit calculated sum and add the carries
    	while (sum >> 16)
    		sum = (sum & 0xFFFF) + (sum >> 16);
    
    	// Take the one's complement of sum
    	sum = ~sum;
    
    	pUdpHeader->th_sum = ntohs((unsigned short)sum);
    }