Home › Forums › Discussions › Support › Изменение пакета › Reply To: Изменение пакета
June 8, 2017 at 9:08 am
#9600
Примера для 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);
}