ICMP(ip_icmp.h)

本文详细介绍了Internet控制消息协议(ICMP)的基本结构、消息类型及代码定义。包括不同类型的ICMP报文格式及其应用场景,如回显请求与应答、目标不可达、重定向等。


#ifndef __NETINET_IP_ICMP_H
#define __NETINET_IP_ICMP_H    1

#include <sys/cdefs.h>
#include <sys/types.h>

__BEGIN_DECLS

struct icmphdr
{
  u_int8_t type;        /* message type */
  u_int8_t code;        /* type sub-code */
  u_int16_t checksum;
  union
  {
    struct
    {
      u_int16_t    id;
      u_int16_t    sequence;
    } echo;            /* echo datagram */
    u_int32_t    gateway;    /* gateway address */
    struct
    {
      u_int16_t    __unused;
      u_int16_t    mtu;
    } frag;            /* path mtu discovery */
  } un;
};


#define ICMP_ECHOREPLY        0    /* Echo Reply            */
#define ICMP_DEST_UNREACH    3    /* Destination Unreachable    */
#define ICMP_SOURCE_QUENCH    4    /* Source Quench        */
#define ICMP_REDIRECT        5    /* Redirect (change route)    */
#define ICMP_ECHO        8    /* Echo Request            */
#define ICMP_TIME_EXCEEDED    11    /* Time Exceeded        */
#define ICMP_PARAMETERPROB    12    /* Parameter Problem        */
#define ICMP_TIMESTAMP        13    /* Timestamp Request        */
#define ICMP_TIMESTAMPREPLY    14    /* Timestamp Reply        */
#define ICMP_INFO_REQUEST    15    /* Information Request        */
#define ICMP_INFO_REPLY        16    /* Information Reply        */
#define ICMP_ADDRESS        17    /* Address Mask Request        */
#define ICMP_ADDRESSREPLY    18    /* Address Mask Reply        */
#define NR_ICMP_TYPES        18


/* Codes for UNREACH. */
#define ICMP_NET_UNREACH    0    /* Network Unreachable        */
#define ICMP_HOST_UNREACH    1    /* Host Unreachable        */
#define ICMP_PROT_UNREACH    2    /* Protocol Unreachable        */
#define ICMP_PORT_UNREACH    3    /* Port Unreachable        */
#define ICMP_FRAG_NEEDED    4    /* Fragmentation Needed/DF set    */
#define ICMP_SR_FAILED        5    /* Source Route failed        */
#define ICMP_NET_UNKNOWN    6
#define ICMP_HOST_UNKNOWN    7
#define ICMP_HOST_ISOLATED    8
#define ICMP_NET_ANO        9
#define ICMP_HOST_ANO        10
#define ICMP_NET_UNR_TOS    11
#define ICMP_HOST_UNR_TOS    12
#define ICMP_PKT_FILTERED    13    /* Packet filtered */
#define ICMP_PREC_VIOLATION    14    /* Precedence violation */
#define ICMP_PREC_CUTOFF    15    /* Precedence cut off */
#define NR_ICMP_UNREACH        15    /* instead of hardcoding immediate value */

/* Codes for REDIRECT. */
#define ICMP_REDIR_NET        0    /* Redirect Net            */
#define ICMP_REDIR_HOST        1    /* Redirect Host        */
#define ICMP_REDIR_NETTOS    2    /* Redirect Net for TOS        */
#define ICMP_REDIR_HOSTTOS    3    /* Redirect Host for TOS    */

/* Codes for TIME_EXCEEDED. */
#define ICMP_EXC_TTL        0    /* TTL count exceeded        */
#define ICMP_EXC_FRAGTIME    1    /* Fragment Reass time exceeded    */


#ifdef __USE_BSD
/*
 * Copyright (c) 1982, 1986, 1993
 *    The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *    @(#)ip_icmp.h    8.1 (Berkeley) 6/10/93
 */

#include <netinet/in.h>
#include <netinet/ip.h>

