casting question in kernel source code

rahul8143_at_gmail.com
Date: 04/17/05


Date: 17 Apr 2005 07:01:28 -0700


hello,
      In kernel source code there is ip_fragment.c file my question is
regarding pointer function and casting for that look at required
snippet from that file
There is structure defined for queueing ip fragments as
struct ipq {
        struct ipq *next; /* linked list pointers */
        struct list_head lru_list; /* lru list member */
        u32 user;
        u32 saddr;
        u32 daddr;
        u16 id;
        u8 protocol;
        u8 last_in;
#define COMPLETE 4
#define FIRST_IN 2
#define LAST_IN 1

        struct sk_buff *fragments; /* linked list of received fragments */
        int len; /* total length of original datagram */
        int meat;
        spinlock_t lock;
        atomic_t refcnt;
        struct timer_list timer; /* when will this queue expire? */
        struct ipq **pprev;
        int iif;
        struct timeval stamp;
};

static void ip_expire(unsigned long arg)
{
        struct ipq *qp = (struct ipq *) arg;

        spin_lock(&qp->lock);

        if (qp->last_in & COMPLETE)
                goto out;

        ipq_kill(qp);
....
....
...
}

static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32
user)
{
        struct ipq *qp;

        if ((qp = frag_alloc_queue()) == NULL)
                goto out_nomem;

        qp->protocol = iph->protocol;
        qp->last_in = 0;
        qp->id = iph->id;
        qp->saddr = iph->saddr;
        qp->daddr = iph->daddr;
        qp->user = user;
        qp->len = 0;
        qp->meat = 0;
        qp->fragments = NULL;
        qp->iif = 0;

        /* Initialize a timer for this entry. */
        init_timer(&qp->timer);
        qp->timer.data = (unsigned long) qp; /* pointer to queue */
        qp->timer.function = ip_expire; /* expire function */
        qp->lock = SPIN_LOCK_UNLOCKED;
        atomic_set(&qp->refcnt, 1);

        return ip_frag_intern(hash, qp);
}

         My question is
1)how ip_expire is called in ip_frag_create? I mean where is its
argument. check that function above.
2) how following casting occurs in ip_expire(unsigned long arg)
struct ipq *qp = (struct ipq *) arg;
 how a unsigned long be converted to structure?
regards,
rahul.