Re: question when using options in headers..
"Mustafa Abu Sedera" <[email protected]>
| Newsgroups | gmane.comp.security.libnet |
|---|---|
| Message-ID | <[email protected]> |
First of all, thank you very much, Mike Shiffman, for your reply. I tried out these things (and other) the last week and still have problems and kindly ask for your help. I am writing a program which captures packets using libpcap from eth0(subnet) then resends them from eth1(main LAN) with a different source IP (kind of NATing). After I capture the packet I rebuild it depending on it's protocol so that libnet computes the checksums for me as they change after this packet alternation. I use tcpdump to sniff the packets going out from eth1 and get a false checksum for my tcp packets and i noticed only those, which contain options. for icmp packets I don't get errors and they work fine because i get replies. udp i didn't test yet. If you please could take a look at the attached file which contains the function i use, don't worry it isn't too long and easy to understand. i spent about the whole day debugging and couldn't find out what's wrong. And i still don't know wether to use ptags or libnet_clear_packet() so if you have any suggestions please tell me. Sorry for the long massage. Best regards. >From: Mike Schiffman <[email protected]> >To: "Mustafa Abu Sedera" <[email protected]> >CC: [email protected] >Subject: Re: question when using options in headers.. >Date: Wed, 28 Jan 2004 09:01:51 -0800 > >q1: Yes that is correct ordering. See sample/tcp1.c for a sample >application using TCP options. To answer the second part: Not using the >options builder function. Since the options string will actually have its >own pblock, if you save existing ptags, then call builder functions inside >of a loop using those ptags, the next call to a builder function WITHOUT a >saved ptag will generate a new pblock at the end of the list. Two things >you can try: 1) place your TCP or IP options inside the payload and adjust >the appropriate header values. 2) try calling an options builder with a 0 >sized payload and save its ptag. I kinda doubt this second one will work >though; there is a ton of pointer math and indirection going on inside the >options builders. > >q2: It all depends on your needs. If you're only sending packets one at a >time with a fire and forget mentality, use only one context. If you need to >send multiple packets over and over again, use the cq interface. > >q3: I just tested the advanced mode and it worked fine as of 1.1.2-rc-05. >Can you be more specific with your error? Are you sure you initialized the >library properly? _________________________________________________________________ Protect your PC - get McAfee.com VirusScan Online http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963
route_packet.h
(application/octet-stream, 6.4 KB)
/*route_pkt() should route the captured pkt from sub-ether(SE) to network-ether(NE)
by replacing the source IP with that of the NE */
int route_packet(libnet_t* l, //initialized LIBNET_RAW4_ADV and "eth1"
struct libnet_ether_addr* eth_addr_dev, //MAC addr of sending NIC
struct libnet_ethernet_hdr* eth_hdr,struct libnet_ipv4_hdr* ip4_hdr)
//points to a valid packet captured with libpcap from eth0
{
int count;
u_char* payload = NULL;
u_int payload_len = 0;
u_int tcp_hdr_len, ip_hdr_len, pkt_len;
struct libnet_tcp_hdr* tcp_hdr;
struct libnet_udp_hdr* udp_hdr;
//statistics
static int num_tcp_pkts = 0;
static int num_icmp_pkts = 0;
static int num_udp_pkts = 0;
//these are only used for testing
u_char src_ip[] = {10, 0, 0, 1};
u_char dst_ip[] = {10, 131, 72, 115};
//check for source MAC to avoid looping
if( 0 == memcmp(eth_hdr->ether_shost, eth_addr_dev, ETHER_ADDR_LEN) )
{
//printf("\nSource MAC = device");
return 0;
}
// to clear any preaviously stored data in the context
// check if i should use tags better???
libnet_clear_packet(l);
ip_hdr_len = ip4_hdr->ip_hl * 4;
pkt_len = ntohs( ip4_hdr->ip_len );
switch( ip4_hdr->ip_p )
{
case IPPROTO_ICMP: //handle icmp as payload because it's checksum won't change
payload = (u_char*)ip4_hdr + ip_hdr_len;
payload_len = pkt_len - ip_hdr_len;
num_icmp_pkts++;
break;
case IPPROTO_TCP:
tcp_hdr = (struct libnet_tcp_hdr*)( (u_char*)ip4_hdr+ip_hdr_len );
tcp_hdr_len = tcp_hdr->th_off * 4;
//if there is a payload
if( pkt_len > (ip_hdr_len + tcp_hdr_len) )
{
payload = (u_char*)tcp_hdr + tcp_hdr_len;
payload_len = pkt_len - ip_hdr_len - tcp_hdr_len;
}
//if we have tcp options
if( tcp_hdr_len > LIBNET_TCP_H)
{
if( -1 == libnet_build_tcp_options((u_char*)tcp_hdr+LIBNET_TCP_H,
tcp_hdr_len - LIBNET_TCP_H, l, 0))
{
printf("\nError in libnet_build_tcp_options(): %s", libnet_geterror(l));
return -1;
}
}
if( -1 == libnet_build_tcp(ntohs(tcp_hdr->th_sport),
ntohs(tcp_hdr->th_dport),
ntohl(tcp_hdr->th_seq),
ntohl(tcp_hdr->th_ack),
tcp_hdr->th_flags,
ntohs(tcp_hdr->th_win),
0, // checksum
ntohs(tcp_hdr->th_urp),
payload_len + tcp_hdr_len, // + LIBNET_TCP_H
payload, // location of payload
payload_len,
l, 0) )
{
printf("\nError in libnet_build_tcp() %s",libnet_geterror(l));
return -1;
}
// it will be used again in build IP function, so set back to NULL and 0
payload = NULL;
payload_len = 0;
num_tcp_pkts++;
break;
case IPPROTO_UDP:
udp_hdr = (struct libnet_udp_hdr*)( (u_char*)ip4_hdr+ip_hdr_len );
//if there is payload
if( pkt_len > (ip_hdr_len + LIBNET_UDP_H) )
{
payload = (u_char*)udp_hdr + LIBNET_UDP_H;
payload_len = pkt_len - ip_hdr_len - LIBNET_UDP_H;
}
if( -1 == libnet_build_udp( ntohs(udp_hdr->uh_sport),
ntohs(udp_hdr->uh_dport),
LIBNET_UDP_H + payload_len,
0,
payload,
payload_len,
l, 0) )
{
printf("\nError in libnet_build_udp(): %s", libnet_geterror(l));
return -1;
}
// it will be used again in build IP function, so set back to 0
payload = NULL;
payload_len = 0;
num_udp_pkts++;
break;
default:
return 0;
}
// if pkt have ip options
if( ip_hdr_len > LIBNET_IPV4_H )
if( -1 == libnet_build_ipv4_options((u_char*)ip4_hdr+LIBNET_IPV4_H,
ip_hdr_len - LIBNET_IPV4_H, l, 0))
{
printf("\nError in libnet_build_ip_options(): %s", libnet_geterror(l));
return -1;
};
if( -1 == libnet_build_ipv4(pkt_len,
ip4_hdr->ip_tos,
ntohs(ip4_hdr->ip_id),
ntohs(ip4_hdr->ip_off),
ip4_hdr->ip_ttl,
ip4_hdr->ip_p,
0, //checksum
*((u_long*)&src_ip), // new src and dst IP addr defined above
*((u_long*)&dst_ip), //looks ugly:)
payload,
payload_len,
l, 0) )
{
printf("\nError in libnet_build_ipv4(): %s", libnet_geterror(l));
return -1;
}
// for debugging
if( -1 == libnet_adv_cull_packet(l, &payload, &payload_len) )
printf("\nError in libnet_cull_pkt(): %s", libnet_geterror(l) );
else
{
for (count = 0; count < payload_len; count++)
{
if( (count%20) == 0 )printf("\n");
printf("%.2x ",payload[count]);
}
}
fflush (stdout);
if( -1 == (count = libnet_write(l)) )
{
printf("\nError in libnet_write(): %s", libnet_geterror(l));
return -1;
}
printf("\nWrote %d bytes to wire...", count);
printf("\nstats: %d ICMP\t %d TCP\t %d UDP",num_icmp_pkts,num_tcp_pkts,num_udp_pkts);
return count;
}