linux下发送arp请求报文 代码
2011-09-29 16:07
274 查看
1,本代码主要是参考 宋敬彬的<<>linux 网络编程>写的,如果完全按照书上的代码编译不能通过,编译通过后运行出现提示:Transport endpoint is not connected。用tcpdump抓包发现没有arp请求报文发送出去。我用的操作系统 为ubuntu9.10 内核2.6.31。在网上查了些资料,修改后可以实现arp请求的基本功能了。
2,修改后的代码如下:
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <linux/if_ether.h>
#include <netinet/in.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/if_arp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct arppacket{ //自己构建的arp包,不含以太网头部
unsigned short ar_hrd; //arp硬件类型
unsigned short ar_pro; //arp协议
unsigned char ar_hln; //arp硬件地址长度
unsigned char ar_pln; //arp协议地址长度
unsigned short ar_op; //arp 操作码 //上面部分也可以用,struct arphdr结构来构造。
unsigned char ar_sha[ETH_ALEN];//发送方mac地址
unsigned char ar_sip[4]; //放送方ip地址
unsigned char ar_dha[ETH_ALEN]; //目的mac地址
unsigned char ar_dip[4]; //目的ip地址 //上面是构造arp数据部分,用于以太网。
char pad[18]; //18个填充字节,满足以太网最少帧长度64字节含4字节校验码。
};
int main(int argc,char *argv[]){
char ef[ETH_FRAME_LEN];
struct ethhdr *p_ethhdr; //以太网头部指针
char eth_dest[ETH_ALEN]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; //目的mac地址
char eth_source[ETH_ALEN]={0x00,0x12,0x34,0x56,0x78,0x90}; //自己构造源mac地址与实际的不相符
char eth_arpmac[ETH_ALEN]={0x00,0x00,0x00,0x00,0x00,0x00};
int n;
int fd;
int i;
if(argc!=3){
printf("usage:%s sourceip destip\n",argv[0]);
exit(1);
}
fd=socket(AF_INET,SOCK_PACKET,htons(ETH_P_ARP)); //
p_ethhdr=(struct ethhdr *)ef;
memcpy(p_ethhdr->h_dest,eth_dest,ETH_ALEN);
memcpy(p_ethhdr->h_source,eth_source,ETH_ALEN);
p_ethhdr->h_proto=htons(0x0806) ;//设置以太网头部的协议类型为0x0806也就是arp协议。
struct arppacket *p_arp;
struct in_addr in;
p_arp=ef+ETH_HLEN;
p_arp->ar_hrd=htons(0x01); //arp硬件类型0x01为以太网类型
p_arp->ar_pro=htons(0x0800); //设置协议类型0x0800表示ip网路
p_arp->ar_hln=6; //以太网地址长度为六
p_arp->ar_pln=4; //ip地址长度为4
p_arp->ar_op=htons(ARPOP_REQUEST);
memcpy(p_arp->ar_sha,eth_source,ETH_ALEN);
memcpy(p_arp->ar_dha,eth_arpmac,ETH_ALEN);
if((in.s_addr=inet_addr(argv[1]))==-1){
perror("inet_addr");
exit(1);
}
memcpy(p_arp->ar_sip,&in.s_addr,4);
if((in.s_addr=inet_addr(argv[2]))==-1){
perror("inet_addr");
exit(1);
}
memcpy(p_arp->ar_dip,&in.s_addr,4);
bzero(p_arp->pad,18);
struct sockaddr to;
strcpy(to.sa_data,"eth0");
for(i=0;i<8;i++){
if(sendto(fd,&ef,64,0,&to,sizeof(to))<0){
perror("sendto");
exit(1);
}
sleep(10);
}
close(fd);
return 0;
}
上面代码基本实现了arp的请求。用tcpdump 抓包可以扑获到arp请求包。如果把sleep时间改成1秒,循环改成死循环,把源ip地址改成网关地址,就可以使局域网中的其他机器都无法上网,因为他们收到arp请求报文后会更新自己的arp表,从而把正确的网关的mac地址会改成一个错误的mac地址。
2,修改后的代码如下:
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <linux/if_ether.h>
#include <netinet/in.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/if_arp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct arppacket{ //自己构建的arp包,不含以太网头部
unsigned short ar_hrd; //arp硬件类型
unsigned short ar_pro; //arp协议
unsigned char ar_hln; //arp硬件地址长度
unsigned char ar_pln; //arp协议地址长度
unsigned short ar_op; //arp 操作码 //上面部分也可以用,struct arphdr结构来构造。
unsigned char ar_sha[ETH_ALEN];//发送方mac地址
unsigned char ar_sip[4]; //放送方ip地址
unsigned char ar_dha[ETH_ALEN]; //目的mac地址
unsigned char ar_dip[4]; //目的ip地址 //上面是构造arp数据部分,用于以太网。
char pad[18]; //18个填充字节,满足以太网最少帧长度64字节含4字节校验码。
};
int main(int argc,char *argv[]){
char ef[ETH_FRAME_LEN];
struct ethhdr *p_ethhdr; //以太网头部指针
char eth_dest[ETH_ALEN]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; //目的mac地址
char eth_source[ETH_ALEN]={0x00,0x12,0x34,0x56,0x78,0x90}; //自己构造源mac地址与实际的不相符
char eth_arpmac[ETH_ALEN]={0x00,0x00,0x00,0x00,0x00,0x00};
int n;
int fd;
int i;
if(argc!=3){
printf("usage:%s sourceip destip\n",argv[0]);
exit(1);
}
fd=socket(AF_INET,SOCK_PACKET,htons(ETH_P_ARP)); //
p_ethhdr=(struct ethhdr *)ef;
memcpy(p_ethhdr->h_dest,eth_dest,ETH_ALEN);
memcpy(p_ethhdr->h_source,eth_source,ETH_ALEN);
p_ethhdr->h_proto=htons(0x0806) ;//设置以太网头部的协议类型为0x0806也就是arp协议。
struct arppacket *p_arp;
struct in_addr in;
p_arp=ef+ETH_HLEN;
p_arp->ar_hrd=htons(0x01); //arp硬件类型0x01为以太网类型
p_arp->ar_pro=htons(0x0800); //设置协议类型0x0800表示ip网路
p_arp->ar_hln=6; //以太网地址长度为六
p_arp->ar_pln=4; //ip地址长度为4
p_arp->ar_op=htons(ARPOP_REQUEST);
memcpy(p_arp->ar_sha,eth_source,ETH_ALEN);
memcpy(p_arp->ar_dha,eth_arpmac,ETH_ALEN);
if((in.s_addr=inet_addr(argv[1]))==-1){
perror("inet_addr");
exit(1);
}
memcpy(p_arp->ar_sip,&in.s_addr,4);
if((in.s_addr=inet_addr(argv[2]))==-1){
perror("inet_addr");
exit(1);
}
memcpy(p_arp->ar_dip,&in.s_addr,4);
bzero(p_arp->pad,18);
struct sockaddr to;
strcpy(to.sa_data,"eth0");
for(i=0;i<8;i++){
if(sendto(fd,&ef,64,0,&to,sizeof(to))<0){
perror("sendto");
exit(1);
}
sleep(10);
}
close(fd);
return 0;
}
上面代码基本实现了arp的请求。用tcpdump 抓包可以扑获到arp请求包。如果把sleep时间改成1秒,循环改成死循环,把源ip地址改成网关地址,就可以使局域网中的其他机器都无法上网,因为他们收到arp请求报文后会更新自己的arp表,从而把正确的网关的mac地址会改成一个错误的mac地址。
相关文章推荐
- Linux arping :向相邻主机发送ARP请求
- ARP报文的发送与接收(Linux下gcc编译)
- 【转】linux socket()调用与arp报文发送
- Linux C 实现最简单的ICMP_ECHO请求报文发送
- linux原始套接字-发送ARP报文
- linux命令发送http的get或post请求(curl和wget两种方法)
- robot framework用SSHLibrary发送ctrl-c 等控制字符(control character)到远端 ssh server(如linux server)的表格代码
- linux C发送 http 请求
- linux原始套接字(1)-arp请求与接收
- linux原始套接字(1)-arp请求与接收
- Linux下UDP发送大量请求导致Operation not permitted的问题探讨
- React Native 使用Fetch发送网络请求的示例代码
- Multipart/form-data POST文件上传详解 理论 简单的HTTP POST 大家通过HTTP向服务器发送POST请求提交数据,都是通过form表单提交的,代码如下: <form me
- 发送请求到webservice,得到错误代码
- Windows 和 Linux下使用socket下载网页页面内容(可设置接收/发送超时)的代码
- java代码发送JSON格式的httpPOST请求
- JavaScript发送AJAX请求的代码
- C#代码模拟http发送get和post请求
- Java 用HTTP的方式发送JSON报文请求
- 报文的发送函数 (linux网络子系统学习 第十三节)