Example #1
0
static void
dump_packet(void)
{
  memcpy(dump, &dump[DUMP_WIDTH], DUMP_WIDTH * (DUMP_HEIGHT - 1));
  tcpdump_print(&dump[DUMP_WIDTH * (DUMP_HEIGHT - 1)], DUMP_WIDTH);
  CTK_WIDGET_REDRAW(&dumplabel);
}
Example #2
0
/** 
 * Main loop to rewrite packets
 */
int
rewrite_packets(tcpedit_t *tcpedit, pcap_t *pin, pcap_dumper_t *pout)
{
    tcpr_dir_t cache_result = TCPR_DIR_C2S;     /* default to primary */
    struct pcap_pkthdr pkthdr, *pkthdr_ptr;     /* packet header */
    const u_char *pktconst = NULL;              /* packet from libpcap */
    u_char **pktdata = NULL;
    static u_char *pktdata_buff;
    static char *frag = NULL;
    COUNTER packetnum = 0;
    int rcode, frag_len, i, proto;

    pkthdr_ptr = &pkthdr;

    if (pktdata_buff == NULL)
        pktdata_buff = (u_char *)safe_malloc(MAXPACKET);

    pktdata = &pktdata_buff;

    if (frag == NULL)
        frag = (char *)safe_malloc(MAXPACKET);

    /* MAIN LOOP 
     * Keep sending while we have packets or until
     * we've sent enough packets
     */
    while ((pktconst = pcap_next(pin, pkthdr_ptr)) != NULL) {
        packetnum++;
        dbgx(2, "packet " COUNTER_SPEC " caplen %d", packetnum, pkthdr.caplen);

        /* 
         * copy over the packet so we can pad it out if necessary and
         * because pcap_next() returns a const ptr
         */
        memcpy(*pktdata, pktconst, pkthdr.caplen);

#ifdef ENABLE_VERBOSE
        if (options.verbose)
            tcpdump_print(&tcpdump, pkthdr_ptr, *pktdata);
#endif

        /* Dual nic processing? */
        if (options.cachedata != NULL) {
            cache_result = check_cache(options.cachedata, packetnum);
        }

        /* sometimes we should not send the packet, in such cases
         * no point in editing this packet at all, just write it to the
         * output file (note, we can't just remove it, or the tcpprep cache
         * file will loose it's indexing
         */

        if (cache_result == TCPR_DIR_NOSEND)
            goto WRITE_PACKET; /* still need to write it so cache stays in sync */

        if ((rcode = tcpedit_packet(tcpedit, &pkthdr_ptr, pktdata, cache_result)) == TCPEDIT_ERROR) {
            return -1;
        } else if ((rcode == TCPEDIT_SOFT_ERROR) && HAVE_OPT(SKIP_SOFT_ERRORS)) {
            /* don't write packet */
            dbgx(1, "Packet " COUNTER_SPEC " is suppressed from being written due to soft errors", packetnum);
            continue;
        }


WRITE_PACKET:
#ifdef ENABLE_FRAGROUTE
        if (options.frag_ctx == NULL) {
            /* write the packet when there's no fragrouting to be done */
            pcap_dump((u_char *)pout, pkthdr_ptr, *pktdata);
        } else {
            /* get the L3 protocol of the packet */
            proto = tcpedit_l3proto(tcpedit, AFTER_PROCESS, *pktdata, pkthdr_ptr->caplen);

            /* packet is IPv4/IPv6 AND needs to be fragmented */
            if ((proto ==  ETHERTYPE_IP || proto == ETHERTYPE_IP6) &&
                ((options.fragroute_dir == FRAGROUTE_DIR_BOTH) ||
                 (cache_result == TCPR_DIR_C2S && options.fragroute_dir == FRAGROUTE_DIR_C2S) ||
                 (cache_result == TCPR_DIR_S2C && options.fragroute_dir == FRAGROUTE_DIR_S2C))) {

                if (fragroute_process(options.frag_ctx, *pktdata, pkthdr_ptr->caplen) < 0)
                    errx(-1, "Error processing packet via fragroute: %s", options.frag_ctx->errbuf);

                i = 0;
                while ((frag_len = fragroute_getfragment(options.frag_ctx, &frag)) > 0) {
                    /* frags get the same timestamp as the original packet */
                    dbgx(1, "processing packet " COUNTER_SPEC " frag: %u (%d)", packetnum, i++, frag_len);
                    pkthdr_ptr->caplen = frag_len;
                    pkthdr_ptr->len = frag_len;
                    pcap_dump((u_char *)pout, pkthdr_ptr, (u_char *)frag);
                }
            } else {
                /* write the packet without fragroute */
                pcap_dump((u_char *)pout, pkthdr_ptr, *pktdata);
            }
        }
#else
    /* write the packet when there's no fragrouting to be done */
    pcap_dump((u_char *)pout, pkthdr_ptr, *pktdata);

#endif
    } /* while() */
    return 0;
}
Example #3
0
/**
 * This is the callback we use with pcap_dispatch to process
 * each packet recieved by libpcap on the two interfaces.
 * Need to return > 0 to denote success
 */
