Пример #1
0
/* Send an ICMP packet, such as host unreachable, to the source and destination addresses */
    void
rst_icmp_send(pkt_t *rst)
{
    struct ip *ih = NULL;
    struct tcphdr *th = NULL;

    int pair = 0;
    char *state = NULL;

    size_t icmp_len = 0;

    ih = (struct ip *)(rst->pkt + sizeof(struct ether_header));
    th = (struct tcphdr *)(rst->pkt + sizeof(struct ether_header) + sizeof(struct ip));

    /* The interface described in "Building Open Source Network Security Tools"
     * appears to be deprecated. The new interface tunnels an IPv4 packet
     * within the ICMP unreachable using the libnet context.
     */
    switch (rst->icmp.type) {

        /* RFC 792
         *
         * Type 3
         *
         * Codes 0, 1, 4, and 5 may be received from a gateway.  Codes 2 and
         * 3 may be received from a host.
         *
         *  0 = net unreachable;
         *  1 = host unreachable;
         *  2 = protocol unreachable;
         *  3 = port unreachable;
         *  4 = fragmentation needed and DF set;
         *  5 = source route failed.
         *
         */
        case ICMP_UNREACH:
            icmp_len = LIBNET_ICMPV4_UNREACH_H + LIBNET_IPV4_H + ICMP_PKTLEN;
            LIBNET_ERR(libnet_build_icmpv4_unreach(
                        rst->icmp.type,                             /* ICMP type, e.g. 3 (Unreachable) */
                        rst->icmp.code,                             /* ICMP code, e.g., 1 (Bad Host) */
                        0,                                          /* auto checksum */
                        (u_char *)ih,                               /* payload */
                        LIBNET_IPV4_H + ICMP_PKTLEN,                /* payload size */
                        rst->l,                                     /* libnet context */
                        0                                           /* ptag */
                        ));
            break;

            /*
             * Type 5
             *
             * Codes 0, 1, 2, and 3 may be received from a gateway.
             *
             *  0 = Redirect datagrams for the Network.
             *  1 = Redirect datagrams for the Host.
             *  2 = Redirect datagrams for the Type of Service and Network.
             *  3 = Redirect datagrams for the Type of Service and Host.
             *
             */
        case ICMP_REDIRECT:
            icmp_len = LIBNET_ICMPV4_REDIRECT_H;
            LIBNET_ERR(libnet_build_icmpv4_unreach(
                        rst->icmp.type,
                        rst->icmp.code,
                        0,
                        (u_char *)ih,
                        LIBNET_IPV4_H + ICMP_PKTLEN,
                        rst->l,
                        0));

            break;

            /*
             * Type 11
             *
             * Code 0 may be received from a gateway.  Code 1 may be received
             * from a host.
             *
             * 0 = time to live exceeded in transit
             * 1 = fragment reassembly time exceeded
             *
             */
        case ICMP_TIMXCEED:
            icmp_len = LIBNET_ICMPV4_TIMXCEED_H + LIBNET_IPV4_H + ICMP_PKTLEN;
            LIBNET_ERR(libnet_build_icmpv4_timeexceed(
                        rst->icmp.type,
                        rst->icmp.code,
                        0,
                        (u_char *)ih,
                        LIBNET_IPV4_H + ICMP_PKTLEN,
                        rst->l,
                        0));
            break;

        case ICMP_PARAMPROB:
        case ICMP_SOURCEQUENCH:
            errx(EXIT_FAILURE, "Not supported by libnet.");
            break;

        default:
            errx(EXIT_FAILURE, "ICMP type %d is not supported yet\n",
                    rst->icmp.type);
    }

    LIBNET_ERR(libnet_build_ipv4(
                LIBNET_IPV4_H + icmp_len,                   /* payload size */
                IPTOS_LOWDELAY | IPTOS_THROUGHPUT,          /* TOS */
                ntohs(ih->ip_id)+1,                                /* IP ID */
                0,                                          /* Frag */
                64,                                         /* TTL */
                IPPROTO_ICMP,                               /* Protocol */
                0,                                          /* auto checksum */
                ih->ip_dst.s_addr,                          /* source */
                ih->ip_src.s_addr,                          /* destination */
                NULL,                                       /* payload */
                0,                                          /* payload size */
                rst->l,                                     /* libnet context */
                0                                           /* libnet ptag */
                ));

    state = ((libnet_write(rst->l) == -1) ? "x" : "I");
    (void)fprintf(stdout, "[%s] SRC = %15s:%-6u DST = %15s:%-6u len = %d/%d\n", state,
                  libnet_addr2name4(PAIR(pair, ih->ip_src.s_addr, ih->ip_dst.s_addr), LIBNET_DONT_RESOLVE),
                  PAIR(pair, ntohs(th->th_sport), ntohs(th->th_dport)),
                  libnet_addr2name4(PAIR(pair, ih->ip_dst.s_addr, ih->ip_src.s_addr), LIBNET_DONT_RESOLVE),
                  PAIR(pair, ntohs(th->th_dport), ntohs(th->th_sport)), LIBNET_IPV4_H + (u_int32_t)icmp_len, ntohs(ih->ip_len));

    (void)fflush(stdout);

    usleep(rst->sleep_for);
}
Пример #2
0
int
main(int argc, char **argv)
{
    int c;
    libnet_t *l;
    libnet_ptag_t t;
    u_long src_ip, dst_ip; 
    u_char payload[8] = {0x00, 0x36, 0xff, 0xff, 0x00, 0x21, 0x00, 0x00};
    u_long payload_s = 8;
    char errbuf[LIBNET_ERRBUF_SIZE];

    printf("libnet 1.1 packet shaping: ICMP unreachable[link]\n"); 

    /*
     *  Initialize the library.  Root priviledges are required.
     */
    l = libnet_init(
            LIBNET_LINK,                            /* injection type */
            NULL,                                   /* network interface */
            errbuf);                                /* errbuf */
 
    if (l == NULL)
    {
        fprintf(stderr, "libnet_init() failed: %s", errbuf);
        exit(EXIT_FAILURE);
    }

    src_ip = 0;
    dst_ip = 0;
    while((c = getopt(argc, argv, "d:s:")) != EOF)
    {
        switch (c)
        {
            case 'd':
                if ((dst_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1)
                {
                    fprintf(stderr, "Bad destination IP address: %s\n", optarg);
                    exit(1);
                }
                break;
            case 's':
                if ((src_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1)
                {
                    fprintf(stderr, "Bad source IP address: %s\n", optarg);
                    exit(1);
                }
                break;
        }
    }
    if (!src_ip || !dst_ip)
    {
        usage(argv[0]);
        exit(EXIT_FAILURE);
    }

    t = libnet_build_icmpv4_unreach(
        ICMP_UNREACH,                               /* type */
        ICMP_UNREACH_PORT,                          /* code */
        0,                                          /* checksum */
            LIBNET_IPV4_H + LIBNET_UDP_H,           /* o length */
            IPTOS_LOWDELAY | IPTOS_THROUGHPUT,      /* o IP tos */
            0xff,                                   /* o IP ID */
            0,                                      /* o frag */
            64,                                     /* o TTL */
            IPPROTO_UDP,                            /* o protocol */
            0x7012,                                 /* o checksum */
            dst_ip,                                 /* o source IP */
            src_ip,                                 /* o destination IP */
            payload,                                /* payload */
            payload_s,                              /* payload size */
        l,                                          /* libnet handle */
        0);
    if (t == -1)
    {
        fprintf(stderr, "Can't build ICMP header: %s\n", libnet_geterror(l));
        goto bad;
    }

    t = libnet_build_ipv4(
        LIBNET_IPV4_H + LIBNET_ICMPV4_UNREACH_H +
        LIBNET_IPV4_H,                              /* length */
        IPTOS_LOWDELAY | IPTOS_THROUGHPUT,          /* TOS */
        0xee,                                       /* IP ID */
        0,                                          /* IP Frag */
        64,                                         /* TTL */
        IPPROTO_ICMP,                               /* protocol */
        0,                                          /* checksum */
        src_ip,                                     /* source IP */
        dst_ip,                                     /* destination IP */
        NULL,                                       /* payload */
        0,                                          /* payload size */
        l,                                          /* libnet handle */
        0);
    if (t == -1)
    {
        fprintf(stderr, "Can't build IP header: %s\n", libnet_geterror(l));
        goto bad;
    }

    t = libnet_build_ethernet(
        enet_dst,                                   /* ethernet destination */
        enet_src,                                   /* ethernet source */
        ETHERTYPE_IP,                               /* protocol type */
        NULL,                                       /* payload */
        0,                                          /* payload size */
        l,                                          /* libnet handle */
        0);                                         /* libnet id */
    if (t == -1)
    {
        fprintf(stderr, "Can't build ethernet header: %s\n", libnet_geterror(l));
        goto bad;
    }

    /*
     *  Write it to the wire.
     */
    c = libnet_write(l);
    if (c == -1)
    {
        fprintf(stderr, "Write error: %s\n", libnet_geterror(l));
        goto bad;
    }
    else
    {
        fprintf(stderr, "Wrote %d byte ICMP packet; check the wire.\n", c);
    }
    libnet_destroy(l);
    return (EXIT_SUCCESS);
bad:
    libnet_destroy(l);
    return (EXIT_FAILURE);
}