首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我将ICMP重定向数据包发送到我的IP地址,但我的IP路由表没有更改

问我将ICMP重定向数据包发送到我的IP地址,但我的IP路由表没有更改
EN

Stack Overflow用户
提问于 2014-10-16 13:27:35
回答 2查看 753关注 0票数 0
代码语言:javascript
复制
#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, "172.21.203.91", &ip1->ip_src);
    inet_pton(AF_INET, "61.135.169.125", &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.31.0.1", &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:已抑制详细输出,使用-v或-vv进行完整协议解码侦听ppp0,链路类型LINUX_SLL (Linux已完成),捕获大小65535字节13:01:46.891807 IP 172.31.0.1 > 172.21.202.91: ICMP重定向61.135.169.125到主机172.21.203.91,长度36

EN

回答 2

Stack Overflow用户

发布于 2014-10-16 16:09:15

您可能需要配置ICMP参数。您是否更改了处理ICMP的任何内核默认值?正如http://man7.org/linux/man-pages/man7/icmp.7.html所说:

代码语言:javascript
复制
   ICMP_REDIRECT packets are not sent when Linux is not acting as a
   router.  They are also accepted only from the old gateway defined in
   the routing table and the redirect routes are expired after some
   time.

可以在/proc下更改ICMP设置请阅读https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt,特别是accept_redirects和secure_redirects。后者在默认情况下禁止从除网关(在路由表中)以外的任何位置进行重定向。

票数 0
EN

Stack Overflow用户

发布于 2017-10-06 20:01:09

Hi @ZhangZhao:上面列出的代码是否正在向您子网中的主机发送icmp重定向报文?您是否在linux内核文件系统中的文件"proc/sys/net/ipv4/conf/all/accept_redirects = 1“下启用了icmp重定向。您可以将ipv4/conf/all文件夹中所有文件的accept_redirects设置为1,然后检查

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26396829

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档