static int raw_init(struct sock *sk) { struct raw_opt *tp = raw4_sk(sk); if (inet_sk(sk)->num == IPPROTO_ICMP) memset(&tp->filter, 0, sizeof(tp->filter)); return 0; }
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)) return -EFAULT; return 0; }
/* * 0 - deliver * 1 - block */ static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb) { int type; type = skb->h.icmph->type; if (type < 32) { __u32 data = raw4_sk(sk)->filter.data; return ((1 << type) & data) != 0; } /* Do not block unknown ICMP types */ return 0; }
static int raw_geticmpfilter(struct sock *sk, char __user *optval, int __user *optlen) { int len, ret = -EFAULT; if (get_user(len, optlen)) goto out; ret = -EINVAL; if (len < 0) goto out; if (len > sizeof(struct icmp_filter)) len = sizeof(struct icmp_filter); ret = -EFAULT; if (put_user(len, optlen) || copy_to_user(optval, &raw4_sk(sk)->filter, len)) goto out; ret = 0; out: return ret; }