libnet 레퍼런스
libnet 라이브러리는 응용 프로그램이 패킷을 생성하여 보낼 수 있게 해주는 라이브러리로, 직접 패킷을 생성하는 것보다 훨씬 간단하게 패킷을 생성하여 보낼 수 있으며, 보통 Libpcap과 함께 쓰인다. 이 두라이브러리를 이용하면 ping과 traceroute 같은 프로그램을 쉽게 작성할 수 있다고 한다.
libnet이 지원하는 함수
메모리의 패킷 관리 함수, 주소 확인 함수, 패킷 구조 생성 함수, 패킷 생성함수등이 있다.
libnet이 지원하는 프로토콜로는
2계층은 ARP와 이더넷 , 3계층은 ICMP,IGMP, IPv4, 4계층은 TCP, UDP, 7계층은 RIP, OSPF,DNS 이 있다.
☆ Memory Alllocation and Initialization
libnet을 이용한 프로그램을 작성하기 위한 첫번째 단계는 패킷을 위한 메모릴를 할당하는거라고 한다.
IP-layer 인터페이스를 사용하면서 30 Byte의 Payload를 갖는 단순한 TCP 패킷을 생성하려고 한다면, 70 Bytes(IP Header + TCP header + Payload)가 필요할 것이다.
Link-layer 인터페이스를 사용하면서 30 Byte의 Payload를 갖는 단순한 TCP 패킷을 생성하려고 한다면, 84 Bytes(Ethemet header + IP header + TCP header + Payload)가 필요할 것이다.
작업이 끝냇을 경우는 libnet_destroy_packet()을 이용하여 메모리를 해체해 주어야 한다. (프로그램의 끝이나, garbage collection 경우)
☆ Network Initialization
이 단계는 네트워크 전송 인터페이스를 얻어오는 것이다.
○ IP-lay : 인터페이스 : libnet_open_raw_sock() (usally IPPROTO_RAW)
(return : a raw socket with IP_HDRINCL set )
○ Link-layer 인터페이스 : libnet_open_link_interface()
☆ Packet Construction
○ 패킷은 모듈별로 생성되어 진다.
○ 각 Protocol Layer 별로 libnet_build로 시작하는 함수들이 있어야만 한다.
○ IP-layer : libn et_build_ip(), libnet_build_tcp()
○ link-layer : libnet_build_ethernet()
○ libnet_build_ethernet() : 0의 offset으로 버퍼의 시작부를 채워진다.
○ libnet_build_ip() : 적절한 위치에 IP header를 생성하기 위해서 14 byte(ETH_H) offset으로 채워진다.
○ libnet_build_tcp() : 시작 부분으로 부터 34 byte(ETH_H + IP_H) offset을 가지고 채워진다.
☆ Packet Checksums
○ 패킷을 생성하는 마지막 단계로 hecksum을 계산하는 것이다.
○ Raw IP interface의 경우, Transportlayer checksum 만을 계산하는 것이 필요하다.
○ Link-layer interface 의 경우, IP checksum만을 계산하는 것이 필요하다.
○ Checksum은 libnet_do_checksum()을 통해서 계산되어진다.
☆ Packet Injection
○ 마지막 단계로 네트워크에 패킷을 전송하는 것이다.
○ IP_layer interface : libnet_write_ip()
○ Link-layer interface : libnet_write_link_layer()
○ return : 성공시 (전송된 바이트수), 실패시 (-1)
*--------------------------------------------------------------------
기 능 : link-layer api / ICMP hostmask packet
컴파일 : # gcc -Wall `libnet-config --defines` libnet_ex2.c
-o libnet_ex2 `libnet-config --libs`
실 행 : # ./libnet_ex2 [-i interface] -s 출발지IP주소 -d 목적지IP주소
--------------------------------------------------------------------*/
#include <libnet.h>
void usage(char *);
u_char enet_src[6] = {0x0d, 0x0e, 0x0a, 0x0d, 0x00, 0x00};
u_char enet_dst[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
int main(int argc, char *argv[])
{
int packet_size, /* size of our packet */
c; /* misc */
u_long src_ip, dst_ip; /* source ip, dest ip */
u_char *packet; /* pointer to our packet buffer */
char err_buf[LIBNET_ERRBUF_SIZE]; /* error buffer */
u_char *device; /* pointer to the device to use */
struct libnet_link_int *network; /* pointer to link interface struct */
printf("libnet example code:\tmodule 2\n\n");
printf("packet injection interface:\tlink layer\n");
printf("packet type:\t\t\tICMP net mask [no payload]\n");
device = NULL;
src_ip = 0;
dst_ip = 0;
while((c = getopt(argc, argv, "i:d:s:")) != EOF)
{
switch(c)
{
case 'd':
if(!(dst_ip = libnet_name_resolve(optarg, LIBNET_RESOLVE)))
{
libnet_error(LIBNET_ERR_FATAL, "Bad destination IP address: %s\n", optarg);
}
break;
case 'i':
device = optarg;
break;
case 's':
if(!(src_ip = libnet_name_resolve(optarg, LIBNET_RESOLVE)))
{
libnet_error(LIBNET_ERR_FATAL, "Bad source IP address: %s\n", optarg);
}
break;
default:
exit(EXIT_FAILURE);
}
}
if(!src_ip || !dst_ip)
{
usage(argv[0]);
exit(EXIT_FAILURE);
}
/*
* Step 1: Network Initialization (interchangable with step 2).
*/
if(device == NULL)
{
struct sockaddr_in sin;
/*
* Try to locate a device.
*/
if(libnet_select_device(&sin, &device, err_buf) == -1)
{
libnet_error(LIBNET_ERR_FATAL, "libnet_select_device failed: %s\n", err_buf);
}
printf("device:\t\t\t\t%s\n", device);
}
if((network = libnet_open_link_interface(device, err_buf)) == NULL)
{
libnet_error(LIBNET_ERR_FATAL, "libnet_open_link_interface: %s\n", err_buf);
}
/*
* We're going to build an ICMP packet with no payload using the
* link-layer API, so this time we need memory for a ethernet header
* as well as memory for the ICMP and IP headers.
*/
packet_size = LIBNET_IP_H + LIBNET_ETH_H + LIBNET_ICMP_MASK_H;
/*
* Step 2: Memory Initialization (interchangable with step 1).
*/
if(libnet_init_packet(packet_size, &packet) == -1)
{
libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n");
}
/*
* Step 3: Packet construction (ethernet header).
*/
libnet _build_ethernet(enet_dst,
enet_src,
ETHERTYPE_IP,
NULL,
0,
packet);
/*
* Step 4: Packet construction (IP header).
*/
libnet_build_ip(ICMP_MASK_H,
0, /* IP tos */
242, /* IP ID */
0, /* Frag */
64, /* TTL */
IPPROTO_ICMP, /* Transport protocol */
src_ip, /* Source IP */
dst_ip, /* Destination IP */
NULL, /* Pointer to payload (none) */
0,
packet + LIBNET_ETH_H); /* Packet header memory */
/*
* Step 5: Packet construction (ICMP header).
*/
libnet_build_icmp_mask(ICMP_MASKREPLY, /* type */
0, /* code */
242, /* id */
0, /* seq */
0xffffffff, /* mask */
NULL, /* payload */
0, /* payload_s */
packet + LIBNET_ETH_H + LIBNET_IP_H);
/*
* Step 6: Packet checksums (ICMP header *AND* IP header).
*/
if(libnet_do_checksum(packet + ETH_H, IPPROTO_ICMP, LIBNET_ICMP_MASK_H) == -1)
{
libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n");
}
if(libnet_do_checksum(packet + ETH_H, IPPROTO_IP, LIBNET_IP_H) == -1)
{
libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n");
}
/*
* Step 7: Packet injection.
*/
c = libnet_write_link_layer(network, device, packet, packet_size);
if(c < packet_size)
{
libnet_error(LN_ERR_WARNING, "libnet_write_link_layer only wrote %d bytes\n", c);
}
else
{
printf("construction and injection completed, wrote all %d bytes\n", c);
}
/*
* Shut down the interface.
*/
if(libnet_close_link_interface(network) == -1)
{
libnet_error(LN_ERR_WARNING, "libnet_close_link_interface couldn't close the interface");
}
/*
* Free packet memory.
*/
libnet_destroy_packet(&packet);
return(c == -1 ? EXIT_FAILURE : EXIT_SUCCESS);
}
void usage(char *name)
{
fprintf(stderr, "usage: %s [-i interface] -s s_ip -d d_ip\n", name);
}
'네트워크' 카테고리의 다른 글
윈도우 네트워크 프로그래밍 (0) | 2010.12.28 |
---|---|
iphdr 구조체와 in_addr 구조체 (0) | 2010.07.08 |
주소 변환하기 (0) | 2010.06.29 |
libpcap 라이브러리 API 정리 (0) | 2010.06.24 |
Libpcap (Pcap) 라이브러리 (0) | 2010.06.23 |
RAW 소켓을 하면서...[ ping 프로그램 ( icmp 프로토콜) ] (0) | 2010.03.29 |
Looping(뻉뺑이) - ? (0) | 2010.01.22 |
브리지와 스위치의 차이점 (0) | 2010.01.22 |
libpcap : 패킷 캡쳐 라이브러리 / libnet : 패킷 생성 라이브러리 (0) | 2009.12.03 |
네트워크/프토토콜/LAN,MAN,WAN / TCP/IP /DNS /ping,tracert / dhcp/ 라우터 랜카드,..백본...등등 (0) | 2009.05.05 |