#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
ping.c
Supongo que te gusta
Origin blog.csdn.net/myidea999/article/details/101177206
Recomendado
Clasificación