/*
 * Internal of an ICMP Router Advertisement
 */
struct icmp_ra_addr
{
  u_int32_t ira_addr;
  u_int32_t ira_preference;
};

struct icmp
{
  u_int8_t  icmp_type;    /* type of message, see below */
  u_int8_t  icmp_code;    /* type sub code */
  u_int16_t icmp_cksum;    /* ones complement checksum of struct */
  union
  {
    u_char ih_pptr;        /* ICMP_PARAMPROB */
    struct in_addr ih_gwaddr;    /* gateway address */
    struct ih_idseq        /* echo datagram */
    {
      u_int16_t icd_id;
      u_int16_t icd_seq;
    } ih_idseq;
    u_int32_t ih_void;

    /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
    struct ih_pmtu
    {
      u_int16_t ipm_void;
      u_int16_t ipm_nextmtu;
    } ih_pmtu;

    struct ih_rtradv
    {
      u_int8_t irt_num_addrs;
      u_int8_t irt_wpa;
      u_int16_t irt_lifetime;
    } ih_rtradv;
  } icmp_hun;
#define    icmp_pptr    icmp_hun.ih_pptr
#define    icmp_gwaddr    icmp_hun.ih_gwaddr
#define    icmp_id        icmp_hun.ih_idseq.icd_id
#define    icmp_seq    icmp_hun.ih_idseq.icd_seq
#define    icmp_void    icmp_hun.ih_void
#define    icmp_pmvoid    icmp_hun.ih_pmtu.ipm_void
#define    icmp_nextmtu    icmp_hun.ih_pmtu.ipm_nextmtu
#define    icmp_num_addrs    icmp_hun.ih_rtradv.irt_num_addrs
#define    icmp_wpa    icmp_hun.ih_rtradv.irt_wpa
#define    icmp_lifetime    icmp_hun.ih_rtradv.irt_lifetime
  union
  {
    struct
    {
      u_int32_t its_otime;
      u_int32_t its_rtime;
      u_int32_t its_ttime;
    } id_ts;
    struct
    {
      struct ip idi_ip;
      /* options and then 64 bits of data */
    } id_ip;
    struct icmp_ra_addr id_radv;
    u_int32_t   id_mask;
    u_int8_t    id_data[1];
  } icmp_dun;
#define    icmp_otime    icmp_dun.id_ts.its_otime
#define    icmp_rtime    icmp_dun.id_ts.its_rtime
#define    icmp_ttime    icmp_dun.id_ts.its_ttime
#define    icmp_ip        icmp_dun.id_ip.idi_ip
#define    icmp_radv    icmp_dun.id_radv
#define    icmp_mask    icmp_dun.id_mask
#define    icmp_data    icmp_dun.id_data
};

/*
 * Lower bounds on packet lengths for various types.
 * For the error advice packets must first insure that the
 * packet is large enough to contain the returned ip header.
 * Only then can we do the check to see if 64 bits of packet
 * data have been returned, since we need to check the returned
 * ip header length.
 */
#define    ICMP_MINLEN    8                /* abs minimum */
#define    ICMP_TSLEN    (8 + 3 * sizeof (n_time))    /* timestamp */
#define    ICMP_MASKLEN    12                /* address mask */
#define    ICMP_ADVLENMIN    (8 + sizeof (struct ip) + 8)    /* min */
#ifndef _IP_VHL
#define    ICMP_ADVLEN(p)    (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
    /* N.B.: must separately check that ip_hl >= 5 */
#else
#define    ICMP_ADVLEN(p)    (8 + (IP_VHL_HL((p)->icmp_ip.ip_vhl) << 2) + 8)
    /* N.B.: must separately check that header length >= 5 */
#endif

