|
|||||||||||
|
LIbnet ICMP Code3 Type4
From: Travis Dawson <tdawson(at)sprintlabs.com>
Date: Mon Jun 23 2003 - 23:01:30 EDT
I attached my code below. The problem I am having now is that I can create
the packet, just cannot get the last TCP header in there.
Any help would be appreciated.
A good final ICMP packet should appear like: Frame 7 (70 bytes on wire, 70 bytes captured)
Arrival Time: Jun 20, 2003 13:50:22.643781000
Time delta from previous packet: 0.002650000 seconds
Time relative to first packet: 1.185803000 seconds
Frame Number: 7
Packet Length: 70 bytes
Capture Length: 70 bytes
Ethernet II, Src: 00:02:16:e9:8e:82, Dst: 00:09:6b:90:72:32
Destination: 00:09:6b:90:72:32 (00:09:6b:90:72:32)
Source: 00:02:16:e9:8e:82 (00:02:16:e9:8e:82)
Type: IP (0x0800)
Internet Protocol, Src Addr: 10.0.65.1 (10.0.65.1), Dst Addr: 10.0.65.128 (10.0.65.128)
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
0000 00.. = Differentiated Services Codepoint: Default (0x00)
.... ..0. = ECN-Capable Transport (ECT): 0
.... ...0 = ECN-CE: 0
Total Length: 56
Identification: 0xce00
Flags: 0x00
.0.. = Don't fragment: Not set
..0. = More fragments: Not set
Fragment offset: 0
Time to live: 255
Protocol: ICMP (0x01)
Header checksum: 0x5743 (correct)
Source: 10.0.65.1 (10.0.65.1)
Destination: 10.0.65.128 (10.0.65.128)
Internet Control Message Protocol
Type: 3 (Destination unreachable)
Code: 4 (Fragmentation needed)
Checksum: 0xaaf2 (correct)
MTU of next hop: 800
Internet Protocol, Src Addr: 10.0.65.128 (10.0.65.128), Dst Addr:
8.1.1.133 (8.1.1.133)
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
0000 00.. = Differentiated Services Codepoint: Default (0x00)
.... ..0. = ECN-Capable Transport (ECT): 0
.... ...0 = ECN-CE: 0
Total Length: 1440
Identification: 0xb3d1
Flags: 0x04
.1.. = Don't fragment: Set
..0. = More fragments: Not set
Fragment offset: 0
Time to live: 63
Protocol: TCP (0x06)
Header checksum: 0x2d81 (correct)
Source: 10.0.65.128 (10.0.65.128)
Destination: 8.1.1.133 (8.1.1.133)
Transmission Control Protocol, Src Port: 11001 (11001), Dst Port:
telnet (23)
Source port: 11001 (11001)
Destination port: telnet (23)
/* CODE */ /*
#if (HAVE_CONFIG_H) #include "../include/config.h" #endif #include "./libnet_fix.h" int axtoi(char *);
libnet_ptag_t libnet_build_icmpv4_unreach_mtu(u_char , u_char , u_short ,
u_short , u_char , u_short ,
u_short , u_char , u_char ,
u_short , u_long , u_long ,
int ,
u_char *, u_long , libnet_t *, libnet_ptag_t );
int
int c;
int mtu;
char type[10];
u_short n_chksum = 0x1111;
u_short pkt_type = IPPROTO_UDP;
u_short hdr_type = LIBNET_UDP_H;
libnet_t *l;
libnet_ptag_t t;
u_long src_ip, dst_ip, err_ip;
u_char payload[8] = {0x00, 0x36, 0xff, 0xff, 0x00, 0x21, 0x00, 0x00};
u_long payload_s = 8;
char errbuf[LIBNET_ERRBUF_SIZE];
printf("libnet 1.1 packet shaping: ICMP Unreach w MTU\n");
/*
* Initialize the library. Root priviledges are required.
*/
l = libnet_init(
LIBNET_LINK, /* injection type */
NULL, /* network interface */
errbuf); /* errbuf */
if (l == NULL)
{
fprintf(stderr, "libnet_init() failed: %s", errbuf);
exit(EXIT_FAILURE);
}
src_ip = 0;
dst_ip = 0;
err_ip = 0;
while((c = getopt(argc, argv, "d:s:e:m:p:c:")) != EOF)
{
switch (c)
{
case 'd':
if ((dst_ip = libnet_name2addr4(l, optarg,
LIBNET_RESOLVE)) == -1)
{
fprintf(stderr, "Bad destination IP address: %s\n",
optarg);
exit(1);
}
break;
case 's':
if ((src_ip = libnet_name2addr4(l, optarg,
LIBNET_RESOLVE)) == -1)
{
fprintf(stderr, "Bad source IP address: %s\n", optarg);
exit(1);
}
break;
case 'e':
if ((err_ip = libnet_name2addr4(l, optarg,
LIBNET_RESOLVE)) == -1)
{
fprintf(stderr, "Bad Error IP address: %s\n", optarg);
exit(1);
}
break;
case 'm':
if (optarg > 0)
{
mtu = atoi( optarg );
}
break;
case 'c':
n_chksum = axtoi( optarg );
break;
case 'p':
switch ( atoi (optarg) )
{
case 50:
hdr_type = LIBNET_IPSEC_ESP_HDR_H ;
pkt_type = IPPROTO_ESP;
break;
case 51:
hdr_type = LIBNET_IPSEC_AH_H;
pkt_type = IPPROTO_AH;
break;
case 6:
hdr_type = LIBNET_TCP_H;
pkt_type = IPPROTO_TCP;
break;
case 17:
hdr_type = LIBNET_UDP_H;
pkt_type = IPPROTO_UDP;
break;
case 47:
hdr_type = 20;
pkt_type = 47;
break;
default:
hdr_type = LIBNET_UDP_H;
pkt_type = IPPROTO_UDP;
break;
}
break;
}
}
if (!src_ip || !dst_ip)
{
usage(argv[0]);
exit(EXIT_FAILURE);
}
t = libnet_build_icmpv4_unreach_mtu(
ICMP_UNREACH, /* type */
ICMP_UNREACH_NEEDFRAG, /* code */
0, /* checksum */
LIBNET_IPV4_H + hdr_type, /* o length */
IPTOS_LOWDELAY | IPTOS_THROUGHPUT, /* o IP tos */
0xff, /* o IP ID */
0, /* o frag */
64, /* o TTL */
pkt_type, /* o protocol */
n_chksum, /* o checksum */
src_ip, /* o victim source IP */
dst_ip, /* o victim
destination IP */
mtu, /* MTU */
payload, /* payload */
payload_s, /* payload size */
l, /* libnet handle */
0);
if (t == -1)
{
fprintf(stderr, "Can't build ICMP header: %s\n", libnet_geterror(l));
goto bad;
}
if (err_ip)
{
/* tdawson
* If there is an err_ip then make it the src_ip of the outer
spoofed packet we send
*/
t = libnet_build_ipv4(
LIBNET_IPV4_H + LIBNET_ICMPV4_UNREACH_H +
LIBNET_IPV4_H, /* length */
IPTOS_LOWDELAY | IPTOS_THROUGHPUT, /* TOS */
0xee, /* IP ID */
0, /* IP Frag */
64, /* TTL */
IPPROTO_ICMP, /* protocol */
0, /* checksum */
err_ip, /* source IP */
src_ip, /* destination IP
}
void
fprintf(stderr, "usage: %s
-s source_ip
-d destination_ip
-m MTU
-e Error_ip
-c checksum (backwards hex)
-p Protocol number(6=TCP,17=udp,50=IPSec-ESP,51=IPSec-AH,47=GRE)\n",
name);
}
libnet_ptag_t
u_short orig_len, u_char orig_tos, u_short orig_id,
u_short orig_frag, u_char orig_ttl, u_char orig_prot,
u_short orig_check, u_long orig_src, u_long orig_dst,
int new_mtu,
u_char *payload, u_long payload_s, libnet_t *l, libnet_ptag_t
ptag)
{
u_long n;
u_short h;
libnet_ptag_t ipv4, ret;
libnet_pblock_t *p, *q;
struct libnet_icmpv4_hdr icmp_hdr;
if (l == NULL)
{
return (-1);
}
n = LIBNET_ICMPV4_UNREACH_H; /* size of memory block */
/* hl for checksum */
h = LIBNET_ICMPV4_UNREACH_H + LIBNET_IPV4_H;
/*
* Find the existing protocol block if a ptag is specified, or create
* a new one.
*/
p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_ICMPV4_UNREACH_H);
if (p == NULL)
{
return (-1);
}
icmp_hdr.icmp_type = type; /* packet type */
icmp_hdr.icmp_code = code; /* packet code */
/* Tdawson
* This should automagically set itself if set to 0
* BUT ITS NOT!!!! so we manualy set the checksum
*/
icmp_hdr.icmp_sum = sum; /* checksum */
icmp_hdr.icmp_id = 0; /* must be 0 */
icmp_hdr.icmp_seq = 0; /* must be 0 */
icmp_hdr.hun.frag.mtu = ntohs(new_mtu);
n = libnet_pblock_append(l, p, (u_char *)&icmp_hdr,
LIBNET_ICMPV4_UNREACH_H);
if (n == -1)
{
goto bad;
}
/*
* Build the original IPv4 header in its own pblock. We stick the
* payload here.
*/
ipv4 = libnet_build_ipv4(orig_len, orig_tos, orig_id, orig_frag, orig_ttl,
orig_prot, orig_check, orig_src, orig_dst, payload, payload_s, l, 0);
if (ipv4 == -1)
{
/* error set elsewhere */
goto bad;
}
if (orig_check == 0)
{
/* XXX - this isn't working. */
/* This just screws up code) */
q = libnet_pblock_probe(l, ipv4, n, LIBNET_PBLOCK_IPV4_H);
libnet_pblock_setflags(q, LIBNET_PBLOCK_DO_CHECKSUM);
}
if (sum == 0)
{
/*
* If checksum is zero, by default libnet will compute a checksum
* for the user. The programmer can override this by calling
* libnet_toggle_checksum(l, ptag, 1);
*/
libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM);
}
ret = (ptag ? ptag : libnet_pblock_update(l, p, h,
LIBNET_PBLOCK_ICMPV4_UNREACH_H));
/* reorder ICMP and IPv4 headers to make the packet assemble properly */
libnet_pblock_swap(l, ret, ipv4);
return (ret);
bad:
libnet_pblock_free(p);
return (-1);
} /*
int axtoi(char *hexStg) {
int n = 0; // position in string
int m = 0; // position in digit[] to shift
int count; // loop index
int intValue = 0; // integer value of hex string
int digit[5]; // hold values to convert
while (n < 4) {
if (hexStg[n]=='\0')
break;
if (hexStg[n] > 0x29 && hexStg[n] < 0x40 ) //if 0 to 9
digit[n] = hexStg[n] & 0x0f; //convert to int
else if (hexStg[n] >='a' && hexStg[n] <= 'f') //if a to f
digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int
else if (hexStg[n] >='A' && hexStg[n] <= 'F') //if A to F
digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int
else break;
n++;
} count = n; m = n - 1; n = 0; while(n < count) {
// digit[n] is value of hex digit at position n
// (m << 2) is the number of positions to shift
// OR the bits into return value
intValue = intValue | (digit[n] << (m << 2));
m--; // adjust the position to set
n++; // next digit to process
} return (intValue); } /* EOF */
-tdawson
To unsubscribe, e-mail: libnet-unsubscribe@securityfocus.com For additional commands, e-mail: libnet-help@securityfocus.com Received on Mon Jun 23 23:15:09 2003 This archive was generated by hypermail 2.1.8 : Wed Aug 23 2006 - 14:02:24 EDT |
||||||||||
|
|||||||||||