raw.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:16k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * INET An implementation of the TCP/IP protocol suite for the LINUX
  3.  * operating system.  INET is implemented using the  BSD Socket
  4.  * interface as the means of communication with the user level.
  5.  *
  6.  * RAW - implementation of IP "raw" sockets.
  7.  *
  8.  * Version: $Id: raw.c,v 1.63.2.1 2002/03/05 12:47:34 davem Exp $
  9.  *
  10.  * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
  11.  * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  12.  *
  13.  * Fixes:
  14.  * Alan Cox : verify_area() fixed up
  15.  * Alan Cox : ICMP error handling
  16.  * Alan Cox : EMSGSIZE if you send too big a packet
  17.  * Alan Cox :  Now uses generic datagrams and shared
  18.  * skbuff library. No more peek crashes,
  19.  * no more backlogs
  20.  * Alan Cox : Checks sk->broadcast.
  21.  * Alan Cox : Uses skb_free_datagram/skb_copy_datagram
  22.  * Alan Cox : Raw passes ip options too
  23.  * Alan Cox : Setsocketopt added
  24.  * Alan Cox : Fixed error return for broadcasts
  25.  * Alan Cox : Removed wake_up calls
  26.  * Alan Cox : Use ttl/tos
  27.  * Alan Cox : Cleaned up old debugging
  28.  * Alan Cox : Use new kernel side addresses
  29.  * Arnt Gulbrandsen : Fixed MSG_DONTROUTE in raw sockets.
  30.  * Alan Cox : BSD style RAW socket demultiplexing.
  31.  * Alan Cox : Beginnings of mrouted support.
  32.  * Alan Cox : Added IP_HDRINCL option.
  33.  * Alan Cox : Skip broadcast check if BSDism set.
  34.  * David S. Miller : New socket lookup architecture.
  35.  *
  36.  * This program is free software; you can redistribute it and/or
  37.  * modify it under the terms of the GNU General Public License
  38.  * as published by the Free Software Foundation; either version
  39.  * 2 of the License, or (at your option) any later version.
  40.  */
  41.  
  42. #include <linux/config.h> 
  43. #include <asm/system.h>
  44. #include <asm/uaccess.h>
  45. #include <asm/ioctls.h>
  46. #include <linux/types.h>
  47. #include <linux/sched.h>
  48. #include <linux/errno.h>
  49. #include <linux/timer.h>
  50. #include <linux/mm.h>
  51. #include <linux/kernel.h>
  52. #include <linux/fcntl.h>
  53. #include <linux/socket.h>
  54. #include <linux/in.h>
  55. #include <linux/inet.h>
  56. #include <linux/netdevice.h>
  57. #include <linux/mroute.h>
  58. #include <net/ip.h>
  59. #include <net/protocol.h>
  60. #include <linux/skbuff.h>
  61. #include <net/sock.h>
  62. #include <net/icmp.h>
  63. #include <net/udp.h>
  64. #include <net/raw.h>
  65. #include <net/inet_common.h>
  66. #include <net/checksum.h>
  67. struct sock *raw_v4_htable[RAWV4_HTABLE_SIZE];
  68. rwlock_t raw_v4_lock = RW_LOCK_UNLOCKED;
  69. static void raw_v4_hash(struct sock *sk)
  70. {
  71. struct sock **skp = &raw_v4_htable[sk->num & (RAWV4_HTABLE_SIZE - 1)];
  72. write_lock_bh(&raw_v4_lock);
  73. if ((sk->next = *skp) != NULL)
  74. (*skp)->pprev = &sk->next;
  75. *skp = sk;
  76. sk->pprev = skp;
  77. sock_prot_inc_use(sk->prot);
  78.   sock_hold(sk);
  79. write_unlock_bh(&raw_v4_lock);
  80. }
  81. static void raw_v4_unhash(struct sock *sk)
  82. {
  83.   write_lock_bh(&raw_v4_lock);
  84. if (sk->pprev) {
  85. if (sk->next)
  86. sk->next->pprev = sk->pprev;
  87. *sk->pprev = sk->next;
  88. sk->pprev = NULL;
  89. sock_prot_dec_use(sk->prot);
  90. __sock_put(sk);
  91. }
  92. write_unlock_bh(&raw_v4_lock);
  93. }
  94. struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
  95.      unsigned long raddr, unsigned long laddr,
  96.      int dif)
  97. {
  98. struct sock *s = sk;
  99. for (s = sk; s; s = s->next) {
  100. if (s->num == num  &&
  101.     !(s->daddr && s->daddr != raddr)  &&
  102.     !(s->rcv_saddr && s->rcv_saddr != laddr) &&
  103.     !(s->bound_dev_if && s->bound_dev_if != dif))
  104. break; /* gotcha */
  105. }
  106. return s;
  107. }
  108. /*
  109.  * 0 - deliver
  110.  * 1 - block
  111.  */
  112. static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb)
  113. {
  114. int type;
  115. type = skb->h.icmph->type;
  116. if (type < 32) {
  117. __u32 data = sk->tp_pinfo.tp_raw4.filter.data;
  118. return ((1 << type) & data) != 0;
  119. }
  120. /* Do not block unknown ICMP types */
  121. return 0;
  122. }
  123. /* IP input processing comes here for RAW socket delivery.
  124.  * This is fun as to avoid copies we want to make no surplus
  125.  * copies.
  126.  *
  127.  * RFC 1122: SHOULD pass TOS value up to the transport layer.
  128.  * -> It does. And not only TOS, but all IP header.
  129.  */
  130. struct sock *raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
  131. {
  132. struct sock *sk;
  133. read_lock(&raw_v4_lock);
  134. if ((sk = raw_v4_htable[hash]) == NULL)
  135. goto out;
  136. sk = __raw_v4_lookup(sk, iph->protocol,
  137.      iph->saddr, iph->daddr,
  138.      skb->dev->ifindex);
  139. while (sk) {
  140. struct sock *sknext = __raw_v4_lookup(sk->next, iph->protocol,
  141.       iph->saddr, iph->daddr,
  142.       skb->dev->ifindex);
  143. if (iph->protocol != IPPROTO_ICMP ||
  144.     !icmp_filter(sk, skb)) {
  145. struct sk_buff *clone;
  146. if (!sknext)
  147. break;
  148. clone = skb_clone(skb, GFP_ATOMIC);
  149. /* Not releasing hash table! */
  150. if (clone)
  151. raw_rcv(sk, clone);
  152. }
  153. sk = sknext;
  154. }
  155. out:
  156. if (sk)
  157. sock_hold(sk);
  158. read_unlock(&raw_v4_lock);
  159. return sk;
  160. }
  161. void raw_err (struct sock *sk, struct sk_buff *skb, u32 info)
  162. {
  163. int type = skb->h.icmph->type;
  164. int code = skb->h.icmph->code;
  165. int err = 0;
  166. int harderr = 0;
  167. /* Report error on raw socket, if:
  168.    1. User requested ip_recverr.
  169.    2. Socket is connected (otherwise the error indication
  170.       is useless without ip_recverr and error is hard.
  171.  */
  172. if (!sk->protinfo.af_inet.recverr && sk->state != TCP_ESTABLISHED)
  173. return;
  174. switch (type) {
  175. default:
  176. case ICMP_TIME_EXCEEDED:
  177. err = EHOSTUNREACH;
  178. break;
  179. case ICMP_SOURCE_QUENCH:
  180. return;
  181. case ICMP_PARAMETERPROB:
  182. err = EPROTO;
  183. harderr = 1;
  184. break;
  185. case ICMP_DEST_UNREACH:
  186. err = EHOSTUNREACH;
  187. if (code > NR_ICMP_UNREACH)
  188. break;
  189. err = icmp_err_convert[code].errno;
  190. harderr = icmp_err_convert[code].fatal;
  191. if (code == ICMP_FRAG_NEEDED) {
  192. harderr = sk->protinfo.af_inet.pmtudisc !=
  193. IP_PMTUDISC_DONT;
  194. err = EMSGSIZE;
  195. }
  196. }
  197. if (sk->protinfo.af_inet.recverr) {
  198. struct iphdr *iph = (struct iphdr*)skb->data;
  199. u8 *payload = skb->data + (iph->ihl << 2);
  200. if (sk->protinfo.af_inet.hdrincl)
  201. payload = skb->data;
  202. ip_icmp_error(sk, skb, err, 0, info, payload);
  203. }
  204. if (sk->protinfo.af_inet.recverr || harderr) {
  205. sk->err = err;
  206. sk->error_report(sk);
  207. }
  208. }
  209. static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb)
  210. {
  211. /* Charge it to the socket. */
  212. if (sock_queue_rcv_skb(sk, skb) < 0) {
  213. IP_INC_STATS(IpInDiscards);
  214. kfree_skb(skb);
  215. return NET_RX_DROP;
  216. }
  217. IP_INC_STATS(IpInDelivers);
  218. return NET_RX_SUCCESS;
  219. }
  220. int raw_rcv(struct sock *sk, struct sk_buff *skb)
  221. {
  222. skb_push(skb, skb->data - skb->nh.raw);
  223. raw_rcv_skb(sk, skb);
  224. return 0;
  225. }
  226. struct rawfakehdr 
  227. {
  228. struct iovec *iov;
  229. u32 saddr;
  230. struct dst_entry *dst;
  231. };
  232. /*
  233.  * Send a RAW IP packet.
  234.  */
  235. /*
  236.  * Callback support is trivial for SOCK_RAW
  237.  */
  238.   
  239. static int raw_getfrag(const void *p, char *to, unsigned int offset,
  240. unsigned int fraglen)
  241. {
  242. struct rawfakehdr *rfh = (struct rawfakehdr *) p;
  243. return memcpy_fromiovecend(to, rfh->iov, offset, fraglen);
  244. }
  245. /*
  246.  * IPPROTO_RAW needs extra work.
  247.  */
  248.  
  249. static int raw_getrawfrag(const void *p, char *to, unsigned int offset,
  250. unsigned int fraglen)
  251. {
  252. struct rawfakehdr *rfh = (struct rawfakehdr *) p;
  253. if (memcpy_fromiovecend(to, rfh->iov, offset, fraglen))
  254. return -EFAULT;
  255. if (!offset) {
  256. struct iphdr *iph = (struct iphdr *)to;
  257. if (!iph->saddr)
  258. iph->saddr = rfh->saddr;
  259. iph->check   = 0;
  260. iph->tot_len = htons(fraglen); /* This is right as you can't
  261.   frag RAW packets */
  262. /*
  263.    * Deliberate breach of modularity to keep 
  264.    * ip_build_xmit clean (well less messy).
  265.  */
  266. if (!iph->id)
  267. ip_select_ident(iph, rfh->dst, NULL);
  268. iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
  269. }
  270. return 0;
  271. }
  272. static int raw_sendmsg(struct sock *sk, struct msghdr *msg, int len)
  273. {
  274. struct ipcm_cookie ipc;
  275. struct rawfakehdr rfh;
  276. struct rtable *rt = NULL;
  277. int free = 0;
  278. u32 daddr;
  279. u8  tos;
  280. int err;
  281. /* This check is ONLY to check for arithmetic overflow
  282.    on integer(!) len. Not more! Real check will be made
  283.    in ip_build_xmit --ANK
  284.    BTW socket.c -> af_*.c -> ... make multiple
  285.    invalid conversions size_t -> int. We MUST repair it f.e.
  286.    by replacing all of them with size_t and revise all
  287.    the places sort of len += sizeof(struct iphdr)
  288.    If len was ULONG_MAX-10 it would be cathastrophe  --ANK
  289.  */
  290. err = -EMSGSIZE;
  291. if (len < 0 || len > 0xFFFF)
  292. goto out;
  293. /*
  294.  * Check the flags.
  295.  */
  296. err = -EOPNOTSUPP;
  297. if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message */
  298. goto out;               /* compatibility */
  299.  
  300. /*
  301.  * Get and verify the address. 
  302.  */
  303. if (msg->msg_namelen) {
  304. struct sockaddr_in *usin = (struct sockaddr_in*)msg->msg_name;
  305. err = -EINVAL;
  306. if (msg->msg_namelen < sizeof(*usin))
  307. goto out;
  308. if (usin->sin_family != AF_INET) {
  309. static int complained;
  310. if (!complained++)
  311. printk(KERN_INFO "%s forgot to set AF_INET in "
  312.  "raw sendmsg. Fix it!n",
  313.  current->comm);
  314. err = -EINVAL;
  315. if (usin->sin_family)
  316. goto out;
  317. }
  318. daddr = usin->sin_addr.s_addr;
  319. /* ANK: I did not forget to get protocol from port field.
  320.  * I just do not know, who uses this weirdness.
  321.  * IP_HDRINCL is much more convenient.
  322.  */
  323. } else {
  324. err = -EINVAL;
  325. if (sk->state != TCP_ESTABLISHED) 
  326. goto out;
  327. daddr = sk->daddr;
  328. }
  329. ipc.addr = sk->saddr;
  330. ipc.opt = NULL;
  331. ipc.oif = sk->bound_dev_if;
  332. if (msg->msg_controllen) {
  333. err = ip_cmsg_send(msg, &ipc);
  334. if (err)
  335. goto out;
  336. if (ipc.opt)
  337. free = 1;
  338. }
  339. rfh.saddr = ipc.addr;
  340. ipc.addr = daddr;
  341. if (!ipc.opt)
  342. ipc.opt = sk->protinfo.af_inet.opt;
  343. if (ipc.opt) {
  344. err = -EINVAL;
  345. /* Linux does not mangle headers on raw sockets,
  346.  * so that IP options + IP_HDRINCL is non-sense.
  347.  */
  348. if (sk->protinfo.af_inet.hdrincl)
  349. goto done;
  350. if (ipc.opt->srr) {
  351. if (!daddr)
  352. goto done;
  353. daddr = ipc.opt->faddr;
  354. }
  355. }
  356. tos = RT_TOS(sk->protinfo.af_inet.tos) | sk->localroute;
  357. if (msg->msg_flags & MSG_DONTROUTE)
  358. tos |= RTO_ONLINK;
  359. if (MULTICAST(daddr)) {
  360. if (!ipc.oif)
  361. ipc.oif = sk->protinfo.af_inet.mc_index;
  362. if (!rfh.saddr)
  363. rfh.saddr = sk->protinfo.af_inet.mc_addr;
  364. }
  365. err = ip_route_output(&rt, daddr, rfh.saddr, tos, ipc.oif);
  366. if (err)
  367. goto done;
  368. err = -EACCES;
  369. if (rt->rt_flags & RTCF_BROADCAST && !sk->broadcast)
  370. goto done;
  371. if (msg->msg_flags & MSG_CONFIRM)
  372. goto do_confirm;
  373. back_from_confirm:
  374. rfh.iov = msg->msg_iov;
  375. rfh.saddr = rt->rt_src;
  376. rfh.dst = &rt->u.dst;
  377. if (!ipc.addr)
  378. ipc.addr = rt->rt_dst;
  379. err = ip_build_xmit(sk, sk->protinfo.af_inet.hdrincl ? raw_getrawfrag :
  380.             raw_getfrag, &rfh, len, &ipc, rt, msg->msg_flags);
  381. done:
  382. if (free)
  383. kfree(ipc.opt);
  384. ip_rt_put(rt);
  385. out: return err < 0 ? err : len;
  386. do_confirm:
  387. dst_confirm(&rt->u.dst);
  388. if (!(msg->msg_flags & MSG_PROBE) || len)
  389. goto back_from_confirm;
  390. err = 0;
  391. goto done;
  392. }
  393. static void raw_close(struct sock *sk, long timeout)
  394. {
  395.         /*
  396.  * Raw sockets may have direct kernel refereneces. Kill them.
  397.  */
  398. ip_ra_control(sk, 0, NULL);
  399. inet_sock_release(sk);
  400. }
  401. /* This gets rid of all the nasties in af_inet. -DaveM */
  402. static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
  403. {
  404. struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
  405. int ret = -EINVAL;
  406. int chk_addr_ret;
  407. if (sk->state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
  408. goto out;
  409. chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
  410. ret = -EADDRNOTAVAIL;
  411. if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
  412.     chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
  413. goto out;
  414. sk->rcv_saddr = sk->saddr = addr->sin_addr.s_addr;
  415. if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
  416. sk->saddr = 0;  /* Use device */
  417. sk_dst_reset(sk);
  418. ret = 0;
  419. out: return ret;
  420. }
  421. /*
  422.  * This should be easy, if there is something there
  423.  * we return it, otherwise we block.
  424.  */
  425. int raw_recvmsg(struct sock *sk, struct msghdr *msg, int len,
  426. int noblock, int flags, int *addr_len)
  427. {
  428. int copied = 0;
  429. int err = -EOPNOTSUPP;
  430. struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
  431. struct sk_buff *skb;
  432. if (flags & MSG_OOB)
  433. goto out;
  434. if (addr_len)
  435. *addr_len = sizeof(*sin);
  436. if (flags & MSG_ERRQUEUE) {
  437. err = ip_recv_error(sk, msg, len);
  438. goto out;
  439. }
  440. skb = skb_recv_datagram(sk, flags, noblock, &err);
  441. if (!skb)
  442. goto out;
  443. copied = skb->len;
  444. if (len < copied) {
  445. msg->msg_flags |= MSG_TRUNC;
  446. copied = len;
  447. }
  448. err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
  449. if (err)
  450. goto done;
  451. sock_recv_timestamp(msg, sk, skb);
  452. /* Copy the address. */
  453. if (sin) {
  454. sin->sin_family = AF_INET;
  455. sin->sin_addr.s_addr = skb->nh.iph->saddr;
  456. memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
  457. }
  458. if (sk->protinfo.af_inet.cmsg_flags)
  459. ip_cmsg_recv(msg, skb);
  460. done:
  461. skb_free_datagram(sk, skb);
  462. out: return err ? : copied;
  463. }
  464. static int raw_init(struct sock *sk)
  465. {
  466. struct raw_opt *tp = &(sk->tp_pinfo.tp_raw4);
  467. if (sk->num == IPPROTO_ICMP)
  468. memset(&tp->filter, 0, sizeof(tp->filter));
  469. return 0;
  470. }
  471. static int raw_seticmpfilter(struct sock *sk, char *optval, int optlen)
  472. {
  473. if (optlen > sizeof(struct icmp_filter))
  474. optlen = sizeof(struct icmp_filter);
  475. if (copy_from_user(&sk->tp_pinfo.tp_raw4.filter, optval, optlen))
  476. return -EFAULT;
  477. return 0;
  478. }
  479. static int raw_geticmpfilter(struct sock *sk, char *optval, int *optlen)
  480. {
  481. int len, ret = -EFAULT;
  482. if (get_user(len, optlen))
  483. goto out;
  484. ret = -EINVAL;
  485. if (len < 0)
  486. goto out;
  487. if (len > sizeof(struct icmp_filter))
  488. len = sizeof(struct icmp_filter);
  489. ret = -EFAULT;
  490. if (put_user(len, optlen) ||
  491.     copy_to_user(optval, &sk->tp_pinfo.tp_raw4.filter, len))
  492. goto out;
  493. ret = 0;
  494. out: return ret;
  495. }
  496. static int raw_setsockopt(struct sock *sk, int level, int optname, 
  497.   char *optval, int optlen)
  498. {
  499. if (level != SOL_RAW)
  500. return ip_setsockopt(sk, level, optname, optval, optlen);
  501. if (optname == ICMP_FILTER) {
  502. if (sk->num != IPPROTO_ICMP)
  503. return -EOPNOTSUPP;
  504. else
  505. return raw_seticmpfilter(sk, optval, optlen);
  506. }
  507. return -ENOPROTOOPT;
  508. }
  509. static int raw_getsockopt(struct sock *sk, int level, int optname, 
  510.   char *optval, int *optlen)
  511. {
  512. if (level != SOL_RAW)
  513. return ip_getsockopt(sk, level, optname, optval, optlen);
  514. if (optname == ICMP_FILTER) {
  515. if (sk->num != IPPROTO_ICMP)
  516. return -EOPNOTSUPP;
  517. else
  518. return raw_geticmpfilter(sk, optval, optlen);
  519. }
  520. return -ENOPROTOOPT;
  521. }
  522. static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg)
  523. {
  524. switch (cmd) {
  525. case SIOCOUTQ: {
  526. int amount = atomic_read(&sk->wmem_alloc);
  527. return put_user(amount, (int *)arg);
  528. }
  529. case SIOCINQ: {
  530. struct sk_buff *skb;
  531. int amount = 0;
  532. spin_lock_irq(&sk->receive_queue.lock);
  533. skb = skb_peek(&sk->receive_queue);
  534. if (skb != NULL)
  535. amount = skb->len;
  536. spin_unlock_irq(&sk->receive_queue.lock);
  537. return put_user(amount, (int *)arg);
  538. }
  539. default:
  540. #ifdef CONFIG_IP_MROUTE
  541. return ipmr_ioctl(sk, cmd, arg);
  542. #else
  543. return -ENOIOCTLCMD;
  544. #endif
  545. }
  546. }
  547. static void get_raw_sock(struct sock *sp, char *tmpbuf, int i)
  548. {
  549. unsigned int dest = sp->daddr,
  550.      src = sp->rcv_saddr;
  551. __u16 destp = 0,
  552.       srcp  = sp->num;
  553. sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
  554. " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p",
  555. i, src, srcp, dest, destp, sp->state, 
  556. atomic_read(&sp->wmem_alloc), atomic_read(&sp->rmem_alloc),
  557. 0, 0L, 0,
  558. sock_i_uid(sp), 0,
  559. sock_i_ino(sp),
  560. atomic_read(&sp->refcnt), sp);
  561. }
  562. int raw_get_info(char *buffer, char **start, off_t offset, int length)
  563. {
  564. int len = 0, num = 0, i;
  565. off_t pos = 128;
  566. off_t begin;
  567. char tmpbuf[129];
  568. if (offset < 128) 
  569. len += sprintf(buffer, "%-127sn",
  570.        "  sl  local_address rem_address   st tx_queue "
  571.        "rx_queue tr tm->when retrnsmt   uid  timeout "
  572.        "inode");
  573. read_lock(&raw_v4_lock);
  574. for (i = 0; i < RAWV4_HTABLE_SIZE; i++) {
  575. struct sock *sk;
  576. for (sk = raw_v4_htable[i]; sk; sk = sk->next, num++) {
  577. if (sk->family != PF_INET)
  578. continue;
  579. pos += 128;
  580. if (pos <= offset)
  581. continue;
  582. get_raw_sock(sk, tmpbuf, i);
  583. len += sprintf(buffer + len, "%-127sn", tmpbuf);
  584. if (len >= length)
  585. goto out;
  586. }
  587. }
  588. out:
  589. read_unlock(&raw_v4_lock);
  590. begin = len - (pos - offset);
  591. *start = buffer + begin;
  592. len -= begin;
  593. if (len > length)
  594. len = length;
  595. if (len < 0)
  596. len = 0; 
  597. return len;
  598. }
  599. struct proto raw_prot = {
  600. name: "RAW",
  601. close: raw_close,
  602. connect: udp_connect,
  603. disconnect: udp_disconnect,
  604. ioctl: raw_ioctl,
  605. init: raw_init,
  606. setsockopt: raw_setsockopt,
  607. getsockopt: raw_getsockopt,
  608. sendmsg: raw_sendmsg,
  609. recvmsg: raw_recvmsg,
  610. bind: raw_bind,
  611. backlog_rcv: raw_rcv_skb,
  612. hash: raw_v4_hash,
  613. unhash: raw_v4_unhash,
  614. };