memset(&t, 0, sizeof(t));
s->sopt_td = &t;
- printf("%s called with cmd %d len %d\n", __FUNCTION__, cmd, len);
+ // printf("%s called with cmd %d len %d\n", __FUNCTION__, cmd, len);
if (cmd < IP_DUMMYNET_CONFIGURE && ip_fw_ctl_ptr)
ret = ip_fw_ctl_ptr(s);
#define NF_IP_POST_ROUTING NF_INET_POST_ROUTING
#endif
+/*
+ * ipfw hooks the POST_ROUTING and the PRE_ROUTING chain.
+ * PlanetLab tags the xid in the LOCAL_INPUT and in the
+ * POST_ROUTING chain, so if we want to intercept the
+ * traffic by using the id we need to hook the LOCAL_INPUT
+ * chain instead of the PRE_ROUTING.
+ */
+#ifdef IPFW_PLANETLAB
+#define IPFW_HOOK_IN NF_IP_LOCAL_IN
+#else
+#define IPFW_HOOK_IN NF_IP_PRE_ROUTING
+#endif
+
/*
* The main netfilter hook.
* To make life simple, we queue everything and then do all the
#endif
/* XXX add the interface */
- if (info->hook == NF_IP_PRE_ROUTING) {
+ if (info->hook == IPFW_HOOK_IN) {
ret = ipfw_check_in(NULL, &m, info->indev, PFIL_IN, NULL);
} else {
ret = ipfw_check_out(NULL, &m, info->outdev, PFIL_OUT, NULL);
{
struct sock *sk;
int ret = -1; /* default return value */
+ int uid = -1; /* user id */
+ int st = -1; /* state */
if (proto != IPPROTO_TCP)
return -1;
/*
* On a match, sk is returned with a refcount.
- * In tcp states less that TCP_TIME_WAIT sk references a struct sock
- * which is what we want,
- * otherwise it references a struct inet_timewait_sock which does
- * not point to credentials.
+ * In tcp some states reference a valid struct sock
+ * which is what we want, otherwise the struct sock
+ * referenced can be invalid, as in the case of the
+ * TCP_TIME_WAIT state, when it references a
+ * struct inet_timewait_sock which does not point to credentials.
+ * To be safe we exclude TCP_CLOSE and TCP_LAST_ACK states too.
+ *
* Once again we need conditional code because the UID and GID
* location changes between the two kernels.
*/
#define _CURR_UID f_cred->fsuid
#define _CURR_GID f_cred->fsgid
#endif
- if (sk->sk_state < TCP_TIME_WAIT && sk->sk_socket && sk->sk_socket->file) {
+ st = sk->sk_state;
+ if (st != TCP_TIME_WAIT && st != TCP_CLOSE && st != TCP_LAST_ACK &&
+ sk->sk_socket && sk->sk_socket->file) {
ugp->fw_uid = sk->sk_socket->file->_CURR_UID;
+ uid = ugp->fw_uid;
ret = 1;
}
sock_put(sk);
#undef _CURR_UID
#undef _CURR_GID
- //printf("%s dir %d skb->dst %p skb->dev %p ret %d\n", __FUNCTION__, dir, skb->dst, skb->dev, ret);
+ //printf("%s dir %d sb>dst %p sb>dev %p ret %d id %d st%d\n", __FUNCTION__, dir, skb->dst, skb->dev, ret, uid, st);
return ret;
}
{
.hook = call_ipfw,
.pf = PF_INET,
- .hooknum = NF_IP_PRE_ROUTING,
+ .hooknum = IPFW_HOOK_IN,
.priority = NF_IP_PRI_FILTER,
SET_MOD_OWNER
},