static int
live_callback(struct live_data_t *livedata, struct pcap_pkthdr *pkthdr,
              const u_char * nextpkt)
{
    ipv4_hdr_t *ip_hdr = NULL;
    ipv6_hdr_t *ip6_hdr = NULL;
    pcap_t *send = NULL;
    static u_char *pktdata = NULL;     /* full packet buffer */
    int cache_mode, retcode;
    static unsigned long packetnum = 0;
    struct macsrc_t *node, finder;  /* rb tree nodes */
#ifdef DEBUG
    u_char dstmac[ETHER_ADDR_LEN];
#endif
    u_int16_t l2proto;

    packetnum++;
    dbgx(2, "packet %lu caplen %d", packetnum, pkthdr->caplen);

    /* only malloc the first time */
    if (pktdata == NULL) {
        /* create packet buffers */
        pktdata = (u_char *)safe_malloc(MAXPACKET);
    } else {
        /* zero out the old packet info */
        memset(pktdata, '\0', MAXPACKET);
    }

    /* copy the packet to our buffer */
    memcpy(pktdata, nextpkt, pkthdr->caplen);


#ifdef ENABLE_VERBOSE
    /* decode packet? */
    if (livedata->options->verbose)
        tcpdump_print(livedata->options->tcpdump, pkthdr, nextpkt);
#endif


    /* lookup our source MAC in the tree */
    memcpy(&finder.key, &pktdata[ETHER_ADDR_LEN], ETHER_ADDR_LEN);
#ifdef DEBUG
    memcpy(&dstmac, pktdata, ETHER_ADDR_LEN);
    dbgx(1, "SRC MAC: " MAC_FORMAT "\tDST MAC: " MAC_FORMAT,
        MAC_STR(finder.key), MAC_STR(dstmac));
#endif

    /* first, is this a packet sent locally?  If so, ignore it */
    if ((memcmp(livedata->options->intf1_mac, &finder.key, ETHER_ADDR_LEN)) == 0) {
        dbgx(1, "Packet matches the MAC of %s, skipping.", livedata->options->intf1);
        return (1);
    }
    else if ((memcmp(livedata->options->intf2_mac, &finder.key, ETHER_ADDR_LEN)) == 0) {
        dbgx(1, "Packet matches the MAC of %s, skipping.", livedata->options->intf2);
        return (1);
    }

    node = RB_FIND(macsrc_tree, &macsrc_root, &finder);

    /* if we can't find the node, build a new one */
    if (node == NULL) {
        dbg(1, "Unable to find MAC in the tree");
        node = new_node();
        node->source = livedata->source;
        memcpy(&node->key, &finder.key, ETHER_ADDR_LEN);
        RB_INSERT(macsrc_tree, &macsrc_root, node);
    }

    /* otherwise compare sources */
    else if (node->source != livedata->source) {
        dbg(1, "Found the dest MAC in the tree and it doesn't match this source NIC... skipping packet");
        /*
         * IMPORTANT!!!
         * Never send a packet out the same interface we sourced it on!
         */
        return (1);
    }

    /* what is our cache mode? */
    cache_mode = livedata->source == PCAP_INT1 ? TCPR_DIR_C2S : TCPR_DIR_S2C;

    l2proto = tcpedit_l3proto(livedata->tcpedit, BEFORE_PROCESS, pktdata, pkthdr->len);
    dbgx(2, "Packet protocol: %04hx", l2proto);

    /* should we skip this packet based on CIDR match? */
    if (l2proto == ETHERTYPE_IP) {
        dbg(3, "Packet is IPv4");
        ip_hdr = (ipv4_hdr_t *)tcpedit_l3data(livedata->tcpedit, BEFORE_PROCESS, pktdata, pkthdr->len);

        /* look for include or exclude CIDR match */
        if (livedata->options->xX.cidr != NULL) {
            if (!process_xX_by_cidr_ipv4(livedata->options->xX.mode, livedata->options->xX.cidr, ip_hdr)) {
                dbg(2, "Skipping IPv4 packet due to CIDR match");
                return (1);
            }
        }

    }
    else if (l2proto == ETHERTYPE_IP6) {
        dbg(3, "Packet is IPv6");
        ip6_hdr = (ipv6_hdr_t *)tcpedit_l3data(livedata->tcpedit, BEFORE_PROCESS, pktdata, pkthdr->len);

        /* look for include or exclude CIDR match */
        if (livedata->options->xX.cidr != NULL) {
            if (!process_xX_by_cidr_ipv6(livedata->options->xX.mode, livedata->options->xX.cidr, ip6_hdr)) {
                dbg(2, "Skipping IPv6 packet due to CIDR match");
                return (1);
            }
        }

    }

    if ((retcode = tcpedit_packet(livedata->tcpedit, &pkthdr, &pktdata, cache_mode)) < 0) {
        if (retcode == TCPEDIT_SOFT_ERROR) {
            return 1;
        } else { /* TCPEDIT_ERROR */
            return -1;
        }
    }

    /* 
     * send packets out the OTHER interface
     * and update the dst mac if necessary
     */
    switch(node->source) {
        case PCAP_INT1:
            dbgx(2, "Packet source was %s... sending out on %s", livedata->options->intf1, 
                livedata->options->intf2);
            send = livedata->options->pcap2;
            break;

        case PCAP_INT2:
            dbgx(2, "Packet source was %s... sending out on %s", livedata->options->intf2, 
                livedata->options->intf1);
            send = livedata->options->pcap1;
            break;

        default:
            errx(-1, "wtf?  our node->source != PCAP_INT1 and != PCAP_INT2: %c", 
                 node->source);
    }

    /*
     * write packet out on the network 
     */
     if (pcap_sendpacket(send, pktdata, pkthdr->caplen) < 0)
         errx(-1, "Unable to send packet out %s: %s", 
            send == livedata->options->pcap1 ? livedata->options->intf1 : livedata->options->intf2, pcap_geterr(send));

    stats.bytes_sent += pkthdr->caplen;
    stats.pkts_sent++;

    dbgx(1, "Sent packet " COUNTER_SPEC, stats.pkts_sent);


    return (1);
} /* live_callback() */