>    At present I am creating a new mblk copying the original IP,UDP 
> packets + new data
> in new mblk, updating the length and checksums, then I freemsg() the 
> original
> mblk at **mp and make mp point at the newly created mblk. I know this
> is not the correct way of doing as someone else maybe be pointing at 
> original *mp.

oh! don't worry about doing freemsg(). You are releasing your reference
on the message by calling freemsg() which is perfectly fine. freemsg()
internally takes care of other references by not freeing the dblk
if the reference count is greater than 1.

I see an issue with your code though. A message is defined as chain
of message blocks (mblk_t) connected via b_cont field. For your case,
a single UDP packet could be spanned over multiple mblks connected
by b_cont field (still it would be single message). Your code looks
at the first mblk only and assume it contains the full packet,
which may not be the case. You should loop through the chain
and append your data at the last mblk of the message.

b_next and b_prev are used to chain _messages_ together.

Following diagram will help:

message A    mblk_A1.b_cont ---> mblk_A2.b_cont ---> mblk_A3.b_cont

               A   |  b_next
        b_prev |   V

message B   mblk_B1.b_cont ---> mblk_B2.b_cont ---> mblk_B3.b_cont

               A   |  b_next
        b_prev |   V

message C   mblk_C1.b_cont ---> mblk_C2.b_cont ---> mblk_C3.b_cont


prakah

> 
> Here is the code snip
> 
> pfil_hook_function (...)
> {
>         struct udphdr *oldudp,*udp;
>         u_short sz,newlen;
>         mblk_t *m;
>         struct ip *ip,*oldip;
>         char data[6] = {0};
>         int datalen = 6 ;
> 
>         oldip = (struct ip *)((*mp)->b_rptr) ;
>         oldudp = (char *)oldip + hlen ;
>         newlen = ntohs(oldudp->uh_ulen) + datalen;
> 
>         sz = hlen + newlen;
> 
>         if ((m = (mblk_t *)allocb((size_t)sz, BPRI_HI)) == NULL) {
>                 return 0;
>         }
>         MTYPE(m) = M_DATA;
>         m->b_wptr = m->b_rptr + sz;
>         bzero((char *)m->b_rptr, (size_t)sz);
>         udp = (struct udp *)(m->b_rptr + hlen);
>         bcopy(oldudp,udp,ntohs(oldudp->uh_ulen));
>         bcopy(data,(char *)udp + ntohs(oldudp->uh_ulen),datalen);
> 
>         ip = (struct ip *)m->b_rptr;
>         bcopy(oldip,ip,hlen);
>         ip->ip_len        = htons(oldip->ip_len + datalen);
>         ip->ip_sum        =  0 ;
>         ip->ip_sum        = my_ip_checksum(ip, hlen) ;
>         udp->uh_ulen      = htons(newlen) ;
>         udp->uh_sum       = 0 ;
>         udp->uh_sum       = my_udp_checksum(ip->ip_dst.s_addr,
>                                             
> ip->ip_src.s_addr,udp->uh_ulen,udp,
>                                             newlen);
>         m->b_prev = (*mp)->b_prev ;
>         m->b_next = (*mp)->b_next ;
> 
>         m->b_cont = (*mp)->b_cont ;
>         freemsg(*mp);
> 
>         *mp = m;
> 
>         return 0;
> }
> 
> Any suggestions, or a better way of doing this ?
> 
> Thanks,
> -Sachin
> 
> 
> 
> 
> _______________________________________________
> ug-bosug mailing list
> List-Unsubscribe: mailto:ug-bosug-unsubscribe at opensolaris.org
> List-Owner: mailto:ug-bosug-owner at opensolaris.org
> List-Archives: http://www.opensolaris.org/jive/forum.jspa?forumID=54


Reply via email to