Programming Interfaces Guide

The Packet Hook

The packet hook function is called when a packet is received. In this case the function mypkthook() should expect to be called for each inbound packet that arrives in the kernel from a physical network interface. Packets generated internally, that flow between zones using the shared IP instance model or over the loopback interface, will not be seen.

To illustrate the difference between accepting a packet and allowing the function to return normally with what is required to drop a packet, the code below prints out the source and destination address of every 100th packet and then drops the packet, introducing a packet loss of 1%.

static int
mypkthook(hook_event_token_t tok, hook_data_t data, void *arg)
{
    static int counter = 0;
    mytupe_t *ctx = arg;
    hook_pkt_event_t *pkt = (hook_pkt_event_t)data;
    struct ip *ip;
    size_t bytes;

    bytes = msgdsize(pkt->hpe_mb);

    ip = (struct ip *)pkt->hpe_hdr;

    counter++;
    if (counter == 100) {
        printf("drop %d bytes received from %x to %x\n", bytes,
            ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr));
        counter = 0;
        freemsg(*pkt->hpe_mp);
        *pkt->hpe_mp = NULL;
        pkt->hpe_mb = NULL;
        pkt->hpe_hdr = NULL;
        return (1);
    }
    return (0);
}

Packets received by this function, and all others that are called as a callback from a packet event, are received one at a time. There is no chaining together of packets with this interface, so you should expect only one packet per call and expect b_next to always be NULL. While there is no other packet, a single packet may be comprised of several mblk_t structures chained together with b_cont.