summaryrefslogtreecommitdiffstats
path: root/net/ipv6/udp.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-08-25 09:12:35 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-08-25 09:12:35 +0000
commitc7fc24dc4420057f103afe8fc64524ebc25c5d37 (patch)
tree3682407a599b8f9f03fc096298134cafba1c9b2f /net/ipv6/udp.c
parent1d793fade8b063fde3cf275bf1a5c2d381292cd9 (diff)
o Merge with Linux 2.1.116.
o New Newport console code. o New G364 console code.
Diffstat (limited to 'net/ipv6/udp.c')
-rw-r--r--net/ipv6/udp.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 6078ab679..2dac0570f 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -7,7 +7,7 @@
*
* Based on linux/ipv4/udp.c
*
- * $Id: udp.c,v 1.27 1998/03/21 07:28:06 davem Exp $
+ * $Id: udp.c,v 1.31 1998/07/15 05:05:45 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -147,7 +147,7 @@ static struct sock *udp_v6_lookup(struct in6_addr *saddr, u16 sport,
for(sk = udp_hash[hnum & (UDP_HTABLE_SIZE - 1)]; sk != NULL; sk = sk->next) {
if((sk->num == hnum) &&
- (sk->family == AF_INET6) &&
+ (sk->family == PF_INET6) &&
!(sk->dead && (sk->state == TCP_CLOSE))) {
struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
int score = 0;
@@ -185,12 +185,18 @@ static struct sock *udp_v6_lookup(struct in6_addr *saddr, u16 sport,
int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
{
struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
+ struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
struct in6_addr *daddr;
struct dst_entry *dst;
- struct ipv6_pinfo *np;
struct inet6_ifaddr *ifa;
struct flowi fl;
int addr_type;
+ int err;
+
+ if (usin->sin6_family == AF_INET) {
+ err = udp_connect(sk, uaddr, addr_len);
+ goto ipv4_connected;
+ }
if (addr_len < sizeof(*usin))
return(-EINVAL);
@@ -199,7 +205,6 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
return(-EAFNOSUPPORT);
addr_type = ipv6_addr_type(&usin->sin6_addr);
- np = &sk->net_pinfo.af_inet6;
if (addr_type == IPV6_ADDR_ANY) {
/*
@@ -212,18 +217,21 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
if (addr_type == IPV6_ADDR_MAPPED) {
struct sockaddr_in sin;
- int err;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = daddr->s6_addr32[3];
+ sin.sin_port = usin->sin6_port;
err = udp_connect(sk, (struct sockaddr*) &sin, sizeof(sin));
-
+
+ipv4_connected:
if (err < 0)
return err;
- ipv6_addr_copy(&np->daddr, daddr);
-
+ ipv6_addr_set(&np->daddr, 0, 0,
+ __constant_htonl(0x0000ffff),
+ sk->daddr);
+
if(ipv6_addr_any(&np->saddr)) {
ipv6_addr_set(&np->saddr, 0, 0,
__constant_htonl(0x0000ffff),
@@ -236,7 +244,7 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
__constant_htonl(0x0000ffff),
sk->rcv_saddr);
}
-
+ return 0;
}
ipv6_addr_copy(&np->daddr, daddr);
@@ -347,6 +355,8 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, int len,
if (skb->protocol == __constant_htons(ETH_P_IP)) {
ipv6_addr_set(&sin6->sin6_addr, 0, 0,
__constant_htonl(0xffff), skb->nh.iph->saddr);
+ if (sk->ip_cmsg_flags)
+ ip_cmsg_recv(msg, skb);
} else {
memcpy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr,
sizeof(struct in6_addr));
@@ -668,6 +678,9 @@ static int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, int ulen)
return(-EINVAL);
if (sin6) {
+ if (sin6->sin6_family == AF_INET)
+ return udp_sendmsg(sk, msg, ulen);
+
if (addr_len < sizeof(*sin6))
return(-EINVAL);
@@ -689,7 +702,7 @@ static int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, int ulen)
}
} else {
if (sk->state != TCP_ESTABLISHED)
- return(-EINVAL);
+ return(-ENOTCONN);
udh.uh.dest = sk->dport;
daddr = &sk->net_pinfo.af_inet6.daddr;
@@ -702,8 +715,10 @@ static int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, int ulen)
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = daddr->s6_addr32[3];
+ sin.sin_port = udh.uh.dest;
+ msg->msg_name = (struct sockaddr *)(&sin);
- return udp_sendmsg(sk, msg, len);
+ return udp_sendmsg(sk, msg, ulen);
}
udh.daddr = NULL;