ip 数据报文打印


int debug_verbose = 0;

#define    ADDRTOA_BUF (32*2 + 3 + 1 + 3 + 1 + 1)


void dmp_block(char *s, caddr_t bb, int len)
{
    int i;
    unsigned char *b = bb;

    printk("dmp: "
           "at %s, len=%d:\n", s, len);

    for(i = 0; i < len; i++ /*, c++*/) {
        if(!(i % 16)) {
            printk(
                   "debug:   @%03x:",
                   i);
        }
        printk(" %02x", b[i]);
        if(!((i + 1) % 16)) {
            printk("\n");
        }
    }
    if(i % 16) {
        printk("\n");
    }
}

static void
print_ip6(struct ipv6hdr *ip)
{
    char buf[ADDRTOA_BUF];

    printk("debug:   IPV6:");
    printk(" prio:%d", ip->priority);
    printk(" ver:%d", ip->version);
    printk(" flow:%02x%02x%02x", ip->flow_lbl[0], ip->flow_lbl[1], ip->flow_lbl[2]);
    printk(" pllen:%d", ntohs(ip->payload_len));
    printk(" hopl:%d", ip->hop_limit);
    printk(" nexthdr:%d", ip->nexthdr);
    if(ip->nexthdr == IPPROTO_UDP)
        printk(" (UDP)");
    if(ip->nexthdr == IPPROTO_TCP)
        printk(" (TCP)");
    if(ip->nexthdr == IPPROTO_ICMP)
        printk(" (ICMP)");
    if(ip->nexthdr == IPPROTO_ICMPV6)
        printk(" (ICMP)");
    if(ip->nexthdr == IPPROTO_ESP)
        printk(" (ESP)");
    if(ip->nexthdr == IPPROTO_AH)
        printk(" (AH)");
    if(ip->nexthdr == IPPROTO_COMP)
        printk(" (COMP)");
    inet_addrtot(AF_INET6, &ip->saddr, 0, buf, sizeof(buf));
    printk(" saddr:%s", buf);
#if 0
    if(ip->protocol == IPPROTO_UDP)
        printk(":%d",
               ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
    if(ip->protocol == IPPROTO_TCP)
        printk(":%d",
               ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
#endif
    inet_addrtot(AF_INET6, &ip->daddr, 0, buf, sizeof(buf));
    printk(" daddr:%s", buf);
#if 0
    if(ip->protocol == IPPROTO_UDP)
        printk(":%d",
               ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
    if(ip->protocol == IPPROTO_TCP)
        printk(":%d",
               ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
    if(ip->protocol == IPPROTO_ICMP)
        printk(" type:code=%d:%d",
               ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type,
               ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code);
#endif
    printk("\n");

    if(debug_verbose) {
        __u8 *c;
        int len = ntohs(ip->payload_len);

        c = (__u8 *)&ip[1];
        dmp_block("ip_print", c, len);
    }
}

static void
print_ip4(struct iphdr *ip)
{
    char buf[ADDRTOA_BUF];
    struct tcphdr *tcphdr = NULL;

    if (!ip)
        return;

    /* we are taking some liberties here assuming that the IP and TCP
     * headers are contiguous in memory */
    switch (ip->protocol) {
    case IPPROTO_TCP:
    case IPPROTO_UDP:
        /* NOTE: we only use this for getting port numbers, and they
         * are at the same offsets for both tcp and udp headers
         */
        tcphdr = (struct tcphdr*)((caddr_t)ip + (ip->ihl << 2));
        break;
    }

    printk("IP:");
    printk(" ihl:%d", ip->ihl << 2);
    printk(" ver:%d", ip->version);
    printk(" tos:%d", ip->tos);
    printk(" tlen:%d", ntohs(ip->tot_len));
    printk(" id:%d", ntohs(ip->id));
    printk(" %s%s%sfrag_off:%d",
               ip->frag_off & __constant_htons(IP_CE) ? "CE " : "",
               ip->frag_off & __constant_htons(IP_DF) ? "DF " : "",
               ip->frag_off & __constant_htons(IP_MF) ? "MF " : "",
               (ntohs(ip->frag_off) & IP_OFFSET) << 3);
    printk(" ttl:%d", ip->ttl);
    printk(" proto:%d", ip->protocol);
    if(ip->protocol == IPPROTO_UDP)
        printk(" (UDP)");
    if(ip->protocol == IPPROTO_TCP)
        printk(" (TCP)");
    if(ip->protocol == IPPROTO_ICMP)
        printk(" (ICMP)");
    if(ip->protocol == IPPROTO_ESP)
        printk(" (ESP)");
    if(ip->protocol == IPPROTO_AH)
        printk(" (AH)");
    if(ip->protocol == IPPROTO_COMP)
        printk(" (COMP)");
    printk(" chk:%d", ntohs(ip->check));
    addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf));
    printk(" saddr:%s", buf);
    if(tcphdr)
        printk(":%d",
               ntohs(tcphdr->source));
    addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf));
    printk(" daddr:%s", buf);
    if(tcphdr)
        printk(":%d",
               ntohs(tcphdr->dest));
    if(ip->protocol == IPPROTO_ICMP)
        printk(" type:code=%d:%d",
               ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type,
               ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code);
    if(ip->protocol == IPPROTO_TCP) {
        printk(" seq=%u ack=%u", tcphdr->seq, tcphdr->ack_seq);
        if (tcphdr->fin) printk(" FIN");
        if (tcphdr->syn) printk(" SYN");
        if (tcphdr->rst) printk(" RST");
        if (tcphdr->psh) printk(" PSH");
        if (tcphdr->ack) printk(" ACK");
        if (tcphdr->urg) printk(" URG");
        if (tcphdr->ece) printk(" ECE");
        if (tcphdr->cwr) printk(" CWR");
    }
    printk("\n");

    if(debug_verbose) {
        __u8 *c;
        int len = ntohs(ip->tot_len) - ip->ihl*4;

        c = ((__u8*)ip) + ip->ihl*4;
        dmp_block("ip_print", c, len);
    }
}

void print_ip(void *ip)
{

    if (((struct iphdr *) ip)->version == 6)
        print_ip6((struct ipv6hdr *) ip);
    else
        print_ip4((struct iphdr *) ip);
}

该函数既可以打印ipv4 报文,又可以打印ipv6报文,如果打开debug_verbose选项还可以打印数据包的详细信息,默认关闭只打印三层头部和四层头部信息,很方便开发者调试。比如已icmp协议为例打印格式如下

IP:
 ihl:20
 ver:4
 tos:0
 tlen:60
 id:1627
 frag_off:0
 ttl:127
 proto:1
 (ICMP)
 chk:55287
 saddr:3.3.3.2
 daddr:10.53.77.53
 type:code=0:0

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一叶知秋yyds

分享是一种美德,感谢金主打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值