aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/key/af_key.c107
1 files changed, 38 insertions, 69 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 2b05cb6c15c6..771bd61d6303 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -592,25 +592,30 @@ static inline int pfkey_sockaddr_len(sa_family_t family)
592 return 0; 592 return 0;
593} 593}
594 594
595static int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, 595static
596 xfrm_address_t *xaddr) 596int pfkey_sockaddr_extract(const struct sockaddr *sa, xfrm_address_t *xaddr)
597{ 597{
598 switch (((struct sockaddr*)(addr + 1))->sa_family) { 598 switch (sa->sa_family) {
599 case AF_INET: 599 case AF_INET:
600 xaddr->a4 = 600 xaddr->a4 =
601 ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr; 601 ((struct sockaddr_in *)sa)->sin_addr.s_addr;
602 return AF_INET; 602 return AF_INET;
603#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 603#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
604 case AF_INET6: 604 case AF_INET6:
605 memcpy(xaddr->a6, 605 memcpy(xaddr->a6,
606 &((struct sockaddr_in6 *)(addr + 1))->sin6_addr, 606 &((struct sockaddr_in6 *)sa)->sin6_addr,
607 sizeof(struct in6_addr)); 607 sizeof(struct in6_addr));
608 return AF_INET6; 608 return AF_INET6;
609#endif 609#endif
610 default:
611 return 0;
612 } 610 }
613 /* NOTREACHED */ 611 return 0;
612}
613
614static
615int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, xfrm_address_t *xaddr)
616{
617 return pfkey_sockaddr_extract((struct sockaddr *)(addr + 1),
618 xaddr);
614} 619}
615 620
616static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **ext_hdrs) 621static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **ext_hdrs)
@@ -1828,10 +1833,6 @@ static int
1828parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) 1833parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1829{ 1834{
1830 struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr; 1835 struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr;
1831 struct sockaddr_in *sin;
1832#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1833 struct sockaddr_in6 *sin6;
1834#endif
1835 int mode; 1836 int mode;
1836 1837
1837 if (xp->xfrm_nr >= XFRM_MAX_DEPTH) 1838 if (xp->xfrm_nr >= XFRM_MAX_DEPTH)
@@ -1856,31 +1857,19 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1856 1857
1857 /* addresses present only in tunnel mode */ 1858 /* addresses present only in tunnel mode */
1858 if (t->mode == XFRM_MODE_TUNNEL) { 1859 if (t->mode == XFRM_MODE_TUNNEL) {
1859 struct sockaddr *sa; 1860 u8 *sa = (u8 *) (rq + 1);
1860 sa = (struct sockaddr *)(rq+1); 1861 int family, socklen;
1861 switch(sa->sa_family) { 1862
1862 case AF_INET: 1863 family = pfkey_sockaddr_extract((struct sockaddr *)sa,
1863 sin = (struct sockaddr_in*)sa; 1864 &t->saddr);
1864 t->saddr.a4 = sin->sin_addr.s_addr; 1865 if (!family)
1865 sin++;
1866 if (sin->sin_family != AF_INET)
1867 return -EINVAL;
1868 t->id.daddr.a4 = sin->sin_addr.s_addr;
1869 break;
1870#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1871 case AF_INET6:
1872 sin6 = (struct sockaddr_in6*)sa;
1873 memcpy(t->saddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr));
1874 sin6++;
1875 if (sin6->sin6_family != AF_INET6)
1876 return -EINVAL;
1877 memcpy(t->id.daddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr));
1878 break;
1879#endif
1880 default:
1881 return -EINVAL; 1866 return -EINVAL;
1882 } 1867
1883 t->encap_family = sa->sa_family; 1868 socklen = pfkey_sockaddr_len(family);
1869 if (pfkey_sockaddr_extract((struct sockaddr *)(sa + socklen),
1870 &t->id.daddr) != family)
1871 return -EINVAL;
1872 t->encap_family = family;
1884 } else 1873 } else
1885 t->encap_family = xp->family; 1874 t->encap_family = xp->family;
1886 1875
@@ -2375,44 +2364,24 @@ static int parse_sockaddr_pair(struct sadb_x_ipsecrequest *rq,
2375 xfrm_address_t *saddr, xfrm_address_t *daddr, 2364 xfrm_address_t *saddr, xfrm_address_t *daddr,
2376 u16 *family) 2365 u16 *family)
2377{ 2366{
2378 struct sockaddr *sa = (struct sockaddr *)(rq + 1); 2367 u8 *sa = (u8 *) (rq + 1);
2368 int af, socklen;
2369
2379 if (rq->sadb_x_ipsecrequest_len < 2370 if (rq->sadb_x_ipsecrequest_len <
2380 pfkey_sockaddr_pair_size(sa->sa_family)) 2371 pfkey_sockaddr_pair_size(((struct sockaddr *)sa)->sa_family))
2381 return -EINVAL; 2372 return -EINVAL;
2382 2373
2383 switch (sa->sa_family) { 2374 af = pfkey_sockaddr_extract((struct sockaddr *) sa,
2384 case AF_INET: 2375 saddr);
2385 { 2376 if (!af)
2386 struct sockaddr_in *sin; 2377 return -EINVAL;
2387 sin = (struct sockaddr_in *)sa; 2378
2388 if ((sin+1)->sin_family != AF_INET) 2379 socklen = pfkey_sockaddr_len(af);
2389 return -EINVAL; 2380 if (pfkey_sockaddr_extract((struct sockaddr *) (sa + socklen),
2390 memcpy(&saddr->a4, &sin->sin_addr, sizeof(saddr->a4)); 2381 daddr) != af)
2391 sin++;
2392 memcpy(&daddr->a4, &sin->sin_addr, sizeof(daddr->a4));
2393 *family = AF_INET;
2394 break;
2395 }
2396#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2397 case AF_INET6:
2398 {
2399 struct sockaddr_in6 *sin6;
2400 sin6 = (struct sockaddr_in6 *)sa;
2401 if ((sin6+1)->sin6_family != AF_INET6)
2402 return -EINVAL;
2403 memcpy(&saddr->a6, &sin6->sin6_addr,
2404 sizeof(saddr->a6));
2405 sin6++;
2406 memcpy(&daddr->a6, &sin6->sin6_addr,
2407 sizeof(daddr->a6));
2408 *family = AF_INET6;
2409 break;
2410 }
2411#endif
2412 default:
2413 return -EINVAL; 2382 return -EINVAL;
2414 }
2415 2383
2384 *family = af;
2416 return 0; 2385 return 0;
2417} 2386}
2418 2387