patch-2.4.5 linux/net/ipv4/raw.c
Next file: linux/net/ipv4/route.c
Previous file: linux/net/ipv4/protocol.c
Back to the patch index
Back to the overall index
- Lines: 508
- Date:
Wed May 16 10:31:27 2001
- Orig file:
v2.4.4/linux/net/ipv4/raw.c
- Orig date:
Thu Apr 12 12:11:39 2001
diff -u --recursive --new-file v2.4.4/linux/net/ipv4/raw.c linux/net/ipv4/raw.c
@@ -5,7 +5,7 @@
*
* RAW - implementation of IP "raw" sockets.
*
- * Version: $Id: raw.c,v 1.60 2001/02/23 06:32:11 davem Exp $
+ * Version: $Id: raw.c,v 1.61 2001/05/03 20:56:04 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -14,8 +14,9 @@
* Alan Cox : verify_area() fixed up
* Alan Cox : ICMP error handling
* Alan Cox : EMSGSIZE if you send too big a packet
- * Alan Cox : Now uses generic datagrams and shared skbuff
- * library. No more peek crashes, no more backlogs
+ * Alan Cox : Now uses generic datagrams and shared
+ * skbuff library. No more peek crashes,
+ * no more backlogs
* Alan Cox : Checks sk->broadcast.
* Alan Cox : Uses skb_free_datagram/skb_copy_datagram
* Alan Cox : Raw passes ip options too
@@ -101,11 +102,11 @@
{
struct sock *s = sk;
- for(s = sk; s; s = s->next) {
- if((s->num == num) &&
- !(s->daddr && s->daddr != raddr) &&
- !(s->rcv_saddr && s->rcv_saddr != laddr) &&
- !(s->bound_dev_if && s->bound_dev_if != dif))
+ for (s = sk; s; s = s->next) {
+ if (s->num == num &&
+ !(s->daddr && s->daddr != raddr) &&
+ !(s->rcv_saddr && s->rcv_saddr != laddr) &&
+ !(s->bound_dev_if && s->bound_dev_if != dif))
break; /* gotcha */
}
return s;
@@ -117,7 +118,7 @@
*/
static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb)
{
- int type;
+ int type;
type = skb->h.icmph->type;
if (type < 32)
@@ -145,19 +146,19 @@
iph->saddr, iph->daddr,
skb->dev->ifindex);
- while(sk != NULL) {
+ while (sk) {
struct sock *sknext = __raw_v4_lookup(sk->next, iph->protocol,
iph->saddr, iph->daddr,
skb->dev->ifindex);
if (iph->protocol != IPPROTO_ICMP ||
- ! icmp_filter(sk, skb)) {
+ !icmp_filter(sk, skb)) {
struct sk_buff *clone;
- if(sknext == NULL)
+ if (!sknext)
break;
clone = skb_clone(skb, GFP_ATOMIC);
/* Not releasing hash table! */
- if(clone)
+ if (clone)
raw_rcv(sk, clone);
}
sk = sknext;
@@ -203,14 +204,15 @@
err = icmp_err_convert[code].errno;
harderr = icmp_err_convert[code].fatal;
if (code == ICMP_FRAG_NEEDED) {
- harderr = (sk->protinfo.af_inet.pmtudisc != IP_PMTUDISC_DONT);
+ harderr = sk->protinfo.af_inet.pmtudisc !=
+ IP_PMTUDISC_DONT;
err = EMSGSIZE;
}
}
if (sk->protinfo.af_inet.recverr) {
struct iphdr *iph = (struct iphdr*)skb->data;
- u8 *payload = skb->data+(iph->ihl<<2);
+ u8 *payload = skb->data + (iph->ihl << 2);
if (sk->protinfo.af_inet.hdrincl)
payload = skb->data;
@@ -227,8 +229,7 @@
{
/* Charge it to the socket. */
- if (sock_queue_rcv_skb(sk,skb)<0)
- {
+ if (sock_queue_rcv_skb(sk, skb) < 0) {
IP_INC_STATS(IpInDiscards);
kfree_skb(skb);
return NET_RX_DROP;
@@ -240,7 +241,7 @@
int raw_rcv(struct sock *sk, struct sk_buff *skb)
{
- skb_push(skb, skb->data-skb->nh.raw);
+ skb_push(skb, skb->data - skb->nh.raw);
raw_rcv_skb(sk, skb);
return 0;
@@ -248,9 +249,9 @@
struct rawfakehdr
{
- struct iovec *iov;
+ struct iovec *iov;
u32 saddr;
- struct dst_entry *dst;
+ struct dst_entry *dst;
};
/*
@@ -261,7 +262,8 @@
* Callback support is trivial for SOCK_RAW
*/
-static int raw_getfrag(const void *p, char *to, unsigned int offset, unsigned int fraglen)
+static int raw_getfrag(const void *p, char *to, unsigned int offset,
+ unsigned int fraglen)
{
struct rawfakehdr *rfh = (struct rawfakehdr *) p;
return memcpy_fromiovecend(to, rfh->iov, offset, fraglen);
@@ -271,27 +273,28 @@
* IPPROTO_RAW needs extra work.
*/
-static int raw_getrawfrag(const void *p, char *to, unsigned int offset, unsigned int fraglen)
+static int raw_getrawfrag(const void *p, char *to, unsigned int offset,
+ unsigned int fraglen)
{
struct rawfakehdr *rfh = (struct rawfakehdr *) p;
if (memcpy_fromiovecend(to, rfh->iov, offset, fraglen))
return -EFAULT;
- if (offset==0) {
+ if (!offset) {
struct iphdr *iph = (struct iphdr *)to;
if (!iph->saddr)
iph->saddr = rfh->saddr;
- iph->check=0;
- iph->tot_len=htons(fraglen); /* This is right as you can't frag
- RAW packets */
+ iph->check = 0;
+ iph->tot_len = htons(fraglen); /* This is right as you can't
+ frag RAW packets */
/*
* Deliberate breach of modularity to keep
* ip_build_xmit clean (well less messy).
*/
if (!iph->id)
ip_select_ident(iph, rfh->dst, NULL);
- iph->check=ip_fast_csum((unsigned char *)iph, iph->ihl);
+ iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
}
return 0;
}
@@ -317,15 +320,17 @@
If len was ULONG_MAX-10 it would be cathastrophe --ANK
*/
+ err = -EMSGSIZE;
if (len < 0 || len > 0xFFFF)
- return -EMSGSIZE;
+ goto out;
/*
* Check the flags.
*/
- if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message compatibility */
- return -EOPNOTSUPP;
+ err = -EOPNOTSUPP;
+ if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message */
+ goto out; /* compatibility */
/*
* Get and verify the address.
@@ -333,14 +338,18 @@
if (msg->msg_namelen) {
struct sockaddr_in *usin = (struct sockaddr_in*)msg->msg_name;
+ err = -EINVAL;
if (msg->msg_namelen < sizeof(*usin))
- return(-EINVAL);
+ goto out;
if (usin->sin_family != AF_INET) {
static int complained;
if (!complained++)
- printk(KERN_INFO "%s forgot to set AF_INET in raw sendmsg. Fix it!\n", current->comm);
+ printk(KERN_INFO "%s forgot to set AF_INET in "
+ "raw sendmsg. Fix it!\n",
+ current->comm);
+ err = -EINVAL;
if (usin->sin_family)
- return -EINVAL;
+ goto out;
}
daddr = usin->sin_addr.s_addr;
/* ANK: I did not forget to get protocol from port field.
@@ -348,8 +357,9 @@
* IP_HDRINCL is much more convenient.
*/
} else {
+ err = -EINVAL;
if (sk->state != TCP_ESTABLISHED)
- return(-EINVAL);
+ goto out;
daddr = sk->daddr;
}
@@ -358,11 +368,11 @@
ipc.oif = sk->bound_dev_if;
if (msg->msg_controllen) {
- int tmp = ip_cmsg_send(msg, &ipc);
- if (tmp)
- return tmp;
+ err = ip_cmsg_send(msg, &ipc);
+ if (err)
+ goto out;
if (ipc.opt)
- free=1;
+ free = 1;
}
rfh.saddr = ipc.addr;
@@ -385,7 +395,7 @@
}
}
tos = RT_TOS(sk->protinfo.af_inet.tos) | sk->localroute;
- if (msg->msg_flags&MSG_DONTROUTE)
+ if (msg->msg_flags & MSG_DONTROUTE)
tos |= RTO_ONLINK;
if (MULTICAST(daddr)) {
@@ -401,31 +411,31 @@
goto done;
err = -EACCES;
- if (rt->rt_flags&RTCF_BROADCAST && !sk->broadcast)
+ if (rt->rt_flags & RTCF_BROADCAST && !sk->broadcast)
goto done;
- if (msg->msg_flags&MSG_CONFIRM)
+ if (msg->msg_flags & MSG_CONFIRM)
goto do_confirm;
back_from_confirm:
- rfh.iov = msg->msg_iov;
- rfh.saddr = rt->rt_src;
- rfh.dst = &rt->u.dst;
+ rfh.iov = msg->msg_iov;
+ rfh.saddr = rt->rt_src;
+ rfh.dst = &rt->u.dst;
if (!ipc.addr)
ipc.addr = rt->rt_dst;
- err=ip_build_xmit(sk, sk->protinfo.af_inet.hdrincl ? raw_getrawfrag : raw_getfrag,
- &rfh, len, &ipc, rt, msg->msg_flags);
+ err = ip_build_xmit(sk, sk->protinfo.af_inet.hdrincl ? raw_getrawfrag :
+ raw_getfrag, &rfh, len, &ipc, rt, msg->msg_flags);
done:
if (free)
kfree(ipc.opt);
ip_rt_put(rt);
- return err<0 ? err : len;
+out: return err < 0 ? err : len;
do_confirm:
dst_confirm(&rt->u.dst);
- if (!(msg->msg_flags&MSG_PROBE) || len)
+ if (!(msg->msg_flags & MSG_PROBE) || len)
goto back_from_confirm;
err = 0;
goto done;
@@ -445,19 +455,22 @@
static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
{
struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
+ int ret = -EINVAL;
int chk_addr_ret;
- if((sk->state != TCP_CLOSE) || (addr_len < sizeof(struct sockaddr_in)))
- return -EINVAL;
+ if (sk->state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
+ goto out;
chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
- if(addr->sin_addr.s_addr != 0 && chk_addr_ret != RTN_LOCAL &&
- chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
- return -EADDRNOTAVAIL;
+ ret = -EADDRNOTAVAIL;
+ if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
+ chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
+ goto out;
sk->rcv_saddr = sk->saddr = addr->sin_addr.s_addr;
- if(chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
+ if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
sk->saddr = 0; /* Use device */
sk_dst_reset(sk);
- return 0;
+ ret = 0;
+out: return ret;
}
/*
@@ -466,29 +479,30 @@
*/
int raw_recvmsg(struct sock *sk, struct msghdr *msg, int len,
- int noblock, int flags,int *addr_len)
+ int noblock, int flags, int *addr_len)
{
- int copied=0;
+ int copied = 0;
+ int err = -EOPNOTSUPP;
+ struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
struct sk_buff *skb;
- int err;
- struct sockaddr_in *sin=(struct sockaddr_in *)msg->msg_name;
if (flags & MSG_OOB)
- return -EOPNOTSUPP;
+ goto out;
if (addr_len)
- *addr_len=sizeof(*sin);
+ *addr_len = sizeof(*sin);
- if (flags & MSG_ERRQUEUE)
- return ip_recv_error(sk, msg, len);
+ if (flags & MSG_ERRQUEUE) {
+ err = ip_recv_error(sk, msg, len);
+ goto out;
+ }
- skb=skb_recv_datagram(sk,flags,noblock,&err);
- if(skb==NULL)
- return err;
+ skb = skb_recv_datagram(sk, flags, noblock, &err);
+ if (!skb)
+ goto out;
copied = skb->len;
- if (len < copied)
- {
+ if (len < copied) {
msg->msg_flags |= MSG_TRUNC;
copied = len;
}
@@ -508,7 +522,7 @@
ip_cmsg_recv(msg, skb);
done:
skb_free_datagram(sk, skb);
- return (err ? : copied);
+out: return err ? : copied;
}
static int raw_init(struct sock *sk)
@@ -530,19 +544,21 @@
static int raw_geticmpfilter(struct sock *sk, char *optval, int *optlen)
{
- int len;
+ int len, ret = -EFAULT;
- if (get_user(len,optlen))
- return -EFAULT;
+ if (get_user(len, optlen))
+ goto out;
+ ret = -EINVAL;
if (len < 0)
- return -EINVAL;
+ goto out;
if (len > sizeof(struct icmp_filter))
len = sizeof(struct icmp_filter);
- if (put_user(len, optlen))
- return -EFAULT;
- if (copy_to_user(optval, &sk->tp_pinfo.tp_raw4.filter, len))
- return -EFAULT;
- return 0;
+ ret = -EFAULT;
+ if (put_user(len, optlen) ||
+ copy_to_user(optval, &sk->tp_pinfo.tp_raw4.filter, len))
+ goto out;
+ ret = 0;
+out: return ret;
}
static int raw_setsockopt(struct sock *sk, int level, int optname,
@@ -551,13 +567,12 @@
if (level != SOL_RAW)
return ip_setsockopt(sk, level, optname, optval, optlen);
- switch (optname) {
- case ICMP_FILTER:
+ if (optname == ICMP_FILTER) {
if (sk->num != IPPROTO_ICMP)
return -EOPNOTSUPP;
- return raw_seticmpfilter(sk, optval, optlen);
- };
-
+ else
+ return raw_seticmpfilter(sk, optval, optlen);
+ }
return -ENOPROTOOPT;
}
@@ -567,26 +582,23 @@
if (level != SOL_RAW)
return ip_getsockopt(sk, level, optname, optval, optlen);
- switch (optname) {
- case ICMP_FILTER:
+ if (optname == ICMP_FILTER) {
if (sk->num != IPPROTO_ICMP)
return -EOPNOTSUPP;
- return raw_geticmpfilter(sk, optval, optlen);
- };
-
+ else
+ return raw_geticmpfilter(sk, optval, optlen);
+ }
return -ENOPROTOOPT;
}
static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg)
{
- switch(cmd) {
- case SIOCOUTQ:
- {
+ switch (cmd) {
+ case SIOCOUTQ: {
int amount = atomic_read(&sk->wmem_alloc);
return put_user(amount, (int *)arg);
}
- case SIOCINQ:
- {
+ case SIOCINQ: {
struct sk_buff *skb;
int amount = 0;
@@ -609,13 +621,11 @@
static void get_raw_sock(struct sock *sp, char *tmpbuf, int i)
{
- unsigned int dest, src;
- __u16 destp, srcp;
+ unsigned int dest = sp->daddr,
+ src = sp->rcv_saddr;
+ __u16 destp = 0,
+ srcp = sp->num;
- dest = sp->daddr;
- src = sp->rcv_saddr;
- destp = 0;
- srcp = sp->num;
sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
" %02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p",
i, src, srcp, dest, destp, sp->state,
@@ -629,15 +639,15 @@
int raw_get_info(char *buffer, char **start, off_t offset, int length)
{
int len = 0, num = 0, i;
- off_t pos = 0;
+ off_t pos = 128;
off_t begin;
char tmpbuf[129];
if (offset < 128)
len += sprintf(buffer, "%-127s\n",
" sl local_address rem_address st tx_queue "
- "rx_queue tr tm->when retrnsmt uid timeout inode");
- pos = 128;
+ "rx_queue tr tm->when retrnsmt uid timeout "
+ "inode");
read_lock(&raw_v4_lock);
for (i = 0; i < RAWV4_HTABLE_SIZE; i++) {
struct sock *sk;
@@ -649,8 +659,8 @@
if (pos <= offset)
continue;
get_raw_sock(sk, tmpbuf, i);
- len += sprintf(buffer+len, "%-127s\n", tmpbuf);
- if(len >= length)
+ len += sprintf(buffer + len, "%-127s\n", tmpbuf);
+ if (len >= length)
goto out;
}
}
@@ -659,7 +669,7 @@
begin = len - (pos - offset);
*start = buffer + begin;
len -= begin;
- if(len > length)
+ if (len > length)
len = length;
if (len < 0)
len = 0;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)