내 PC로 들어오는 ip 패킷을 수정하려고합니다. iptables를 사용하여 패킷을 큐에 넣고 libnetfilter_queue 라이브러리를 사용하여 실제로는 일부 http-header 내용을 수정합니다. 단일 문자를 변경하더라도 패킷은 TCP 체크섬의 변경으로 인해 거부됩니다. 그래서, 수정 된 패킷의 TCP 체크섬을 다시 계산하려고합니다. 처음에는 체크섬 기능을 테스트하기 위해 패킷을 수정하는 것이 아니라 단순히 체크섬을 다시 계산합니다. 그러나 계산 된 체크섬은 원래의 체크섬과 일치하지 않습니다. `여기서계산 된 tcp checksum과 원래 tcp checksum이 일치하지 않습니다.
unsigned short tcp_sum_calc(unsigned short len_tcp, unsigned short src_addr[],unsigned short dest_addr[], unsigned short buff[])
{
unsigned char prot_tcp=6;
unsigned long sum;
int nleft;
unsigned short *w;
sum = 0;
nleft = len_tcp;
w=buff;
/* calculate the checksum for the tcp header and payload */
while(nleft > 1)
{
sum = sum + ntohs(*w);
w++;
nleft = nleft - 2;
}
/* if nleft is 1 there ist still on byte left. We add a padding byte (0xFF) to build a 16bit word */
if(nleft>0)
{
cout<<"check out";
// sum += *w&0xFF;
sum += ntohs(*w&0xFF00); // is this the correct way of doing
}
/* add the pseudo header */
sum += ntohs(src_addr[0]);
sum += ntohs(src_addr[1]);
sum += ntohs(dest_addr[0]);
sum += ntohs(dest_addr[1]);
sum += len_tcp;
sum += prot_tcp;
// keep only the last 16 bits of the 32 bit calculated sum and add the carries
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
// Take the one's complement of sum
sum = ~sum;
return ((unsigned short) sum);
}
libnetfilter_queue 모듈의 콜백 함수이다 : 여기서
static int analyzeResponse(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,struct nfq_data *nfa, void *data)
{
int len=0,id=0;
struct iphdr *ip;
struct tcphdr *tcp;
char *pktData;
string tempPkt;
unsigned short chksum=0,ip_hdr_len,tcp_len;
unsigned int src_ip, des_ip;
struct nfqnl_msg_packet_hdr *pktHeader;
pktHeader = nfq_get_msg_packet_hdr(nfa);
if (pktHeader)
{
id = ntohl(pktHeader->packet_id);
}
len = nfq_get_payload ((struct nfq_data *) nfa, (char**)&ip);
if(len)
{
pktData=(char*)ip;
ip_hdr_len=(unsigned short)(pktData[0]&0x7);
src_ip=ip->saddr;
des_ip=ip->daddr;
int pos;
tempPkt.assign(pktData,len);
pos=tempPkt.find("teststring",0);
tempPkt.replace("teststring");
pktData=(char*)tempPkt.c_str();
tcp = (struct tcphdr*) (pktData + (4*ip_hdr_len));
cout<<"*********************************************************************************";
cout<<ip_hdr_len;
cout<<"\ntcp checksum: "<<tcp->check;
cout<<"\nip packet length: "<<ip->tot_len;
cout<<"\nip packet length_calc: "<<len;
cout<<"\nip source address: "<<src_ip;
cout<<"\nip destination address: "<<des_ip;
cout<<"*********************************************************************************";
tcp->check=0;
tcp_len=len - (4*ip_hdr_len);
chksum = tcp_sum_calc(tcp_len, (unsigned short *) &src_ip, (unsigned short *) &des_ip, (unsigned short *) &tcp);
tcp->check=chksum;
cout<<"\nnew checkksum: "<<chksum;
return nfq_set_verdict(qh, id, NF_ACCEPT, len, (unsigned char*)pktData);
}
return nfq_set_verdict(qh, id, NF_ACCEPT, len, (unsigned char*)pktData);
}
출력된다
5
tcp checksum: 11687
ip packet length: 54017
ip packet length_calc: 467
ip source address: 1719453657
ip destination address: 2569775296
new checkksum: 36507
`
나는 필요한 수정을했다. 그러나 아직도 작동하지 않는다. –
@adnankamili 그것은 아직도 작동하지 않는다. .. 그러나 행동은 바뀌 었 느냐? –
예 행동이 바뀌 었습니다. 아무도 수정 된 코드를 게시 할 수 있습니까? –