ARP头文件的解释

发表于:2007-06-09来源:作者:点击数: 标签:
/*注释 ie_minix*/ /*要了解ARP包,他的结构和一些常量你必须知道是什么意思*/ #ifndef_NET_IF_ARP_H_ #define_NET_IF_ARP_H_ /* *地址解释协议. * *查看RFC826对该协议的描述.ARP包长度是变化的 *头部(arphdr)结构定义了固定长度部分. */ structarphdr{ u_sh

/*        注释ie_minix   */
/*        要了解ARP包,他的结构和一些常量你必须知道是什么意思*/                               
#ifndef _NET_IF_ARP_H_
#define _NET_IF_ARP_H_

/*
 * 地址解释协议.
 *
 * 查看 RFC 826 对该协议的描述.  ARP 包长度是变化的
 * 头部(arphdr)结构定义了固定长度部分.
 */
struct arphdr {
u_short ar_hrd; /* 格式化的硬件地址 */
#define ARPHRD_ETHER  1 /* 以太网格式 */
#define ARPHRD_IEEE802 6 /* 令牌环网格式 */
#define ARPHRD_FRELAY  15 /* 帧中继硬件格式 */
u_short ar_pro; /* 协议地址格式 */
u_char ar_hln; /* 硬件地址长度*/
u_char ar_pln; /* 协议地址长度 */
u_short ar_op; /* 以下之一: */
#define ARPOP_REQUEST 1 /* 发出请求解释一IP地址 */
#define ARPOP_REPLY 2 /* 回应上一个请求 */
#define ARPOP_REVREQUEST 3 /* 请求一IP地址(给出硬件地址,实际上是逆向地址解释) */
#define ARPOP_REVREPLY 4 /* 回应逆向地址解释 */
#define ARPOP_INVREQUEST 8  /* 请求对方的ID */
#define ARPOP_INVREPLY 9 /* 回应对方的ID */
/*
 * 下面的字段是可变长的,
 * 主要是依照上面给出的定义.
 */
#ifdef COMMENT_ONLY
u_char ar_sha[]; /* 发送者硬件地址 */
u_char ar_spa[]; /* 发送者协议地址 */
u_char ar_tha[]; /* 目的方硬件地址 */
u_char ar_tpa[]; /* 目的方协议地址*/
#endif
};

/*
 * ARP ioctl 请求
 */
struct arpreq {
struct sockaddr arp_pa; /* 协议地址 */
struct sockaddr arp_ha; /* 硬件地址 */
int arp_flags; /* 标识 */
};
/*  arp_flags 和 at_flags 域的值 */
#define ATF_INUSE 0x01 /* 入口在使用 */
#define ATF_COM 0x02 /* 完整的入口 (enaddr 有效) */
#define ATF_PERM 0x04 /* 持久的入口 */
#define ATF_PUBL 0x08 /* 发布一入口 (回应其他主机) */
#define ATF_USETRAILERS 0x10 /* 有追踪请求 */

#ifdef _KERNEL
/*
 * 该结构是以太网设备驱动程序和ARP程序所共享. 
 */
struct arpcom {
/*
 *  ifnet 结构必须在此结构的第一个位置.
 */
struct  ifnet ac_if;
u_char ac_enaddr[6]; /* 以太网硬件地址*/
int ac_multicnt; /* 多播地址列表数 */
void *ac_netgraph; /* PPPoE(ADSL)的指针 */
};

extern u_char etherbroadcastaddr[6];
#endif

#endif /* !_NET_IF_ARP_H_ */

 i2era 回复于:2003-06-11 18:32:49
楼上的高手啊,给偶这个新手写个程序吧,感激不尽哦~~~
send_arp
这是程序在Linux的实现(),给写个FreeBSD上的吧,多谢哦~~~
[code:1:1855781ad0]
/* 
This program sends out one ARP packet with source/target IP 
and Ethernet hardware addresses suuplied by the user. It  
compiles and works on Linux and will probably work on any  
Unix that has SOCK_PACKET. volobuev@t1.chem.umn.edu  
*/  
/*it do not compile at FreeBSD. :( 
*/ 
#include <netdb.h> 
#include <sys/socket.h> 
#include <sys/types.h> 
#include <stdio.h> 
#include <errno.h> 
#include <sys/ioctl.h> 
#include <net/if.h> 
#include <signal.h> 
#include <netinet/ip.h> 
#include <netinet/in.h> 
#include <string.h> 
#include <arpa/inet.h> 
#include <netinet/ip_icmp.h> 
#include <linux/if_ether.h> 
#define ETH_HW_ADDR_LEN 6  
#define IP_ADDR_LEN 4  
#define ARP_FRAME_TYPE 0x0806  
#define ETHER_HW_TYPE 1  
#define IP_PROTO_TYPE 0x0800  
#define OP_ARP_REQUEST 2  
#define OP_ARP_QUEST 1 
#define DEFAULT_DEVICE "eth0"  
char usage[] = {"send_arp: sends out custom ARP packet. yuri volobuev 
   usage: send_arp src_ip_addr src_hw_addr targ_ip_addr tar_hw_addr number"};  
struct arp_packet  
{  
u_char targ_hw_addr[ETH_HW_ADDR_LEN];  
u_char src_hw_addr[ETH_HW_ADDR_LEN];  
u_short frame_type;  
u_short hw_type;  
u_short prot_type;  
u_char hw_addr_size;  
u_char prot_addr_size;  
u_short op;  
u_char sndr_hw_addr[ETH_HW_ADDR_LEN];  
u_char sndr_ip_addr[IP_ADDR_LEN];  
u_char rcpt_hw_addr[ETH_HW_ADDR_LEN];  
u_char rcpt_ip_addr[IP_ADDR_LEN];  
u_char padding[18];  
};  
void die (char *);  
void get_ip_addr (struct in_addr *, char *);  
void get_hw_addr (char *, char *);  
int main (int argc, char * argv[])  
{  
struct in_addr src_in_addr, targ_in_addr;  
struct arp_packet pkt;  
struct sockaddr sa;  
int sock;  
int j,number; 
if (argc != 6)  
die(usage);  
sock = socket(AF_INET, SOCK_PACKET, htons(ETH_P_RARP));  
if (sock < 0)  
{  
perror("socket");  
exit(1);  
}  
number=atoi(argv[5]); 
pkt.frame_type = htons(ARP_FRAME_TYPE);  
pkt.hw_type = htons(ETHER_HW_TYPE);  
pkt.prot_type = htons(IP_PROTO_TYPE);  
pkt.hw_addr_size = ETH_HW_ADDR_LEN;  
pkt.prot_addr_size = IP_ADDR_LEN;  
pkt.op = htons(OP_ARP_QUEST);  
get_hw_addr(pkt.targ_hw_addr, argv[4]);  
get_hw_addr(pkt.rcpt_hw_addr, argv[4]);  
get_hw_addr(pkt.src_hw_addr, argv[2]);  
get_hw_addr(pkt.sndr_hw_addr, argv[2]);  
get_ip_addr(&src_in_addr, argv[1]);  
get_ip_addr(&targ_in_addr, argv[3]);  
memcpy(pkt.sndr_ip_addr, &src_in_addr, IP_ADDR_LEN);  
memcpy(pkt.rcpt_ip_addr, &targ_in_addr, IP_ADDR_LEN);  
bzero(pkt.padding,18);  
strcpy(sa.sa_data,DEFAULT_DEVICE);  
for (j=0;j<number;j++) 

if (sendto(sock,&pkt,sizeof(pkt),0,&sa,sizeof(sa)) < 0)  
{  
perror("sendto");  
exit(1);  
}   

exit(0);  
}  
void die (char *str)  
{  
fprintf(stderr,"%s\n",str);  
exit(1);  
}  
void get_ip_addr (struct in_addr *in_addr, char *str)  
{  
struct hostent *hostp;  
in_addr->s_addr = inet_addr(str);  
if(in_addr->s_addr == -1) 
{  
if ((hostp = gethostbyname(str)))  
bcopy(hostp->h_addr, in_addr, hostp->h_length);  
else {  
fprintf(stderr, "send_arp: unknown host %s\n", str);  
exit(1);  
     }  
}  
}  
void get_hw_addr (char *buf, char *str)  
{  
int i;  
char c, val;  
for(i = 0; i < ETH_HW_ADDR_LEN; i++)  
{  
if (!(c = tolower(*str++)))  
die("Invalid hardware address");  
if (isdigit(c))  
val = c - '0';  
else if (c >= 'a' && c <= 'f')  
val = c-'a'+10;  
     else  
die("Invalid hardware address");  
*buf = val << 4;  
if (!(c = tolower(*str++)))  
die("Invalid hardware address");  
if (isdigit(c))  
val = c - '0';  
else if (c >= 'a' && c <= 'f')  
val = c-'a'+10;  
     else  
die("Invalid hardware address");  
*buf++ |= val;  
if (*str == ':')  
str++;  
}  
}
[/code:1:1855781ad0]

 xie_minix 回复于:2003-06-11 21:22:18
这位朋友,真对不起,现在我正在对if_ether.c做说明(也就是整个的ARP的实现代码),完成了以后我一定给你写.

 xie_minix 回复于:2003-06-11 21:27:52
顺便请问一下, "楼上的高手"是什么意思啊,有什么典故吗,

 i2era 回复于:2003-06-11 22:23:39
[quote:89366d92f4="xie_minix"]顺便请问一下, "楼上的高手"是什么意思啊,有什么典故吗,[/quote:89366d92f4]     
"楼上的高手"就是指你呀,HoHo~~~

 i2era 回复于:2003-06-11 22:24:10
[quote:6632b49261="xie_minix"]这位朋友,真对不起,现在我正在对if_ether.c做说明(也就是整个的ARP的实现代码),完成了以后我一定给你写.[/quote:6632b49261]     
非常感谢!     
PS:ports下有个arping,可以看看,也许有用~~~

 jinbsd 回复于:2003-06-12 10:12:14
可以给我看看你写的ARP实现的原代码吗?

 黑夜编码人 回复于:2003-06-12 12:21:09
BSD上写这种程序好像必须用到BPF,不如Linux下方便,我在网上找了快2个月的时间了,都没有找到BPF编程方面的资料。 
哪位有共享出来一下三。

原文转自:http://www.ltesting.net