⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 536.htm

📁 unix高级编程原吗
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://apue.dhs.org"><font face="黑体"><big><big>apue</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center">               ● UNIX网络编程                       (BM: clown)                </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p   align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="index.htm">回到开始</a>][<a href="519.htm">上一层</a>][<a href="537.htm">下一篇</a>]
<hr><p align="left"><small>发信人: scz (小四), 信区: Security WWW-POST <br>

标  题: libnet使用举例(12) <br>

发信站: 武汉白云黄鹤站 (Fri Dec 15 10:08:22 2000) , 站内信件 <br>

作者:小四 < mailto: scz@nsfocus.com > <br>

主页:http://www.nsfocus.com <br>

日期:2000-12-12 16:20 <br>

本系列1-11都是raw socket layer programming,今天介绍link layer programming, <br>

  <br>

下面是链路层编程用到的部分关键函数: <br>

int libnet_build_ethernet ( u_char * daddr, u_char * saddr, u_short id, <br>

                            const u_char * payload, int payload_s, <br>

                            u_char * buf ); <br>

该函数用于构造以太网物理帧,daddr、saddr分别指向一个6字节数组,对应物理帧 <br>

的目标MAC、源MAC。id指定物理帧类型,有效值如下: <br>

值                  代表的类型 <br>

ETHERTYPE_PUP       PUP protocol <br>

ETHERTYPE_IP        IP protocol <br>

ETHERTYPE_ARP       ARP protocol <br>

ETHERTYPE_REVARP    Reverse ARP protocol <br>

ETHERTYPE_VLAN      IEEE VLAN tagging <br>

ETHERTYPE_LOOPBACK  Used to test intefaces <br>

payload为NULL,payload_s为零。最后一个参数buf,指向通过libnet_init_packet <br>

分配并初始化过的数据区,此时buf指向的实际是物理帧头。 <br>



必须意识到,某些链路层接口(比如BPF)不允许伪装物理帧源MAC,除非你自己更改内 <br>

核。 <br>

int libnet_build_arp ( u_short hrd, u_short pro, u_short hln, u_short pln, <br>

                       u_short op, u_char * sha, u_char * spa, u_char * tha, <br>

  <br>

                       u_char * tpa, const u_char * payload, int payload_s, <br>

                       u_char * buf ); <br>

该函数用于构造ARP报文。对于常见应用来说,hrd为ARPHRD_ETHER,pro为 <br>

ETHERTYPE_IP,hln为ETHER_ADDR_LEN(就是6,MAC地址长度),pln为4(IPv4地址长度), <br>

  <br>

op指定ARP操作类型,有效取值有ARPOP_REQUEST、ARPOP_REPLY、ARPOP_REVREQUEST、 <br>

ARPOP_REVREPLY、ARPOP_INVREQUEST 以及 ARPOP_INVREPLY,我不知道最后两种类型 <br>

是什么意思,这里op以主机字节序提供,比如0x0002就是ARPOP_REPLY。sha指定发送 <br>

方MAC地址,spa指定发送方IP地址,tha指定接收方MAC地址,tpa指定接收方IP地址, <br>

payload为NULL,payload_s为零。形参buf需要指向一个已分配好的数据区,ARP层从 <br>

该指针开始。 <br>

struct libnet_link_int * libnet_open_link_interface ( char * device, char * <br>

ebuf <br>

 ); <br>

int libnet_close_link_interface ( struct libnet_link_int * l ); <br>

如果需要直接发送链路层物理帧,必须事先使用libnet_open_link_interface()打开 <br>

接口设备。device指定接口设备名,对于Linux就是"eth0"一类的名字。ebuf通常定 <br>



义如下: <br>

char err_buf[ LIBNET_ERRBUF_SIZE ]; <br>

/usr/include/libnet/libnet-macros.h: <br>

#define LIBNET_ERRBUF_SIZE 256 <br>

如果调用失败返回NULL,成功则填充一个libnet_link_int结构,并返回这个结构指 <br>

针。libnet_close_link_interface()与libnet_open_link_interface()对应,关闭 <br>

先前打开的接口设备,失败返回-1,成功返回1。 <br>

int libnet_select_device ( struct sockaddr_in * sin, u_char ** device, u_cha <br>

r * <br>

ebuf ); <br>

如果你不能确定libnet_open_link_interface()第一形参使用什么样的接口设备名, <br>

