udp是一种无连接的传输层协议,不像tcp在传输数据前要先发起连接,因此要可以说没有办法阻断udp之间的通讯。有一些资料称可以伪造目的主机发出目的端口不可达的ICMP报文,从而误导源主机中止与目的主机的udp通讯,伪造icmp目的端口不可达的代码如下:
unsigned short iTotalSize = sizeof(ip_header) + 8 + count;
unsigned short iICMPSize = 8 + count;
struct sockaddr_in server;
if(createSocket()<0) return -1;
iph.ip_vhl = (4 << 4) | (sizeof(ip_header) / sizeof(unsigned long));
iph.ip_tos = 0;
iph.ip_len = htons(iTotalSize);
iph.ip_id = htons(17393);
iph.ip_off = 0;
iph.ip_ttl = 255;
iph.ip_p = IPPROTO_ICMP;
iph.ip_sum = 0;
isrcip = inet_addr(srcIP);
idstip = inet_addr(dstIP);
memcpy(&iph.ip_src, &isrcip, 4);
memcpy(&iph.ip_dst, &idstip, 4);
iph.ip_sum = checksum((unsigned short *)&iph, 20);
icmph.type = 3;
icmph.code = 3;
icmph.checksum = 0;
icmph.id = 0;
icmph.seq = 0;
memcpy(icmph.data, forgedData, count);
icmph.checksum = checksum((unsigned short *)&icmph, iICMPSize);
memset(buff, 0x00, 2048);
ptr = buff;
memcpy(ptr, &iph, sizeof(ip_header));
ptr += sizeof(ip_header);
memcpy(ptr, &icmph, iICMPSize);
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(dstIP);
num = sendto(sockfd, buff, iTotalSize, 0, (struct sockaddr *)&server, sizeof(struct sockaddr));
return num;
}
试验证明这种方法没有任何效果,现在的udp程式会忽略icmp端口不可达的报文,继续进行通讯。
还有一种方式是arp欺骗,控制系统伪造arp响应包,改变主机arp缓存中的mac地址,这样主机所有的数据都会发往伪造的mac地址上,这种方式称为网关欺骗。但是arp欺骗不容易控制,主机每隔一段时间就会发出arp request报文,伪造的arp响应包不一定会比真实的网关发出的报文快,这样就会造成主机一会儿连接上,一会儿有断网的现象,同时arp欺骗还容易引起严重的后果,比如造成局域网内所有的机器都断网。
arp欺骗的原理和示例代码:http://blog.chinaunix.net/u2/62281/showart_1206130.html
这样看来要阻断udp通讯是不可能的事了,其实办法还是有的,只要伪造目的主机发出相应的udp报文给源主机,同样能达到阻断udp通讯的效果。
unsigned short iTotalSize = sizeof(ip_header) + sizeof(udp_header) + count;
unsigned short iUdpSize = sizeof(udp_header) + count;
struct sockaddr_in server;
if(createSocket()<0) return -1;
iph.ip_vhl = (4 << 4) | (sizeof(ip_header) / sizeof(unsigned long));
iph.ip_tos = 0x0;
iph.ip_len = htons(iTotalSize);
iph.ip_id = 0;
iph.ip_off = 0;
iph.ip_ttl = 55;
iph.ip_p = IPPROTO_UDP;
iph.ip_sum = 0;
isrcip = inet_addr(srcIP);
idstip = inet_addr(dstIP);
memcpy(&iph.ip_src, &isrcip, 4);
memcpy(&iph.ip_dst, &idstip, 4);
iph.ip_sum = checksum((unsigned short *)&iph, 20);
udph.uh_dport = htons(dstPort);
udph.uh_sport = htons(srcPort);
udph.uh_ulen = htons(iUdpSize);
udph.uh_sum = 0;
psdh.s_addr = isrcip;
psdh.d_addr = idstip;
psdh.mbz = 0;
psdh.protocol = IPPROTO_UDP;
psdh.tcpl = htons(iUdpSize);
memcpy(buff, &psdh, sizeof(psd_header));
memcpy(buff+sizeof(psd_header), &udph, sizeof(udp_header));
memcpy(buff+sizeof(psd_header)+sizeof(udp_header), forgedData, count);
udph.uh_sum = checksum((unsigned short *)buff, sizeof(psd_header)+sizeof(udp_header)+count);
memset(buff, 0x00, 2048);
ptr = buff;
memcpy(ptr, &iph, sizeof(ip_header));
ptr += sizeof(ip_header);
memcpy(ptr, &udph, sizeof(udp_header));
ptr += sizeof(udp_header);
memcpy(ptr, forgedData, count);
server.sin_family = AF_INET;
server.sin_port = htons(dstPort);
server.sin_addr.s_addr = inet_addr(dstIP);
num = sendto(sockfd, buff, iTotalSize, 0, (struct sockaddr *)&server, sizeof(struct sockaddr));
return num;
}