diff options
Diffstat (limited to 'net/decnet')
-rw-r--r-- | net/decnet/TODO | 4 | ||||
-rw-r--r-- | net/decnet/af_decnet.c | 53 | ||||
-rw-r--r-- | net/decnet/dn_neigh.c | 6 | ||||
-rw-r--r-- | net/decnet/dn_nsp_in.c | 2 | ||||
-rw-r--r-- | net/decnet/dn_nsp_out.c | 5 | ||||
-rw-r--r-- | net/decnet/dn_route.c | 47 |
6 files changed, 64 insertions, 53 deletions
diff --git a/net/decnet/TODO b/net/decnet/TODO index c5e7f5cd7..0f5c3a649 100644 --- a/net/decnet/TODO +++ b/net/decnet/TODO @@ -16,10 +16,6 @@ Steve's quick list of things that need finishing off: o sendmsg() in the raw socket layer (yes, its for sending routing messages) - o Better filtering of traffic in raw sockets. Aside from receiving routing - messages, there really doesn't seem to be a lot else that raw sockets - could be useful for... suggestions on a postcard please :-) - o Fix /proc for raw sockets o Lots of testing with real applications diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 04728d5d8..7860597ab 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -106,6 +106,7 @@ Version 0.0.6 2.1.110 07-aug-98 Eduardo Marcelo Serrat #include <linux/netdevice.h> #include <linux/inet.h> #include <linux/route.h> +#include <linux/netfilter.h> #include <net/sock.h> #include <asm/segment.h> #include <asm/system.h> @@ -1005,6 +1006,12 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags) memcpy(&newsk->protinfo.dn.addr, &sk->protinfo.dn.addr, sizeof(struct sockaddr_dn)); + /* + * If we are listening on a wild socket, we don't want + * the newly created socket on the wrong hash queue. + */ + newsk->protinfo.dn.addr.sdn_flags &= ~SDF_WILD; + skb_pull(skb, dn_username2sockaddr(skb->data, skb->len, &newsk->protinfo.dn.addr, &type)); skb_pull(skb, dn_username2sockaddr(skb->data, skb->len, &newsk->protinfo.dn.peer, &type)); *(dn_address *)newsk->protinfo.dn.peer.sdn_add.a_addr = cb->src; @@ -1300,9 +1307,6 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char *opt struct dn_scp *scp = &sk->protinfo.dn; struct optdata_dn opt; struct accessdata_dn acc; -#ifdef CONFIG_DECNET_FW - char tmp_fw[MAX(sizeof(struct dn_fwtest),sizeof(struct dn_fwnew))]; -#endif int err; if (optlen && !optval) @@ -1404,34 +1408,15 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char *opt dn_nsp_send_disc(sk, 0x38, 0, GFP_KERNEL); break; -#ifdef CONFIG_DECNET_FW - case DN_FW_APPEND: - case DN_FW_REPLACE: - case DN_FW_DELETE: - case DN_FW_DELETE_NUM: - case DN_FW_INSERT: - case DN_FW_FLUSH: - case DN_FW_ZERO: - case DN_FW_CHECK: - case DN_FW_CREATECHAIN: - case DN_FW_DELETECHAIN: - case DN_FW_POLICY: - - if (!capable(CAP_NET_ADMIN)) - return -EACCES; - if ((optlen > sizeof(tmp_fw)) || (optlen < 1)) - return -EINVAL; - if (copy_from_user(&tmp_fw, optval, optlen)) - return -EFAULT; - err = dn_fw_ctl(optname, &tmp_fw, optlen); - return err; -#endif default: +#ifdef CONFIG_NETFILTER + return nf_setsockopt(sk, PF_DECnet, optname, optval, optlen); +#endif case DSO_LINKINFO: case DSO_STREAM: case DSO_SEQPACKET: - return -EOPNOTSUPP; + return -ENOPROTOOPT; } return 0; @@ -1511,12 +1496,22 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char *opt return -EFAULT; break; + default: +#ifdef CONFIG_NETFILTER + { + int val, len = *optlen; + val = nf_getsockopt(sk, PF_DECnet, optname, + optval, &len); + if (val >= 0) + val = put_user(len, optlen); + return val; + } +#endif case DSO_STREAM: case DSO_SEQPACKET: case DSO_CONACCEPT: case DSO_CONREJECT: - default: - return -EOPNOTSUPP; + return -ENOPROTOOPT; } return 0; @@ -1975,7 +1970,7 @@ static struct packet_type dn_dix_packet_type = __constant_htons(ETH_P_DNA_RT), NULL, /* All devices */ dn_route_rcv, - NULL, + (void*)1, NULL, }; diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index eb50c8c54..b2c6b2051 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c @@ -432,7 +432,7 @@ void dn_neigh_pointopoint_hello(struct sk_buff *skb) /* * Ethernet router hello message received */ -void dn_neigh_router_hello(struct sk_buff *skb) +int dn_neigh_router_hello(struct sk_buff *skb) { struct rtnode_hello_message *msg = (struct rtnode_hello_message *)skb->data; @@ -485,12 +485,13 @@ void dn_neigh_router_hello(struct sk_buff *skb) } kfree_skb(skb); + return 0; } /* * Endnode hello message received */ -void dn_neigh_endnode_hello(struct sk_buff *skb) +int dn_neigh_endnode_hello(struct sk_buff *skb) { struct endnode_hello_message *msg = (struct endnode_hello_message *)skb->data; struct neighbour *neigh; @@ -523,6 +524,7 @@ void dn_neigh_endnode_hello(struct sk_buff *skb) } kfree_skb(skb); + return 0; } diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c index 9cb0c6394..66c72b4bd 100644 --- a/net/decnet/dn_nsp_in.c +++ b/net/decnet/dn_nsp_in.c @@ -320,7 +320,7 @@ static void dn_nsp_disc_conf(struct sock *sk, struct sk_buff *skb) struct dn_scp *scp = &sk->protinfo.dn; unsigned short reason; - if (skb->len != 2) + if (skb->len < 2) goto out; reason = dn_ntohs(*(__u16 *)skb->data); diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c index 3b487617d..e4d0adad3 100644 --- a/net/decnet/dn_nsp_out.c +++ b/net/decnet/dn_nsp_out.c @@ -19,6 +19,7 @@ * Moved output state machine into one function * Steve Whitehouse: New output state machine * Paul Koning: Connect Confirm message fix. + * Eduardo Serrat: Fix to stop dn_nsp_do_disc() sending malformed packets. */ /****************************************************************************** @@ -510,7 +511,7 @@ static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg, int ddl, unsigned char *dd, __u16 rem, __u16 loc) { struct sk_buff *skb = NULL; - int size = 7 + (ddl ? (ddl + 1) : 0); + int size = 8 + ddl; unsigned char *msg; if ((dst == NULL) || (rem == 0)) { @@ -530,9 +531,9 @@ static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg, msg += 2; *(__u16 *)msg = dn_htons(reason); msg += 2; + *msg++ = ddl; if (ddl) { - *msg++ = ddl; memcpy(msg, dd, ddl); } diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index cc2ffeeef..27ff3a10f 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -30,6 +30,9 @@ * my copying the IPv4 routing code. The * hooks here are modified and will continue * to evolve for a while. + * Steve Whitehouse : Real SMP at last :-) Also new netfilter + * stuff. Look out raw sockets your days + * are numbered! */ /****************************************************************************** @@ -359,9 +362,22 @@ drop_it: return 0; } +static int dn_route_discard(struct sk_buff *skb) +{ + kfree_skb(skb); + return 0; +} + +static int dn_route_ptp_hello(struct sk_buff *skb) +{ + dn_dev_hello(skb); + dn_neigh_pointopoint_hello(skb); + return 0; +} + int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) { - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb; unsigned char flags = 0; int padlen = 0; __u16 len = dn_ntohs(*(__u16 *)skb->data); @@ -370,8 +386,8 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type if (dn == NULL) goto dump_it; - cb->stamp = jiffies; - cb->iif = dev->ifindex; + if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) + goto out; skb_pull(skb, 2); @@ -382,6 +398,10 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type flags = *skb->data; + cb = (struct dn_skb_cb *)skb->cb; + cb->stamp = jiffies; + cb->iif = dev->ifindex; + /* * If we have padding, remove it. */ @@ -426,24 +446,20 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type switch(flags & DN_RT_CNTL_MSK) { case DN_RT_PKT_HELO: - dn_dev_hello(skb); - dn_neigh_pointopoint_hello(skb); - return 0; + NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_route_ptp_hello); + goto out; case DN_RT_PKT_L1RT: case DN_RT_PKT_L2RT: -#ifdef CONFIG_DECNET_ROUTER - return dn_fib_rt_message(skb); -#else - break; -#endif /* CONFIG_DECNET_ROUTER */ + NF_HOOK(PF_DECnet, NF_DN_ROUTE, skb, skb->dev, NULL, dn_route_discard); + goto out; case DN_RT_PKT_ERTH: - dn_neigh_router_hello(skb); - return 0; + NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_neigh_router_hello); + goto out; case DN_RT_PKT_EEDH: - dn_neigh_endnode_hello(skb); - return 0; + NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_neigh_endnode_hello); + goto out; } } else { if (dn->parms.state != DN_DEV_S_RU) @@ -461,6 +477,7 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type dump_it: kfree_skb(skb); +out: return 0; } |