可以调用libnet_select_device()获取它。后者遍历接口链表,从中选择第一个可用 <br>

的非回送接口。sin、device不得为NULL,sin必须指向一个sockaddr_in结构, <br>

device必须指向一个指针,*sin、*device的初值无所谓。调用成功返回1,*device <br>

指向一个有效接口设备名,可以用于后续的libnet_open_link_interface()调用。失 <br>

败返回-1,ebuf将包含失败原因。 <br>

struct ether_addr * libnet_get_hwaddr ( struct libnet_link_int * l, <br>

                                        const u_char * device, <br>

                                        const u_char * ebuf ); <br>

第一形参来自libnet_open_link_interface(),device指向接口设备名。成功则返回 <br>

指定接口的MAC地址,失败返回0(NULL),ebuf将包含失败原因。 <br>

int libnet_write_link_layer ( struct libnet_link_int * l, const u_char * dev <br>



ice, <br>

                              u_char * buf, int len ); <br>

该函数用于直接发送链路层物理帧,第一形参来自libnet_open_link_interface(), <br>

device指向接口设备名。buf指向物理帧头,一般由libnet_init_packet分配并初始 <br>

化,libnet_destroy_packet()负责释放。len指定物理帧长度。失败返回-1,否则返 <br>

回发送出去的字节数。 <br>

写个arpsend程序来验证这些可爱的函数,recvMac必须为真实有效的MAC地址,否则 <br>

谁接收呢。sendMac根据需要可以伪装,但链路层支持为BPF时无法伪装,除非自己更 <br>

改内核。关于ARP协议本身的讨论太多,不做进一步说明。没有提供随机数支持,如 <br>

果你自己有特殊需要,可以参看本系列1-11中反复使用的技术,也可以直接使用 <br>

libnet本身提供的libnet_seed_prand()、libnet_get_prand()函数。如果有时间, <br>

会提供另外一个程序演示这两个随机函数。 <br>

-------------------------------------------------------------------------- <br>

/* <br>

 * File   : arpsend program for I386/Linux using libnet <br>

 * Version: 0.01 aleph <br>

 * Author : scz < mailto: scz@nsfocus.com > <br>

 *        : http://www.nsfocus.com <br>

 * Complie: gcc -O3 -o arpsend arpsend.c `libnet-config --defines --cflags` <br>

`lib <br>

net-config --libs` -Wall <br>

 * Usage  : ./arpsend --recv 000000111111 --si 192.168.8.90 --sm 00000022222 <br>



2 -- <br>

num 30 <br>

 * Date   : 2000-12-13 16:43 <br>

 */ <br>

/******************************************************************* <br>

 *                                                                 * <br>

 *                            Head File                            * <br>

 *                                                                 * <br>

 *******************************************************************/ <br>

#define _GNU_SOURCE <br>

#include <stdio.h> <br>

#include <stdlib.h> <br>

#include <getopt.h>  /* for getopt() */ <br>

#include <libnet.h> <br>

/******************************************************************* <br>

 *                                                                 * <br>

 *                            Macro                                * <br>

 *                                                                 * <br>

 *******************************************************************/ <br>

#define SUCCESS            0 <br>

#define FAILURE           -1 <br>

#define DEFAULTARPNUMBER   0x5  /* 缺省发送ARP报文数目 */ <br>



/******************************************************************* <br>

 *                                                                 * <br>

 *                       Static Global Var                         * <br>

 *                                                                 * <br>

 *******************************************************************/ <br>

static u_char *                 packet       = NULL; <br>

static size_t                   packet_size  = LIBNET_ETH_H + LIBNET_ARP_H; <br>

static struct libnet_link_int * link_handler = NULL; <br>

/******************************************************************* <br>

 *                                                                 * <br>

 *                        Function Prototype                       * <br>

 *                                                                 * <br>

 *******************************************************************/ <br>

static void   Libnet_close_link_interface ( struct libnet_link_int * l ); <br>

/* <br>

static void   Libnet_get_hwaddr           ( struct libnet_link_int * l, cons <br>

t u_ <br>

char * device, u_char * mac ); <br>

*/ <br>

static void   Libnet_init_packet          ( size_t p_size, u_char ** buf ); <br>

static struct libnet_link_int * Libnet_open_link_interface ( char * device ) <br>

; <br>

; <br>

