icmp请求

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip_icmp.h>
#include <sys/time.h> /* icmp报文长度 */
#define ICMP_PACKET_LEN sizeof(struct icmp) void err_exit(const char *err_msg)
{
perror(err_msg);
exit();
} /* 校验和 */
unsigned short check_sum(unsigned short *addr, int len)
{
int nleft = len;
int sum = ;
unsigned short *w = addr;
unsigned short answer = ; while(nleft > )
{
sum += *w++;
nleft -= ;
}
if(nleft == )
{
*(unsigned char *)(&answer) = *(unsigned char *)w;
sum += answer;
} sum = (sum >> ) + (sum & 0xffff);
sum += (sum >> );
answer = ~sum; return answer;
} /* 填充icmp报文 */
struct icmp *fill_icmp_packet(int icmp_type, int icmp_sequ)
{
struct icmp *icmp_packet; icmp_packet = (struct icmp *)malloc(ICMP_PACKET_LEN);
icmp_packet->icmp_type = icmp_type;
icmp_packet->icmp_code = ;
icmp_packet->icmp_cksum = ;
icmp_packet->icmp_id = htons(getpid());
icmp_packet->icmp_seq = htons(icmp_sequ);
/* 发送时间 */
gettimeofday((struct timeval *)icmp_packet->icmp_data, NULL);
/* 校验和 */
icmp_packet->icmp_cksum = check_sum((unsigned short *)icmp_packet, ICMP_PACKET_LEN); return icmp_packet;
} /* 发送icmp请求 */
void icmp_request(const char *dst_ip, int icmp_type, int icmp_sequ)
{
struct sockaddr_in dst_addr;
struct icmp *icmp_packet;
int sockfd, ret_len;
char buf[ICMP_PACKET_LEN]; /* 请求的地址 */
bzero(&dst_addr, sizeof(struct sockaddr_in));
dst_addr.sin_family = AF_INET;
dst_addr.sin_addr.s_addr = inet_addr(dst_ip); if ((sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)) == -)
err_exit("sockfd()"); /* icmp包 */
icmp_packet = fill_icmp_packet(icmp_type, icmp_sequ);
memcpy(buf, icmp_packet, ICMP_PACKET_LEN); /* 发送请求 */
ret_len = sendto(sockfd, buf, ICMP_PACKET_LEN, , (struct sockaddr *)&dst_addr, sizeof(struct sockaddr_in));
if (ret_len > )
printf("sendto() ok!!!\n"); close(sockfd);
} int main(int argc, const char *argv[])
{
if (argc != )
{
printf("usage:%s dst_ip\n", argv[]);
exit();
} /* 发送icmp请求 */
icmp_request(argv[], , ); return ;
}

icmp接收

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h> /* IP首部长度 */
#define IP_HEADER_LEN sizeof(struct ip)
/* icmp报文长度 */
#define ICMP_PACKET_LEN sizeof(struct icmp)
/* IP + ICMP长度 */
#define IP_ICMP_PACKET_LEN IP_HEADER_LEN + ICMP_PACKET_LEN void err_exit(const char *err_msg)
{
perror(err_msg);
exit();
} /* 计算发送时间与接收时间的毫秒差 */
float time_interval(struct timeval *recv_time, struct timeval *send_time)
{
float msec = ; /* 如果接收的时间微妙小于发送的微妙 */
if (recv_time->tv_usec < send_time->tv_usec)
{
recv_time->tv_sec -= ;
recv_time->tv_usec += ;
}
msec = (recv_time->tv_sec - send_time->tv_sec) * 1000.0 + (recv_time->tv_usec - send_time->tv_usec) / 1000.0; return msec;
} int main(void)
{
struct ip *ip_header;
struct icmp *icmp_packet;
char buf[IP_ICMP_PACKET_LEN];
struct timeval *recv_timeval, *send_timeval;
int sockfd, ret_len; if ((sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)) == -)
err_exit("sockfd()"); recv_timeval = malloc(sizeof(struct timeval));
while ()
{
ret_len = recv(sockfd, buf, IP_ICMP_PACKET_LEN, );
if (ret_len > )
{
/* 接收时间 */
gettimeofday(recv_timeval, NULL);
/* 取出ip首部 */
/* 取出icmp报文 */
ip_header = (struct ip *)buf;
icmp_packet = (struct icmp *)(buf + IP_HEADER_LEN);
/* 取出发送时间 */
send_timeval = (struct timeval *)icmp_packet->icmp_data;
printf("===============================\n");
printf("from ip:%s\n", inet_ntoa(ip_header->ip_src));
printf("icmp_type:%d\n", icmp_packet->icmp_type);
printf("icmp_code:%d\n", icmp_packet->icmp_code);
printf("time interval:%.3fms\n", time_interval(recv_timeval, send_timeval));
}
} free(recv_timeval);
close(sockfd);
return ;
}

