简单网络嗅探的实现

/*************************************
  mysniff.h
*************************************/

#ifndef _SNIFFER_H
#define _SNIFFER_H


/*
*     Display an MAC address in readable format.
*/
#define HWADDR(addr) /
    ((unsigned char *)&addr)[0], /
    ((unsigned char *)&addr)[1], /
    ((unsigned char *)&addr)[2], /
    ((unsigned char *)&addr)[3], /
    ((unsigned char *)&addr)[4], /
    ((unsigned char *)&addr)[5]

/*
*     Display an IP address in readable format.
*/
#define NIPQUAD(addr) /
    ((unsigned char *)&addr)[0], /
    ((unsigned char *)&addr)[1], /
    ((unsigned char *)&addr)[2], /
    ((unsigned char *)&addr)[3]

#define HIPQUAD(addr) /
    ((unsigned char *)&addr)[3], /
    ((unsigned char *)&addr)[2], /
    ((unsigned char *)&addr)[1], /
    ((unsigned char *)&addr)[0]

#define PWORD(addr) /
    ((unsigned char *)&addr)[0], /
    ((unsigned char *)&addr)[1]

#endif /*************************************


 * mysinff.c
*************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/if_ether.h>
#include <net/if_arp.h>

#include "mysniff.h"

#define BUFSIZE 2048

static void hex_print(const u_char *buf, int len, int offset);
static int echo_eth(const u_char *buf);
static int echo_ip(const u_char *buf);
static int echo_arp(const u_char *buf);
static int echo_tcp(const u_char *buf);
static int echo_udp(const u_char *buf);

int main()
{
    int listenfd;
    int n;
    char buf[BUFSIZE];

    /*建立PACKET套接字*/ 
    if ((listenfd = socket(PF_PACKET, SOCK_RAW,htons(ETH_P_ALL))) < 0) { 

          perror("socket");
          exit(1);
    }

    for (;;) {
          if ((n = recv(listenfd, buf, BUFSIZE, 0)) > 0){
                hex_print(buf, n, 0);
                echo_eth(buf);
          }
    }
    return 0;
}

static int echo_eth(const u_char *buf)
{
    struct ethhdr *eth = (struct ethhdr *) buf;

    printf("/n以太帧包头");
    printf("/n目的MAC地址: %02X:%02X:%02X:%02X:%02X:%02X",HWADDR(eth->h_dest));
    printf("/n源MAC地址:%02X:%02X:%02X:%02X:%02X:%02X",HWADDR(eth->h_source));
    printf("/n协议: %02X-%02X", PWORD(eth->h_proto));
    switch (ntohs(eth->h_proto)) {
    case ETH_P_IP:
          return echo_ip((u_char *)(eth+1));
    case ETH_P_ARP:
          return echo_arp((u_char *)(eth+1));
    default:
          return -1;
    }
    return 0;
}

static int echo_arp(const u_char *buf)
{
    struct ether_arp *arph = (struct ether_arp *) buf;

    printf("/nARP地址解析协议包头");
    printf("/n硬件类型: %d", ntohs(arph->arp_hrd));
    printf("/n协议类型: %02X-%02X", PWORD(arph->arp_pro));
    printf("/n硬件地址长度: %d", arph->arp_hln);
    printf("/n协议地址长度: %d", arph->arp_pln);
    printf("/n操作码: %d", ntohs(arph->arp_op));
    printf("/n发送方硬件地址: %02X:%02X:%02X:%02X:%02X:%02X",
          HWADDR(arph->arp_sha));
    printf("/n发送方IP地址: %d.%d.%d.%d", NIPQUAD(arph->arp_spa));
    printf("/n目的方硬件地址: %02X:%02X:%02X:%02X:%02X:%02X",
          HWADDR(arph->arp_tha));
    printf("/n目的方IP地址: %d.%d.%d.%d", NIPQUAD(arph->arp_tpa));

    return 0;
}

static int echo_ip(const u_char *buf)
{
    struct iphdr *iph = (struct iphdr *) buf;

    printf("/nIPv4包头");
    printf("/n版本: %d", iph->version);
    printf("/n包头长度: %d (%d bytes)", iph->ihl, iph->ihl*4);
    printf("/n服务类型(TOS):0x%02X", iph->tos);
    printf("/n总长度: %d", ntohs(iph->tot_len));
    printf("/n标识: %d", ntohs(iph->id));
    printf("/n标志: %02X %02X", PWORD(iph->frag_off));
    printf("/n生存时间(TTL): %d hops", iph->ttl);
    printf("/n协议: %d", iph->protocol);
    printf("/n校验和: 0x%02X%02X", PWORD(iph->check));
    printf("/n源IP地址: %d.%d.%d.%d", NIPQUAD(iph->saddr));
    printf("/n目的地址: %d.%d.%d.%d", NIPQUAD(iph->daddr));

    switch (iph->protocol) {
    case IPPROTO_TCP:
          return echo_tcp((u_char *)&iph[1]);
    case IPPROTO_UDP:
          return echo_udp((u_char *)&iph[1]);
    default:
          return -1;
    }
    return 0;
}

static int echo_tcp(const u_char *buf)
{
    struct tcphdr *tcph = (struct tcphdr *) buf;

    printf("/nTCP包头");
    printf("/n源端口: %d", ntohs(tcph->source));
    printf("/n目的端口: %d", ntohs(tcph->dest));
    printf("/n序列号: %u", ntohl(tcph->seq));
    printf("/n确认号: %u", ntohl(tcph->ack_seq));
    printf("/n头部长度: %d (%d bytes)", tcph->doff, tcph->doff*4);
    printf("保留位/n: 0x%X", tcph->res1);
    printf("/n代码位: r:%d,u:%d,a:%d,p:%d,r:%d,s:%d,f:%d",
          tcph->res2, tcph->urg, tcph->ack, tcph->psh,
          tcph->rst, tcph->syn, tcph->fin);
    printf("/n接收窗口大小: %d", ntohs(tcph->window));
    printf("/n校验和: 0x%02X%02X", PWORD(tcph->check));
    printf("/n紧急数据指针: %d", ntohs(tcph->urg_ptr));

    return 0;
}

static int echo_udp(const u_char *buf)
{
    struct udphdr *udph = (struct udphdr *) buf;

    printf("/nUDP包头");
    printf("/n源端口: %d", ntohs(udph->source));
    printf("/n目的端口: %d", ntohs(udph->dest));
    printf("/n数据长度: %d bytes", ntohs(udph->len));
    printf("/n校验位: 0x%X", udph->check);

    return 0;
}

static void hex_print(const u_char *buf, int len, int offset)
{
    u_int i, j, jm;
    int c;

    printf("/n");
    for (i = 0; i < len; i += 0x10) {
          printf(" %04x: ", (u_int)(i + offset));
          jm = len - i;
          jm = jm > 16 ? 16 : jm;

          for (j = 0; j < jm; j++) {
                if ((j % 2) == 1)
                    printf("%02x ", (u_int) buf[i+j]);
                else printf("%02x", (u_int) buf[i+j]);
          }
          for (; j < 16; j++) {
                if ((j % 2) == 1) printf("   ");
                else printf(" ");
          }
          printf(" ");

          for (j = 0; j < jm; j++) {
                c = buf[i+j];
                c = isprint(c) ? c : '.';
                printf("%c", c);
          }
          printf("/n");
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值