该程序处理ICMP消息队列(系统ping)。我需要修改接收的数据(函数swap_bytes - 下面的代码)并重新计算ICMP校验和。所以我有一个类似的回调函数:
static int callback(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
struct nfq_data *nfa, void *data) {
u_int32_t id; /* ID packet. */
unsigned short checksum;
int payload_len;
unsigned char *payloadData;
struct icmphdr *icmp_header;
/* Some informations about the packet: */
//id = print_packet(nfa);
//fprintf(stdout, "Leaving callback.\n\n");
/* Modification */
payload_len = nfq_get_payload(nfa, &payloadData);
icmp_header = (struct icmphdr *)payloadData;
swap_bytes(payloadData, payload_len);
icmp_header->checksum = 0;
checksum = internet_checksum(
(unsigned short *)&icmp_header,
payload_len+sizeof(struct icmphdr)
);
icmp_header->checksum = (checksum == 0) ? 0xffff : checksum;
/* verdict */
return nfq_set_verdict(qh, id, NF_ACCEPT, payload_len, payloadData);
}
swap_bytes函数:
unsigned char* swap_bytes(unsigned char *data, unsigned int data_length) {
unsigned char tmp;
unsigned char *head, *tail;
head = data;
tail = &data[data_length - 1];
while (head < tail) {
tmp = *head;
*head = *tail;
*tail = tmp;
head++;
tail--;
}
return data;
}
计算校验和:
unsigned short internet_checksum(unsigned short *addr, int count) {
register int sum = 0;
while (count > 1) {
sum += *addr++;
count -= 2;
}
if (count > 0) {
sum += *(unsigned char *) addr;
}
while (sum >> 16) {
sum = (sum & 0xffff) + (sum >> 16);
}
return (~sum);
}
问题是校验和计算不正确,因为我没有收到ICMP回复。我尝试了很多没有结果的方法。谢谢你的帮助。