udp.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:23k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * UDP over IPv6
  3.  * Linux INET6 implementation 
  4.  *
  5.  * Authors:
  6.  * Pedro Roque <roque@di.fc.ul.pt>
  7.  *
  8.  * Based on linux/ipv4/udp.c
  9.  *
  10.  * $Id: udp.c,v 1.64 2001/09/01 00:31:50 davem Exp $
  11.  *
  12.  * Fixes:
  13.  * Hideaki YOSHIFUJI : sin6_scope_id support
  14.  *
  15.  * This program is free software; you can redistribute it and/or
  16.  *      modify it under the terms of the GNU General Public License
  17.  *      as published by the Free Software Foundation; either version
  18.  *      2 of the License, or (at your option) any later version.
  19.  */
  20. #include <linux/config.h>
  21. #include <linux/errno.h>
  22. #include <linux/types.h>
  23. #include <linux/socket.h>
  24. #include <linux/sockios.h>
  25. #include <linux/sched.h>
  26. #include <linux/net.h>
  27. #include <linux/in6.h>
  28. #include <linux/netdevice.h>
  29. #include <linux/if_arp.h>
  30. #include <linux/ipv6.h>
  31. #include <linux/icmpv6.h>
  32. #include <linux/init.h>
  33. #include <asm/uaccess.h>
  34. #include <net/sock.h>
  35. #include <net/snmp.h>
  36. #include <net/ipv6.h>
  37. #include <net/ndisc.h>
  38. #include <net/protocol.h>
  39. #include <net/transp_v6.h>
  40. #include <net/ip6_route.h>
  41. #include <net/addrconf.h>
  42. #include <net/ip.h>
  43. #include <net/udp.h>
  44. #include <net/inet_common.h>
  45. #include <net/checksum.h>
  46. struct udp_mib udp_stats_in6[NR_CPUS*2];
  47. /* Grrr, addr_type already calculated by caller, but I don't want
  48.  * to add some silly "cookie" argument to this method just for that.
  49.  */
  50. static int udp_v6_get_port(struct sock *sk, unsigned short snum)
  51. {
  52. write_lock_bh(&udp_hash_lock);
  53. if (snum == 0) {
  54. int best_size_so_far, best, result, i;
  55. if (udp_port_rover > sysctl_local_port_range[1] ||
  56.     udp_port_rover < sysctl_local_port_range[0])
  57. udp_port_rover = sysctl_local_port_range[0];
  58. best_size_so_far = 32767;
  59. best = result = udp_port_rover;
  60. for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) {
  61. struct sock *sk;
  62. int size;
  63. sk = udp_hash[result & (UDP_HTABLE_SIZE - 1)];
  64. if (!sk) {
  65. if (result > sysctl_local_port_range[1])
  66. result = sysctl_local_port_range[0] +
  67. ((result - sysctl_local_port_range[0]) &
  68.  (UDP_HTABLE_SIZE - 1));
  69. goto gotit;
  70. }
  71. size = 0;
  72. do {
  73. if (++size >= best_size_so_far)
  74. goto next;
  75. } while ((sk = sk->next) != NULL);
  76. best_size_so_far = size;
  77. best = result;
  78. next:;
  79. }
  80. result = best;
  81. for(;; result += UDP_HTABLE_SIZE) {
  82. if (result > sysctl_local_port_range[1])
  83. result = sysctl_local_port_range[0]
  84. + ((result - sysctl_local_port_range[0]) &
  85.    (UDP_HTABLE_SIZE - 1));
  86. if (!udp_lport_inuse(result))
  87. break;
  88. }
  89. gotit:
  90. udp_port_rover = snum = result;
  91. } else {
  92. struct sock *sk2;
  93. int addr_type = ipv6_addr_type(&sk->net_pinfo.af_inet6.rcv_saddr);
  94. for (sk2 = udp_hash[snum & (UDP_HTABLE_SIZE - 1)];
  95.      sk2 != NULL;
  96.      sk2 = sk2->next) {
  97. if (sk2->num == snum &&
  98.     sk2 != sk &&
  99.     sk2->bound_dev_if == sk->bound_dev_if &&
  100.     (!sk2->rcv_saddr ||
  101.      addr_type == IPV6_ADDR_ANY ||
  102.      !ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr,
  103.     &sk2->net_pinfo.af_inet6.rcv_saddr) ||
  104.      (addr_type == IPV6_ADDR_MAPPED &&
  105.       sk2->family == AF_INET &&
  106.       sk->rcv_saddr == sk2->rcv_saddr)) &&
  107.     (!sk2->reuse || !sk->reuse))
  108. goto fail;
  109. }
  110. }
  111. sk->num = snum;
  112. if (sk->pprev == NULL) {
  113. struct sock **skp = &udp_hash[snum & (UDP_HTABLE_SIZE - 1)];
  114. if ((sk->next = *skp) != NULL)
  115. (*skp)->pprev = &sk->next;
  116. *skp = sk;
  117. sk->pprev = skp;
  118. sock_prot_inc_use(sk->prot);
  119. sock_hold(sk);
  120. }
  121. write_unlock_bh(&udp_hash_lock);
  122. return 0;
  123. fail:
  124. write_unlock_bh(&udp_hash_lock);
  125. return 1;
  126. }
  127. static void udp_v6_hash(struct sock *sk)
  128. {
  129. BUG();
  130. }
  131. static void udp_v6_unhash(struct sock *sk)
  132. {
  133.   write_lock_bh(&udp_hash_lock);
  134. if (sk->pprev) {
  135. if (sk->next)
  136. sk->next->pprev = sk->pprev;
  137. *sk->pprev = sk->next;
  138. sk->pprev = NULL;
  139. sk->num = 0;
  140. sock_prot_dec_use(sk->prot);
  141. __sock_put(sk);
  142. }
  143. write_unlock_bh(&udp_hash_lock);
  144. }
  145. static struct sock *udp_v6_lookup(struct in6_addr *saddr, u16 sport,
  146.   struct in6_addr *daddr, u16 dport, int dif)
  147. {
  148. struct sock *sk, *result = NULL;
  149. unsigned short hnum = ntohs(dport);
  150. int badness = -1;
  151.   read_lock(&udp_hash_lock);
  152. for(sk = udp_hash[hnum & (UDP_HTABLE_SIZE - 1)]; sk != NULL; sk = sk->next) {
  153. if((sk->num == hnum) &&
  154.    (sk->family == PF_INET6)) {
  155. struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
  156. int score = 0;
  157. if(sk->dport) {
  158. if(sk->dport != sport)
  159. continue;
  160. score++;
  161. }
  162. if(!ipv6_addr_any(&np->rcv_saddr)) {
  163. if(ipv6_addr_cmp(&np->rcv_saddr, daddr))
  164. continue;
  165. score++;
  166. }
  167. if(!ipv6_addr_any(&np->daddr)) {
  168. if(ipv6_addr_cmp(&np->daddr, saddr))
  169. continue;
  170. score++;
  171. }
  172. if(sk->bound_dev_if) {
  173. if(sk->bound_dev_if != dif)
  174. continue;
  175. score++;
  176. }
  177. if(score == 4) {
  178. result = sk;
  179. break;
  180. } else if(score > badness) {
  181. result = sk;
  182. badness = score;
  183. }
  184. }
  185. }
  186. if (result)
  187. sock_hold(result);
  188.   read_unlock(&udp_hash_lock);
  189. return result;
  190. }
  191. /*
  192.  *
  193.  */
  194. int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
  195. {
  196. struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
  197. struct ipv6_pinfo       *np = &sk->net_pinfo.af_inet6;
  198. struct in6_addr *daddr;
  199. struct in6_addr saddr;
  200. struct dst_entry *dst;
  201. struct flowi fl;
  202. struct ip6_flowlabel *flowlabel = NULL;
  203. int addr_type;
  204. int err;
  205. if (usin->sin6_family == AF_INET) {
  206. err = udp_connect(sk, uaddr, addr_len);
  207. goto ipv4_connected;
  208. }
  209. if (addr_len < SIN6_LEN_RFC2133)
  210.    return -EINVAL;
  211. if (usin->sin6_family != AF_INET6) 
  212.    return -EAFNOSUPPORT;
  213. fl.fl6_flowlabel = 0;
  214. if (np->sndflow) {
  215. fl.fl6_flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
  216. if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
  217. flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
  218. if (flowlabel == NULL)
  219. return -EINVAL;
  220. ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst);
  221. }
  222. }
  223. addr_type = ipv6_addr_type(&usin->sin6_addr);
  224. if (addr_type == IPV6_ADDR_ANY) {
  225. /*
  226.  * connect to self
  227.  */
  228. usin->sin6_addr.s6_addr[15] = 0x01;
  229. }
  230. daddr = &usin->sin6_addr;
  231. if (addr_type == IPV6_ADDR_MAPPED) {
  232. struct sockaddr_in sin;
  233. sin.sin_family = AF_INET;
  234. sin.sin_addr.s_addr = daddr->s6_addr32[3];
  235. sin.sin_port = usin->sin6_port;
  236. err = udp_connect(sk, (struct sockaddr*) &sin, sizeof(sin));
  237. ipv4_connected:
  238. if (err < 0)
  239. return err;
  240. ipv6_addr_set(&np->daddr, 0, 0, 
  241.       __constant_htonl(0x0000ffff),
  242.       sk->daddr);
  243. if(ipv6_addr_any(&np->saddr)) {
  244. ipv6_addr_set(&np->saddr, 0, 0, 
  245.       __constant_htonl(0x0000ffff),
  246.       sk->saddr);
  247. }
  248. if(ipv6_addr_any(&np->rcv_saddr)) {
  249. ipv6_addr_set(&np->rcv_saddr, 0, 0, 
  250.       __constant_htonl(0x0000ffff),
  251.       sk->rcv_saddr);
  252. }
  253. return 0;
  254. }
  255. if (addr_type&IPV6_ADDR_LINKLOCAL) {
  256. if (addr_len >= sizeof(struct sockaddr_in6) &&
  257.     usin->sin6_scope_id) {
  258. if (sk->bound_dev_if && sk->bound_dev_if != usin->sin6_scope_id) {
  259. fl6_sock_release(flowlabel);
  260. return -EINVAL;
  261. }
  262. sk->bound_dev_if = usin->sin6_scope_id;
  263. }
  264. /* Connect to link-local address requires an interface */
  265. if (sk->bound_dev_if == 0)
  266. return -EINVAL;
  267. }
  268. ipv6_addr_copy(&np->daddr, daddr);
  269. np->flow_label = fl.fl6_flowlabel;
  270. sk->dport = usin->sin6_port;
  271. /*
  272.  * Check for a route to destination an obtain the
  273.  * destination cache for it.
  274.  */
  275. fl.proto = IPPROTO_UDP;
  276. fl.fl6_dst = &np->daddr;
  277. fl.fl6_src = &saddr;
  278. fl.oif = sk->bound_dev_if;
  279. fl.uli_u.ports.dport = sk->dport;
  280. fl.uli_u.ports.sport = sk->sport;
  281. if (flowlabel) {
  282. if (flowlabel->opt && flowlabel->opt->srcrt) {
  283. struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt;
  284. fl.fl6_dst = rt0->addr;
  285. }
  286. } else if (np->opt && np->opt->srcrt) {
  287. struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
  288. fl.fl6_dst = rt0->addr;
  289. }
  290. dst = ip6_route_output(sk, &fl);
  291. if ((err = dst->error) != 0) {
  292. dst_release(dst);
  293. fl6_sock_release(flowlabel);
  294. return err;
  295. }
  296. ip6_dst_store(sk, dst, fl.fl6_dst);
  297. /* get the source adddress used in the apropriate device */
  298. err = ipv6_get_saddr(dst, daddr, &saddr);
  299. if (err == 0) {
  300. if(ipv6_addr_any(&np->saddr))
  301. ipv6_addr_copy(&np->saddr, &saddr);
  302. if(ipv6_addr_any(&np->rcv_saddr)) {
  303. ipv6_addr_copy(&np->rcv_saddr, &saddr);
  304. sk->rcv_saddr = LOOPBACK4_IPV6;
  305. }
  306. sk->state = TCP_ESTABLISHED;
  307. }
  308. fl6_sock_release(flowlabel);
  309. return err;
  310. }
  311. static void udpv6_close(struct sock *sk, long timeout)
  312. {
  313. inet_sock_release(sk);
  314. }
  315. /*
  316.  *  This should be easy, if there is something there we
  317.  *  return it, otherwise we block.
  318.  */
  319. int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, int len,
  320.   int noblock, int flags, int *addr_len)
  321. {
  322.    struct sk_buff *skb;
  323.    int copied, err;
  324.    if (addr_len)
  325.    *addr_len=sizeof(struct sockaddr_in6);
  326.   
  327. if (flags & MSG_ERRQUEUE)
  328. return ipv6_recv_error(sk, msg, len);
  329. skb = skb_recv_datagram(sk, flags, noblock, &err);
  330. if (!skb)
  331. goto out;
  332.   copied = skb->len - sizeof(struct udphdr);
  333.    if (copied > len) {
  334.    copied = len;
  335.    msg->msg_flags |= MSG_TRUNC;
  336.    }
  337. if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
  338. err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
  339.       copied);
  340. } else if (msg->msg_flags&MSG_TRUNC) {
  341. if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)))
  342. goto csum_copy_err;
  343. err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
  344.       copied);
  345. } else {
  346. err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
  347. if (err == -EINVAL)
  348. goto csum_copy_err;
  349. }
  350. if (err)
  351. goto out_free;
  352. sock_recv_timestamp(msg, sk, skb);
  353. /* Copy the address. */
  354. if (msg->msg_name) {
  355. struct sockaddr_in6 *sin6;
  356.   
  357. sin6 = (struct sockaddr_in6 *) msg->msg_name;
  358. sin6->sin6_family = AF_INET6;
  359. sin6->sin6_port = skb->h.uh->source;
  360. sin6->sin6_flowinfo = 0;
  361. sin6->sin6_scope_id = 0;
  362. if (skb->protocol == __constant_htons(ETH_P_IP)) {
  363. ipv6_addr_set(&sin6->sin6_addr, 0, 0,
  364.       __constant_htonl(0xffff), skb->nh.iph->saddr);
  365. if (sk->protinfo.af_inet.cmsg_flags)
  366. ip_cmsg_recv(msg, skb);
  367. } else {
  368. memcpy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr,
  369.        sizeof(struct in6_addr));
  370. if (sk->net_pinfo.af_inet6.rxopt.all)
  371. datagram_recv_ctl(sk, msg, skb);
  372. if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
  373. struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
  374. sin6->sin6_scope_id = opt->iif;
  375. }
  376. }
  377.    }
  378. err = copied;
  379. out_free:
  380. skb_free_datagram(sk, skb);
  381. out:
  382. return err;
  383. csum_copy_err:
  384. /* Clear queue. */
  385. if (flags&MSG_PEEK) {
  386. int clear = 0;
  387. spin_lock_irq(&sk->receive_queue.lock);
  388. if (skb == skb_peek(&sk->receive_queue)) {
  389. __skb_unlink(skb, &sk->receive_queue);
  390. clear = 1;
  391. }
  392. spin_unlock_irq(&sk->receive_queue.lock);
  393. if (clear)
  394. kfree_skb(skb);
  395. }
  396. /* Error for blocking case is chosen to masquerade
  397.    as some normal condition.
  398.  */
  399. err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
  400. UDP6_INC_STATS_USER(UdpInErrors);
  401. goto out_free;
  402. }
  403. void udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
  404.        int type, int code, int offset, __u32 info)
  405. {
  406. struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
  407. struct net_device *dev = skb->dev;
  408. struct in6_addr *saddr = &hdr->saddr;
  409. struct in6_addr *daddr = &hdr->daddr;
  410. struct udphdr *uh = (struct udphdr*)(skb->data+offset);
  411. struct sock *sk;
  412. int err;
  413. sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, dev->ifindex);
  414.    
  415. if (sk == NULL)
  416. return;
  417. if (!icmpv6_err_convert(type, code, &err) &&
  418.     !sk->net_pinfo.af_inet6.recverr)
  419. goto out;
  420. if (sk->state!=TCP_ESTABLISHED &&
  421.     !sk->net_pinfo.af_inet6.recverr)
  422. goto out;
  423. if (sk->net_pinfo.af_inet6.recverr)
  424. ipv6_icmp_error(sk, skb, err, uh->dest, ntohl(info), (u8 *)(uh+1));
  425. sk->err = err;
  426. sk->error_report(sk);
  427. out:
  428. sock_put(sk);
  429. }
  430. static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
  431. {
  432. #if defined(CONFIG_FILTER)
  433. if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
  434. if ((unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum))) {
  435. UDP6_INC_STATS_BH(UdpInErrors);
  436. IP6_INC_STATS_BH(Ip6InDiscards);
  437. kfree_skb(skb);
  438. return 0;
  439. }
  440. skb->ip_summed = CHECKSUM_UNNECESSARY;
  441. }
  442. #endif
  443. if (sock_queue_rcv_skb(sk,skb)<0) {
  444. UDP6_INC_STATS_BH(UdpInErrors);
  445. IP6_INC_STATS_BH(Ip6InDiscards);
  446. kfree_skb(skb);
  447. return 0;
  448. }
  449.    IP6_INC_STATS_BH(Ip6InDelivers);
  450. UDP6_INC_STATS_BH(UdpInDatagrams);
  451. return 0;
  452. }
  453. static struct sock *udp_v6_mcast_next(struct sock *sk,
  454.       u16 loc_port, struct in6_addr *loc_addr,
  455.       u16 rmt_port, struct in6_addr *rmt_addr,
  456.       int dif)
  457. {
  458. struct sock *s = sk;
  459. unsigned short num = ntohs(loc_port);
  460. for(; s; s = s->next) {
  461. if(s->num == num) {
  462. struct ipv6_pinfo *np = &s->net_pinfo.af_inet6;
  463. if(s->dport) {
  464. if(s->dport != rmt_port)
  465. continue;
  466. }
  467. if(!ipv6_addr_any(&np->daddr) &&
  468.    ipv6_addr_cmp(&np->daddr, rmt_addr))
  469. continue;
  470. if (s->bound_dev_if && s->bound_dev_if != dif)
  471. continue;
  472. if(!ipv6_addr_any(&np->rcv_saddr)) {
  473. if(ipv6_addr_cmp(&np->rcv_saddr, loc_addr) == 0)
  474. return s;
  475. }
  476. if(!inet6_mc_check(s, loc_addr))
  477. continue;
  478. return s;
  479. }
  480. }
  481. return NULL;
  482. }
  483. /*
  484.  * Note: called only from the BH handler context,
  485.  * so we don't need to lock the hashes.
  486.  */
  487. static void udpv6_mcast_deliver(struct udphdr *uh,
  488. struct in6_addr *saddr, struct in6_addr *daddr,
  489. struct sk_buff *skb)
  490. {
  491. struct sock *sk, *sk2;
  492. struct sk_buff *buff;
  493. int dif;
  494. read_lock(&udp_hash_lock);
  495. sk = udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)];
  496. dif = skb->dev->ifindex;
  497. sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
  498. if (!sk)
  499. goto free_skb;
  500. buff = NULL;
  501. sk2 = sk;
  502. while((sk2 = udp_v6_mcast_next(sk2->next, uh->dest, daddr,
  503.   uh->source, saddr, dif))) {
  504. if (!buff) {
  505. buff = skb_clone(skb, GFP_ATOMIC);
  506. if (!buff)
  507. continue;
  508. }
  509. if (sock_queue_rcv_skb(sk2, buff) >= 0)
  510. buff = NULL;
  511. }
  512. if (buff)
  513. kfree_skb(buff);
  514. if (sock_queue_rcv_skb(sk, skb) < 0) {
  515. free_skb:
  516. kfree_skb(skb);
  517. }
  518. read_unlock(&udp_hash_lock);
  519. }
  520. int udpv6_rcv(struct sk_buff *skb)
  521. {
  522. struct sock *sk;
  523.    struct udphdr *uh;
  524. struct net_device *dev = skb->dev;
  525. struct in6_addr *saddr, *daddr;
  526. u32 ulen = 0;
  527. if (!pskb_may_pull(skb, sizeof(struct udphdr)))
  528. goto short_packet;
  529. saddr = &skb->nh.ipv6h->saddr;
  530. daddr = &skb->nh.ipv6h->daddr;
  531. uh = skb->h.uh;
  532. ulen = ntohs(uh->len);
  533. /* Check for jumbo payload */
  534. if (ulen == 0)
  535. ulen = skb->len;
  536. if (ulen > skb->len || ulen < sizeof(*uh))
  537. goto short_packet;
  538. if (uh->check == 0) {
  539. /* IPv6 draft-v2 section 8.1 says that we SHOULD log
  540.    this error. Well, it is reasonable.
  541.  */
  542. if (net_ratelimit())
  543. printk(KERN_INFO "IPv6: udp checksum is 0n");
  544. goto discard;
  545. }
  546. if (ulen < skb->len) {
  547. if (__pskb_trim(skb, ulen))
  548. goto discard;
  549. saddr = &skb->nh.ipv6h->saddr;
  550. daddr = &skb->nh.ipv6h->daddr;
  551. uh = skb->h.uh;
  552. }
  553. if (skb->ip_summed==CHECKSUM_HW) {
  554. skb->ip_summed = CHECKSUM_UNNECESSARY;
  555. if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) {
  556. NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "udp v6 hw csum failure.n"));
  557. skb->ip_summed = CHECKSUM_NONE;
  558. }
  559. }
  560. if (skb->ip_summed != CHECKSUM_UNNECESSARY)
  561. skb->csum = ~csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, 0);
  562. /* 
  563.  * Multicast receive code 
  564.  */
  565. if (ipv6_addr_type(daddr) & IPV6_ADDR_MULTICAST) {
  566. udpv6_mcast_deliver(uh, saddr, daddr, skb);
  567. return 0;
  568. }
  569. /* Unicast */
  570. /* 
  571.  * check socket cache ... must talk to Alan about his plans
  572.  * for sock caches... i'll skip this for now.
  573.  */
  574. sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, dev->ifindex);
  575. if (sk == NULL) {
  576. if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
  577.     (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)))
  578. goto discard;
  579. UDP6_INC_STATS_BH(UdpNoPorts);
  580. icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev);
  581. kfree_skb(skb);
  582. return(0);
  583. }
  584. /* deliver */
  585. udpv6_queue_rcv_skb(sk, skb);
  586. sock_put(sk);
  587. return(0);
  588. short_packet:
  589. if (net_ratelimit())
  590. printk(KERN_DEBUG "UDP: short packet: %d/%un", ulen, skb->len);
  591. discard:
  592. UDP6_INC_STATS_BH(UdpInErrors);
  593. kfree_skb(skb);
  594. return(0);
  595. }
  596. /*
  597.  * Sending
  598.  */
  599. struct udpv6fakehdr 
  600. {
  601. struct udphdr uh;
  602. struct iovec *iov;
  603. __u32 wcheck;
  604. __u32 pl_len;
  605. struct in6_addr *daddr;
  606. };
  607. /*
  608.  * with checksum
  609.  */
  610. static int udpv6_getfrag(const void *data, struct in6_addr *addr,
  611.  char *buff, unsigned int offset, unsigned int len)
  612. {
  613. struct udpv6fakehdr *udh = (struct udpv6fakehdr *) data;
  614. char *dst;
  615. int final = 0;
  616. int clen = len;
  617. dst = buff;
  618. if (offset) {
  619. offset -= sizeof(struct udphdr);
  620. } else {
  621. dst += sizeof(struct udphdr);
  622. final = 1;
  623. clen -= sizeof(struct udphdr);
  624. }
  625. if (csum_partial_copy_fromiovecend(dst, udh->iov, offset,
  626.    clen, &udh->wcheck))
  627. return -EFAULT;
  628. if (final) {
  629. struct in6_addr *daddr;
  630. udh->wcheck = csum_partial((char *)udh, sizeof(struct udphdr),
  631.    udh->wcheck);
  632. if (udh->daddr) {
  633. daddr = udh->daddr;
  634. } else {
  635. /*
  636.  * use packet destination address
  637.  * this should improve cache locality
  638.  */
  639. daddr = addr + 1;
  640. }
  641. udh->uh.check = csum_ipv6_magic(addr, daddr,
  642. udh->pl_len, IPPROTO_UDP,
  643. udh->wcheck);
  644. if (udh->uh.check == 0)
  645. udh->uh.check = -1;
  646. memcpy(buff, udh, sizeof(struct udphdr));
  647. }
  648. return 0;
  649. }
  650. static int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, int ulen)
  651. {
  652. struct ipv6_txoptions opt_space;
  653. struct udpv6fakehdr udh;
  654. struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
  655. struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) msg->msg_name;
  656. struct ipv6_txoptions *opt = NULL;
  657. struct ip6_flowlabel *flowlabel = NULL;
  658. struct flowi fl;
  659. int addr_len = msg->msg_namelen;
  660. struct in6_addr *daddr;
  661. int len = ulen + sizeof(struct udphdr);
  662. int addr_type;
  663. int hlimit = -1;
  664. int err;
  665. /* Rough check on arithmetic overflow,
  666.    better check is made in ip6_build_xmit
  667.    */
  668. if (ulen < 0 || ulen > INT_MAX - sizeof(struct udphdr))
  669. return -EMSGSIZE;
  670. fl.fl6_flowlabel = 0;
  671. fl.oif = 0;
  672. if (sin6) {
  673. if (sin6->sin6_family == AF_INET)
  674. return udp_sendmsg(sk, msg, ulen);
  675. if (addr_len < SIN6_LEN_RFC2133)
  676. return -EINVAL;
  677. if (sin6->sin6_family && sin6->sin6_family != AF_INET6)
  678. return -EINVAL;
  679. if (sin6->sin6_port == 0)
  680. return -EINVAL;
  681. udh.uh.dest = sin6->sin6_port;
  682. daddr = &sin6->sin6_addr;
  683. if (np->sndflow) {
  684. fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
  685. if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
  686. flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
  687. if (flowlabel == NULL)
  688. return -EINVAL;
  689. daddr = &flowlabel->dst;
  690. }
  691. }
  692. /* Otherwise it will be difficult to maintain sk->dst_cache. */
  693. if (sk->state == TCP_ESTABLISHED &&
  694.     !ipv6_addr_cmp(daddr, &sk->net_pinfo.af_inet6.daddr))
  695. daddr = &sk->net_pinfo.af_inet6.daddr;
  696. if (addr_len >= sizeof(struct sockaddr_in6) &&
  697.     sin6->sin6_scope_id &&
  698.     ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL)
  699. fl.oif = sin6->sin6_scope_id;
  700. } else {
  701. if (sk->state != TCP_ESTABLISHED)
  702. return -ENOTCONN;
  703. udh.uh.dest = sk->dport;
  704. daddr = &sk->net_pinfo.af_inet6.daddr;
  705. fl.fl6_flowlabel = np->flow_label;
  706. }
  707. addr_type = ipv6_addr_type(daddr);
  708. if (addr_type == IPV6_ADDR_MAPPED) {
  709. struct sockaddr_in sin;
  710. sin.sin_family = AF_INET;
  711. sin.sin_addr.s_addr = daddr->s6_addr32[3];
  712. sin.sin_port = udh.uh.dest;
  713. msg->msg_name = (struct sockaddr *)(&sin);
  714. msg->msg_namelen = sizeof(sin);
  715. fl6_sock_release(flowlabel);
  716. return udp_sendmsg(sk, msg, ulen);
  717. }
  718. udh.daddr = NULL;
  719. if (!fl.oif)
  720. fl.oif = sk->bound_dev_if;
  721. fl.fl6_src = NULL;
  722. if (msg->msg_controllen) {
  723. opt = &opt_space;
  724. memset(opt, 0, sizeof(struct ipv6_txoptions));
  725. err = datagram_send_ctl(msg, &fl, opt, &hlimit);
  726. if (err < 0) {
  727. fl6_sock_release(flowlabel);
  728. return err;
  729. }
  730. if ((fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
  731. flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
  732. if (flowlabel == NULL)
  733. return -EINVAL;
  734. }
  735. if (!(opt->opt_nflen|opt->opt_flen))
  736. opt = NULL;
  737. }
  738. if (opt == NULL)
  739. opt = np->opt;
  740. if (flowlabel)
  741. opt = fl6_merge_options(&opt_space, flowlabel, opt);
  742. if (opt && opt->srcrt)
  743. udh.daddr = daddr;
  744. udh.uh.source = sk->sport;
  745. udh.uh.len = len < 0x10000 ? htons(len) : 0;
  746. udh.uh.check = 0;
  747. udh.iov = msg->msg_iov;
  748. udh.wcheck = 0;
  749. udh.pl_len = len;
  750. fl.proto = IPPROTO_UDP;
  751. fl.fl6_dst = daddr;
  752. if (fl.fl6_src == NULL && !ipv6_addr_any(&np->saddr))
  753. fl.fl6_src = &np->saddr;
  754. fl.uli_u.ports.dport = udh.uh.dest;
  755. fl.uli_u.ports.sport = udh.uh.source;
  756. err = ip6_build_xmit(sk, udpv6_getfrag, &udh, &fl, len, opt, hlimit,
  757.      msg->msg_flags);
  758. fl6_sock_release(flowlabel);
  759. if (err < 0)
  760. return err;
  761. UDP6_INC_STATS_USER(UdpOutDatagrams);
  762. return ulen;
  763. }
  764. static struct inet6_protocol udpv6_protocol = 
  765. {
  766. udpv6_rcv, /* UDP handler */
  767. udpv6_err, /* UDP error control */
  768. NULL, /* next */
  769. IPPROTO_UDP, /* protocol ID */
  770. 0, /* copy */
  771. NULL, /* data */
  772. "UDPv6" /* name */
  773. };
  774. #define LINE_LEN 190
  775. #define LINE_FMT "%-190sn"
  776. static void get_udp6_sock(struct sock *sp, char *tmpbuf, int i)
  777. {
  778. struct in6_addr *dest, *src;
  779. __u16 destp, srcp;
  780. dest  = &sp->net_pinfo.af_inet6.daddr;
  781. src   = &sp->net_pinfo.af_inet6.rcv_saddr;
  782. destp = ntohs(sp->dport);
  783. srcp  = ntohs(sp->sport);
  784. sprintf(tmpbuf,
  785. "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
  786. "%02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p",
  787. i,
  788. src->s6_addr32[0], src->s6_addr32[1],
  789. src->s6_addr32[2], src->s6_addr32[3], srcp,
  790. dest->s6_addr32[0], dest->s6_addr32[1],
  791. dest->s6_addr32[2], dest->s6_addr32[3], destp,
  792. sp->state, 
  793. atomic_read(&sp->wmem_alloc), atomic_read(&sp->rmem_alloc),
  794. 0, 0L, 0,
  795. sock_i_uid(sp), 0,
  796. sock_i_ino(sp),
  797. atomic_read(&sp->refcnt), sp);
  798. }
  799. int udp6_get_info(char *buffer, char **start, off_t offset, int length)
  800. {
  801. int len = 0, num = 0, i;
  802. off_t pos = 0;
  803. off_t begin;
  804. char tmpbuf[LINE_LEN+2];
  805. if (offset < LINE_LEN+1)
  806. len += sprintf(buffer, LINE_FMT,
  807.        "  sl  " /* 6 */
  808.        "local_address                         " /* 38 */
  809.        "remote_address                        " /* 38 */
  810.        "st tx_queue rx_queue tr tm->when retrnsmt" /* 41 */
  811.        "   uid  timeout inode"); /* 21 */
  812. /*----*/
  813. /*144 */
  814. pos = LINE_LEN+1;
  815. read_lock(&udp_hash_lock);
  816. for (i = 0; i < UDP_HTABLE_SIZE; i++) {
  817. struct sock *sk;
  818. for (sk = udp_hash[i]; sk; sk = sk->next, num++) {
  819. if (sk->family != PF_INET6)
  820. continue;
  821. pos += LINE_LEN+1;
  822. if (pos <= offset)
  823. continue;
  824. get_udp6_sock(sk, tmpbuf, i);
  825. len += sprintf(buffer+len, LINE_FMT, tmpbuf);
  826. if(len >= length)
  827. goto out;
  828. }
  829. }
  830. out:
  831. read_unlock(&udp_hash_lock);
  832. begin = len - (pos - offset);
  833. *start = buffer + begin;
  834. len -= begin;
  835. if(len > length)
  836. len = length;
  837. if (len < 0)
  838. len = 0; 
  839. return len;
  840. }
  841. struct proto udpv6_prot = {
  842. name: "UDP",
  843. close: udpv6_close,
  844. connect: udpv6_connect,
  845. disconnect: udp_disconnect,
  846. ioctl: udp_ioctl,
  847. destroy: inet6_destroy_sock,
  848. setsockopt: ipv6_setsockopt,
  849. getsockopt: ipv6_getsockopt,
  850. sendmsg: udpv6_sendmsg,
  851. recvmsg: udpv6_recvmsg,
  852. backlog_rcv: udpv6_queue_rcv_skb,
  853. hash: udp_v6_hash,
  854. unhash: udp_v6_unhash,
  855. get_port: udp_v6_get_port,
  856. };
  857. extern struct proto_ops inet6_dgram_ops;
  858. static struct inet_protosw udpv6_protosw = {
  859. type:        SOCK_DGRAM,
  860. protocol:    IPPROTO_UDP,
  861. prot:        &udpv6_prot,
  862. ops:         &inet6_dgram_ops,
  863. capability:  -1,
  864. no_check:    UDP_CSUM_DEFAULT,
  865. flags:       INET_PROTOSW_PERMANENT,
  866. };
  867. void __init udpv6_init(void)
  868. {
  869. inet6_add_protocol(&udpv6_protocol);
  870. inet6_register_protosw(&udpv6_protosw);
  871. }