我的任务是创建一个利用原始套接字的简单TCP扫描程序。我找到了一个包含所需代码的网页。编写和运行代码没问题,一切似乎都正常。但是,当我尝试在Wireshark中跟踪程序包时,它不存在。我浏览所有接口,我看任何接口,甚至尝试过滤结果,但无济于事。我的目标是从端口20的非循环接口(147.229.206.115)发送到www.google.com(172.217.23.196)以确定是否打开,关闭或过滤了一个程序包。该代码包含ip和tcp的自定义标头,因为我们必须手动设置:
struct ipheader {
unsigned char iph_ihl:5, /* Little-endian */
iph_ver:4;
unsigned char iph_tos;
unsigned short int iph_len;
unsigned short int iph_ident;
unsigned char iph_flags;
unsigned short int iph_offset;
unsigned char iph_ttl;
unsigned char iph_protocol;
unsigned short int iph_chksum;
unsigned int iph_sourceip;
unsigned int iph_destip;
};
struct tcpheader {
unsigned short int tcph_srcport;
unsigned short int tcph_destport;
unsigned int tcph_seqnum;
unsigned int tcph_acknum;
unsigned char tcph_reserved:4, tcph_offset:4;
unsigned int
tcp_res1:4, /*little-endian*/
tcph_hlen:4, /*length of tcp header in 32-bit words*/
tcph_fin:1, /*Finish flag "fin"*/
tcph_syn:1, /*Synchronize sequence numbers to start a connection*/
tcph_rst:1, /*Reset flag */
tcph_psh:1, /*Push, sends data to the application*/
tcph_ack:1, /*acknowledge*/
tcph_urg:1, /*urgent pointer*/
tcph_res2:2;
unsigned short int tcph_win;
unsigned short int tcph_chksum;
unsigned short int tcph_urgptr;
};
int raw_socket;
// creating the raw socket
raw_socket = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
if(raw_socket < 0){
fprintf(stderr, "Failed to create the socket\n");
exit(INTERNAL_ERROR);
}
// datagram to represent the packet
char datagram[4096];
// we need to map it so the datagram can represent it
struct ipheader* iph = (struct ipheader*) datagram;
struct tcpheader* tcph = (struct tcpheader*) datagram + sizeof(ipheader);
struct sockaddr_in sin;
// set the source parameters
sin.sin_family = AF_INET;
sin.sin_port = htons(order_num); // destination port num
sin.sin_addr.s_addr = inet_addr("172.217.23.196"); // destination ip
// zero out the buffer
memset(datagram, 0, 4096);
// filling in the ip header
iph->iph_ihl = 5;
iph->iph_ver = 4;
iph->iph_tos = 0;
iph->iph_len = sizeof(struct ipheader) + sizeof(struct tcpheader);
iph->iph_ident = htonl(54321); // this dosn't matter
iph->iph_offset = 0;
iph->iph_ttl = 255;
iph->iph_protocol = 6;
iph->iph_chksum = 0;
// setting the source and destination
iph->iph_sourceip = inet_addr("147.229.206.115");
iph->iph_destip = sin.sin_addr.s_addr;
// setting the tcph header
tcph->tcph_srcport = htons(5678);
tcph->tcph_destport = htons(20);
tcph->tcph_seqnum = random();
tcph->tcph_acknum = 0;
tcph->tcph_res2 = 0;
tcph->tcph_offset = 0;
tcph->tcph_syn = TH_FIN;
tcph->tcph_win = htonl(65535);
tcph->tcph_chksum = 0;
tcph->tcph_urgptr = 0;
// calculate the checksum
iph->iph_chksum = 0;//csum((unsigned short *) datagram, iph->iph_len >> 1);
// we need to tell kernel that headers are included in the packet
int one = 1;
const int *val = &one;
if(setsockopt(raw_socket, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0){
fprintf(stderr, "Error setting IP_HDRINCL %d\n", errno);
exit(INTERNAL_ERROR);
}
// sending the packet
if(sendto(raw_socket, datagram, iph->iph_len, 0, (struct sockaddr *) &sin, sizeof(sin)) < 0){
fprintf(stderr, "Error while sending %d\n", errno);
exit(INTERNAL_ERROR);
}
// close the raw socket
close(raw_socket);
我的问题是,如果我在Wireshark中看不到包裹,如何知道包裹是否已寄出?我在做什么错了?