| 1 | #include "include/libnet.h" |
| 2 | #include "include/pg.h" |
| 3 | #include "include/packet.h" |
| 4 | |
| 5 | |
| 6 | extern unsigned char * genPayload (int data_type, unsigned int seed, |
| 7 | int data_length); |
| 8 | |
| 9 | uint16_t libnet_get_ethernet_proto(struct packet_desc *packet_vars) { |
| 10 | |
| 11 | uint16_t proto = 0; |
| 12 | |
| 13 | if (packet_vars->l3_pkt_type) { |
| 14 | if (packet_vars->l3_pkt_type & L3_PKT_TYPE_IPV4) { |
| 15 | proto = ETHERTYPE_IP; |
| 16 | } else if (packet_vars->l3_pkt_type & L3_PKT_TYPE_IPV6) { |
| 17 | proto = ETHERTYPE_IPV6; |
| 18 | } else { |
| 19 | proto = 0; |
| 20 | } |
| 21 | } else if (packet_vars->l2_pkt_type & L2_PKT_TYPE_ARP) { |
| 22 | proto = ETHERTYPE_ARP; |
| 23 | } else if (packet_vars->l2_pkt_type & L2_PKT_TYPE_RARP) { |
| 24 | proto = ETHERTYPE_REVARP; |
| 25 | #if 0 /* Needs to be implemented to support user defined frame types */ |
| 26 | } else if (packet_vars->ether.proto) { |
| 27 | frame_type = packet_vars->ether.proto; |
| 28 | #endif |
| 29 | } |
| 30 | |
| 31 | return (proto); |
| 32 | } |
| 33 | |
| 34 | int libnet_gen_l4_packet( struct packet_desc *packet_vars, libnet_t *l ) { |
| 35 | |
| 36 | libnet_ptag_t t; |
| 37 | char *payload; |
| 38 | u_short payload_s; |
| 39 | u_long src_ip, dst_ip; |
| 40 | u_short src_prt, dst_prt; |
| 41 | u_short options = 0; |
| 42 | |
| 43 | if (packet_vars->l4_pkt_type == 0) { |
| 44 | /* NO L4 Processing*/ |
| 45 | return(1); |
| 46 | } |
| 47 | if ((packet_vars->l3_pkt_type == 0) || (packet_vars->l2_pkt_type == 0)) { |
| 48 | printf(" TEST PROGRAM ERROR !! \n"); |
| 49 | return(-1); |
| 50 | } |
| 51 | #if 0 |
| 52 | if( /*TCP_OPTIONS*/) { |
| 53 | // Add code here |
| 54 | } |
| 55 | #endif |
| 56 | payload = genPayload(packet_vars->payload.data_type, |
| 57 | packet_vars->payload.data_seed,packet_vars->l4_len); |
| 58 | payload_s = packet_vars->l4_len; |
| 59 | |
| 60 | if (packet_vars->l4_pkt_type & L4_PKT_TYPE_TCP) { |
| 61 | printf(" Building TCP Packet!! \n"); |
| 62 | t = libnet_build_tcp( |
| 63 | packet_vars->tcp.src_port, /* source port */ |
| 64 | packet_vars->tcp.dst_port, /* destination port */ |
| 65 | packet_vars->tcp.seq_no, /* sequence number */ |
| 66 | packet_vars->tcp.ack_no, /* acknowledgement num */ |
| 67 | packet_vars->tcp.tcp_flags, /* control flags */ |
| 68 | 0, /* window size */ |
| 69 | packet_vars->tcp.checksum, /* checksum */ |
| 70 | 0, /* urgent pointer */ |
| 71 | LIBNET_TCP_H + options + payload_s, /* TCP packet size */ |
| 72 | payload, /* payload */ |
| 73 | payload_s, /* payload size */ |
| 74 | l, /* libnet handle */ |
| 75 | 0); /* libnet id */ |
| 76 | |
| 77 | if (t == -1) |
| 78 | { |
| 79 | fprintf(stderr, "Can't build TCP header: %s\n", libnet_geterror(l)); |
| 80 | return(-1); |
| 81 | } |
| 82 | |
| 83 | } else if (packet_vars->l4_pkt_type & L4_PKT_TYPE_UDP) { |
| 84 | |
| 85 | printf(" Building UDP Packet!! \n"); |
| 86 | t = libnet_build_udp( |
| 87 | packet_vars->udp.src_port, /* source port */ |
| 88 | packet_vars->udp.dst_port , /* destination port */ |
| 89 | LIBNET_UDP_H + payload_s, /* packet length */ |
| 90 | packet_vars->udp.checksum, /* checksum */ |
| 91 | payload, /* payload */ |
| 92 | payload_s, /* payload size */ |
| 93 | l, /* libnet handle */ |
| 94 | 0); /* libnet id */ |
| 95 | if (t == -1) |
| 96 | { |
| 97 | fprintf(stderr, "Can't build UDP header: %s\n", libnet_geterror(l)); |
| 98 | return(-1); |
| 99 | } |
| 100 | |
| 101 | } else if (packet_vars->l4_pkt_type & L4_PKT_TYPE_AH) { |
| 102 | printf(" Building AH Packet!! \n"); |
| 103 | packet_vars->ipsec_ah.nh = 0; |
| 104 | packet_vars->ipsec_ah.len = |
| 105 | packet_vars->ipsec_ah.res = 0; |
| 106 | packet_vars->ipsec_ah.auth = 0xa5a5a5a5; |
| 107 | |
| 108 | t = libnet_build_ipsec_ah( |
| 109 | packet_vars->ipsec_ah.nh, |
| 110 | packet_vars->ipsec_ah.len, |
| 111 | packet_vars->ipsec_ah.res, |
| 112 | packet_vars->ipsec_ah.spi, |
| 113 | packet_vars->ipsec_ah.seq, |
| 114 | packet_vars->ipsec_ah.auth, |
| 115 | payload, |
| 116 | payload_s, |
| 117 | l, |
| 118 | 0); |
| 119 | if (t == -1) |
| 120 | { |
| 121 | fprintf(stderr, "Can't build IPSEC_AH header: %s\n", |
| 122 | libnet_geterror(l)); |
| 123 | return(-1); |
| 124 | } |
| 125 | |
| 126 | } else if (packet_vars->l4_pkt_type & L4_PKT_TYPE_ESP) { |
| 127 | printf(" Building ESP Packet!! \n"); |
| 128 | t = libnet_build_ipsec_esp_hdr( |
| 129 | packet_vars->ipsec_ah.spi, |
| 130 | packet_vars->ipsec_ah.seq, |
| 131 | 0xa5a5a5a5, // TMP - not sure what can be used here |
| 132 | payload, |
| 133 | payload_s, |
| 134 | l, |
| 135 | 0); |
| 136 | if (t == -1) { |
| 137 | fprintf(stderr, "Can't build IPSEC_ESP header: %s\n", |
| 138 | libnet_geterror(l)); |
| 139 | return(-1); |
| 140 | } |
| 141 | } else if (packet_vars->l4_pkt_type & L4_PKT_TYPE_SCTP) { |
| 142 | printf("---Building SCTP packet\n"); |
| 143 | t = libnet_build_sctp( |
| 144 | packet_vars->sctp.src_port, /* source port */ |
| 145 | packet_vars->sctp.dst_port, /* dest port */ |
| 146 | packet_vars->sctp.vtag, /* verification tag */ |
| 147 | packet_vars->sctp.checksum, /* checksum */ |
| 148 | payload, /* payload */ |
| 149 | payload_s, /* payload size */ |
| 150 | l, /* libnet handle */ |
| 151 | 0); /* libnet id */ |
| 152 | if (t == -1) { |
| 153 | fprintf(stderr, "Can't build SCTP header: %s\n", libnet_geterror(l)); |
| 154 | return(-1); |
| 155 | } |
| 156 | } else if (packet_vars->l4_pkt_type & L4_PKT_TYPE_ICMP) { |
| 157 | u_int8_t icmp_type; |
| 158 | |
| 159 | if (packet_vars->l3_pkt_type & L3_PKT_TYPE_IPV4) { |
| 160 | if (packet_vars->icmp.type == ICMP_TYPE_ECHO_REQ) { |
| 161 | icmp_type = ICMP_ECHO; |
| 162 | } else if (packet_vars->icmp.type == ICMP_TYPE_ECHO_REPLY) { |
| 163 | icmp_type = ICMP_ECHOREPLY; |
| 164 | } else { |
| 165 | fprintf(stderr, "Unsupported ICMP type: %d\n", packet_vars->icmp.type); |
| 166 | return(-1); |
| 167 | } |
| 168 | printf("---Building ICMPv4 packet\n"); |
| 169 | } else if (packet_vars->l3_pkt_type & L3_PKT_TYPE_IPV6) { |
| 170 | if (packet_vars->icmp.type == ICMP_TYPE_ECHO_REQ) { |
| 171 | icmp_type = ICMP6_ECHO; |
| 172 | } else if (packet_vars->icmp.type == ICMP_TYPE_ECHO_REPLY) { |
| 173 | icmp_type = ICMP6_ECHOREPLY; |
| 174 | } else { |
| 175 | fprintf(stderr, "Unsupported ICMP type: %d\n", packet_vars->icmp.type); |
| 176 | return(-1); |
| 177 | } |
| 178 | printf("---Building ICMPv6 packet\n"); |
| 179 | } else { |
| 180 | fprintf(stderr, "Unsupported L3 type %d for ICMP\n", |
| 181 | packet_vars->l3_pkt_type); |
| 182 | return(-1); |
| 183 | } |
| 184 | |
| 185 | t = libnet_build_icmpv4_echo( |
| 186 | icmp_type, /* type */ |
| 187 | 0, /* code */ |
| 188 | packet_vars->icmp.checksum, /* checksum */ |
| 189 | packet_vars->icmp.id, /* id */ |
| 190 | packet_vars->icmp.seq, /* sequence number */ |
| 191 | payload, /* payload */ |
| 192 | payload_s, /* payload size */ |
| 193 | l, /* libnet handle */ |
| 194 | 0); /* libnet id */ |
| 195 | if (t == -1) { |
| 196 | fprintf(stderr, "Can't build ICMP header: %s\n", libnet_geterror(l)); |
| 197 | return(-1); |
| 198 | } |
| 199 | } else if (packet_vars->l4_pkt_type & L4_PKT_TYPE_IGMP) { |
| 200 | printf("---Building IGMP packet\n"); |
| 201 | t = libnet_build_igmp( |
| 202 | packet_vars->igmp.type, /* IGMP type */ |
| 203 | 0, /* IGMP code (unused in v1 and v2) */ |
| 204 | packet_vars->igmp.checksum, /* checksum */ |
| 205 | packet_vars->igmp.grp_ip, /* Group host IP */ |
| 206 | payload, /* payload */ |
| 207 | payload_s, /* payload size */ |
| 208 | l, /* libnet handle */ |
| 209 | 0); /* libnet id */ |
| 210 | if (t == -1) { |
| 211 | fprintf(stderr, "Can't build IGMP header: %s\n", libnet_geterror(l)); |
| 212 | return(-1); |
| 213 | } |
| 214 | } else if (packet_vars->l4_pkt_type & L4_PKT_TYPE_PIM) { |
| 215 | printf("---Building PIM packet\n"); |
| 216 | t = libnet_build_pim( |
| 217 | packet_vars->pim.version, /* PIM version */ |
| 218 | packet_vars->pim.type, /* PIM type */ |
| 219 | packet_vars->pim.checksum, /* checksum */ |
| 220 | payload, /* payload */ |
| 221 | payload_s, /* payload size */ |
| 222 | l, /* libnet handle */ |
| 223 | 0); /* libnet id */ |
| 224 | if (t == -1) { |
| 225 | fprintf(stderr, "Can't build PIM header: %s\n", libnet_geterror(l)); |
| 226 | return(-1); |
| 227 | } |
| 228 | } else if (packet_vars->l4_pkt_type & L4_PKT_TYPE_RSVP) { |
| 229 | printf("---Building RSVP packet\n"); |
| 230 | t = libnet_build_rsvp( |
| 231 | packet_vars->rsvp.version, /* RSVP version */ |
| 232 | packet_vars->rsvp.flags, /* RSVP flags */ |
| 233 | packet_vars->rsvp.type, /* RSVP mesg type */ |
| 234 | packet_vars->rsvp.do_chksum, /* 1 - pkt is chksummed, 0, its not */ |
| 235 | packet_vars->rsvp.checksum, /* checksum */ |
| 236 | packet_vars->rsvp.ttl, /* IP TTL */ |
| 237 | LIBNET_RSVP_H + payload_s, /* pkt len */ |
| 238 | payload, /* payload */ |
| 239 | payload_s, /* payload size */ |
| 240 | l, /* libnet handle */ |
| 241 | 0); /* libnet id */ |
| 242 | if (t == -1) { |
| 243 | fprintf(stderr, "Can't build RSVP header: %s\n", libnet_geterror(l)); |
| 244 | return(-1); |
| 245 | } |
| 246 | } else if (packet_vars->l4_pkt_type & L4_PKT_TYPE_GRE) { |
| 247 | /* update l4_len */ |
| 248 | uint16_t flag_ver = 0; |
| 249 | uint16_t type = 0; |
| 250 | uint16_t len = 0; |
| 251 | |
| 252 | printf("---Building GRE,v0 packet\n"); |
| 253 | |
| 254 | if (packet_vars->gre.csum) { |
| 255 | flag_ver |= GRE_CSUM; |
| 256 | } |
| 257 | if (packet_vars->gre.rout) { |
| 258 | flag_ver |= GRE_ROUTING; |
| 259 | } |
| 260 | if (packet_vars->gre.key) { |
| 261 | flag_ver |= GRE_KEY; |
| 262 | } |
| 263 | if (packet_vars->gre.seq) { |
| 264 | flag_ver |= GRE_SEQ; |
| 265 | } |
| 266 | flag_ver |= GRE_VERSION_0; |
| 267 | |
| 268 | type = libnet_get_ethernet_proto(packet_vars); |
| 269 | |
| 270 | len = libnet_getgre_length(flag_ver); |
| 271 | packet_vars->l4_len += (len - LIBNET_GRE_H); |
| 272 | packet_vars->payload.data_length += (len - LIBNET_GRE_H); |
| 273 | len += payload_s; |
| 274 | |
| 275 | t = libnet_build_gre( |
| 276 | flag_ver, /* flags and version fields */ |
| 277 | type, /* protocol type */ |
| 278 | packet_vars->gre.checksum, /* checksum */ |
| 279 | 0, /* offset */ |
| 280 | packet_vars->gre.key_val, /* key */ |
| 281 | packet_vars->gre.seq_num, /* sequence number */ |
| 282 | len, /* GRE pkt length */ |
| 283 | payload, |
| 284 | payload_s, |
| 285 | l, |
| 286 | 0); |
| 287 | if (t == -1) { |
| 288 | fprintf(stderr, "Can't build GRE,v0 header: %s\n", libnet_geterror(l)); |
| 289 | return(-1); |
| 290 | } |
| 291 | } else if (packet_vars->l4_pkt_type & L4_PKT_TYPE_EGRE) { |
| 292 | /* update l4_len */ |
| 293 | uint16_t flag_ver = 0; |
| 294 | uint16_t len = 0; |
| 295 | |
| 296 | printf("---Building GRE,v1 packet\n"); |
| 297 | |
| 298 | flag_ver |= GRE_KEY; |
| 299 | if (packet_vars->egre.seq) { |
| 300 | flag_ver |= GRE_SEQ; |
| 301 | } |
| 302 | if (packet_vars->egre.ack) { |
| 303 | flag_ver |= GRE_ACK; |
| 304 | } |
| 305 | flag_ver |= GRE_VERSION_1; |
| 306 | |
| 307 | len = libnet_getgre_length(flag_ver); |
| 308 | packet_vars->l4_len += (len - LIBNET_GRE_H); |
| 309 | packet_vars->payload.data_length += (len - LIBNET_GRE_H); |
| 310 | len += payload_s; |
| 311 | |
| 312 | t = libnet_build_egre( |
| 313 | flag_ver, /* flags and version fields */ |
| 314 | 0x880b, /* protocol type */ |
| 315 | payload_s, /* payload length */ |
| 316 | 0, /* call ID */ |
| 317 | packet_vars->egre.seq_num, /* sequence number */ |
| 318 | packet_vars->egre.ack_num, /* ack number */ |
| 319 | len, /* GRE pkt length */ |
| 320 | payload, |
| 321 | payload_s, |
| 322 | l, |
| 323 | 0); |
| 324 | if (t == -1) { |
| 325 | fprintf(stderr, "Can't build GRE,v1 header: %s\n", libnet_geterror(l)); |
| 326 | return(-1); |
| 327 | } |
| 328 | } else {/*??*/ |
| 329 | printf("UNSUPPORTED PKT_TYPE !! \n"); |
| 330 | return(-1); |
| 331 | } |
| 332 | |
| 333 | return(1); |
| 334 | } |
| 335 | |