#include "include/libnet.h"
#include "include/packet.h"
extern unsigned char * genPayload (int data_type
, unsigned int seed
,
int libnet_gen_l3_packet (struct packet_desc
*packet_vars
, libnet_t
*l
) {
libnet_ptag_t t
,t1
,t2
,t3
,ipo
;
u_short src_prt
, dst_prt
;
int i
,no_of_options_bytes
;
struct libnet_in6_addr ipv6_src_ip
;
struct libnet_in6_addr ipv6_dst_ip
;
if(packet_vars
->l3_pkt_type
== 0 ) {
if((packet_vars
->l2_pkt_type
== 0) ){
printf(" TEST PROGRAM ERROR !! \n");
if(packet_vars
->l3_len
) {
payload
= genPayload(packet_vars
->payload
.data_type
,
packet_vars
->payload
.data_seed
,packet_vars
->l3_len
);
payload_s
= packet_vars
->l3_len
;
/* fill up options in case it is needed*/
opt
[i
] = 0xa0 + i
; /*load up options with some value*/
no_of_options_bytes
= packet_vars
->ip
.options
;
if ((packet_vars
->l3_pkt_type
& L3_PKT_TYPE_IPV4
) &&
(no_of_options_bytes
> 0)) {
printf(" Build IPV4 with options - length - %d \n", no_of_options_bytes
);
ipo
= libnet_build_ipv4_options(
fprintf(stderr
, "Can't build IPV4 options: %s\n", libnet_geterror(l
));
/* Default value for l4_header and L4_protocol*/
/*Determine L4Protocol field based upon input*/
if(packet_vars
->l4_pkt_type
& L4_PKT_TYPE_TCP
) {
l4_header_length
= LIBNET_TCP_H
;
L4Protocol
= IPPROTO_TCP
;
} else if(packet_vars
->l4_pkt_type
& L4_PKT_TYPE_UDP
) {
l4_header_length
= LIBNET_UDP_H
;
L4Protocol
= IPPROTO_UDP
;
} else if(packet_vars
->l4_pkt_type
& L4_PKT_TYPE_SCTP
) {
l4_header_length
= LIBNET_SCTP_H
;
L4Protocol
= IPPROTO_SCTP
;
} else if(packet_vars
->l4_pkt_type
& L4_PKT_TYPE_AH
) {
l4_header_length
= LIBNET_IPSEC_AH_H
;
} else if(packet_vars
->l4_pkt_type
& L4_PKT_TYPE_ESP
) {
l4_header_length
= LIBNET_IPSEC_ESP_HDR_H
;
L4Protocol
= IPPROTO_ESP
;
} else if(packet_vars
->l4_pkt_type
& L4_PKT_TYPE_ICMP
) {
if(packet_vars
->l3_pkt_type
& L3_PKT_TYPE_IPV4
) {
l4_header_length
= LIBNET_ICMPV4_H
;
L4Protocol
= IPPROTO_ICMP
;
} else if(packet_vars
->l3_pkt_type
& L3_PKT_TYPE_IPV6
) {
l4_header_length
= LIBNET_ICMPV6_H
;
L4Protocol
= IPPROTO_ICMP6
;
fprintf(stderr
, "Incompatible L3 protocol type for ICMP\n");
} else if(packet_vars
->l4_pkt_type
& L4_PKT_TYPE_IGMP
) {
l4_header_length
= LIBNET_IGMP_H
;
L4Protocol
= IPPROTO_IGMP
;
} else if(packet_vars
->l4_pkt_type
& L4_PKT_TYPE_PIM
) {
l4_header_length
= LIBNET_PIM_H
;
L4Protocol
= IPPROTO_PIM
;
} else if(packet_vars
->l4_pkt_type
& L4_PKT_TYPE_RSVP
) {
l4_header_length
= LIBNET_RSVP_H
;
L4Protocol
= IPPROTO_RSVP
;
} else if((packet_vars
->l4_pkt_type
& L4_PKT_TYPE_GRE
) ||
(packet_vars
->l4_pkt_type
& L4_PKT_TYPE_EGRE
)) {
l4_header_length
= LIBNET_GRE_H
;
L4Protocol
= IPPROTO_GRE
;
} else {/* MORE TO BE ADDED */}
// if user wants to override the protocol chosen for error condition
if( ( packet_vars
->payload
.error_code
& PG_L4_PROTO_USER_MODE
) )
L4Protocol
= packet_vars
->ip
.proto
;
printf("L4PktType - %x L4Protocol Chosen as - 0x%x \n",
packet_vars
->l4_pkt_type
,L4Protocol
);
if ((packet_vars
->l3_pkt_type
& L3_PKT_TYPE_FRAG
) &&
(packet_vars
->l3_pkt_type
& L3_PKT_TYPE_IPV4
)) {
ip_frag
= packet_vars
->ip
.frag
; /* NO SURE WHAT TO CHOOSE TBD */
if(packet_vars
->l3_pkt_type
& L3_PKT_TYPE_IPV4
) {
printf(" BUILDING L3Packet -\n");
LIBNET_IPV4_H
+ l4_header_length
+ no_of_options_bytes
+ packet_vars
->l4_len
+ payload_s
,/* length */
packet_vars
->ip
.tos
, /* TOS */
L4Protocol
, /* protocol */
packet_vars
->ip
.src_addr
, /* source IP */
packet_vars
->ip
.dst_addr
, /* destination IP */
payload_s
, /* payload size */
fprintf(stderr
, "Can't build IPV4 header: %s\n", libnet_geterror(l
));
} else if (packet_vars
->l3_pkt_type
& L3_PKT_TYPE_IPV6
) {
/* Need variable nh, ipv6FragId to be supported */
/* This is an extension header, the first header must have been formed first */
if( (packet_vars
->l3_pkt_type
& L3_PKT_TYPE_IPV6
) &&
(no_of_options_bytes
> 0)){
printf(" Build IPV6 with options - length - %d \n", no_of_options_bytes
);
/* This needs new src to be cloned in the libnet */
ipo
= libnet_build_ipv6_options(0, /* ot */
no_of_options_bytes
, /* ip_ol */
fprintf(stderr
, "Can't build IPV6 options: %s\n", libnet_geterror(l
));
/* This is an extension header, the first header must have been formed first */
if(packet_vars
->l3_pkt_type
& L3_PKT_TYPE_FRAG
) {
printf(" Build IPV6 with fragment \n");
ipo
= libnet_build_ipv6_frag(packet_vars
->ipv6
.nexthdr
,
0, /* ip_nh (toberesolved), reserved */
packet_vars
->ipv6
.ipv6FragId
, /* ip_id (toberesolved)*/
fprintf(stderr
, "Can't build IPV6 fragment : %s\n", libnet_geterror(l
));
if(packet_vars
->l3_pkt_type
& L3_PKT_TYPE_IPV6
) {
printf(" Build IPV6 first header \n");
/* toberesolved. this needs to be a function - depending on whether there is extension header following. This assumes no ext hdr */
total_length
= l4_header_length
+ no_of_options_bytes
+
packet_vars
->l4_len
+ payload_s
;
// Override from TEST if set to 0xff -
if(ipv6_nexthdr
!= 0xff) {
ipv6_nexthdr
= L4Protocol
;
} else ipv6_nexthdr
= packet_vars
->ipv6
.nexthdr
;
ipv6_src_ip
.libnet_s6_addr
[i
] = packet_vars
->ipv6
.src_addr
[i
];
ipv6_dst_ip
.libnet_s6_addr
[i
] = packet_vars
->ipv6
.dst_addr
[i
];
fprintf(stderr
, "Can't build IPV6: %s\n", libnet_geterror(l
));
} /*end first ipv6 header*/
printf(" UNSUPPORTED PROTOCOL !! \n");