arp-icmp应答伪装

#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 not define struct ether_arp*/
struct ether_arp {
struct arphdr ea_hdr; /* fixed-size header */
u_int8_t arp_sha[ETH_ALEN]; /* sender hardware address */
u_int8_t arp_spa[]; /* sender protocol address */
u_int8_t arp_tha[ETH_ALEN]; /* target hardware address */
u_int8_t arp_tpa[]; /* target protocol address */
};
#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)
#define HDR_LEN_ICMP sizeof(struct icmp) static unsigned char s_frame_data[ETH_FRAME_LEN];
static unsigned int s_frame_size = ;
static int s_interface_index = -;
static unsigned char s_interface_mac[ETH_ALEN];
static struct in_addr s_interface_ip;
static unsigned char s_src_mac[ETH_ALEN] = {0x38,0x97,0xd6,0x51,0xa0,0x02}; static int
xsend_frame_ether(uint8_t *frame, int size, int ifindex, int skfd);
static int
xrecv_frame_ether(uint8_t *frame, int size, 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* data, int size);
static void
xutil_swap_int(uint32_t *a, uint32_t *b); static int xunused
xdump_frame_byte(uint8_t *data, int size);
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 (struct 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 = ; while (size > ) {
cksm += *data++;
size -= sizeof(uint16_t);
} if (size) {
cksm += *(uint8_t*)data;
} cksm = (cksm>>) + (cksm&0xffff);
cksm += (cksm>>); return (uint16_t)(~cksm);
} static void
xutil_swap_int(uint32_t *a, uint32_t *b)
{
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
return ;
} static int
xdump_frame_byte(uint8_t *data, int size)
{
int i; for(i=; i<size; i++) {
if((i%) == ) {
printf( "[%02x] ", i/ );
}
printf( "%02x ", data[i] );
if(((i+)%) == ) {
printf( "\n" );
}
} printf( "\n" );
return ;
} static int
xdump_frame_ether(struct ether_header *eth)
{
if (NULL == eth) {
return -;
} printf("========frame ether========\n");
printf("type :0x%04x\n", htons(eth->ether_type));
printf("d-mac:%02x-%02x-%02x-%02x-%02x-%02x\n",\
eth->ether_dhost[], eth->ether_dhost[], eth->ether_dhost[], \
eth->ether_dhost[], eth->ether_dhost[], eth->ether_dhost[]); printf("s-mac:%02x-%02x-%02x-%02x-%02x-%02x\n",\
eth->ether_shost[], eth->ether_shost[], eth->ether_shost[], \
eth->ether_shost[], eth->ether_shost[], eth->ether_shost[]);
return ;
} static int
xdump_frame_arp (struct ether_arp *arp)
{
if (NULL == arp) {
return -;
} printf("========frame arp ========\n");
printf("arp_hrd=%d \n", htons(arp->arp_hrd));
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[], arp->arp_sha[], arp->arp_sha[], \
arp->arp_sha[], arp->arp_sha[], arp->arp_sha[], \
arp->arp_spa[], arp->arp_spa[], arp->arp_spa[], \
arp->arp_spa[]);
printf("arp_tgr=%02x-%02x-%02x-%02x-%02x-%02x %d.%d.%d.%d\n", \
arp->arp_tha[], arp->arp_tha[], arp->arp_tha[], \
arp->arp_tha[], arp->arp_tha[], arp->arp_tha[], \
arp->arp_tpa[], arp->arp_tpa[], arp->arp_tpa[], \
arp->arp_tpa[]);
return ;
} static int
xdump_frame_ip(struct ip *iph)
{
if (NULL == iph) {
return -;
} printf("========frame ip ========\n");
printf("ip_v =0x%x\n", iph->ip_v ); /* 4位版本号 */
printf("ip_hl =0x%x\n", iph->ip_hl ); /* 4位IP头部长度 32bit */
printf("ip_tos=0x%x\n", iph->ip_tos ); /* 8位服务类型 */
printf("ip_len=0x%x\n", htons(iph->ip_len) ); /*16位数据包总长度 */
printf("ip_id =0x%x\n", htons(iph->ip_id) ); /*16位标志符 */
printf("ip_off=0x%x\n", htons(iph->ip_off) ); /* 3位标记+13位片偏移 */
printf("ip_ttl=0x%x\n", iph->ip_ttl ); /* 8位生存时间 */
printf("ip_p =0x%x\n", iph->ip_p ); /* 8位协议号 */
printf("ip_sum=0x%x\n", htons(iph->ip_sum) ); /*16位首部校验和 */
printf("ip_src=%s \n", inet_ntoa(iph->ip_src)); /*32位源地址 */
printf("ip_dst=%s \n", inet_ntoa(iph->ip_dst)); /*32位目的地址 */
return ;
} static int
xdump_frame_icmp (struct icmp *icmph)
{
if (NULL == icmph) {
return -;
} printf("========frame icmp ========\n");
printf("icmp_type =0x%x\n", icmph->icmp_type ); /* 8位类型 */
printf("icmp_code =0x%x\n", icmph->icmp_code ); /* 8位代码 */
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 ;
} static int
xsend_frame_ether(uint8_t *frame, int size, int ifindex, int skfd)
{
struct sockaddr_ll sll;
socklen_t sln = ; struct sockaddr_ll *psll = NULL; if (- != ifindex) {
bzero(&sll, sizeof(sll));
sll.sll_ifindex = ifindex;
sll.sll_family = PF_PACKET;
sll.sll_protocol = htons(ETH_P_ALL); psll = &sll;
sln = sizeof(struct sockaddr_ll);
} size = sendto(skfd, frame, size, , (struct sockaddr*)psll, sln);
if (size < ) {
xprint_err("ioctl() SIOCGIFINDEX failed! errno=%d (%s)\n", \
errno, strerror(errno));
} return size;
} 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<=) {
xprint_err("param failed! frame=%p size=%d\n", frame, size);
return -;
} if (- != 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(frame, , size*sizeof(uint8_t));
size = recvfrom(skfd, frame, size, , (struct sockaddr*)psll, psln); if (size < ) {
xprint_err("recvfrom() failed! errno=%d (%s)\n", \
errno, strerror(errno));
}
return size;
} 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 -;
} /*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, ); memcpy(arp->arp_sha, s_src_mac, ETH_ALEN);
memcpy(arp->arp_spa, &ipaddr, ); #if xdebug
printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("========frame size:%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 -;
} xprint_log("ok. size=%d\n", s_frame_size);
return ;
} 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 = (struct 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 ;
} /*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 = ;
iph->ip_sum = ;
iph->ip_sum = xutil_check_sum((uint16_t*)iph, HDR_LEN_IP); /*icmp*/
icmph->icmp_type = ICMP_ECHOREPLY;
icmph->icmp_cksum = ;
icmph->icmp_cksum = \
xutil_check_sum((uint16_t*)icmph, s_frame_size-HDR_LEN_ETH-HDR_LEN_IP); #if xdebug
printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("========frame size:%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, skfd)) {
return -;
} xprint_log("ok. size=%d\n", s_frame_size);
return ;
} int main(int argc, char **argv)
{
int skfd = -;
in_addr_t xping_addr = ; if (argc <= ) {
printf("usage: %s interface ipaddr\n",argv[]);
printf(" ex: %s eth0 192.168.88.1\n", argv[]);
return -;
} skfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (skfd < ) {
xprint_err("socket() failed! errno=%d (%s)\n", errno, strerror(errno));
return -;
} struct ifreq ifr;
bzero(&ifr,sizeof(ifr));
strcpy(ifr.ifr_name, argv[]);
if (- == ioctl(skfd, SIOCGIFINDEX, &ifr)) {
xprint_err("ioctl() SIOCGIFINDEX failed! errno=%d (%s)\n", \
errno, strerror(errno));
return -;
}
s_interface_index = ifr.ifr_ifindex; if (- == ioctl(skfd, SIOCGIFHWADDR, &ifr)) {
xprint_err("ioctl() SIOCGIFHWADDR failed! errno=%d (%s)\n", \
errno, strerror(errno));
return -;
}
memcpy(s_interface_mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN); if (- == ioctl(skfd, SIOCGIFADDR, &ifr)) {
xprint_err("ioctl() SIOCGIFADDR failed! errno=%d (%s)\n", \
errno, strerror(errno));
return -;
}
s_interface_ip.s_addr = \
((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr.s_addr; if (- == ioctl(skfd, SIOCGIFFLAGS, &ifr)) {
xprint_err("ioctl() IFF_PROMISC failed! errno=%d (%s)\n", \
errno, strerror(errno));
return -;
} if ((ifr.ifr_flags&IFF_PROMISC) != IFF_PROMISC) {
ifr.ifr_flags |= IFF_PROMISC;
if(- == ioctl(skfd, SIOCSIFFLAGS, &ifr)) {
xprint_err("ioctl() IFF_PROMISC failed! errno=%d (%s)\n", \
errno, strerror(errno));
return -;
}
} printf("========host info ========\n");
printf("ifr_ifindex=%d %s\n", s_interface_index, argv[]);
printf("ifr_hwaddr =%02x-%02x-%02x-%02x-%02x-%02x\n", \
s_interface_mac[], s_interface_mac[], s_interface_mac[],
s_interface_mac[], s_interface_mac[], s_interface_mac[]);
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("header_icmp=%d\n", HDR_LEN_ICMP);
printf("\n"); printf("press any key continue!\n");
getchar();
printf("waiting for someone ping %s ...\n", argv[]); #if 0
int on = ;
if ( != setsockopt(skfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on))) {
xprint_err("setsockopt() IP_HDRINCL failed! errno=%d (%s)\n", \
errno, strerror(errno));
return -;
}
#endif xping_addr = inet_addr(argv[]); while() {
uint16_t ether_type = ;
struct ether_header* eth = NULL; memset(s_frame_data, 0x00, sizeof(unsigned char)*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);
break;
}
case ETHERTYPE_IP: {
xsend_reply_icmp(xping_addr, skfd);
break;
}
default: {
break;
}
}
} close(skfd);
return ;
}

