Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2208773
  • 博文数量: 436
  • 博客积分: 9833
  • 博客等级: 中将
  • 技术积分: 5558
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-29 10:27
文章存档

2013年(47)

2012年(79)

2011年(192)

2010年(118)

分类: LINUX

2010-10-29 17:30:13

ICMP差错报文的格式

 

             不可达,超时,源泉抑制

type

len

cksum

Void(必须是0)

被破坏分组的IP首部

 

                需要分片

type

len

cksum

Pmvoid(必须是0)

nextmtu

被破坏分组的IP首部

 

                参数问题

type

len

cksum

pptr

(必须是0)

被破坏分组的IP首部

 

 

                          信宿不可达报文类型表

代码值

类型描述

 

代码值

类型描述

0

网络不可达

 

7

信宿主机未知

1

主机不可达

 

8

信源主机被隔离

2

协议不可达

 

9

与信宿网络的通信被禁止

3

端口不可达

 

10

与信宿主机的通信杯禁止

4

需要分片和DF设置

 

11

对请求的服务类型,网络不可达

5

源路由失败

 

12

对请求的服务类型,主机不可达

6

信宿网络未知

 

 

 

/* Handle ICMP_UNREACH and ICMP_QUENCH. */处理ICMP_UNREACHICMP_QUENCH//处理不可达和源终止//

static void

icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb) ;//调用icmp_unreach函数类型3

{

  struct inet_protocol *ipprot;

  struct iphdr *iph; //定义IP头部

  unsigned char hash;

  int err;//定义变量

 

  err = (icmph->type << 8) | icmph->code;// ICMP包类型为8,响应请求

  iph = (struct iphdr *) (icmph + 1);//IP的头标位ICMP的头标加1

  switch(icmph->code & 7) //icmph指向代码(8)并与7与后进行判断,得到不可达类型的代号

{

    case ICMP_NET_UNREACH://当网络不可达时

        DPRINTF((DBG_ICMP, "ICMP: %s: network unreachable.\n",

                            in_ntoa(iph->daddr))); //输出网络不可访问的目的IP地址 

break;

    case ICMP_HOST_UNREACH: //当主机不可达时

 

        DPRINTF((DBG_ICMP, "ICMP: %s: host unreachable.\n",

                        in_ntoa(iph->daddr))); //输出主机不可访问   目的IP地址    

break;

 

        break;

    case ICMP_PROT_UNREACH://当端口不可达时

 

        printk("ICMP: %s:%d: protocol unreachable.\n",

            in_ntoa(iph->daddr), ntohs(iph->protocol));

//输出ICMP协议不可达   目的IP地址     协议首地址

break;

    case ICMP_PORT_UNREACH:

        DPRINTF((DBG_ICMP, "ICMP: %s:%d: port unreachable.\n",

            in_ntoa(iph->daddr), -1 /* FIXME: ntohs(iph->port) */));

        break;????

    case ICMP_FRAG_NEEDED://当需要分片时和DF设置时

        printk("ICMP: %s: fragmentation needed and DF set.\n",

                            in_ntoa(iph->daddr));//输出碎片需要和DF设置 目的IP地址

        break;

    case ICMP_SR_FAILED://当源路由失败时

        printk("ICMP: %s: Source Route Failed.\n", in_ntoa(iph->daddr));

        break;// 目的IP地址 源路由失败

    default:

        DPRINTF((DBG_ICMP, "ICMP: Unreachable: CODE=%d from %s\n",

                    (icmph->code & 7), in_ntoa(iph->daddr)));

        break;

  }

//若不是上述情况 则输出DBG_ICMP icmp不可达 code的值 目的ip地址

 

 

  /* Get the protocol(s). *///获取通讯协定

  hash = iph->protocol & (MAX_INET_PROTOS -1);

//hash等于iph->protocol(MAX_INET_PROTOS -1)

 

 

  /* This can change while we are doing it. */

  ipprot = (struct inet_protocol *) inet_protos[hash];//如果找到相关的协议

  while(ipprot != NULL) {

    struct inet_protocol *nextip;//到路由的下一跳

 

    nextip = (struct inet_protocol *) ipprot->next;// ipprot 等于inet的协议   inet_protos[hash]ipprot不为空,ipprot等于 inet的协议 *ipprot指向下一个值

 

 

    /* Pass it off to everyone who wants it. */

    if (iph->protocol == ipprot->protocol && ipprot->err_handler) {

        ipprot->err_handler(err, (unsigned char *)(icmph + 1),

                    iph->daddr, iph->saddr, ipprot);

    }//

 

    ipprot = nextip;

  }

  skb->sk = NULL;

  kfree_skb(skb, FREE_READ);

}
阅读(1583) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~