/* Definition of type and code fields. */
/* defined above: ICMP_ECHOREPLY, ICMP_REDIRECT, ICMP_ECHO */
#define    ICMP_UNREACH        3        /* dest unreachable, codes: */
#define    ICMP_SOURCEQUENCH    4        /* packet lost, slow down */
#define    ICMP_ROUTERADVERT    9        /* router advertisement */
#define    ICMP_ROUTERSOLICIT    10        /* router solicitation */
#define    ICMP_TIMXCEED        11        /* time exceeded, code: */
#define    ICMP_PARAMPROB        12        /* ip header bad */
#define    ICMP_TSTAMP        13        /* timestamp request */
#define    ICMP_TSTAMPREPLY    14        /* timestamp reply */
#define    ICMP_IREQ        15        /* information request */
#define    ICMP_IREQREPLY        16        /* information reply */
#define    ICMP_MASKREQ        17        /* address mask request */
#define    ICMP_MASKREPLY        18        /* address mask reply */

#define    ICMP_MAXTYPE        18

/* UNREACH codes */
#define    ICMP_UNREACH_NET            0    /* bad net */
#define    ICMP_UNREACH_HOST            1    /* bad host */
#define    ICMP_UNREACH_PROTOCOL            2    /* bad protocol */
#define    ICMP_UNREACH_PORT            3    /* bad port */
#define    ICMP_UNREACH_NEEDFRAG            4    /* IP_DF caused drop */
#define    ICMP_UNREACH_SRCFAIL            5    /* src route failed */
#define    ICMP_UNREACH_NET_UNKNOWN        6    /* unknown net */
#define    ICMP_UNREACH_HOST_UNKNOWN       7    /* unknown host */
#define    ICMP_UNREACH_ISOLATED            8    /* src host isolated */
#define    ICMP_UNREACH_NET_PROHIB            9    /* net denied */
#define    ICMP_UNREACH_HOST_PROHIB        10    /* host denied */
#define    ICMP_UNREACH_TOSNET            11    /* bad tos for net */
#define    ICMP_UNREACH_TOSHOST            12    /* bad tos for host */
#define    ICMP_UNREACH_FILTER_PROHIB      13    /* admin prohib */
#define    ICMP_UNREACH_HOST_PRECEDENCE    14    /* host prec vio. */
#define    ICMP_UNREACH_PRECEDENCE_CUTOFF  15    /* prec cutoff */

/* REDIRECT codes */
#define    ICMP_REDIRECT_NET    0        /* for network */
#define    ICMP_REDIRECT_HOST    1        /* for host */
#define    ICMP_REDIRECT_TOSNET    2        /* for tos and net */
#define    ICMP_REDIRECT_TOSHOST    3        /* for tos and host */

/* TIMEXCEED codes */
#define    ICMP_TIMXCEED_INTRANS    0        /* ttl==0 in transit */
#define    ICMP_TIMXCEED_REASS    1        /* ttl==0 in reass */

/* PARAMPROB code */
#define    ICMP_PARAMPROB_OPTABSENT 1        /* req. opt. absent */

