00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
#include <linux/config.h>
00043
#include <asm/system.h>
00044
#include <asm/uaccess.h>
00045
#include <asm/ioctls.h>
00046
#include <linux/types.h>
00047
#include <linux/sched.h>
00048
#include <linux/errno.h>
00049
#include <linux/timer.h>
00050
#include <linux/mm.h>
00051
#include <linux/kernel.h>
00052
#include <linux/fcntl.h>
00053
#include <linux/socket.h>
00054
#include <linux/in.h>
00055
#include <linux/inet.h>
00056
#include <linux/netdevice.h>
00057
#include <linux/mroute.h>
00058
#include <net/ip.h>
00059
#include <net/protocol.h>
00060
#include <linux/skbuff.h>
00061
#include <net/sock.h>
00062
#include <net/icmp.h>
00063
#include <net/udp.h>
00064
#include <net/raw.h>
00065
#include <net/inet_common.h>
00066
#include <net/checksum.h>
00067
00068 struct sock *
raw_v4_htable[
RAWV4_HTABLE_SIZE];
00069 rwlock_t
raw_v4_lock = RW_LOCK_UNLOCKED;
00070
00071 static void raw_v4_hash(
struct sock *sk)
00072 {
00073
struct sock **skp = &
raw_v4_htable[sk->
num & (
RAWV4_HTABLE_SIZE - 1)];
00074
00075 write_lock_bh(&
raw_v4_lock);
00076
if ((sk->
next = *skp) != NULL)
00077 (*skp)->pprev = &sk->
next;
00078 *skp = sk;
00079 sk->
pprev = skp;
00080
sock_prot_inc_use(sk->prot);
00081
sock_hold(sk);
00082 write_unlock_bh(&
raw_v4_lock);
00083 }
00084
00085 static void raw_v4_unhash(
struct sock *sk)
00086 {
00087 write_lock_bh(&
raw_v4_lock);
00088
if (sk->
pprev) {
00089
if (sk->
next)
00090 sk->
next->
pprev = sk->
pprev;
00091 *sk->
pprev = sk->
next;
00092 sk->
pprev = NULL;
00093
sock_prot_dec_use(sk->
prot);
00094
__sock_put(sk);
00095 }
00096 write_unlock_bh(&
raw_v4_lock);
00097 }
00098
00099 struct sock *
__raw_v4_lookup(
struct sock *sk,
unsigned short num,
00100
unsigned long raddr,
unsigned long laddr,
00101
int dif)
00102 {
00103
struct sock *s = sk;
00104
00105
for (s = sk; s; s = s->next) {
00106
if (s->num == num &&
00107 !(s->daddr && s->daddr != raddr) &&
00108 !(s->rcv_saddr && s->rcv_saddr != laddr) &&
00109 !(s->bound_dev_if && s->bound_dev_if != dif))
00110
break;
00111 }
00112
return s;
00113 }
00114
00115
00116
00117
00118
00119 static __inline__
int icmp_filter(
struct sock *sk,
struct sk_buff *skb)
00120 {
00121
int type;
00122
00123 type = skb->
h.icmph->type;
00124
if (type < 32) {
00125 __u32 data = sk->
tp_pinfo.tp_raw4.filter.data;
00126
00127
return ((1 << type) & data) != 0;
00128 }
00129
00130
00131
return 0;
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141 struct sock *
raw_v4_input(
struct sk_buff *skb,
struct iphdr *iph,
int hash)
00142 {
00143
struct sock *sk;
00144
00145 read_lock(&
raw_v4_lock);
00146
if ((sk =
raw_v4_htable[hash]) == NULL)
00147
goto out;
00148 sk =
__raw_v4_lookup(sk, iph->
protocol,
00149 iph->
saddr, iph->
daddr,
00150 skb->
dev->
ifindex);
00151
00152
while (sk) {
00153
struct sock *sknext =
__raw_v4_lookup(sk->next, iph->
protocol,
00154 iph->
saddr, iph->
daddr,
00155 skb->
dev->
ifindex);
00156
if (iph->
protocol !=
IPPROTO_ICMP ||
00157 !
icmp_filter(sk, skb)) {
00158
struct sk_buff *clone;
00159
00160
if (!sknext)
00161
break;
00162 clone =
skb_clone(skb, GFP_ATOMIC);
00163
00164
if (clone)
00165
raw_rcv(sk, clone);
00166 }
00167 sk = sknext;
00168 }
00169 out:
00170
if (sk)
00171
sock_hold(sk);
00172 read_unlock(&
raw_v4_lock);
00173
00174
return sk;
00175 }
00176
00177 void raw_err (
struct sock *sk,
struct sk_buff *skb, u32 info)
00178 {
00179
int type = skb->
h.icmph->type;
00180
int code = skb->
h.icmph->code;
00181
int err = 0;
00182
int harderr = 0;
00183
00184
00185
00186
00187
00188
00189
if (!sk->
protinfo.af_inet.recverr && sk->
state != TCP_ESTABLISHED)
00190
return;
00191
00192
switch (type) {
00193
default:
00194
case ICMP_TIME_EXCEEDED:
00195 err = EHOSTUNREACH;
00196
break;
00197
case ICMP_SOURCE_QUENCH:
00198
return;
00199
case ICMP_PARAMETERPROB:
00200 err = EPROTO;
00201 harderr = 1;
00202
break;
00203
case ICMP_DEST_UNREACH:
00204 err = EHOSTUNREACH;
00205
if (code > NR_ICMP_UNREACH)
00206
break;
00207 err =
icmp_err_convert[code].
errno;
00208 harderr =
icmp_err_convert[code].
fatal;
00209
if (code == ICMP_FRAG_NEEDED) {
00210 harderr = sk->
protinfo.af_inet.pmtudisc !=
00211
IP_PMTUDISC_DONT;
00212 err = EMSGSIZE;
00213 }
00214 }
00215
00216
if (sk->
protinfo.af_inet.recverr) {
00217
struct iphdr *iph = (
struct iphdr*)skb->
data;
00218 u8 *payload = skb->
data + (iph->ihl << 2);
00219
00220
if (sk->
protinfo.af_inet.hdrincl)
00221 payload = skb->
data;
00222
ip_icmp_error(sk, skb, err, 0, info, payload);
00223 }
00224
00225
if (sk->
protinfo.af_inet.recverr || harderr) {
00226 sk->
err = err;
00227 sk->
error_report(sk);
00228 }
00229 }
00230
00231 static int raw_rcv_skb(
struct sock * sk,
struct sk_buff * skb)
00232 {
00233
00234
00235
if (
sock_queue_rcv_skb(sk, skb) < 0) {
00236
IP_INC_STATS(IpInDiscards);
00237
kfree_skb(skb);
00238
return NET_RX_DROP;
00239 }
00240
00241
IP_INC_STATS(IpInDelivers);
00242
return NET_RX_SUCCESS;
00243 }
00244
00245 int raw_rcv(
struct sock *sk,
struct sk_buff *skb)
00246 {
00247
skb_push(skb, skb->
data - skb->
nh.raw);
00248
00249
raw_rcv_skb(sk, skb);
00250
return 0;
00251 }
00252
00253 struct rawfakehdr
00254 {
00255 struct iovec *
iov;
00256 u32
saddr;
00257 struct dst_entry *
dst;
00258 };
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 static int raw_getfrag(
const void *p,
char *to,
unsigned int offset,
00269
unsigned int fraglen)
00270 {
00271
struct rawfakehdr *rfh = (
struct rawfakehdr *) p;
00272
return memcpy_fromiovecend(to, rfh->iov, offset, fraglen);
00273 }
00274
00275
00276
00277
00278
00279 static int raw_getrawfrag(
const void *p,
char *to,
unsigned int offset,
00280
unsigned int fraglen)
00281 {
00282
struct rawfakehdr *rfh = (
struct rawfakehdr *) p;
00283
00284
if (
memcpy_fromiovecend(to, rfh->iov, offset, fraglen))
00285
return -EFAULT;
00286
00287
if (!offset) {
00288
struct iphdr *iph = (
struct iphdr *)to;
00289
if (!iph->saddr)
00290 iph->saddr = rfh->saddr;
00291 iph->check = 0;
00292 iph->tot_len = htons(fraglen);
00293
00294
00295
00296
00297
00298
if (!iph->id)
00299
ip_select_ident(iph, rfh->dst, NULL);
00300 iph->check =
ip_fast_csum((
unsigned char *)iph, iph->ihl);
00301 }
00302
return 0;
00303 }
00304
00305 static int raw_sendmsg(
struct sock *sk,
struct msghdr *msg,
int len)
00306 {
00307
struct ipcm_cookie ipc;
00308
struct rawfakehdr rfh;
00309
struct rtable *rt = NULL;
00310
int free = 0;
00311 u32 daddr;
00312 u8 tos;
00313
int err;
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 err = -EMSGSIZE;
00327
if (len < 0 || len > 0xFFFF)
00328
goto out;
00329
00330
00331
00332
00333
00334 err = -EOPNOTSUPP;
00335
if (msg->msg_flags & MSG_OOB)
00336
goto out;
00337
00338
00339
00340
00341
00342
if (msg->msg_namelen) {
00343
struct sockaddr_in *usin = (
struct sockaddr_in*)msg->msg_name;
00344 err = -EINVAL;
00345
if (msg->msg_namelen <
sizeof(*usin))
00346
goto out;
00347
if (usin->sin_family != AF_INET) {
00348
static int complained;
00349
if (!complained++)
00350 printk(KERN_INFO
"%s forgot to set AF_INET in "
00351
"raw sendmsg. Fix it!\n",
00352 current->comm);
00353 err = -EINVAL;
00354
if (usin->sin_family)
00355
goto out;
00356 }
00357 daddr = usin->sin_addr.s_addr;
00358
00359
00360
00361
00362 }
else {
00363 err = -EDESTADDRREQ;
00364
if (sk->
state != TCP_ESTABLISHED)
00365
goto out;
00366 daddr = sk->
daddr;
00367 }
00368
00369 ipc.
addr = sk->
saddr;
00370 ipc.
opt = NULL;
00371 ipc.
oif = sk->
bound_dev_if;
00372
00373
if (msg->msg_controllen) {
00374 err =
ip_cmsg_send(msg, &ipc);
00375
if (err)
00376
goto out;
00377
if (ipc.
opt)
00378 free = 1;
00379 }
00380
00381 rfh.
saddr = ipc.
addr;
00382 ipc.
addr = daddr;
00383
00384
if (!ipc.
opt)
00385 ipc.
opt = sk->
protinfo.af_inet.opt;
00386
00387
if (ipc.
opt) {
00388 err = -EINVAL;
00389
00390
00391
00392
if (sk->
protinfo.af_inet.hdrincl)
00393
goto done;
00394
if (ipc.
opt->
srr) {
00395
if (!daddr)
00396
goto done;
00397 daddr = ipc.
opt->
faddr;
00398 }
00399 }
00400 tos = RT_TOS(sk->
protinfo.af_inet.tos) | sk->
localroute;
00401
if (msg->msg_flags & MSG_DONTROUTE)
00402 tos |=
RTO_ONLINK;
00403
00404
if (
MULTICAST(daddr)) {
00405
if (!ipc.
oif)
00406 ipc.
oif = sk->
protinfo.af_inet.mc_index;
00407
if (!rfh.
saddr)
00408 rfh.
saddr = sk->
protinfo.af_inet.mc_addr;
00409 }
00410
00411 err =
ip_route_output(&rt, daddr, rfh.
saddr, tos, ipc.
oif);
00412
00413
if (err)
00414
goto done;
00415
00416 err = -EACCES;
00417
if (rt->rt_flags & RTCF_BROADCAST && !sk->
broadcast)
00418
goto done;
00419
00420
if (msg->msg_flags & MSG_CONFIRM)
00421
goto do_confirm;
00422 back_from_confirm:
00423
00424 rfh.
iov = msg->msg_iov;
00425 rfh.
saddr = rt->rt_src;
00426 rfh.
dst = &rt->u.dst;
00427
if (!ipc.
addr)
00428 ipc.
addr = rt->rt_dst;
00429 err =
ip_build_xmit(sk, sk->
protinfo.af_inet.hdrincl ?
raw_getrawfrag :
00430
raw_getfrag, &rfh, len, &ipc, rt, msg->msg_flags);
00431
00432 done:
00433
if (free)
00434 kfree(ipc.
opt);
00435
ip_rt_put(rt);
00436
00437 out:
return err < 0 ? err : len;
00438
00439 do_confirm:
00440
dst_confirm(&rt->u.dst);
00441
if (!(msg->msg_flags & MSG_PROBE) || len)
00442
goto back_from_confirm;
00443 err = 0;
00444
goto done;
00445 }
00446
00447 static void raw_close(
struct sock *sk,
long timeout)
00448 {
00449
00450
00451
00452
ip_ra_control(sk, 0, NULL);
00453
00454
inet_sock_release(sk);
00455 }
00456
00457
00458 static int raw_bind(
struct sock *sk,
struct sockaddr *uaddr,
int addr_len)
00459 {
00460
struct sockaddr_in *addr = (
struct sockaddr_in *) uaddr;
00461
int ret = -EINVAL;
00462
int chk_addr_ret;
00463
00464
if (sk->
state != TCP_CLOSE || addr_len <
sizeof(
struct sockaddr_in))
00465 goto out;
00466 chk_addr_ret =
inet_addr_type(addr->sin_addr.s_addr);
00467 ret = -EADDRNOTAVAIL;
00468
if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
00469 chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
00470
goto out;
00471 sk->
rcv_saddr = sk->
saddr = addr->sin_addr.s_addr;
00472
if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
00473 sk->
saddr = 0;
00474
sk_dst_reset(sk);
00475 ret = 0;
00476 out:
return ret;
00477 }
00478
00479
00480
00481
00482
00483
00484 int raw_recvmsg(
struct sock *sk,
struct msghdr *msg,
int len,
00485
int noblock,
int flags,
int *addr_len)
00486 {
00487
int copied = 0;
00488
int err = -EOPNOTSUPP;
00489
struct sockaddr_in *sin = (
struct sockaddr_in *)msg->msg_name;
00490
struct sk_buff *skb;
00491
00492
if (flags & MSG_OOB)
00493
goto out;
00494
00495
if (addr_len)
00496 *addr_len =
sizeof(*sin);
00497
00498
if (flags & MSG_ERRQUEUE) {
00499 err =
ip_recv_error(sk, msg, len);
00500
goto out;
00501 }
00502
00503 skb =
skb_recv_datagram(sk, flags, noblock, &err);
00504
if (!skb)
00505
goto out;
00506
00507 copied = skb->len;
00508
if (len < copied) {
00509 msg->msg_flags |= MSG_TRUNC;
00510 copied = len;
00511 }
00512
00513 err =
skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
00514
if (err)
00515
goto done;
00516
00517
sock_recv_timestamp(msg, sk, skb);
00518
00519
00520
if (sin) {
00521 sin->sin_family = AF_INET;
00522 sin->sin_addr.s_addr = skb->nh.iph->saddr;
00523 memset(&sin->sin_zero, 0,
sizeof(sin->sin_zero));
00524 }
00525
if (sk->
protinfo.af_inet.cmsg_flags)
00526
ip_cmsg_recv(msg, skb);
00527 done:
00528
skb_free_datagram(sk, skb);
00529 out:
return err ? : copied;
00530 }
00531
00532 static int raw_init(
struct sock *sk)
00533 {
00534
struct raw_opt *tp = &(sk->
tp_pinfo.tp_raw4);
00535
if (sk->
num ==
IPPROTO_ICMP)
00536 memset(&tp->filter, 0,
sizeof(tp->filter));
00537
return 0;
00538 }
00539
00540 static int raw_seticmpfilter(
struct sock *sk,
char *optval,
int optlen)
00541 {
00542
if (optlen >
sizeof(
struct icmp_filter))
00543 optlen =
sizeof(
struct icmp_filter);
00544
if (copy_from_user(&sk->
tp_pinfo.tp_raw4.filter, optval, optlen))
00545
return -EFAULT;
00546
return 0;
00547 }
00548
00549 static int raw_geticmpfilter(
struct sock *sk,
char *optval,
int *optlen)
00550 {
00551
int len, ret = -EFAULT;
00552
00553
if (get_user(len, optlen))
00554
goto out;
00555 ret = -EINVAL;
00556
if (len < 0)
00557
goto out;
00558
if (len >
sizeof(
struct icmp_filter))
00559 len =
sizeof(
struct icmp_filter);
00560 ret = -EFAULT;
00561
if (put_user(len, optlen) ||
00562 copy_to_user(optval, &sk->
tp_pinfo.tp_raw4.filter, len))
00563
goto out;
00564 ret = 0;
00565 out:
return ret;
00566 }
00567
00568 static int raw_setsockopt(
struct sock *sk,
int level,
int optname,
00569
char *optval,
int optlen)
00570 {
00571
if (level != SOL_RAW)
00572
return ip_setsockopt(sk, level, optname, optval, optlen);
00573
00574
if (optname == ICMP_FILTER) {
00575
if (sk->
num !=
IPPROTO_ICMP)
00576
return -EOPNOTSUPP;
00577
else
00578
return raw_seticmpfilter(sk, optval, optlen);
00579 }
00580
return -ENOPROTOOPT;
00581 }
00582
00583 static int raw_getsockopt(
struct sock *sk,
int level,
int optname,
00584
char *optval,
int *optlen)
00585 {
00586
if (level != SOL_RAW)
00587
return ip_getsockopt(sk, level, optname, optval, optlen);
00588
00589
if (optname == ICMP_FILTER) {
00590
if (sk->
num !=
IPPROTO_ICMP)
00591
return -EOPNOTSUPP;
00592
else
00593
return raw_geticmpfilter(sk, optval, optlen);
00594 }
00595
return -ENOPROTOOPT;
00596 }
00597
00598 static int raw_ioctl(
struct sock *sk,
int cmd,
unsigned long arg)
00599 {
00600
switch (cmd) {
00601
case SIOCOUTQ: {
00602
int amount = atomic_read(&sk->
wmem_alloc);
00603
return put_user(amount, (
int *)arg);
00604 }
00605
case SIOCINQ: {
00606
struct sk_buff *skb;
00607
int amount = 0;
00608
00609 spin_lock_irq(&sk->
receive_queue.
lock);
00610 skb =
skb_peek(&sk->
receive_queue);
00611
if (skb != NULL)
00612 amount = skb->len;
00613 spin_unlock_irq(&sk->
receive_queue.
lock);
00614
return put_user(amount, (
int *)arg);
00615 }
00616
00617
default:
00618
#ifdef CONFIG_IP_MROUTE
00619
return ipmr_ioctl(sk, cmd, arg);
00620
#else
00621
return -ENOIOCTLCMD;
00622
#endif
00623
}
00624 }
00625
00626 static void get_raw_sock(
struct sock *sp,
char *tmpbuf,
int i)
00627 {
00628
unsigned int dest = sp->
daddr,
00629 src = sp->
rcv_saddr;
00630 __u16 destp = 0,
00631 srcp = sp->
num;
00632
00633 sprintf(tmpbuf,
"%4d: %08X:%04X %08X:%04X"
00634
" %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p",
00635 i, src, srcp, dest, destp, sp->
state,
00636 atomic_read(&sp->
wmem_alloc), atomic_read(&sp->
rmem_alloc),
00637 0, 0L, 0,
00638 sock_i_uid(sp), 0,
00639
sock_i_ino(sp),
00640 atomic_read(&sp->
refcnt), sp);
00641 }
00642
00643 int raw_get_info(
char *buffer,
char **start, off_t offset,
int length)
00644 {
00645
int len = 0, num = 0, i;
00646 off_t pos = 128;
00647 off_t begin;
00648
char tmpbuf[129];
00649
00650
if (offset < 128)
00651 len += sprintf(buffer,
"%-127s\n",
00652
" sl local_address rem_address st tx_queue "
00653
"rx_queue tr tm->when retrnsmt uid timeout "
00654
"inode");
00655 read_lock(&
raw_v4_lock);
00656
for (i = 0; i <
RAWV4_HTABLE_SIZE; i++) {
00657
struct sock *sk;
00658
00659
for (sk =
raw_v4_htable[i]; sk; sk = sk->
next, num++) {
00660
if (sk->family != PF_INET)
00661
continue;
00662 pos += 128;
00663
if (pos <= offset)
00664
continue;
00665
get_raw_sock(sk, tmpbuf, i);
00666 len += sprintf(buffer + len,
"%-127s\n", tmpbuf);
00667
if (len >= length)
00668
goto out;
00669 }
00670 }
00671 out:
00672 read_unlock(&
raw_v4_lock);
00673 begin = len - (pos - offset);
00674 *start = buffer + begin;
00675 len -= begin;
00676
if (len > length)
00677 len = length;
00678
if (len < 0)
00679 len = 0;
00680
return len;
00681 }
00682
00683 struct proto raw_prot = {
00684 name:
"RAW",
00685 close:
raw_close,
00686 connect:
udp_connect,
00687 disconnect:
udp_disconnect,
00688 ioctl:
raw_ioctl,
00689 init:
raw_init,
00690 setsockopt:
raw_setsockopt,
00691 getsockopt:
raw_getsockopt,
00692 sendmsg:
raw_sendmsg,
00693 recvmsg:
raw_recvmsg,
00694 bind:
raw_bind,
00695 backlog_rcv:
raw_rcv_skb,
00696 hash:
raw_v4_hash,
00697 unhash:
raw_v4_unhash,
00698 };