最新文章

  1. 第50课 关于对话框(About)
  2. 多个SVG图形集成到一个SVG图形上
  3. Web服务及http协议
  4. loopback 05
  5. Android_开发工具的下载和开发环境的搭建
  6. 【树莓派2B倒腾日志】之安装系统及配置
  7. IntelliJ IDEA中怎样使用JUnit4
  8. IOS网络请求中文转码
  9. OpenCV ——双线性插值(Bilinear interpolation)
  10. 小程序中曾经遇到的坑(1)----canvas画布
  11. Multipath在OpenStack中的faulty device的成因及解决(part 1)
  12. Android 推送和统计最优轮循(心跳策略)探究实践
  13. Python内置函数(34)——isinstance
  14. python Selenium启动chromedriver
  15. Java类集 List, Set, Map, Stack, Properties基本使用
  16. 数据库中表的位置,在sysdatabases中
  17. [转]Restrict关键字
  18. [LeetCode&amp;Python] Problem 104. Maximum Depth of Binary Tree
  19. 利用Windows 2003系统中实现两个网段的路由
  20. 排列组合算法(基于c++实现)

热门文章

  1. pyinstaller打包后的exe退出时,类中的__del__不执行问题
  2. git移除某文件夹的版本控制
  3. 如何使用MongoDB+Springboot实现分布式ID?
  4. Oracle中文乱码解决
  5. docker启用镜像常用脚本
  6. python入门基本知识
  7. python如果想输出原格式的内容,可以加&#39;&#39;&#39; &#39;&#39;&#39;,占位符使用方式
  8. gcc常用语法
  9. C++基础 inline 默认参数 函数占位参数 函数重载
  10. Codeforces Round #482 (Div. 2) :C - Kuro and Walking Route