#define    ICMP_INFOTYPE(type) \
    ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
    (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \
    (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
    (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
    (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)

#endif /* __USE_BSD */

__END_DECLS

#endif /* netinet/ip_icmp.h */
make -C /lib/modules/3.10.0-1160.119.1.el7.x86_64/build M=/home/user/1/core_test_folder modules # 行首是制表符 make[1]: Entering directory '/usr/src/kernels/3.10.0-1160.119.1.el7.x86_64' CC [M] /home/user/1/core_test_folder/icmp_ping_monitor.o /home/user/1/core_test_folder/icmp_ping_monitor.c: 在函数‘ping_hook’中: /home/user/1/core_test_folder/icmp_ping_monitor.c:37:5: 错误:隐式声明函数‘ip_hdr’ [-Werror=implicit-function-declaration] iph = ip_hdr(skb); ^ /home/user/1/core_test_folder/icmp_ping_monitor.c:37:9: 警告:赋值时将整数赋给指针,未作类型转换 [默认启用] iph = ip_hdr(skb); ^ /home/user/1/core_test_folder/icmp_ping_monitor.c:38:12: 错误:提领指向不完全类型的指针 if (iph->protocol != IPPROTO_ICMP) ^ /home/user/1/core_test_folder/icmp_ping_monitor.c:47:47: 错误:提领指向不完全类型的指针 stats.entries[stats.index].daddr = iph->daddr; ^ /home/user/1/core_test_folder/icmp_ping_monitor.c: 在文件作用域: /home/user/1/core_test_folder/icmp_ping_monitor.c:58:5: 警告:从不兼容的指针类型初始化 [默认启用] .hook = ping_hook, ^ /home/user/1/core_test_folder/icmp_ping_monitor.c:58:5: 警告:(在‘nfho.hook’的初始化附近) [默认启用] cc1: some warnings being treated as errors scripts/Makefile.build:339: recipe for target '/home/user/1/core_test_folder/icmp_ping_monitor.o' failed make[2]: *** [/home/user/1/core_test_folder/icmp_ping_monitor.o] Error 1 Makefile:1316: recipe for target '_module_/home/user/1/core_test_folder' failed make[1]: *** [_module_/home/user/1/core_test_folder] Error 2 make[1]: Leaving directory '/usr/src/kernels/3.10.0-1160.119.1.el7.x86_64' Makefile:11: recipe for target 'all' failed make: *** [all] Error 2
08-12
基于以下错误,给我修复后的完整代码,以及makefile文件:make: Entering directory '/usr/src/kernels/3.10.0-1160.119.1.el7.x86_64' CC [M] /home/user/1/core_test_folder/icmp_ping_monitor.o /home/user/1/core_test_folder/icmp_ping_monitor.c:41:13: 错误:‘ping_hook’未声明(不在函数内) .hook = ping_hook, ^ /home/user/1/core_test_folder/icmp_ping_monitor.c:47:18: 错误:expected declaration specifiers or ‘...’ before ‘&’ token nf_register_hook(&nfho); // 注册 ^ /home/user/1/core_test_folder/icmp_ping_monitor.c:48:20: 错误:expected declaration specifiers or ‘...’ before ‘&’ token nf_unregister_hook(&nfho); // 注销 ^ /home/user/1/core_test_folder/icmp_ping_monitor.c: 在函数‘ping_stat_init’中: /home/user/1/core_test_folder/icmp_ping_monitor.c:142:15: 警告:从不兼容的指针类型赋值 [默认启用] nfho.hook = ping_hook; ^ /home/user/1/core_test_folder/icmp_ping_monitor.c:146:5: 错误:隐式声明函数‘nf_register_net_hook’ [-Werror=implicit-function-declaration] nf_register_net_hook(&init_net, &nfho); ^ /home/user/1/core_test_folder/icmp_ping_monitor.c:151:9: 错误:隐式声明函数‘nf_unregister_net_hook’ [-Werror=implicit-function-declaration] nf_unregister_net_hook(&init_net, &nfho); ^ cc1: some warnings being treated as errors scripts/Makefile.build:339: recipe for target '/home/user/1/core_test_folder/icmp_ping_monitor.o' failed make[1]: *** [/home/user/1/core_test_folder/icmp_ping_monitor.o] Error 1 Makefile:1316: recipe for target '_module_/home/user/1/core_test_folder' failed make: *** [_module_/home/user/1/core_test_folder] Error 2 make: Leaving directory '/usr/src/kernels/3.10.0-1160.119.1.el7.x86_64'
08-12
#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/netfilter.h> #include <linux/netfilter_ipv4.h> #include <linux/ip.h> #include <linux/icmp.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <linux/spinlock.h> #include <linux/ktime.h> #define PROCFS_NAME "icmp_stat" MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("ICMP packet size statistics module"); static int n_param = 100; module_param(n_param, int, S_IRUGO); MODULE_PARM_DESC(n_param, "Size of ICMP data to match (100-1000)"); static struct nf_hook_ops nfho; static struct list_head icmp_list; static DEFINE_SPINLOCK(icmp_lock); static int packet_count = 0; struct icmp_packet_info { struct list_head list; ktime_t timestamp; __be32 src_ip; unsigned int id; }; static unsigned int icmp_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) { struct iphdr *ip_header; struct icmphdr *icmp_header; unsigned int data_len; if (!skb) { return NF_ACCEPT; } ip_header = ip_hdr(skb); if (ip_header->protocol != IPPROTO_ICMP) { return NF_ACCEPT; } if (skb->len < sizeof(struct iphdr) + sizeof(struct icmphdr)) { return NF_ACCEPT; } icmp_header = (struct icmphdr *)(skb->data + (ip_header->ihl * 4)); if (icmp_header->type != ICMP_ECHO && icmp_header->type != ICMP_ECHOREPLY) { return NF_ACCEPT; } /* 计算数据部分长度 */ data_len = ntohs(ip_header->tot_len) - (ip_header->ihl * 4) - sizeof(struct icmphdr); if (data_len == n_param) { struct icmp_packet_info *info = kmalloc(sizeof(*info), GFP_ATOMIC); if (!info) { return NF_ACCEPT; } info->timestamp = ktime_get_real(); info->src_ip = ip_header->saddr; info->id = ntohs(icmp_header->un.echo.id); spin_lock(&icmp_lock); list_add(&info->list, &icmp_list); packet_count++; spin_unlock(&icmp_lock); } return NF_ACCEPT; } static void *icmp_seq_start(struct seq_file *s, loff_t *pos) { spin_lock(&icmp_lock); return seq_list_start(&icmp_list, *pos); } static void *icmp_seq_next(struct seq_file *s, void *v, loff_t *pos) { return seq_list_next(v, &icmp_list, pos); } static void icmp_seq_stop(struct seq_file *s, void *v) { spin_unlock(&icmp_lock); } static int icmp_seq_show(struct seq_file *s, void *v) { struct icmp_packet_info *info = list_entry(v, struct icmp_packet_info, list); struct timespec64 ts = ktime_to_timespec64(info->timestamp); seq_printf(s, "Time: %lld.%09ld | Source: %pI4 | ID: %u\n", (s64)ts.tv_sec, ts.tv_nsec, &info->src_ip, info->id); return 0; } static const struct seq_operations icmp_seq_ops = { .start = icmp_seq_start, .next = icmp_seq_next, .stop = icmp_seq_stop, .show = icmp_seq_show}; static int icmp_proc_open(struct inode *inode, struct file *file) { return seq_open(file, &icmp_seq_ops); } static const struct proc_ops icmp_proc_ops = { .proc_open = icmp_proc_open, .proc_read = seq_read, .proc_lseek = seq_lseek, .proc_release = seq_release, }; static int __init icmp_stat_init(void) { if (n_param < 100 || n_param > 1000) { printk(KERN_ERR "Invalid n_param value: %d. Must be between 100 and 1000\n", n_param); return -EINVAL; } INIT_LIST_HEAD(&icmp_list); nfho.hook = icmp_hook; nfho.hooknum = NF_INET_PRE_ROUTING; nfho.pf = PF_INET; nfho.priority = NF_IP_PRI_FIRST; nf_register_net_hook(&init_net, &nfho); proc_create(PROCFS_NAME, 0, NULL, &icmp_proc_ops); printk(KERN_INFO "ICMP stat module loaded. Tracking data size: %d bytes\n", n_param); return 0; } static void __exit icmp_stat_exit(void) { struct icmp_packet_info *info, *tmp; nf_unregister_net_hook(&init_net, &nfho); remove_proc_entry(PROCFS_NAME, NULL); spin_lock(&icmp_lock); list_for_each_entry_safe(info, tmp, &icmp_list, list) { list_del(&info->list); kfree(info); } spin_unlock(&icmp_lock); printk(KERN_INFO "ICMP stat module unloaded. Total packets tracked: %d\n", packet_count); } module_init(icmp_stat_init); module_exit(icmp_stat_exit); 修改代码使得 /proc/icmp_stat 的数据中多记录一条数据,数据内容是报文的总数
最新发布
08-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值