ICQ support on netfilter

Vijay G. Bharadwaj vgb@wam.umd.edu
Mon, 19 Jun 2000 11:42:50 -0400 (EDT)


> if I could hack an ip_conntrack_icq to do it.  It could probably be
> done in userspace, actually.  I heard netfilter allows userspace hooks
> into the packet data.  Is there a simple bit of example code which
> does this?

Get the iptables distribution. Install the libipq library and
headers. Add a QUEUE rule in the appropriate place. Then use this:

        struct ipq_handle *h;
        int rval;

        h = ipq_create_handle(0);
        /* Tell the queue to send packets up to size BUFSIZE */
        rval = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);

        /* Read a queued packet. */
        rval = ipq_read(h, packet, BUFSIZE, 0);

        /* Check if it's a packet or an error. */
        switch (ipq_message_type(packet))
        {
            /* It's an error. The system is trying to tell us something. */
            case NLMSG_ERROR:
                printf("Received error message %d\n", ipq_get_msgerr(packet));
                exit(1);

                /* A packet! */
                case IPQM_PACKET:
                {
                    ipq_packet_msg_t *m = ipq_get_packet(packet);
                    unsigned char *payload = m->payload;
                    int i;

                    if (rval == 0)
                         break;

                    /* Mess with the packet here. Must recalc checksums
                     * if any. payload is ptr to packet. Can even replace
                     * entire packet and hand a new one back to system. */

                     /* Reinject the packet so the system can continue
                      * processing it. This is when IP finally gets the
                      * packet. */
                     rval = ipq_set_verdict(h, m->packet_id, NF_ACCEPT,
                                            m->data_len, payload);

                     if (rval < 0)
                        die(&handle, h, &ent);
                        break;
                 }

                 /* Should never happen. */
                 default:
                      printf("Unknown message!\n");
                      die(&handle, h, &ent);
        }

        /* Clean up and get out. */
        ipq_destroy_handle(h);
        return 0;

This only handles one packet, so you might want to put the middle part in
a loop. Also add error checking and salt to taste. Serve at room
temperature.

-Vijay