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

Linux/Unix编程

开发平台:

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.2.1 2002/03/05 12:47:34 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.       htonl(0x0000ffff),
  242.       sk->daddr);
  243. if(ipv6_addr_any(&np->saddr)) {
  244. ipv6_addr_set(&np->saddr, 0, 0, 
  245.       htonl(0x0000ffff),
  246.       sk->saddr);
  247. }
  248. if(ipv6_addr_any(&np->rcv_saddr)) {
  249. ipv6_addr_set(&np->rcv_saddr, 0, 0, 
  250.       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. if (!sk->bound_dev_if && (addr_type&IPV6_ADDR_MULTICAST))
  264. fl.oif = np->mcast_oif;
  265. }
  266. /* Connect to link-local address requires an interface */
  267. if (sk->bound_dev_if == 0)
  268. return -EINVAL;
  269. }
  270. ipv6_addr_copy(&np->daddr, daddr);
  271. np->flow_label = fl.fl6_flowlabel;
  272. sk->dport = usin->sin6_port;
  273. /*
  274.  * Check for a route to destination an obtain the
  275.  * destination cache for it.
  276.  */
  277. fl.proto = IPPROTO_UDP;
  278. fl.fl6_dst = &np->daddr;
  279. fl.fl6_src = &saddr;
  280. fl.oif = sk->bound_dev_if;
  281. fl.uli_u.ports.dport = sk->dport;
  282. fl.uli_u.ports.sport = sk->sport;
  283. if (!fl.oif && (addr_type&IPV6_ADDR_MULTICAST))
  284. fl.oif = np->mcast_oif;
  285. if (flowlabel) {
  286. if (flowlabel->opt && flowlabel->opt->srcrt) {
  287. struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt;
  288. fl.fl6_dst = rt0->addr;
  289. }
  290. } else if (np->opt && np->opt->srcrt) {
  291. struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
  292. fl.fl6_dst = rt0->addr;
  293. }
  294. dst = ip6_route_output(sk, &fl);
  295. if ((err = dst->error) != 0) {
  296. dst_release(dst);
  297. fl6_sock_release(flowlabel);
  298. return err;
  299. }
  300. ip6_dst_store(sk, dst, fl.fl6_dst);
  301. /* get the source adddress used in the apropriate device */
  302. err = ipv6_get_saddr(dst, daddr, &saddr);
  303. if (err == 0) {
  304. if(ipv6_addr_any(&np->saddr))
  305. ipv6_addr_copy(&np->saddr, &saddr);
  306. if(ipv6_addr_any(&np->rcv_saddr)) {
  307. ipv6_addr_copy(&np->rcv_saddr, &saddr);
  308. sk->rcv_saddr = LOOPBACK4_IPV6;
  309. }
  310. sk->state = TCP_ESTABLISHED;
  311. }
  312. fl6_sock_release(flowlabel);
  313. return err;
  314. }
  315. static void udpv6_close(struct sock *sk, long timeout)
  316. {
  317. inet_sock_release(sk);
  318. }
  319. /*
  320.  *  This should be easy, if there is something there we
  321.  *  return it, otherwise we block.
  322.  */
  323. int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, int len,
  324.   int noblock, int flags, int *addr_len)
  325. {
  326.    struct sk_buff *skb;
  327.    int copied, err;
  328.    if (addr_len)
  329.    *addr_len=sizeof(struct sockaddr_in6);
  330.   
  331. if (flags & MSG_ERRQUEUE)
  332. return ipv6_recv_error(sk, msg, len);
  333. skb = skb_recv_datagram(sk, flags, noblock, &err);
  334. if (!skb)
  335. goto out;
  336.   copied = skb->len - sizeof(struct udphdr);
  337.    if (copied > len) {
  338.    copied = len;
  339.    msg->msg_flags |= MSG_TRUNC;
  340.    }
  341. if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
  342. err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
  343.       copied);
  344. } else if (msg->msg_flags&MSG_TRUNC) {
  345. if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)))
  346. goto csum_copy_err;
  347. err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
  348.       copied);
  349. } else {
  350. err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
  351. if (err == -EINVAL)
  352. goto csum_copy_err;
  353. }
  354. if (err)
  355. goto out_free;
  356. sock_recv_timestamp(msg, sk, skb);
  357. /* Copy the address. */
  358. if (msg->msg_name) {
  359. struct sockaddr_in6 *sin6;
  360.   
  361. sin6 = (struct sockaddr_in6 *) msg->msg_name;
  362. sin6->sin6_family = AF_INET6;
  363. sin6->sin6_port = skb->h.uh->source;
  364. sin6->sin6_flowinfo = 0;
  365. sin6->sin6_scope_id = 0;
  366. if (skb->protocol == htons(ETH_P_IP)) {
  367. ipv6_addr_set(&sin6->sin6_addr, 0, 0,
  368.       htonl(0xffff), skb->nh.iph->saddr);
  369. if (sk->protinfo.af_inet.cmsg_flags)
  370. ip_cmsg_recv(msg, skb);
  371. } else {
  372. memcpy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr,
  373.        sizeof(struct in6_addr));
  374. if (sk->net_pinfo.af_inet6.rxopt.all)
  375. datagram_recv_ctl(sk, msg, skb);
  376. if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
  377. struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
  378. sin6->sin6_scope_id = opt->iif;
  379. }
  380. }
  381.    }
  382. err = copied;
  383. out_free:
  384. skb_free_datagram(sk, skb);
  385. out:
  386. return err;
  387. csum_copy_err:
  388. /* Clear queue. */
  389. if (flags&MSG_PEEK) {
  390. int clear = 0;
  391. spin_lock_irq(&sk->receive_queue.lock);
  392. if (skb == skb_peek(&sk->receive_queue)) {
  393. __skb_unlink(skb, &sk->receive_queue);
  394. clear = 1;
  395. }
  396. spin_unlock_irq(&sk->receive_queue.lock);
  397. if (clear)
  398. kfree_skb(skb);
  399. }
  400. /* Error for blocking case is chosen to masquerade
  401.    as some normal condition.
  402.  */
  403. err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
  404. UDP6_INC_STATS_USER(UdpInErrors);
  405. goto out_free;
  406. }
  407. void udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
  408.        int type, int code, int offset, __u32 info)
  409. {
  410. struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
  411. struct net_device *dev = skb->dev;
  412. struct in6_addr *saddr = &hdr->saddr;
  413. struct in6_addr *daddr = &hdr->daddr;
  414. struct udphdr *uh = (struct udphdr*)(skb->data+offset);
  415. struct sock *sk;
  416. int err;
  417. sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, dev->ifindex);
  418.    
  419. if (sk == NULL)
  420. return;
  421. if (!icmpv6_err_convert(type, code, &err) &&
  422.     !sk->net_pinfo.af_inet6.recverr)
  423. goto out;
  424. if (sk->state!=TCP_ESTABLISHED &&
  425.     !sk->net_pinfo.af_inet6.recverr)
  426. goto out;
  427. if (sk->net_pinfo.af_inet6.recverr)
  428. ipv6_icmp_error(sk, skb, err, uh->dest, ntohl(info), (u8 *)(uh+1));
  429. sk->err = err;
  430. sk->error_report(sk);
  431. out:
  432. sock_put(sk);
  433. }
  434. static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
  435. {
  436. #if defined(CONFIG_FILTER)
  437. if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
  438. if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
  439. UDP6_INC_STATS_BH(UdpInErrors);
  440. IP6_INC_STATS_BH(Ip6InDiscards);
  441. kfree_skb(skb);
  442. return 0;
  443. }
  444. skb->ip_summed = CHECKSUM_UNNECESSARY;
  445. }
  446. #endif
  447. if (sock_queue_rcv_skb(sk,skb)<0) {
  448. UDP6_INC_STATS_BH(UdpInErrors);
  449. IP6_INC_STATS_BH(Ip6InDiscards);
  450. kfree_skb(skb);
  451. return 0;
  452. }
  453.    IP6_INC_STATS_BH(Ip6InDelivers);
  454. UDP6_INC_STATS_BH(UdpInDatagrams);
  455. return 0;
  456. }
  457. static struct sock *udp_v6_mcast_next(struct sock *sk,
  458.       u16 loc_port, struct in6_addr *loc_addr,
  459.       u16 rmt_port, struct in6_addr *rmt_addr,
  460.       int dif)
  461. {
  462. struct sock *s = sk;
  463. unsigned short num = ntohs(loc_port);
  464. for(; s; s = s->next) {
  465. if(s->num == num) {
  466. struct ipv6_pinfo *np = &s->net_pinfo.af_inet6;
  467. if(s->dport) {
  468. if(s->dport != rmt_port)
  469. continue;
  470. }
  471. if(!ipv6_addr_any(&np->daddr) &&
  472.    ipv6_addr_cmp(&np->daddr, rmt_addr))
  473. continue;
  474. if (s->bound_dev_if && s->bound_dev_if != dif)
  475. continue;
  476. if(!ipv6_addr_any(&np->rcv_saddr)) {
  477. if(ipv6_addr_cmp(&np->rcv_saddr, loc_addr) == 0)
  478. return s;
  479. }
  480. if(!inet6_mc_check(s, loc_addr))
  481. continue;
  482. return s;
  483. }
  484. }
  485. return NULL;
  486. }
  487. /*
  488.  * Note: called only from the BH handler context,
  489.  * so we don't need to lock the hashes.
  490.  */
  491. static void udpv6_mcast_deliver(struct udphdr *uh,
  492. struct in6_addr *saddr, struct in6_addr *daddr,
  493. struct sk_buff *skb)
  494. {
  495. struct sock *sk, *sk2;
  496. struct sk_buff *buff;
  497. int dif;
  498. read_lock(&udp_hash_lock);
  499. sk = udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)];
  500. dif = skb->dev->ifindex;
  501. sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
  502. if (!sk)
  503. goto free_skb;
  504. buff = NULL;
  505. sk2 = sk;
  506. while((sk2 = udp_v6_mcast_next(sk2->next, uh->dest, daddr,
  507.   uh->source, saddr, dif))) {
  508. if (!buff) {
  509. buff = skb_clone(skb, GFP_ATOMIC);
  510. if (!buff)
  511. continue;
  512. }
  513. if (sock_queue_rcv_skb(sk2, buff) >= 0)
  514. buff = NULL;
  515. }
  516. if (buff)
  517. kfree_skb(buff);
  518. if (sock_queue_rcv_skb(sk, skb) < 0) {
  519. free_skb:
  520. kfree_skb(skb);
  521. }
  522. read_unlock(&udp_hash_lock);
  523. }
  524. int udpv6_rcv(struct sk_buff *skb)
  525. {
  526. struct sock *sk;
  527.    struct udphdr *uh;
  528. struct net_device *dev = skb->dev;
  529. struct in6_addr *saddr, *daddr;
  530. u32 ulen = 0;
  531. if (!pskb_may_pull(skb, sizeof(struct udphdr)))
  532. goto short_packet;
  533. saddr = &skb->nh.ipv6h->saddr;
  534. daddr = &skb->nh.ipv6h->daddr;
  535. uh = skb->h.uh;
  536. ulen = ntohs(uh->len);
  537. /* Check for jumbo payload */
  538. if (ulen == 0)
  539. ulen = skb->len;
  540. if (ulen > skb->len || ulen < sizeof(*uh))
  541. goto short_packet;
  542. if (uh->check == 0) {
  543. /* IPv6 draft-v2 section 8.1 says that we SHOULD log
  544.    this error. Well, it is reasonable.
  545.  */
  546. if (net_ratelimit())
  547. printk(KERN_INFO "IPv6: udp checksum is 0n");
  548. goto discard;
  549. }
  550. if (ulen < skb->len) {
  551. if (__pskb_trim(skb, ulen))
  552. goto discard;
  553. saddr = &skb->nh.ipv6h->saddr;
  554. daddr = &skb->nh.ipv6h->daddr;
  555. uh = skb->h.uh;
  556. }
  557. if (skb->ip_summed==CHECKSUM_HW) {
  558. skb->ip_summed = CHECKSUM_UNNECESSARY;
  559. if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) {
  560. NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "udp v6 hw csum failure.n"));
  561. skb->ip_summed = CHECKSUM_NONE;
  562. }
  563. }
  564. if (skb->ip_summed != CHECKSUM_UNNECESSARY)
  565. skb->csum = ~csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, 0);
  566. /* 
  567.  * Multicast receive code 
  568.  */
  569. if (ipv6_addr_type(daddr) & IPV6_ADDR_MULTICAST) {
  570. udpv6_mcast_deliver(uh, saddr, daddr, skb);
  571. return 0;
  572. }
  573. /* Unicast */
  574. /* 
  575.  * check socket cache ... must talk to Alan about his plans
  576.  * for sock caches... i'll skip this for now.
  577.  */
  578. sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, dev->ifindex);
  579. if (sk == NULL) {
  580. if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
  581.     (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)))
  582. goto discard;
  583. UDP6_INC_STATS_BH(UdpNoPorts);
  584. icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev);
  585. kfree_skb(skb);
  586. return(0);
  587. }
  588. /* deliver */
  589. udpv6_queue_rcv_skb(sk, skb);
  590. sock_put(sk);
  591. return(0);
  592. short_packet:
  593. if (net_ratelimit())
  594. printk(KERN_DEBUG "UDP: short packet: %d/%un", ulen, skb->len);
  595. discard:
  596. UDP6_INC_STATS_BH(UdpInErrors);
  597. kfree_skb(skb);
  598. return(0);
  599. }
  600. /*
  601.  * Sending
  602.  */
  603. struct udpv6fakehdr 
  604. {
  605. struct udphdr uh;
  606. struct iovec *iov;
  607. __u32 wcheck;
  608. __u32 pl_len;
  609. struct in6_addr *daddr;
  610. };
  611. /*
  612.  * with checksum
  613.  */
  614. static int udpv6_getfrag(const void *data, struct in6_addr *addr,
  615.  char *buff, unsigned int offset, unsigned int len)
  616. {
  617. struct udpv6fakehdr *udh = (struct udpv6fakehdr *) data;
  618. char *dst;
  619. int final = 0;
  620. int clen = len;
  621. dst = buff;
  622. if (offset) {
  623. offset -= sizeof(struct udphdr);
  624. } else {
  625. dst += sizeof(struct udphdr);
  626. final = 1;
  627. clen -= sizeof(struct udphdr);
  628. }
  629. if (csum_partial_copy_fromiovecend(dst, udh->iov, offset,
  630.    clen, &udh->wcheck))
  631. return -EFAULT;
  632. if (final) {
  633. struct in6_addr *daddr;
  634. udh->wcheck = csum_partial((char *)udh, sizeof(struct udphdr),
  635.    udh->wcheck);
  636. if (udh->daddr) {
  637. daddr = udh->daddr;
  638. } else {
  639. /*
  640.  * use packet destination address
  641.  * this should improve cache locality
  642.  */
  643. daddr = addr + 1;
  644. }
  645. udh->uh.check = csum_ipv6_magic(addr, daddr,
  646. udh->pl_len, IPPROTO_UDP,
  647. udh->wcheck);
  648. if (udh->uh.check == 0)
  649. udh->uh.check = -1;
  650. memcpy(buff, udh, sizeof(struct udphdr));
  651. }
  652. return 0;
  653. }
  654. static int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, int ulen)
  655. {
  656. struct ipv6_txoptions opt_space;
  657. struct udpv6fakehdr udh;
  658. struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
  659. struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) msg->msg_name;
  660. struct ipv6_txoptions *opt = NULL;
  661. struct ip6_flowlabel *flowlabel = NULL;
  662. struct flowi fl;
  663. int addr_len = msg->msg_namelen;
  664. struct in6_addr *daddr;
  665. int len = ulen + sizeof(struct udphdr);
  666. int addr_type;
  667. int hlimit = -1;
  668. int err;
  669. /* Rough check on arithmetic overflow,
  670.    better check is made in ip6_build_xmit
  671.    */
  672. if (ulen < 0 || ulen > INT_MAX - sizeof(struct udphdr))
  673. return -EMSGSIZE;
  674. fl.fl6_flowlabel = 0;
  675. fl.oif = 0;
  676. if (sin6) {
  677. if (sin6->sin6_family == AF_INET)
  678. return udp_sendmsg(sk, msg, ulen);
  679. if (addr_len < SIN6_LEN_RFC2133)
  680. return -EINVAL;
  681. if (sin6->sin6_family && sin6->sin6_family != AF_INET6)
  682. return -EINVAL;
  683. if (sin6->sin6_port == 0)
  684. return -EINVAL;
  685. udh.uh.dest = sin6->sin6_port;
  686. daddr = &sin6->sin6_addr;
  687. if (np->sndflow) {
  688. fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
  689. if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
  690. flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
  691. if (flowlabel == NULL)
  692. return -EINVAL;
  693. daddr = &flowlabel->dst;
  694. }
  695. }
  696. /* Otherwise it will be difficult to maintain sk->dst_cache. */
  697. if (sk->state == TCP_ESTABLISHED &&
  698.     !ipv6_addr_cmp(daddr, &sk->net_pinfo.af_inet6.daddr))
  699. daddr = &sk->net_pinfo.af_inet6.daddr;
  700. if (addr_len >= sizeof(struct sockaddr_in6) &&
  701.     sin6->sin6_scope_id &&
  702.     ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL)
  703. fl.oif = sin6->sin6_scope_id;
  704. } else {
  705. if (sk->state != TCP_ESTABLISHED)
  706. return -ENOTCONN;
  707. udh.uh.dest = sk->dport;
  708. daddr = &sk->net_pinfo.af_inet6.daddr;
  709. fl.fl6_flowlabel = np->flow_label;
  710. }
  711. addr_type = ipv6_addr_type(daddr);
  712. if (addr_type == IPV6_ADDR_MAPPED) {
  713. struct sockaddr_in sin;
  714. sin.sin_family = AF_INET;
  715. sin.sin_addr.s_addr = daddr->s6_addr32[3];
  716. sin.sin_port = udh.uh.dest;
  717. msg->msg_name = (struct sockaddr *)(&sin);
  718. msg->msg_namelen = sizeof(sin);
  719. fl6_sock_release(flowlabel);
  720. return udp_sendmsg(sk, msg, ulen);
  721. }
  722. udh.daddr = NULL;
  723. if (!fl.oif)
  724. fl.oif = sk->bound_dev_if;
  725. fl.fl6_src = NULL;
  726. if (msg->msg_controllen) {
  727. opt = &opt_space;
  728. memset(opt, 0, sizeof(struct ipv6_txoptions));
  729. err = datagram_send_ctl(msg, &fl, opt, &hlimit);
  730. if (err < 0) {
  731. fl6_sock_release(flowlabel);
  732. return err;
  733. }
  734. if ((fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
  735. flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
  736. if (flowlabel == NULL)
  737. return -EINVAL;
  738. }
  739. if (!(opt->opt_nflen|opt->opt_flen))
  740. opt = NULL;
  741. }
  742. if (opt == NULL)
  743. opt = np->opt;
  744. if (flowlabel)
  745. opt = fl6_merge_options(&opt_space, flowlabel, opt);
  746. if (opt && opt->srcrt)
  747. udh.daddr = daddr;
  748. udh.uh.source = sk->sport;
  749. udh.uh.len = len < 0x10000 ? htons(len) : 0;
  750. udh.uh.check = 0;
  751. udh.iov = msg->msg_iov;
  752. udh.wcheck = 0;
  753. udh.pl_len = len;
  754. fl.proto = IPPROTO_UDP;
  755. fl.fl6_dst = daddr;
  756. if (fl.fl6_src == NULL && !ipv6_addr_any(&np->saddr))
  757. fl.fl6_src = &np->saddr;
  758. fl.uli_u.ports.dport = udh.uh.dest;
  759. fl.uli_u.ports.sport = udh.uh.source;
  760. err = ip6_build_xmit(sk, udpv6_getfrag, &udh, &fl, len, opt, hlimit,
  761.      msg->msg_flags);
  762. fl6_sock_release(flowlabel);
  763. if (err < 0)
  764. return err;
  765. UDP6_INC_STATS_USER(UdpOutDatagrams);
  766. return ulen;
  767. }
  768. static struct inet6_protocol udpv6_protocol = 
  769. {
  770. udpv6_rcv, /* UDP handler */
  771. udpv6_err, /* UDP error control */
  772. NULL, /* next */
  773. IPPROTO_UDP, /* protocol ID */
  774. 0, /* copy */
  775. NULL, /* data */
  776. "UDPv6" /* name */
  777. };
  778. #define LINE_LEN 190
  779. #define LINE_FMT "%-190sn"
  780. static void get_udp6_sock(struct sock *sp, char *tmpbuf, int i)
  781. {
  782. struct in6_addr *dest, *src;
  783. __u16 destp, srcp;
  784. dest  = &sp->net_pinfo.af_inet6.daddr;
  785. src   = &sp->net_pinfo.af_inet6.rcv_saddr;
  786. destp = ntohs(sp->dport);
  787. srcp  = ntohs(sp->sport);
  788. sprintf(tmpbuf,
  789. "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
  790. "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p",
  791. i,
  792. src->s6_addr32[0], src->s6_addr32[1],
  793. src->s6_addr32[2], src->s6_addr32[3], srcp,
  794. dest->s6_addr32[0], dest->s6_addr32[1],
  795. dest->s6_addr32[2], dest->s6_addr32[3], destp,
  796. sp->state, 
  797. atomic_read(&sp->wmem_alloc), atomic_read(&sp->rmem_alloc),
  798. 0, 0L, 0,
  799. sock_i_uid(sp), 0,
  800. sock_i_ino(sp),
  801. atomic_read(&sp->refcnt), sp);
  802. }
  803. int udp6_get_info(char *buffer, char **start, off_t offset, int length)
  804. {
  805. int len = 0, num = 0, i;
  806. off_t pos = 0;
  807. off_t begin;
  808. char tmpbuf[LINE_LEN+2];
  809. if (offset < LINE_LEN+1)
  810. len += sprintf(buffer, LINE_FMT,
  811.        "  sl  " /* 6 */
  812.        "local_address                         " /* 38 */
  813.        "remote_address                        " /* 38 */
  814.        "st tx_queue rx_queue tr tm->when retrnsmt" /* 41 */
  815.        "   uid  timeout inode"); /* 21 */
  816. /*----*/
  817. /*144 */
  818. pos = LINE_LEN+1;
  819. read_lock(&udp_hash_lock);
  820. for (i = 0; i < UDP_HTABLE_SIZE; i++) {
  821. struct sock *sk;
  822. for (sk = udp_hash[i]; sk; sk = sk->next, num++) {
  823. if (sk->family != PF_INET6)
  824. continue;
  825. pos += LINE_LEN+1;
  826. if (pos <= offset)
  827. continue;
  828. get_udp6_sock(sk, tmpbuf, i);
  829. len += sprintf(buffer+len, LINE_FMT, tmpbuf);
  830. if(len >= length)
  831. goto out;
  832. }
  833. }
  834. out:
  835. read_unlock(&udp_hash_lock);
  836. begin = len - (pos - offset);
  837. *start = buffer + begin;
  838. len -= begin;
  839. if(len > length)
  840. len = length;
  841. if (len < 0)
  842. len = 0; 
  843. return len;
  844. }
  845. struct proto udpv6_prot = {
  846. name: "UDP",
  847. close: udpv6_close,
  848. connect: udpv6_connect,
  849. disconnect: udp_disconnect,
  850. ioctl: udp_ioctl,
  851. destroy: inet6_destroy_sock,
  852. setsockopt: ipv6_setsockopt,
  853. getsockopt: ipv6_getsockopt,
  854. sendmsg: udpv6_sendmsg,
  855. recvmsg: udpv6_recvmsg,
  856. backlog_rcv: udpv6_queue_rcv_skb,
  857. hash: udp_v6_hash,
  858. unhash: udp_v6_unhash,
  859. get_port: udp_v6_get_port,
  860. };
  861. extern struct proto_ops inet6_dgram_ops;
  862. static struct inet_protosw udpv6_protosw = {
  863. type:        SOCK_DGRAM,
  864. protocol:    IPPROTO_UDP,
  865. prot:        &udpv6_prot,
  866. ops:         &inet6_dgram_ops,
  867. capability:  -1,
  868. no_check:    UDP_CSUM_DEFAULT,
  869. flags:       INET_PROTOSW_PERMANENT,
  870. };
  871. void __init udpv6_init(void)
  872. {
  873. inet6_add_protocol(&udpv6_protocol);
  874. inet6_register_protosw(&udpv6_protosw);
  875. }