[libdnet-devel] Packet injection using libdnet?
Status: Abandoned
Brought to you by:
dugsong
|
From: Kifah A. <ki...@pr...> - 2003-12-18 16:09:07
|
hi guys,
i have been using the nifty utility "dnet" to test packet injections on
my machines, even using different MAC adresses and stuff..
But for my programm, i have been using libnet packet construction and
injection mechanisms.
Well it seems with libnet i cannot use MAC adresses different than the
"real" MAC adresses of the machine i am injecting on
(libnet_build_ethernet)...which made me think of using libdnet somehow
for this....how should go with this problem?
Another problem is, libnet only lets you inject on interfaces with IP
adress...while i want to inject on an interface which is up, but has no
IP adress (inner interface of a bridge on Openbsd 3.4)
Should build packets with libnet and inject them with libdnet?
Should i check out the whole code of the "dnet" binary?
PS: this is not part of some "hacking" work, but rather part of my
Thesis, which is a long story :-)
Anyway...here is my code sofar if it might make someone curios:
/*
* Copyright 2003 Kifah Abbad All Rights Reserved.
//compile with gcc -o plogd plogd.c /usr/lib/libpcap.a /usr/lib/libnet.a
/usr/local/lib/libdnet.a
*
*
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <syslog.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
#include <netinet/udp.h>
#include <pcap.h>
#include <arpa/inet.h>
#include <stdarg.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <libnet.h>
#include <sys/stat.h>
#define BUFSIZE 1024
#define IP_SIZE 20
#define TCP_SIZE 20
/* static */
pcap_t *ip_socket;
libnet_t *l ;/*Libnet's core context Datatype*/
char errbuf[LIBNET_ERRBUF_SIZE];/*for defining errors*/
int link_offset; /*Used for defining how much offset before finding the
IP Header*/
/* prototypes */
void filter_packet (u_char *, struct pcap_pkthdr *, u_char *);
/* filter routine */
void filter_packet(u, p, packet)
u_char *u, *packet;
struct pcap_pkthdr *p;
{
/****Packet demultiplexing****/
unsigned short ip_options = 0;
struct ip *ip;
struct tcphdr *tcp;
struct icmp *icmp;
struct udphdr *udp;
char *tcp_payload; /* Packet payload */
char *icmp_payload; /* Packet payload */
char *udp_payload; /* Packet payload */
//sizes of the different headers
int size_tcp = sizeof(struct tcphdr);
int size_icmp = sizeof(struct icmp);
//int size_udp = sizeof(struct udp);
static u_char align_buf[4096];
/******Packet Injection Types***/
/****ICMP-Injection******/
int c ;//used for libnet_write
//ICMP Thingies
u_char libnet_icmp_code = icmp->icmp_code;
u_short libnet_icmp_sum = icmp->icmp_hun.ih_idseq.icd_seq;
u_short libnet_icmp_id =
(unsigned)ntohs(icmp->icmp_hun.ih_idseq.icd_id);
u_short libnet_icmp_seq =
(unsigned)ntohs(icmp->icmp_hun.ih_idseq.icd_seq);
u_char *libnet_icmp_payload = icmp->icmp_dun.id_data;
u_long libnet_icmp_payload_s = strlen(libnet_icmp_payload);
libnet_ptag_t libnet_icmp,libnet_ip, libnet_ethernet = 0;
ip = (struct ip *) (packet + link_offset);
bcopy((char *)ip, (char *)align_buf, p->len);
packet = align_buf;
ip = (struct ip *)align_buf;
switch(ip->ip_p)
{
case IPPROTO_TCP:
ip_options = ip->ip_hl;
ip_options -= 5;
ip_options *= 4;
tcp = (struct tcphdr *)(packet + IP_SIZE + ip_options);
tcp_payload= (u_char *)(packet + IP_SIZE + ip_options + size_tcp);
ip->ip_off &= 0xFF9F;
if(ip->ip_off != 0) return;
printf("Capturing now TCP packets");
printf("\tFrom: %s", inet_ntoa(ip->ip_src));
printf("\tTo: %s\n", inet_ntoa(ip->ip_dst));
printf("\tIP PAcket Length: %d\n", ip->ip_len);
printf("\tTCP_Payload: %s\n", tcp_payload);
break;
case IPPROTO_ICMP:
ip_options = ip->ip_hl;
ip_options -= 5;
ip_options *= 4;
//how much do we shift, until the ICMP payload starts
icmp = (struct icmp *)(packet + IP_SIZE + ip_options);
icmp_payload = (u_char *)(packet+IP_SIZE+ip_options+8);
/**********Here we print the different headers for
debugging**********/
printf("Different ip fields");
//show IP source
printf("\tFrom: %s", inet_ntoa(ip->ip_src));
//show IP destination
printf("\tTo: %s\n", inet_ntoa(ip->ip_dst));
//show IP Header Length
printf("\tHeader Length:%d", ip->ip_hl );
//show IP Header Version
printf("\tVersion:%d", ip->ip_v );
//show IP TOS
printf("\tTOS:%d", ip->ip_tos );
//show ip_len
printf("\tip_len:%d", ip->ip_len );
//show ip_id
printf("\tip_id:%d", ip->ip_id );
//show ip_off
printf("\tip_off:%d", ip->ip_off );
//show ip_ttl
printf("\tip_ttl:%d", ip->ip_ttl );
//show ip_protocol
printf("\tip_protocol:%d", ip->ip_p );
//show ip_checksum
printf("\tip_checksum:%d\n", ip->ip_sum );
printf("Different ICMP Fields\n");
//show type
printf("\tICMP_Type: %d\n", icmp->icmp_type);
//show code
printf("\tICMP_Code: %d\n", icmp->icmp_code);
//show checksum
printf("\tICMP_Checksum: %d\n", libnet_icmp_sum);
//ICMP ID
printf("\tICMP ID: %u\n", libnet_icmp_id);
//ICMP SEQ
printf("\tICMP SEQ: %u\n",libnet_icmp_seq);
//ICMP Data
printf("\tICMP DATA: %s\n", libnet_icmp_payload);
printf("\tICMP Payload Length: %d\n",
libnet_icmp_payload_s);
/*********************ICMP with injection libnet library******/
libnet_icmp = libnet_build_icmpv4_echo(
ICMP_ECHO, /* send echo */
0, /* code */
0, /* icmp checksum */
1000, /* icmp ID */
5249, /* num_anws_rr */
NULL,
0,
l,
0
);
if (libnet_icmp == -1)
{
fprintf(stderr, "Can't build ICMP-ECHO packet: %s\n",
libnet_geterror(l));
}
//Build IP Header
libnet_ip = libnet_build_ipv4(
LIBNET_IPV4_H + 8 + libnet_icmp_payload_s,/* notice 8 is the
icmp length */
0, /* TOS */
ip->ip_id, /* IP ID */
0, /* IP Frag */
ip->ip_ttl, /* TTL */
IPPROTO_ICMP, /* protocol */
ip->ip_sum, /* checksum */
inet_addr("10.10.10.11"), /* source IP */
inet_addr("10.10.10.10"), /* destination IP */
NULL, /* payload */
0, /* payload size */
l, /* libnet handle */
0); /* libnet id */
if (libnet_ip == -1)
{
fprintf(stderr, "Can't build IP header: %s\n",
libnet_geterror(l));
exit(EXIT_FAILURE);
}
//build Ethernet Header
libnet_ethernet = libnet_build_ethernet(
"00:60:97:52:5c:d0",
"00:50:da:51:7d:15",
ETHERTYPE_IP,
NULL,
0,
l,
0);
if (libnet_ethernet == -1)
{
fprintf(stderr, "Can't build Ethernet header: %s\n",
libnet_geterror(l));
exit(EXIT_FAILURE);
}
//write packet into wire
c = libnet_write(l);
if (c == -1)
{
fprintf(stderr, "Can't write packet: %s\n",
libnet_geterror(l));
}
/*********************End of Injection************************/
break;
case IPPROTO_UDP:
ip_options = ip->ip_hl;
ip_options -= 5;
ip_options *= 4;
udp = (struct udphdr *)(packet + IP_SIZE + ip_options);
//udp_payload= (u_char *)(packet + IP_SIZE + ip_options + size_udp);
printf("Capturing now UDP packets");
printf("\tFrom: %s", inet_ntoa(ip->ip_src));
printf("\tTo: %s\n", inet_ntoa(ip->ip_dst));
printf("\tIP PAcket Length: %d\n", ip->ip_len);
break;
}
}
int main(argc, argv)
int argc;
char **argv;
{
extern char *optarg;
extern int optind;
char *iface, errbuf[PCAP_ERRBUF_SIZE];
bpf_u_int32 network, netmask;
struct bpf_program prog;
char filter_app[] = "dst host 10.10.10.10"; /*used for filtering on
gif0*/
iface = "gif0";
ip_socket = NULL;
//initilize Libnet
l = libnet_init(LIBNET_LINK, /* Injection type */
NULL, /* Network interface */
errbuf); /* errbuf */
//Build ICMP Echo Packet
if (l == NULL)
{
fprintf(stderr, "libnet_init() failed: %s", errbuf);
exit(EXIT_FAILURE);
}
if (!iface)
{
iface = pcap_lookupdev(errbuf);
}
if (!(ip_socket = pcap_open_live(iface, 1024, 0, 1024, errbuf))){
}
switch(pcap_datalink(ip_socket))
{
case DLT_EN10MB:
case DLT_IEEE802:
link_offset = 14;
break;
case DLT_SLIP:
link_offset = 16;
break;
case DLT_PPP:
case DLT_NULL:
link_offset = 4;
break;
case DLT_RAW:
link_offset = 0;
break;
default:
fprintf(stderr,"unsupported interface type\n");
exit(-1);
}
if (pcap_compile(ip_socket, &prog, filter_app, 1, netmask) < 0)
{}
if (pcap_setfilter(ip_socket, &prog) < 0)
{}
while(1)
pcap_loop(ip_socket, 0, (pcap_handler)filter_packet, NULL);
}
|