加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

linux下C语言实现ARP数据包发送

(2010-11-17 09:08:22)
标签:

it

分类: 技术档案

(来自网络,用于保存)

#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. ferrysnow@gmail.com \nusage : 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++;
                }
        }
}
 

0

阅读 收藏 喜欢 打印举报/Report
前一篇:大火无情
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有