ping.c

 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys / socket.h>
#include <sys / ioctl .h>
#include <sys / types.h>
#include <net / ethernet.h>
#include <net / if_arp.h>
#include <net / if.h>
#include <netinet / if_ether.h>
#include <netinet / ip_icmp.h>
#include <netinet / in.h>
#include <netinet / ip.h>
#include <netpacket / packet.h>
#include <arpa / inet.h>
 
#ifndef arp_hrd / * android no define struct ether_arp * /
struct ether_arp {     struct arphdr ea_hdr;/ * encabezado de tamaño fijo * /

    u_int8_t arp_sha [ETH_ALEN]; / * dirección de hardware del remitente * /
    u_int8_t arp_spa [4]; / * dirección de protocolo del remitente * /
    u_int8_t arp_tha [ETH_ALEN]; / * dirección de hardware de destino * /
    u_int8_t arp_tpa [4]; / * dirección de protocolo de destino * /
};
#define arp_hrd ea_hdr.ar_hrd
#define arp_pro ea_hdr.ar_pro
#define arp_hln ea_hdr.ar_hln
#define arp_pln ea_hdr.ar_pln
#define arp_op ea_hdr.ar_op
#endif
 
#define xprint_log (FMT, ...) \
    printf ( "[% 04d] % s () "fmt, __LINE__, __FUNCTION__, #### __ VA_ARGS__)
#define xprint_err (fmt, ...) \
    printf (" [% 04d]% s () err: "fmt, __LINE__, __FUNCTION__, ## ## __ VA_ARGS__)
 
#define xdebug 0
#define xunused __attribute __ ((unused))
 
#define HDR_LEN_ETH sizeof (struct ether_header)
#define HDR_LEN_ARP sizeof (struct ether_arp)
#define HDR_LEN_IP sizeof (struct ip)
#LEN_tamp
 
 
ICR ETH_FRAME_LEN];
static unsigned int s_frame_size = 0;
static int s_interface_index = -1;
carácter estático sin firmar s_interface_mac [ETH_ALEN];
estructura estática in_addr s_interface_ip; 
static unsigned char s_src_mac [ETH_ALEN] = {0x00,0x11,0x22,0x33,0x44,0x55};
 
 
static int 
xsend_frame_ether (uint8_t * marco, tamaño int, int ifindex, int skfd);
static int
xrecv_frame_ether (uint8_t * marco, tamaño int, int ifindex, int skfd);
 
static int 
xsend_reply_arp (in_addr_t ipaddr, int skfd);
static int
xsend_reply_icmp (in_addr_t ipaddr, int skfd);
 
static uint16_t 
xutil_check_sum (uint16_t * datos, tamaño int);
static void
xutil_swap_int (uint32_t * a, uint32_t * b);
 
static int xunused
xdump_frame_byte (uint8_t * datos, tamaño int);
static int xunused
xdump_frame_ether (struct ether_header * eth);
static int xunused
xdump_frame_arp (struct ether_arp * arp);
static int xunused
xdump_frame_ip (estructura ip * iph);
static int xunused
xdump_frame_icmp (struct icmp * icmph);
 
 
#define __DEFINITION__
 
 
static uint16_t 
xutil_check_sum (uint16_t * data, int size)
{     unsigned int cksm = 0;     while (tamaño> 1) {         cksm + = * data ++;         tamaño - = tamaño de (uint16_t);     }     if (tamaño) {         cksm + = * (uint8_t *) datos;     }     cksm = (cksm >> 16) + (cksm y 0xffff);      cksm + = (cksm >> 16);      return (uint16_t) (~ cksm); } static void xutil_swap_int (uint32_t * a, uint32_t * b) {     * a = * a ^ * b;     * b = * a ^ * b;     * a = * a ^ * b;     regreso ; } static int

    




    



    


    


 








 

xdump_frame_byte (uint8_t * datos, tamaño int)
{     int i;     para (i = 0; i <tamaño; i ++) {         if ((i% 16) == 0) {             printf ("[% 02x]", i / 16);         }         printf ("% 02x", datos [i]);         if (((i + 1)% 16) == 0) {             printf ("\ n");         }     }     printf ("\ n");     return 0; } static int xdump_frame_ether (struct ether_header * eth) {     if (NULL == eth) {         return -1;     }     printf ("======== frame ether ======== \ n");     printf ("tipo: 0x% 04x \ n", htons (eth-> ether_type));

 









 



 






 


    printf ("d-mac:% 02x-% 02x-% 02x-% 02x-% 02x-% 02x \ n", \
        eth-> ether_dhost [0], eth-> ether_dhost [1], eth-> ether_dhost [ 2], \
        eth-> ether_dhost [3], eth-> ether_dhost [4], eth-> ether_dhost [5]);
 
    printf ("s-mac:% 02x-% 02x-% 02x-% 02x-% 02x-% 02x \ n", \
        eth-> ether_shost [0], eth-> ether_shost [1], eth-> ether_shost [ 2], \
        eth-> ether_shost [3], eth-> ether_shost [4], eth-> ether_shost [5]);
    return 0;
}
 
static int
xdump_frame_arp (struct ether_arp * arp)
{     if (NULL == arp) {         return -1;     }     printf ("======== frame arp ======== \ n");     printf ("arp_hrd =% d \ n",



 


    printf ("arp_pro = 0x% 04x \ n", htons (arp-> arp_pro));
    printf ("arp_op =% d \ n", htons (arp-> arp_op));
    printf ("arp_sdr =% 02x-% 02x-% 02x-% 02x-% 02x-% 02x% d.% d.% d.% d \ n", \
        arp-> arp_sha [0], arp-> arp_sha [1], arp-> arp_sha [2], \
        arp-> arp_sha [3], arp-> arp_sha [4], arp-> arp_sha [5], \
        arp-> arp_spa [0], arp-> arp_spa [1], arp-> arp_spa [2], \
        arp-> arp_spa [3]);
    printf ("arp_tgr =% 02x-% 02x-% 02x-% 02x-% 02x-% 02x% d.% d.% d.% d \ n", \
        arp-> arp_tha [0], arp-> arp_tha [1], arp-> arp_tha [2], \
        arp-> arp_tha [3], arp-> arp_tha [4], arp-> arp_tha [5], \
        arp-> arp_tpa [0], arp-> arp_tpa [1], arp-> arp_tpa [2],
        \ arp-> arp_tpa [3]);
    return 0;
}
 
static int
xdump_frame_ip (struct ip * iph)
{     if (NULL == iph) {         return -1;     }     printf ("======== frame ip ======== \ n");     printf ("ip_v = 0x% x \ n", iph-> ip_v); / * número de versión de 4 dígitos * /     printf ("ip_hl = 0x% x \ n", iph-> ip_hl); / * IP de 4 dígitos Longitud del encabezado 32 bits * /     printf ("ip_tos = 0x% x \ n", iph-> ip_tos); / * tipo de servicio de 8 bits * /     printf ("ip_len = 0x% x \ n", htons (iph-> ip_len )); / * Longitud del paquete de 16 bits * /     printf ("ip_id = 0x% x \ n", htons (iph-> ip_id)); / * identificador de 16 bits * /     printf ("ip_off = 0x% x \ n ", htons (iph-> ip_off)); / * marca de 3 bits + desplazamiento de segmento de 13 bits * /     printf ("ip_ttl = 0x% x \ n ", iph-> ip_ttl); / * tiempo de supervivencia de 8 bits * /



    








    printf ("ip_p = 0x% x \ n", iph-> ip_p); / * número de protocolo de 8 dígitos * /
    printf ("ip_sum = 0x% x \ n", htons (iph-> ip_sum)); / *
    Suma de comprobación de encabezado de 16 bits * / printf ("ip_src =% s \ n", inet_ntoa (iph-> ip_src)); / * dirección de origen de 32 bits * /
    printf ("ip_dst =% s \ n", inet_ntoa (iph- > ip_dst)); / * dirección de destino de 32 bits * /
    return 0;
}
 
static int 
xdump_frame_icmp (struct icmp * icmph)
{     if (NULL == icmph) {         return -1;     }     printf ("====== = = frame icmp ======== \ n ");     printf (" icmp_type = 0x% x \ n ", icmph-> icmp_type); / * tipo de 8 bits * /     printf (" icmp_code = 0x% x \ n ", icmph-> icmp_code);/ * Código de 8 dígitos * /



    



    printf ("icmp_cksum = 0x% x \ n", icmph-> icmp_cksum); / * 16 位 ​​校验 和 * /
    printf ("icmp_id = 0x% x \ n", icmph-> icmp_id); / * 16 位 ​​识别 号 进程 id * /
    printf ("icmp_seq = 0x% x \ n", icmph-> icmp_seq); / * 16 位 ​​序列 号 * /
    return 0;
}
 
static int 
xsend_frame_ether (uint8_t * frame, int size, int ifindex, int skfd)
{     struct sockaddr_ll sll;     socklen_t sln = 0;     struct sockaddr_ll * psll = NULL;     if (-1! = ifindex) {         bzero (& sll, sizeof (sll));         sll.sll_ifindex = ifindex;         sll.sll_family = PF_PACKET;         sll.sll_protocol = htons (ETH_P_ALL);         psll = & sll;


    

 





 

        sln = tamaño de (struct sockaddr_ll);
    }
    
    tamaño = enviarto (skfd, marco, tamaño, 0, (struct sockaddr *) psll, sln);
    if (tamaño <0) {         xprint_err ("ioctl () SIOCGIFINDEX falló! errno =% d (% s) \ n", \             errno, strerror (errno));     }     tamaño de retorno; } static int xrecv_frame_ether (uint8_t * frame, int size, int ifindex, int skfd) {     struct sockaddr_ll sll;     socklen_t sln = sizeof (struct sockaddr_ll);     struct sockaddr_ll * psll = NULL;     socklen_t * psln = NULL;     if (NULL == frame || size <= 0) {         xprint_err ("¡param falló! frame =% p size =% d \ n", frame, size);



        


 





 


 


        return -1;
    }
 
    if (-1! = ifindex) {         bzero (& sll, sizeof (sll));         sll.sll_ifindex = ifindex;         sll.sll_family = PF_PACKET;         sll.sll_protocol = htons (ETH_P_ALL);         psll = & sll;         psln = & sln;     }     memset (marco, 0, tamaño * tamaño de (uint8_t));     tamaño = recvfrom (skfd, marco, tamaño, 0, (struct sockaddr *) psll, psln);     if (tamaño <0) {         xprint_err ("recvfrom () falló! errno =% d (% s) \ n", \             errno, strerror (errno));     }     tamaño de retorno; } static int  xsend_reply_arp (in_addr_t ipaddr, int skfd) {




 



 


 






 



    struct ether_header * eth = NULL;
    struct ether_arp * arp = NULL;
    
    eth = (struct ether_header *) s_frame_data;
    arp = (struct ether_arp *) (s_frame_data + HDR_LEN_ETH);
 
    if (* (unsigned int *) arp-> arp_tpa! = ipaddr) {         return -1;     }       / * ether * /     memcpy (eth-> ether_dhost, eth-> ether_shost, ETH_ALEN);     memcpy (eth-> ether_shost, s_src_mac, ETH_ALEN);     / * arp * /     arp-> arp_op = htons (ARPOP_REPLY);     memcpy (arp-> arp_tha, arp-> arp_sha, ETH_ALEN);     memcpy (arp-> arp_tpa, arp-> arp_spa, 4);     memcpy (arp-> arp_sha, s_src_mac, ETH_ALEN);     memcpy (arp-> arp_spa, & ipaddr, 4); #if xdebug


   



   




 


 

    printf ("+++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++ \ n ");
    printf ("======== tamaño de marco:% d \ n", s_frame_size);
    xdump_frame_ether (eth);
    xdump_frame_arp (arp);
    printf ("+++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++ \ n ");
    printf ("\ n");
#endif
 
    if (s_frame_size! = xsend_frame_ether (\
        s_frame_data, s_frame_size, s_interface_index, skfd)) {         return -1;     }     xprint_log ("ok. tamaño =% d \ n", s_frame_size);     return 0; } static int  xsend_reply_icmp (in_addr_t ipaddr, int skfd) {     struct ip * iph = NULL;


 



 




    struct ether_header * eth = NULL;
    struct icmp * icmph = NULL;
    
    eth = (struct ether_header *) s_frame_data;
    iph = (estructura ip *) (s_frame_data + HDR_LEN_ETH);
    icmph = (struct icmp *) (s_frame_data + HDR_LEN_ETH + HDR_LEN_IP);
    
    if ((iph-> ip_p! = IPPROTO_ICMP) || iph-> ip_dst.s_addr! = ipaddr) {         return 1;     }     / * ether * /     memcpy (eth-> ether_dhost, eth-> ether_shost, ETH_ALEN);     memcpy (eth-> ether_shost, s_src_mac, ETH_ALEN);     / * ip * /     xutil_swap_int (& (iph-> ip_src.s_addr), & (iph-> ip_dst.s_addr));     iph-> ip_off = 0;     iph-> ip_sum = 0;     iph-> ip_sum = xutil_check_sum ((uint16_t *) iph, HDR_LEN_IP);


 



    





 
    / * icmp * /
    icmph-> icmp_type = ICMP_ECHOREPLY;
    icmph-> icmp_cksum = 0;
    icmph-> icmp_cksum = \
        xutil_check_sum ((uint16_t *) icmph, s_frame_size-HDR_LEN_ETH-HDR_LEN_IP);
 
#if xdebug
    printf ("++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++ \ n ");
    printf ("======== tamaño de marco:% d \ n", s_frame_size);
    xdump_frame_ether (eth);
    xdump_frame_ip (iph);
    xdump_frame_icmp (icmph);
    printf ("+++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++ \ n ");
    printf ("\ n");
#endif
 
    if (s_frame_size! = xsend_frame_ether (\
        s_frame_data, s_frame_size, s_interface_index,
        return -1;
    }
 
    xprint_log ("ok. tamaño =% d \ n", s_frame_size);
    return 0;
}
 
int main (int argc, char ** argv)
{     int skfd = -1;     in_addr_t xping_addr = 0;     if (argc <= 2) {         printf ("uso:% s interfaz ipaddr \ n", argv [0]);         printf ("ex:% s eth0 192.168.88.1 \ n", argv [0]);         return -1;     }     skfd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));     if (skfd <0) {         xprint_err ("socket () falló! errno =% d (% s) \ n", errno, strerror (errno));         return -1;     }      struct ifreq ifr;     bzero (y


   





 





 


    strcpy (ifr.ifr_name, argv [1]);
    if (-1 == ioctl (skfd, SIOCGIFINDEX, & ifr)) {         xprint_err ("ioctl () SIOCGIFINDEX falló! errno =% d (% s) \ n", \             errno, strerror (errno));         return -1;     }     s_interface_index = ifr.ifr_ifindex;     if (-1 == ioctl (skfd, SIOCGIFHWADDR, & ifr)) {         xprint_err ("ioctl () SIOCGIFHWADDR falló! errno =% d (% s) \ n", \             errno, strerror (errno));         return -1;     }     memcpy (s_interface_mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN);     if (-1 == ioctl (skfd, SIOCGIFADDR, & ifr)) {         xprint_err ("ioctl () SIOCGIFADDR falló! errno =% d (% s) \ n", \





    






 


            errno, strerror (errno));
        return -1;
    }
    s_interface_ip.s_addr = \
        ((struct sockaddr_in *) & (ifr.ifr_addr)) -> sin_addr.s_addr;
        
    if (-1 == ioctl (skfd, SIOCGIFFLAGS, & ifr)) {         xprint_err ("ioctl () IFF_PROMISC falló! errno =% d (% s) \ n", \             errno, strerror (errno));         return -1;     }     if ((ifr.ifr_flags & IFF_PROMISC)! = IFF_PROMISC) {         ifr.ifr_flags | = IFF_PROMISC;         if (-1 == ioctl (skfd, SIOCSIFFLAGS, & ifr)) {             xprint_err ("ioctl () IFF_PROMISC falló! errno =% d (% s) \ n", \                 errno, strerror (errno));             return -1;




 







    }
 
    printf ("======== información del host ======== \ n");
    printf ("ifr_ifindex =% d% s \ n", s_interface_index, argv [1]);
    printf ("ifr_hwaddr =% 02x-% 02x-% 02x-% 02x-% 02x-% 02x \ n", \
        s_interface_mac [0], s_interface_mac [1], s_interface_mac [2], 
        s_interface_mac [3], s_interface_mac [4 ], s_interface_mac [5]);
    printf ("ifr_addr =% s \ n", inet_ntoa (s_interface_ip));
    printf ("ifr_flags = IFF_PROMISC \ n");
    printf ("pid = 0x% x \ n", getpid ());
    printf ("header_eth =% d \ n", HDR_LEN_ETH);
    printf ("header_arp =% d \ n", HDR_LEN_ARP);
    printf ("header_ip =% d \ n", HDR_LEN_IP);
    printf ("

 
    printf ("presione cualquier tecla para continuar! \ n");
    getchar ();
    printf ("esperando a que alguien haga ping% s ... \ n", argv [2]);
    
#if 0
    int on = 1;
    if (0! = setsockopt (skfd, IPPROTO_IP, IP_HDRINCL, & on, sizeof (on))) {         xprint_err ("setsockopt () IP_HDRINCL falló! errno =% d (% s) \ n", \             errno, strerror (errno) );         return -1;     } #endif         xping_addr = inet_addr (argv [2]);     while (1) {         uint16_t ether_type = 0;         struct ether_header * eth = NULL;         memset (s_frame_data, 0x00, sizeof (carácter sin firmar) * ETH_FRAME_LEN);         s_frame_size = xrecv_frame_ether (s_frame_data, ETH_FRAME_LEN, \





    

    



        


            s_interface_index, skfd);
            
        eth = (struct ether_header *) s_frame_data;
        ether_type = htons (eth-> ether_type);
 
        switch (ether_type) {             case ETHERTYPE_ARP: {                 xsend_reply_arp (xping_addr, skfd);                 romper;             }             caso ETHERTYPE_IP: {                      xsend_reply_icmp (xping_addr, skfd);                 romper;             }             predeterminado: {                 descanso;             }         }     }     cerrar (skfd);     return 0; } https://blog.csdn.net/maxzero/article/details/52790853













    



Supongo que te gusta

Origin blog.csdn.net/myidea999/article/details/101177206
Recomendado
Clasificación