On Fri, 21 Apr 2006, Amit Mondal wrote:

> Hi All,
>
> I need a little help with FreeBSD Kernel stuff. I wanna use Divert Socket to
> sniff IP packet in FreeBSD.
> For that I have compiled the kernel with options IPDIVERT and everything is
> ok.
>
> Now, when I am not really sniffing and re-injecting the packet back to the
> network stack, it is basically dropping all the packets. But I want it
> pass-through it, when no application is reading at divert socket. My
> question is, HOW CAN I MAKE IT PASS-THROUGH? IF NO APPLICATION IS READING
> FROM DIVERT SOCKET, IT SHOULD WORK AS IF THERE IS NO DIVERT SOCKET.
>
> Thanks in adavnce
>
> Rgds
> Amit
>

  Attached is a really old patch I made against FreeBSD 4.7.  It might
apply to 4.9.  Even if it doesn't, it should give you a pretty good idea
how to implement the functionality you desire.

  Kelly

--
Kelly Yancey  -  [EMAIL PROTECTED],FreeBSD.org}  -  [EMAIL PROTECTED]
FreeBSD, The Power To Serve: http://www.freebsd.org/
Index: ip_fw2.c
===================================================================
RCS file: /home/cvs/acs/base/src/sys/netinet/ip_fw2.c,v
retrieving revision 1.9
retrieving revision 1.11
diff -u -p -r1.9 -r1.11
--- ip_fw2.c    3 Jan 2003 23:34:19 -0000       1.9
+++ ip_fw2.c    8 Jan 2003 06:14:48 -0000       1.11
@@ -580,17 +580,17 @@ ipfw_log(struct ip_fw *f, u_int hlen, st
        }
        if (oif || m->m_pkthdr.rcvif)
                log(LOG_SECURITY | LOG_INFO,
-                   "ipfw: %d %s %s %s via %s%d%s\n",
+                   "ipfw: %d %s %s %s via %s%d%s (layer %d)\n",
                    f ? f->rulenum : -1,
                    action, proto, oif ? "out" : "in",
                    oif ? oif->if_name : m->m_pkthdr.rcvif->if_name,
                    oif ? oif->if_unit : m->m_pkthdr.rcvif->if_unit,
-                   fragment);
+                   fragment, eh ? 2 : 3);
        else
                log(LOG_SECURITY | LOG_INFO,
-                   "ipfw: %d %s %s [no if info]%s\n",
+                   "ipfw: %d %s %s [no if info]%s (layer %d)\n",
                    f ? f->rulenum : -1,
-                   action, proto, fragment);
+                   action, proto, fragment, eh ? 2 : 3);
        if (limit_reached)
                log(LOG_SECURITY | LOG_NOTICE,
                    "ipfw: limit %d reached on entry %d\n",
@@ -1939,8 +1939,10 @@ check_body:
                                goto done;
 
                        case O_FORWARD_IP:
-                               if (args->eh)   /* not valid on layer2 pkts */
-                                       break;
+                               if (args->eh && oif != NULL) {
+                                       /* ignore outbound layer2 pkts */
+                                       goto next_rule;
+                               }
                                if (!q || dyn_dir == MATCH_FORWARD)
                                        args->next_hop =
                                            &((ipfw_insn_sa *)cmd)->sa;
Index: ip_input.c
===================================================================
RCS file: /home/cvs/acs/base/src/sys/netinet/ip_input.c,v
retrieving revision 1.14
retrieving revision 1.16
diff -u -p -r1.14 -r1.16
--- ip_input.c  3 Jan 2003 04:46:53 -0000       1.14
+++ ip_input.c  8 Jan 2003 06:16:06 -0000       1.16
@@ -369,8 +369,18 @@ ip_input(struct mbuf *m)
                case PACKET_TAG_IPFORWARD:
                        args.next_hop = (struct sockaddr_in *)m->m_hdr.mh_data;
                        break;
+               case PACKET_TAG_IPFORWARD | M_PROTO5: {
+                       /* XXX This should be taken out and shot! */
+                       struct mbuf *tag = m;
+                       m = m->m_next;
+                       args.next_hop = (struct sockaddr_in 
*)tag->m_hdr.mh_data;
+                       m_free(tag);
+                       KASSERT(m->m_type != MT_TAG, ("XXX kill me"));
+                       goto posttags;
+                       }
                }
        }
+posttags:
 
        KASSERT(m != NULL && (m->m_flags & M_PKTHDR) != 0,
            ("ip_input: no HDR"));
Index: if_ethersubr.c
===================================================================
RCS file: /home/cvs/acs/base/src/sys/net/if_ethersubr.c,v
retrieving revision 1.9
retrieving revision 1.11
diff -u -p -r1.9 -r1.11
--- if_ethersubr.c      3 Jan 2003 04:40:06 -0000       1.9
+++ if_ethersubr.c      8 Jan 2003 06:16:05 -0000       1.11
@@ -501,7 +501,7 @@ ether_ipfw_chk(struct mbuf **m0, struct 
        args.oif = flags & ETHER_IPFW_OUTPUT ? ifp : NULL;
        args.divert_rule = divert_rule;
        args.rule = *rule;      /* matching rule to restart             */
-       args.next_hop = NULL;   /* we do not support forward yet        */
+       args.next_hop = NULL;   /* IPFORWARD                            */
        args.eh = &save_eh;     /* MAC header for bridged/MAC packets   */
        i = ip_fw_chk_ptr(&args);
        *m0 = args.m;
@@ -510,7 +510,7 @@ ether_ipfw_chk(struct mbuf **m0, struct 
        if ( (i & IP_FW_PORT_DENY_FLAG) || *m0 == NULL) /* drop */
                return 0;
 
-       if (i == 0) /* a PASS rule.  */
+       if (i == 0 && args.next_hop == NULL) /* a PASS rule.  */
                return 1;
 
        if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG)) {
@@ -589,6 +589,36 @@ ether_ipfw_chk(struct mbuf **m0, struct 
 
                /* If 'tee', continue with original packet */
                return (clone != NULL);
+       }
+#endif
+
+#ifdef INET
+       /*
+        * IPFIREWALL_FORWARD
+        *
+        * XXX Only support IP forwarding during in-bound processing.
+        */
+       if (i == 0 && args.next_hop != NULL && args.oif == NULL) {
+               /*
+                * Packet must be IP to match an IP forward rule.  Tag it and
+                * pass it along to ip_input() for processing.
+                * XXX Relies on nothing in the netisr processing examining
+                *     the leading mbuf as it's our tag rather than a proper
+                *     packet header.
+                * XXX This is pretty expensive (and ugly!).  This can be
+                *     cleaned up using -current's packet tagging.
+                */
+               struct mbuf *tag;
+
+               MGETHDR(tag, M_DONTWAIT, MT_TAG);
+               tag->m_hdr.mh_flags = PACKET_TAG_IPFORWARD | M_PROTO5; /* Hack! 
*/
+               tag->m_hdr.mh_data = (caddr_t)args.next_hop;
+               tag->m_hdr.mh_next = *m0;
+
+               schednetisr(NETISR_IP);
+               (void) IF_HANDOFF(&ipintrq, tag, NULL);
+               *m0 = NULL;
+               return 0;
        }
 #endif
 
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to