Re: How to re-send out the packets captured by my hook function at NF_IP_PRE_ROUTING

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello, Real Oneone

I wrote some code which swap the src and dst address/port and send out
the packet for 2.6 kernel. The packets are captured from PRE_ROUTINT
point. I steal some code from the ipt_MIRROR.c in 2.5.* kernels.  I
don't know why this is not in the 2.6 kernel.

My code works on 2.6.10 kernel.  Please start read my code from the
very end handle_reflect().  Even I can not understand all the code
now. damn.

Jiangbo


   314 /***********************************************************************
   315  *  Reflect the packet to the sender.
   316  *  The code here is almost the same as what
   317  *    net/ipv4/netfilter/ipt_MIRROR.c did.
   318  ***********************************************************************/
   319 static int route_mirror(struct sk_buff *skb)
   320 {
   321         struct iphdr *iph = skb->nh.iph;
   322         struct flowi fl = {
   323                 .nl_u = {
   324                         .ip4_u = {
   325                                 .daddr = iph->saddr,
   326                                 .saddr = iph->daddr,
   327                                 .tos = RT_TOS(iph->tos) | RTO_CONN
   328                         }
   329                 }
   330         };
   331         struct rtable *rt;
   332
   333         /* Query the routing table */
   334         if (ip_route_output_key(&rt, &fl)) {
   335                 printk("ip_route_output_key failed\n");
   336                 return 0;
   337         }
   338
   339         /* check if the interface we are leaving by is the same as the
   340                                          one we arrived on */
   341         if (skb->dev != rt->u.dst.dev) {
   342                 printk(" check dev stuff failed\n");
   343                 //return 0; Seems this do happens sometimes.
   344         }
   345
   346         /* Drop old route. */
   347         dst_release(skb->dst);
   348         skb->dst = &rt->u.dst;
   349         return 1;
   350 }
   351
   352 static int ip_rewrite(struct sk_buff **pskb)
   353 {
   354         u32 odaddr, osaddr;
   355         struct sk_buff* skb=*pskb;
   356
   357         if (!skb_ip_make_writable(pskb, sizeof(struct iphdr)))
   358                 return 0;
   359
   360         odaddr = skb->nh.iph->saddr;
   361         osaddr = skb->nh.iph->daddr;
   362
   363         skb->nfcache |= NFC_ALTERED;
   364
   365         /* Rewrite IP header */
   366         skb->nh.iph->daddr = odaddr;
   367         skb->nh.iph->saddr = osaddr;
   368
   369         /* Switch the ports for some transport protocols*/
   370         if ( skb->nh.iph->protocol ==  6 ||     //6: TCP
   371                  skb->nh.iph->protocol ==  17 ||        //17: UDP
   372                  skb->nh.iph->protocol ==  113 ){       //113: PGM
373 uint16_t port; 374 port = skb->h.uh->dest;
   375                 skb->h.uh->dest = skb->h.uh->source;
   376                 skb->h.uh->source = port;
   377                 dbgout(DBG_MODULE, DBG_VERBOSE, ("reflect
piggybacket packet:"
378 "protocol=%d\n",skb->nh.iph->protocol ));
   379         }
   380         return 1;
   381 }
   382
   383 /* Stolen from ip_finish_output2 */
   384 static void ip_direct_send(struct sk_buff *skb)
   385 {
   386         struct dst_entry *dst = skb->dst;
   387         struct hh_cache *hh = dst->hh;
   388
   389         if (hh) {
   390                 int hh_alen;
   391
   392                 read_lock_bh(&hh->hh_lock);
   393                 hh_alen = HH_DATA_ALIGN(hh->hh_len);
   394                         memcpy(skb->data - hh_alen,
hh->hh_data, hh_alen);
   395                 read_unlock_bh(&hh->hh_lock);
   396                                         skb_push(skb, hh->hh_len);
   397                 hh->hh_output(skb);
   398         } else if (dst->neighbour)
   399                 dst->neighbour->output(skb);
   400         else {
   401                 printk(KERN_DEBUG "khm in MIRROR\n");
   402                 kfree_skb(skb);
   403         }
   404 }
   405
   406 static unsigned int handle_reflect(struct sk_buff **pskb,
407 unsigned int hooknum)
   408 {
   409         struct sk_buff* skb = *pskb;
   410         struct iphdr *iph = skb->nh.iph;
   411
   412         dbgout(DBG_MODULE, DBG_VERBOSE, ("begin the reflection\n"));
   413         if ( inet_addr_type(iph->saddr) == RTN_LOCAL ){
   414                 //The packet will be reflected to local application.
   415                 //Stolen from ip_rcv_finish();
   416
   417                 struct net_device *dev = skb->dev;
   418                 struct iphdr *iph = skb->nh.iph;
   419
   420                 dbgout(DBG_RB, DBG_VERBOSE, ("Reflect to local!"
421 "skb->dev=0x%X\n",(unsigned int)dev));
   422
   423                 if (!ip_rewrite(pskb))
   424                         return NF_DROP;
   425
   426                 dst_release(skb->dst);
   427                 skb->dst = NULL;
   428                 if (ip_route_input(skb, iph->daddr,
iph->saddr, iph->tos, dev))
   429             return NF_DROP;
   430
   431                 dst_input(skb);
   432                 dbgout(DBG_RB, DBG_VERBOSE, ("Reflect to local
seems OK\n"));
   433                 return NF_STOLEN;
   434
   435         }else if ( route_mirror(skb) ) {
   436                 if (!ip_rewrite(pskb))

  437                         return NF_DROP;
   438
   439                 /* If we are not at FORWARD hook (INPUT/PREROUTING),
   440                  * the TTL isn't decreased by the IP stack */
   441                 if (hooknum != NF_IP_FORWARD) {
   442                         if (skb->nh.iph->ttl <= 1) {
   443                                 /* this will traverse normal stack, and
   444                                  * thus call conntrack on the
icmp packet */
   445                                 icmp_send(skb, ICMP_TIME_EXCEEDED,
   446                                                 ICMP_EXC_TTL, 0);
   447                                 return NF_DROP;
   448                         }
   449                         /* Made writable by ip_rewrite */
   450                         ip_decrease_ttl(skb->nh.iph);
   451                 }
   452
   453                 /* Don't let conntrack code see this packet:
454 it will think we are starting a new 455 connection! --RR */
   456                 dbgout(DBG_RB, DBG_VERBOSE, ("ip direct send
the reflection\n"));
   457                 ip_direct_send(skb);
   458
   459                 return NF_STOLEN;
   460         }
   461         return NF_DROP;
   462 }



On 4/26/06, Real Oneone <realoneone@xxxxxxxxx> wrote:
Hi, I plugged a callback function into netfilter at the hook point of
NF_IP_PRE_ROUTING, tring to capture all the packets, make
some changes to some of them, and invoke skb->dev->hard_start_xmit to
send them out directly. However, the kernel crashed before I could get
any printked information.

If you have any idea of how to send the received packets out, please tell me.

Thank you in advance.

Best regards,
Gu, Xinxing
-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux