X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Fraw.c;h=dfb9e7b3fe83ce5b2c6e14f9c39cb4e6e8055f8e;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=d73ccfa2d825e235d1a25181c0672f6bf8f007cc;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index d73ccfa2d..dfb9e7b3f 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -81,7 +81,7 @@ #include struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE]; -rwlock_t raw_v4_lock = RW_LOCK_UNLOCKED; +DEFINE_RWLOCK(raw_v4_lock); static void raw_v4_hash(struct sock *sk) { @@ -130,7 +130,7 @@ struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, struct hlist_node *node; sk_for_each_from(sk, node) { - struct inet_opt *inet = inet_sk(sk); + struct inet_sock *inet = inet_sk(sk); if (inet->num == num && !(inet->daddr && inet->daddr != raddr) && @@ -152,9 +152,12 @@ static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb) { int type; + if (!pskb_may_pull(skb, sizeof(struct icmphdr))) + return 1; + type = skb->h.icmph->type; if (type < 32) { - __u32 data = raw4_sk(sk)->filter.data; + __u32 data = raw_sk(sk)->filter.data; return ((1 << type) & data) != 0; } @@ -200,7 +203,7 @@ out: void raw_err (struct sock *sk, struct sk_buff *skb, u32 info) { - struct inet_opt *inet = inet_sk(sk); + struct inet_sock *inet = inet_sk(sk); int type = skb->h.icmph->type; int code = skb->h.icmph->code; int err = 0; @@ -282,7 +285,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, int length, struct rtable *rt, unsigned int flags) { - struct inet_opt *inet = inet_sk(sk); + struct inet_sock *inet = inet_sk(sk); int hh_len; struct iphdr *iph; struct sk_buff *skb; @@ -397,7 +400,7 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len) { - struct inet_opt *inet = inet_sk(sk); + struct inet_sock *inet = inet_sk(sk); struct ipcm_cookie ipc; struct rtable *rt = NULL; int free = 0; @@ -433,7 +436,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, printk(KERN_INFO "%s forgot to set AF_INET in " "raw sendmsg. Fix it!\n", current->comm); - err = -EINVAL; + err = -EAFNOSUPPORT; if (usin->sin_family) goto out; } @@ -566,7 +569,7 @@ static void raw_close(struct sock *sk, long timeout) /* This gets rid of all the nasties in af_inet. -DaveM */ static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) { - struct inet_opt *inet = inet_sk(sk); + struct inet_sock *inet = inet_sk(sk); struct sockaddr_in *addr = (struct sockaddr_in *) uaddr; int ret = -EINVAL; int chk_addr_ret; @@ -591,10 +594,10 @@ out: return ret; * we return it, otherwise we block. */ -int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, - size_t len, int noblock, int flags, int *addr_len) +static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, + size_t len, int noblock, int flags, int *addr_len) { - struct inet_opt *inet = inet_sk(sk); + struct inet_sock *inet = inet_sk(sk); size_t copied = 0; int err = -EOPNOTSUPP; struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; @@ -644,9 +647,10 @@ out: return err ? err : copied; static int raw_init(struct sock *sk) { - struct raw_opt *tp = raw4_sk(sk); + struct raw_sock *rp = raw_sk(sk); + if (inet_sk(sk)->num == IPPROTO_ICMP) - memset(&tp->filter, 0, sizeof(tp->filter)); + memset(&rp->filter, 0, sizeof(rp->filter)); return 0; } @@ -654,7 +658,7 @@ static int raw_seticmpfilter(struct sock *sk, char __user *optval, int optlen) { if (optlen > sizeof(struct icmp_filter)) optlen = sizeof(struct icmp_filter); - if (copy_from_user(&raw4_sk(sk)->filter, optval, optlen)) + if (copy_from_user(&raw_sk(sk)->filter, optval, optlen)) return -EFAULT; return 0; } @@ -672,7 +676,7 @@ static int raw_geticmpfilter(struct sock *sk, char __user *optval, int __user *o len = sizeof(struct icmp_filter); ret = -EFAULT; if (put_user(len, optlen) || - copy_to_user(optval, &raw4_sk(sk)->filter, len)) + copy_to_user(optval, &raw_sk(sk)->filter, len)) goto out; ret = 0; out: return ret; @@ -738,6 +742,7 @@ static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg) struct proto raw_prot = { .name = "RAW", + .owner = THIS_MODULE, .close = raw_close, .connect = ip4_datagram_connect, .disconnect = udp_disconnect, @@ -771,7 +776,7 @@ static struct sock *raw_get_first(struct seq_file *seq) sk_for_each(sk, node, &raw_v4_htable[state->bucket]) if (sk->sk_family == PF_INET && - vx_check(sk->sk_xid, VX_WATCH|VX_IDENT)) + vx_check(sk->sk_xid, VX_IDENT|VX_WATCH)) goto found; } sk = NULL; @@ -788,7 +793,7 @@ static struct sock *raw_get_next(struct seq_file *seq, struct sock *sk) try_again: ; } while (sk && (sk->sk_family != PF_INET || - !vx_check(sk->sk_xid, VX_WATCH|VX_IDENT))); + !vx_check(sk->sk_xid, VX_IDENT|VX_WATCH))); if (!sk && ++state->bucket < RAWV4_HTABLE_SIZE) { sk = sk_head(&raw_v4_htable[state->bucket]); @@ -832,7 +837,7 @@ static void raw_seq_stop(struct seq_file *seq, void *v) static __inline__ char *get_raw_sock(struct sock *sp, char *tmpbuf, int i) { - struct inet_opt *inet = inet_sk(sp); + struct inet_sock *inet = inet_sk(sp); unsigned int dest = inet->daddr, src = inet->rcv_saddr; __u16 destp = 0,