From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Changho Choi" Subject: skb_put(): add some data to the end of the data in sk_buff Date: Thu, 27 Mar 2003 17:26:22 -0600 Sender: netfilter-admin@lists.netfilter.org Message-ID: <002f01c2f4b8$47e00a20$ce0110ac@purity> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_002C_01C2F485.FC899D20" Return-path: Errors-To: netfilter-admin@lists.netfilter.org List-Help: List-Post: List-Subscribe: , List-Id: List-Unsubscribe: , List-Archive: To: netfilter@lists.netfilter.org This is a multi-part message in MIME format. ------=_NextPart_000_002C_01C2F485.FC899D20 Content-Type: text/plain; charset="ks_c_5601-1987" Content-Transfer-Encoding: quoted-printable Hi, I want to add or subtract 40bytes to the end of the data in sk_buff. So I made a module to do this. Actually, I hooked up a packet LOCAL_OUT for the outgoing packet and = added data structure, sip_tag to the sk_buff like below. I added data using skb_put(). When I install the module and run the scp to transfer some data, it = starts well. But, after it sent about 320KB, the connection is stalled and freezed. Is there any error in my code? I appreciate any comments. Thanks, Changho Choi ps: The reception part(sip_input) is also below. -------------------------------------------------------------------------= ----- sip_output(unsigned int hook, struct sk_buff **pskb, const struct net_device *indev, const struct net_device *outdev, int=20 (*okfn)(struct sk_buff *)) { sip_tag *stag; struct iphdr *ip_hdr; int stag_len; ip_hdr =3D (*pskb)->nh.iph; // ip header stag_len =3D sizeof(sip_tag); =20 // new packet size check if (stag_len > skb_tailroom(*pskb)) { struct sk_buff *newskb; printk("...sip_output: newskb...\n"); newskb =3D skb_copy_expand(*pskb, skb_headroom(*pskb), stag_len, GFP_ATOMIC); if (!newskb) { printk("error: sip_output: resize the pskb...\n"); return 0; } else { kfree_skb(*pskb); *pskb =3D newskb; } } // make a room for the security tag stag =3D (sip_tag *) skb_put(*pskb, stag_len); // assign some values to the stag if(init_stag(ip_hdr, stag) =3D=3D 0) return NF_DROP; // initialize the security tag // update ip header ip_hdr->tot_len =3D htons(ntohs(ip_hdr->tot_len) + stag_len); ip_send_check(ip_hdr); // calculate new checksum =20 (*pskb)->nfcache |=3D NFC_ALTERED; =20 return NF_ACCEPT; } // module install static struct nf_hook_ops secureIP_output =3D { { NULL, NULL }, sip_output, PF_INET, NF_IP_LOCAL_OUT, NF_IP_PRI_FILTER-1 }; int init_module(void) { /* Register hooks */ int ret; =20 ret =3D nf_register_hook(&secureIP_output); if (ret < 0) goto cleanup_output; =20 return ret; =20 cleanup_output: nf_unregister_hook(&secureIP_output); return 0; } void cleanup_module(void) { nf_unregister_hook(&secureIP_output); } ---- reception part I removed my data using skb_trim() and update the ip packet length. static unsigned int sip_input(unsigned int hook, struct sk_buff **pskb, const struct net_device *indev, const struct net_device *outdev, int=20 (*okfn)(struct sk_buff *)) { sip_tag *stag; struct iphdr *ip_hdr; unsigned char mac[8]; int i, stag_len; ip_hdr =3D (*pskb)->nh.iph; stag_len =3D sizeof(sip_tag); // get_sip_info()=20 =20 stag =3D (sip_tag *) ((*pskb)->data + (*pskb)->len - stag_len);=20 if(calculate_mac(ip_hdr, stag, mac) =3D=3D 0) return NF_DROP; // mac calculation failed // check mac value if(memcmp(stag->mac, mac, 8) !=3D 0){ return NF_DROP; } =20 // remove stag skb_trim(*pskb, (*pskb)->len-stag_len); =20 ip_hdr->tot_len =3D ip_hdr->tot_len - stag_len; ip_send_check(ip_hdr); // calculate new checksum =20 (*pskb)->nfcache |=3D NFC_ALTERED; =20 return NF_ACCEPT; } // module installation part static struct nf_hook_ops secureIP_input =3D { { NULL, NULL }, sip_input, PF_INET, NF_IP_LOCAL_IN, NF_IP_PRI_FILTER-2 }; int init_module(void) { /* Register hooks */ int ret; =20 ret =3D nf_register_hook(&secureIP_input); if (ret < 0) goto cleanup_output; =20 return ret; =20 cleanup_output: nf_unregister_hook(&secureIP_input); return 0; } void cleanup_module(void) { nf_unregister_hook(&secureIP_input); } ------=_NextPart_000_002C_01C2F485.FC899D20 Content-Type: text/html; charset="ks_c_5601-1987" Content-Transfer-Encoding: quoted-printable
Hi,
I want to add or subtract 40bytes to = the end of the=20 data in sk_buff.
So I made a module to do = this.
Actually, I hooked up a packet = LOCAL_OUT for the=20 outgoing packet and added data structure, sip_tag to the sk_buff like=20 below.
I added data using = skb_put().
When I install the module and run the = scp to=20 transfer some data, it starts well.
But, after it sent about 320KB, the = connection is=20 stalled and freezed.
Is there any error in my = code?
 
I appreciate any comments.
 
Thanks,
Changho Choi
 
ps: The reception part(sip_input) is = also=20 below.
 
----------------------------------------------------------------= --------------
sip_output(unsigned int hook, struct = sk_buff=20 **pskb,
          &n= bsp;   =20 const struct net_device *indev,=20 const
          &nbs= p;   =20 struct net_device *outdev, int=20
           &nb= sp;  =20 (*okfn)(struct sk_buff *))
{
 sip_tag *stag;
 struct = iphdr=20 *ip_hdr;
 int stag_len;
  ip_hdr =3D = (*pskb)->nh.iph;  //=20 ip header
 
 stag_len =3D=20 sizeof(sip_tag);
 
 // new packet size check
 if = (stag_len > skb_tailroom(*pskb)) {
  struct sk_buff=20 *newskb;
  printk("...sip_output:=20 newskb...\n");
  newskb =3D skb_copy_expand(*pskb,=20 skb_headroom(*pskb),
     =20 stag_len,
      GFP_ATOMIC);
 
  if (!newskb)=20 {
   printk("error: sip_output: resize the=20 pskb...\n");
   return 0;
  } else=20 {
   kfree_skb(*pskb);
   *pskb =3D=20 newskb;
  }
 }
 
 // make a room for the security=20 tag
 stag =3D (sip_tag *) skb_put(*pskb, = stag_len);

 // assign=20 some values to the stag
 if(init_stag(ip_hdr, stag) =3D=3D=20 0)
  return NF_DROP; // initialize the security = tag
 
 // update ip=20 header
 ip_hdr->tot_len =3D htons(ntohs(ip_hdr->tot_len) + = stag_len);
 ip_send_check(ip_hdr); // calculate new=20 checksum
 
 (*pskb)->nfcache |=3D=20 NFC_ALTERED;
 
 return NF_ACCEPT;
}
 
// module install
static struct nf_hook_ops = secureIP_output
=3D { {=20 NULL, NULL }, sip_output,
    PF_INET,=20 NF_IP_LOCAL_OUT,
       = NF_IP_PRI_FILTER-1=20 };
 
int init_module(void)
{
 /* = Register=20 hooks */
 int ret;
 
 ret =3D=20 nf_register_hook(&secureIP_output);
 if (ret <=20 0)
  goto cleanup_output;
 
 return=20 ret;
 
cleanup_output:
 nf_unregister_hook(&secure= IP_output);
 return=20 0;
}
 
void=20 cleanup_module(void)
{
 nf_unregister_hook(&secureIP_outpu= t);
}
 
---- reception part
I removed my data using skb_trim() and = update the=20 ip packet length.
 
static unsigned = int
sip_input(unsigned int hook,=20 struct sk_buff=20 **pskb,
          &n= bsp;   =20 const struct net_device *indev,=20 const
          &nbs= p;   =20 struct net_device *outdev, int=20
           &nb= sp;  =20 (*okfn)(struct sk_buff *))
{
 sip_tag *stag;
 struct = iphdr=20 *ip_hdr;
 unsigned char mac[8];
 int i, = stag_len;
 
 ip_hdr =3D = (*pskb)->nh.iph;
 
 stag_len =3D = sizeof(sip_tag);
 
 //=20 get_sip_info() 
 
 stag =3D (sip_tag *) = ((*pskb)->data +=20 (*pskb)->len - stag_len);
 
 if(calculate_mac(ip_hdr, stag, = mac) =3D=3D=20 0)
  return NF_DROP; // mac calculation = failed
 
 // check mac=20 value
 if(memcmp(stag->mac, mac, 8) !=3D = 0){
  return=20 NF_DROP;
 }
 
 // remove = stag
 skb_trim(*pskb,=20 (*pskb)->len-stag_len);
 
 ip_hdr->tot_len =3D=20 ip_hdr->tot_len - stag_len;
 ip_send_check(ip_hdr); // = calculate new=20 checksum
 
 (*pskb)->nfcache |=3D=20 NFC_ALTERED;
 
 return NF_ACCEPT;
}
 
// module installation = part
static struct nf_hook_ops = secureIP_input
=3D { {=20 NULL, NULL }, sip_input,
    PF_INET,=20 NF_IP_LOCAL_IN,
       = NF_IP_PRI_FILTER-2=20 };
 
int init_module(void)
{
 /* = Register=20 hooks */
 int ret;
 
 ret =3D=20 nf_register_hook(&secureIP_input);
 if (ret <=20 0)
  goto cleanup_output;
 
 return=20 ret;
 
cleanup_output:
 nf_unregister_hook(&secure= IP_input);
 return=20 0;
}
 
void=20 cleanup_module(void)
{
 nf_unregister_hook(&secureIP_input= );
}
------=_NextPart_000_002C_01C2F485.FC899D20--