static void   Libnet_select_device        ( u_char ** device ); <br>

static void   Libnet_write_link_layer     ( struct libnet_link_int * l, cons <br>

t u_ <br>

char * device, u_char * buf, int len ); <br>

static char * Strncpy                     ( char * dest, const char * src, s <br>

ize_ <br>

t n ); <br>

static void   usage                       ( char * arg ); <br>

/*----------------------------------------------------------------------*/ <br>

static void Libnet_close_link_interface ( struct libnet_link_int * l ) <br>

{ <br>

    if ( libnet_close_link_interface( l ) == -1 ) <br>

    { <br>

        libnet_error( LIBNET_ERR_WARNING, "libnet_close_link_interface faile <br>

d\n" <br>

 ); <br>

    } <br>

    return; <br>

}  /* end of Libnet_close_link_interface */ <br>

/* <br>

static void Libnet_get_hwaddr ( struct libnet_link_int * l, const u_char * d <br>

evic <br>

evic <br>

e, u_char * mac ) <br>

{ <br>

    char                err_buf[ LIBNET_ERRBUF_SIZE ]; <br>

    struct ether_addr * m = NULL; <br>

    if ( mac == NULL ) <br>

    { <br>

        return; <br>

    } <br>

    m = libnet_get_hwaddr( l, device, err_buf ); <br>

    if ( m == NULL ) <br>

    { <br>

        libnet_error( LIBNET_ERR_WARNING, "libnet_get_hwaddr failed: %s\n", <br>

err_ <br>

buf ); <br>

    } <br>

    else <br>

    { <br>

        memmove( mac, ( u_char * )m, 6 ); <br>

    } <br>

    return; <br>

} <br>

*/ <br>

*/ <br>

static void Libnet_init_packet ( size_t p_size, u_char ** buf ) <br>

{ <br>

    if ( libnet_init_packet( p_size, buf ) == -1 ) <br>

    { <br>

        libnet_error( LIBNET_ERR_FATAL, "Can't initialize packet\n" ); <br>

    } <br>

    return; <br>

}  /* end of Libnet_init_packet */ <br>

static struct libnet_link_int * Libnet_open_link_interface ( char * device ) <br>

  <br>

{ <br>

    struct libnet_link_int * link = NULL; <br>

    char                     err_buf[ LIBNET_ERRBUF_SIZE ]; <br>

    if ( ( link = libnet_open_link_interface( device, err_buf ) ) == NULL ) <br>

    { <br>

        libnet_error( LIBNET_ERR_FATAL, "libnet_open_link_interface failed: <br>

%s\n <br>

", err_buf ); <br>

    } <br>

    return( link ); <br>

}  /* end of Libnet_open_link_interface */ <br>

static void Libnet_select_device ( u_char ** device ) <br>



{ <br>

    struct sockaddr_in sin; <br>

    char               err_buf[ LIBNET_ERRBUF_SIZE ]; <br>

    if ( device == NULL ) <br>

    { <br>

        libnet_error( LIBNET_ERR_FATAL, "Can't locate a device\n" ); <br>

    } <br>

    if ( libnet_select_device( &sin, device, err_buf ) == -1 ) <br>

    { <br>

        libnet_error( LIBNET_ERR_FATAL, "libnet_select_device failed: %s\n", <br>

 err <br>

_buf ); <br>

    } <br>

    fprintf( stderr, "[ device --> %s ]\n", *device ); <br>

    return; <br>

}  /* end of Libnet_select_device */ <br>

static void Libnet_write_link_layer ( struct libnet_link_int * l, <br>

                                      const u_char * device, u_char * buf, i <br>

nt l <br>

en ) <br>

{ <br>

    int w; <br>

    int w; <br>

    if ( ( w = libnet_write_link_layer( l, device, buf, len ) ) < len ) <br>

    { <br>

        libnet_error( LIBNET_ERR_WARNING, "libnet_write_link_layer only wrot <br>

e %d <br>

 bytes\n", w ); <br>

    } <br>

    return; <br>

}  /* end of Libnet_write_link_layer */ <br>

static char * Strncpy ( char * dest, const char * src, size_t n ) <br>

{ <br>

    char * pChar; <br>

    pChar = strncpy( dest, src, n ); <br>

    if ( pChar == NULL ) <br>

    { <br>

        exit( FAILURE ); <br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -