Added the code for xid matching. (The code is not yet enabled)
[ipfw.git] / dummynet / ip_fw2.c
index 039e084..39d6ab7 100644 (file)
@@ -1978,7 +1978,7 @@ dump_table(struct ip_fw_chain *ch, ipfw_table *tbl)
 }
 #endif
 
-#if 0
+#ifndef linux /* FreeBSD */
 static void
 fill_ugid_cache(struct inpcb *inp, struct ip_fw_ugid *ugp)
 {
@@ -1990,57 +1990,45 @@ fill_ugid_cache(struct inpcb *inp, struct ip_fw_ugid *ugp)
        ugp->fw_ngroups = cr->cr_ngroups;
        bcopy(cr->cr_groups, ugp->fw_groups, sizeof(ugp->fw_groups));
 }
-#endif /* no uigid support */
+#endif
 
 static int
 check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
     struct in_addr dst_ip, u_int16_t dst_port, struct in_addr src_ip,
     u_int16_t src_port, struct ip_fw_ugid *ugp, int *ugid_lookupp,
-    struct inpcb *inp, struct sk_buff *skb)
+    struct inpcb *inp)
 {
-#if 1   /* Linux */
-
-       const struct file *filp;
-
-       if (insn->o.opcode == O_JAIL)
-               return 0;
+#ifdef linux
+       int match = 0;
+       struct sk_buff *skb = ((struct mbuf *)inp)->m_skb;
 
-       if (skb->sk == NULL || skb->sk->sk_socket == NULL)
-               return 0;
-
-       filp = skb->sk->sk_socket->file;
-       if (filp == NULL)
-               return 0;
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,28)
-/* use the current's real uid/gid */
-#define UID f_uid
-#define GID f_gid
-#else /* 2.6.29 */
-/* use the current's file access real uid/gid */
-#define UID f_cred->fsuid
-#define GID f_cred->fsgid
+       if (insn->o.opcode == O_JAIL) {
+#ifdef IPFW_PLANETLAB
+               match = (skb->skb_tag == insn->d[0]);
 #endif
-
-       if (insn->o.opcode == O_UID) {
-               if (filp->UID != (uid_t)insn->d[0])
-                       return 0;
+               return match;
        }
 
-       if (insn->o.opcode == O_GID) {
-               if (filp->GID != (gid_t)insn->d[0])
-                       return 0;
-       }
+       if (*ugid_lookupp == 0) {       /* actively lookup and copy in cache */
+
+               /* returns null if any element of the chain up to file is null.
+                * if sk != NULL then we also have a reference
+                */
+               *ugid_lookupp = linux_lookup(proto,
+                       src_ip.s_addr, htons(src_port),
+                       dst_ip.s_addr, htons(dst_port),
+                       skb, oif ? 1 : 0, ugp);
 
-       /* check for slice_id matching */
-       if (insn->o.opcode == O_GID) {
-               if (filp->GID != (gid_t)insn->d[0])
-                       return 0;
        }
+       if (*ugid_lookupp < 0)
+               return 0;
 
-       return 1;
+       if (insn->o.opcode == O_UID)
+               match = (ugp->fw_uid == (uid_t)insn->d[0]);
+       return match;
+
+#else /* FreeBSD */
 
-#else /* FreeBSD original code */
        struct inpcbinfo *pi;
        int wildcard;
        struct inpcb *pcb;
@@ -2650,7 +2638,7 @@ check_body:
                                                    proto, oif,
                                                    dst_ip, dst_port,
                                                    src_ip, src_port, &fw_ugid_cache,
-                                                   &ugid_lookup, args->inp, m->m_skb);
+                                                   &ugid_lookup, (struct inpcb *)args->m);
                                break;
 
                        case O_RECV: