发送ICMP数据包

914阅读 0评论2012-12-04 andyluo324324
分类:

网络工程

探究式项目结题报告汇编

 

网络源代码分析

 

作者(学号)       1081000088

作者(学号)   袁雅宜 1081000095

 

 

 

20010-2011年第一学期

 

 

 

任课教师:徐远超

 

首都师范大学信息工程学院

 

 

 

* INET      An implementation of the TCP/IP protocol suite for the LINUX

*TCP / IP协议套件的Linux实现INET电子交易系统

 *      operating system.  INET is implemented using the  BSD Socket

*操作系统。 INET是实现使用的BSD套接字

 *      interface as the means of communication with the user level.

*接口作为与用户沟通水平的手段。

 *      Internet Control Message Protocol (ICMP)

 *互联网控制消息协议

 * Version: @(#)icmp.c  1.0.11  06/02/93

 *版本: @(#)icmp.c 1.0.11 06/02/93

 * Authors: Ross Biro,

* Fred N. van Kempen,

 * Mark Evans,

 * 作者: Ross Biro, Fred N. van Kempen, Mark Evans

 * Fixes:// 修正: 

 *      Alan Cox    :   Generic queue usage.// 通用队列使用

 *      Gerhard Koerting:   ICMP addressing corrected//ICMP的处理纠正

 *      Alan Cox    :   Use tos/ttl settings//使用渡/ TTL电设置

 *

 *

 *      This program is free software; you can redistribute it and/or//本程序为自由软件,你可以重新发布与/

 *      modify it under the terms of the GNU General Public License//修改根据GNU通用公共许可证的条款是

 *      as published by the Free Software Foundation; either version//如出版自由软件基金会;任一版本

 *      2 of the License, or (at your option) any later version.// 2使用许可,或在您的选择()的任何版本

 

 

 

 IP协议是在网络层的协议,它主要完成数据包的发送作用,下面这个表是IPv4的数据包格式:  

 

 

 

 

 

ICMP报文格式

       IP头标

       类型(8位)

       代码(8位)

       校验和(16位)

参数(若无,可不用)

信息(长度可变)

 

ICMP类型编码列表

类型代码值

ICMP报文类型描述

类型代码值

ICMP报文类型描述

  0

响应应答(ECHO答应)

   13

时戳请求

  3

信宿不可达

   14

时戳应答

  4

源抑制

   15

信息请求

  5

重定向

   16

信息应答

  8

响应请求(ECHO请求)

   17

地址掩码请求

  11

超时

   18

地址掩码应答

  12

参数失灵

   

 

 

#include

#include

#include

#include

#include

#include

#include "inet.h"

#include "dev.h"

#include "ip.h"

#include "route.h"

#include "protocol.h"

#include "icmp.h"

#include "tcp.h"

#include "skbuff.h"

#include "sock.h"

#include

#include

#include

#include

//以上为头文件.

 

#define min(a,b)     ((a)<(b)?(a):(b))//宏定义 ab的最小值

/* An array of errno for error messages from dest unreach. */

//一个数组——errno(封装在结构体内的复合数据类型)用来表示从目标主机发来的(目标主机)不可达的错误信息

struct icmp_err icmp_err_convert[] = {

/* ICMP报文不可达代码域常量定义 */

  { ENETUNREACH,      1 },      /*   ICMP_NET_UNREACH    */ /* 网络不可达 */

  { EHOSTUNREACH,   1 },      /*   ICMP_HOST_UNREACH */ /* 主机不可达 */

  { ENOPROTOOPT,      1 },      /*   ICMP_PROT_UNREACH  */ /* 协议不可达 */

  { ECONNREFUSED,    1 },      /*   ICMP_PORT_UNREACH  */ /* 端口不可达 */

  { EOPNOTSUPP,        0 },      /*   ICMP_FRAG_NEEDED    */ /* 需设置DF,分段 */

  { EOPNOTSUPP,        0 },      /*   ICMP_SR_FAILED         */ /* 源路由失败 */

  { ENETUNREACH,      1 },      /* ICMP_NET_UNKNOWN  */ /* 未知网络*/

  { EHOSTDOWN,        1 },      /*   ICMP_HOST_UNKNOWN      */ /* 未知主机 */

  { ENONET,          1 },         /*    ICMP_HOST_ISOLATED *//* 源主机被隔离 */

  { ENETUNREACH,      1 },      /*   ICMP_NET_ANO           *//* 从管理上禁止与目的网通信 */

  { EHOSTUNREACH,   1 },      /*   ICMP_HOST_ANO         *//*从管理上禁止与目的主机通信*/

  { EOPNOTSUPP,        0 },      /*   ICMP_NET_UNR_TOS    *//*对服务器类型,网络不可达 */

  { EOPNOTSUPP,        0 } /*   ICMP_HOST_UNR_TOS *//* 对服务类型,主机不可达 */

};

 

 

/* Display the contents of an ICMP header. */

//显示ICMP数据包头部内容信息

static void

print_icmp(struct icmphdr *icmph) //打印icmp//

{

  if (inet_debug != DBG_ICMP) return;

//判断IP头部ProtolICMP的头部的Protol域值相同,说明IP数据报装载的是ICMP报文

 

  printk("ICMP: type = %d, code = %d, checksum = %X\n",

                 icmph->type, icmph->code, icmph->checksum);

 //输出ICMP数据包中的类型,代码,校验和

  printk("      gateway = %s\n", in_ntoa(icmph->un.gateway)); 

//输出存放在套接口实现所分配的内存中的网关

}

 

 

 

/* Send an ICMP message. */

//发送ICMP数据包

void

icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev)

//icmp数据包封装在ip数据报文中发送{

  struct sk_buff *skb; //定义缓存结构

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

  int offset; //定义偏移量

  struct icmphdr  *icmph; //定义ICMP头部

  int len; //定义IP数据报长度

//发送ICMP报文(封装在TCP/IP数据包中)

  DPRINTF((DBG_ICMP, "icmp_send(skb_in = %X, type = %d, code = %d, dev=%X)\n",

                                 skb_in, type, code, dev));

 

 

  /* Get some memory for the reply. */递归语句

//从回复包中得到一些信息

  len = sizeof(struct sk_buff)(包头) + dev->hard_header_len (数据字段长度)+

    sizeof(struct iphdr)IP数据报长度) + sizeof(struct icmphdr)(ICMP的前8个字节) +sizeof(struct iphdr) + 8(IP数据报首部以后的8个字节);/* amount of header to return *///计算IP数据报长度  

 

skb = (struct sk_buff *) alloc_skb(len, GFP_ATOMIC);//IP数据包中,为包头分配内存空间

  if (skb == NULL) //判断以上的内存申请是否成功

     return;

 

  skb->sk = NULL;//包头所指向的头指针

  skb->mem_addr = skb; //包头在片中的地址

  skb->mem_len = len; //包头的长度

  len -= sizeof(struct sk_buff); //包头的长度等于

 

  /* Find the IP header. */

//计算IP数据包头部

  iph = (struct iphdr *) (skb_in->data + dev->hard_header_len);

 

  /* Build Layer 2-3 headers for message back to source. */

  offset = ip_build_header(skb, dev->pa_addr, iph->saddr,

                    &dev, IPPROTO_ICMP, NULL, len, skb_in->ip_hdr->tos,255);

//计算偏移量offset

  if (offset < 0) {//offset<0时进行如下操作

      skb->sk = NULL;//指针清空

      kfree_skb(skb, FREE_READ); //查看接收缓存还够不够

      return;

  }

 

  /* Re-adjust length according to actual IP header size. */

//根据实际IP头部大小重新调整IP数据包长度

  skb->len = offset + sizeof(struct icmphdr) + sizeof(struct iphdr) + 8;//重新计算长度

  icmph = (struct icmphdr *) (skb->data + offset);// //重新计算icmp包头部长度

  icmph->type = type; //重新计算icmp包头类型

  icmph->code = code; //重新计算icmp包头代码

  icmph->checksum = 0; //重新计算icmp包头校验和

  icmph->un.gateway = 0;// icmph->un.gateway0

  memcpy(icmph + 1, iph, sizeof(struct iphdr) + 8);//内存复制操作

 

  icmph->checksum = ip_compute_csum((unsigned char *)icmph,

                         sizeof(struct icmphdr) + sizeof(struct iphdr) + 8);

//重新计算icmp包头校验和

  DPRINTF((DBG_ICMP, ">>\n"));

  print_icmp(icmph);//输出icmp头部信息

  /* Send it and free it. *//IP包发送并清理内存空间

  ip_queue_xmit(NULL, dev, skb, 1);

}

 

功能:(响应状态)发送ICMP报文。

1.Skb结构的包类型不是本机(物理多播或广播),则返回。

2.检查IP的目标地址,是广播或多播,则返回。

3.IP fragment不是第一个(不处理),返回。

4.这个ICMP的类型大于18error域不为空,返回。

5.在没有定义“无限制”条件下,有限制则返回。

6.IP目标地址不是本设备地址和本机地址,以设备地址作源地址入参调用ip_options_echo(在IP_OPTIONS.C中定义),否则以IP目标地址为源地址入参调用,结果不为0(出错),返回。

7.ICMP头准备数据(长度不大于576)。

8.调用icmp_build_xmit,建立和发送ICMP报文,若为“错误报文”,则置优先级为6(网络控制)。

 

 

小节:这一部分的功能主要是发送一个IP数据包,通过返回的ICMP数据包判断出现了说明问题,根据这个问题重新发送。

 

 

 

 

 

上一篇:嵌入式系统中的无线技术 zigbee,bluetooth,wifi,红外协议分析
下一篇:嵌入式系统中的无线技术 zigbee,bluetooth,wifi,红外协议分析