Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
e7d2dc10
Commit
e7d2dc10
authored
Sep 26, 2002
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge master.kernel.org:/home/acme/BK/x25-2.5
into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents
606456cc
53cdc7d9
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
170 additions
and
149 deletions
+170
-149
net/x25/af_x25.c
net/x25/af_x25.c
+170
-149
No files found.
net/x25/af_x25.c
View file @
e7d2dc10
...
@@ -330,7 +330,7 @@ void x25_destroy_socket(struct sock *sk) /* Not static as it's used by the timer
...
@@ -330,7 +330,7 @@ void x25_destroy_socket(struct sock *sk) /* Not static as it's used by the timer
kfree_skb
(
skb
);
kfree_skb
(
skb
);
}
}
if
(
atomic_read
(
&
sk
->
wmem_alloc
)
!=
0
||
atomic_read
(
&
sk
->
rmem_alloc
)
!=
0
)
{
if
(
atomic_read
(
&
sk
->
wmem_alloc
)
||
atomic_read
(
&
sk
->
rmem_alloc
)
)
{
/* Defer: outstanding buffers */
/* Defer: outstanding buffers */
init_timer
(
&
sk
->
timer
);
init_timer
(
&
sk
->
timer
);
sk
->
timer
.
expires
=
jiffies
+
10
*
HZ
;
sk
->
timer
.
expires
=
jiffies
+
10
*
HZ
;
...
@@ -353,73 +353,69 @@ void x25_destroy_socket(struct sock *sk) /* Not static as it's used by the timer
...
@@ -353,73 +353,69 @@ void x25_destroy_socket(struct sock *sk) /* Not static as it's used by the timer
static
int
x25_setsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
static
int
x25_setsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
*
optval
,
int
optlen
)
char
*
optval
,
int
optlen
)
{
{
struct
sock
*
sk
=
sock
->
sk
;
int
opt
;
int
opt
;
struct
sock
*
sk
=
sock
->
sk
;
int
rc
=
-
ENOPROTOOPT
;
if
(
level
!=
SOL_X25
)
if
(
level
!=
SOL_X25
||
optname
!=
X25_QBITINCL
)
return
-
ENOPROTOOPT
;
goto
out
;
rc
=
-
EINVAL
;
if
(
optlen
<
sizeof
(
int
))
if
(
optlen
<
sizeof
(
int
))
return
-
EINVAL
;
goto
out
;
rc
=
-
EFAULT
;
if
(
get_user
(
opt
,
(
int
*
)
optval
))
if
(
get_user
(
opt
,
(
int
*
)
optval
))
return
-
EFAULT
;
goto
out
;
switch
(
optname
)
{
case
X25_QBITINCL
:
x25_sk
(
sk
)
->
qbitincl
=
opt
?
1
:
0
;
return
0
;
default:
x25_sk
(
sk
)
->
qbitincl
=
!!
opt
;
return
-
ENOPROTOOPT
;
rc
=
0
;
}
out:
return
rc
;
}
}
static
int
x25_getsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
static
int
x25_getsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
*
optval
,
int
*
optlen
)
char
*
optval
,
int
*
optlen
)
{
{
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
sk
=
sock
->
sk
;
int
val
=
0
;
int
val
,
len
,
rc
=
-
ENOPROTOOPT
;
int
len
;
if
(
level
!=
SOL_X25
)
if
(
level
!=
SOL_X25
||
optname
!=
X25_QBITINCL
)
return
-
ENOPROTOOPT
;
goto
out
;
rc
=
-
EFAULT
;
if
(
get_user
(
len
,
optlen
))
if
(
get_user
(
len
,
optlen
))
return
-
EFAULT
;
goto
out
;
switch
(
optname
)
{
case
X25_QBITINCL
:
val
=
x25_sk
(
sk
)
->
qbitincl
;
break
;
default:
return
-
ENOPROTOOPT
;
}
len
=
min_t
(
unsigned
int
,
len
,
sizeof
(
int
));
len
=
min_t
(
unsigned
int
,
len
,
sizeof
(
int
));
rc
=
-
EINVAL
;
if
(
len
<
0
)
if
(
len
<
0
)
return
-
EINVAL
;
goto
out
;
rc
=
-
EFAULT
;
if
(
put_user
(
len
,
optlen
))
if
(
put_user
(
len
,
optlen
))
return
-
EFAULT
;
goto
out
;
return
copy_to_user
(
optval
,
&
val
,
len
)
?
-
EFAULT
:
0
;
val
=
x25_sk
(
sk
)
->
qbitincl
;
rc
=
copy_to_user
(
optval
,
&
val
,
len
)
?
-
EFAULT
:
0
;
out:
return
rc
;
}
}
static
int
x25_listen
(
struct
socket
*
sock
,
int
backlog
)
static
int
x25_listen
(
struct
socket
*
sock
,
int
backlog
)
{
{
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
sk
=
sock
->
sk
;
int
rc
=
-
EOPNOTSUPP
;
if
(
sk
->
state
!=
TCP_LISTEN
)
{
if
(
sk
->
state
!=
TCP_LISTEN
)
{
memset
(
&
x25_sk
(
sk
)
->
dest_addr
,
0
,
X25_ADDR_LEN
);
memset
(
&
x25_sk
(
sk
)
->
dest_addr
,
0
,
X25_ADDR_LEN
);
sk
->
max_ack_backlog
=
backlog
;
sk
->
max_ack_backlog
=
backlog
;
sk
->
state
=
TCP_LISTEN
;
sk
->
state
=
TCP_LISTEN
;
r
eturn
0
;
r
c
=
0
;
}
}
return
-
EOPNOTSUPP
;
return
rc
;
}
}
static
struct
sock
*
x25_alloc_socket
(
void
)
static
struct
sock
*
x25_alloc_socket
(
void
)
...
@@ -436,7 +432,7 @@ static struct sock *x25_alloc_socket(void)
...
@@ -436,7 +432,7 @@ static struct sock *x25_alloc_socket(void)
if
(
!
x25
)
if
(
!
x25
)
goto
frees
;
goto
frees
;
memset
(
x25
,
0
x00
,
sizeof
(
*
x25
));
memset
(
x25
,
0
,
sizeof
(
*
x25
));
x25
->
sk
=
sk
;
x25
->
sk
=
sk
;
...
@@ -460,12 +456,14 @@ static int x25_create(struct socket *sock, int protocol)
...
@@ -460,12 +456,14 @@ static int x25_create(struct socket *sock, int protocol)
{
{
struct
sock
*
sk
;
struct
sock
*
sk
;
x25_cb
*
x25
;
x25_cb
*
x25
;
int
rc
=
-
ESOCKTNOSUPPORT
;
if
(
sock
->
type
!=
SOCK_SEQPACKET
||
protocol
!=
0
)
if
(
sock
->
type
!=
SOCK_SEQPACKET
||
protocol
)
return
-
ESOCKTNOSUPPORT
;
goto
out
;
rc
=
-
ENOMEM
;
if
((
sk
=
x25_alloc_socket
())
==
NULL
)
if
((
sk
=
x25_alloc_socket
())
==
NULL
)
return
-
ENOMEM
;
goto
out
;
x25
=
x25_sk
(
sk
);
x25
=
x25_sk
(
sk
);
...
@@ -489,20 +487,21 @@ static int x25_create(struct socket *sock, int protocol)
...
@@ -489,20 +487,21 @@ static int x25_create(struct socket *sock, int protocol)
x25
->
facilities
.
pacsize_out
=
X25_DEFAULT_PACKET_SIZE
;
x25
->
facilities
.
pacsize_out
=
X25_DEFAULT_PACKET_SIZE
;
x25
->
facilities
.
throughput
=
X25_DEFAULT_THROUGHPUT
;
x25
->
facilities
.
throughput
=
X25_DEFAULT_THROUGHPUT
;
x25
->
facilities
.
reverse
=
X25_DEFAULT_REVERSE
;
x25
->
facilities
.
reverse
=
X25_DEFAULT_REVERSE
;
rc
=
0
;
return
0
;
out:
return
rc
;
}
}
static
struct
sock
*
x25_make_new
(
struct
sock
*
osk
)
static
struct
sock
*
x25_make_new
(
struct
sock
*
osk
)
{
{
struct
sock
*
sk
;
struct
sock
*
sk
=
NULL
;
x25_cb
*
x25
,
*
ox25
;
x25_cb
*
x25
,
*
ox25
;
if
(
osk
->
type
!=
SOCK_SEQPACKET
)
if
(
osk
->
type
!=
SOCK_SEQPACKET
)
return
NULL
;
goto
out
;
if
((
sk
=
x25_alloc_socket
())
==
NULL
)
if
((
sk
=
x25_alloc_socket
())
==
NULL
)
return
NULL
;
goto
out
;
x25
=
x25_sk
(
sk
);
x25
=
x25_sk
(
sk
);
...
@@ -527,7 +526,7 @@ static struct sock *x25_make_new(struct sock *osk)
...
@@ -527,7 +526,7 @@ static struct sock *x25_make_new(struct sock *osk)
x25
->
qbitincl
=
ox25
->
qbitincl
;
x25
->
qbitincl
=
ox25
->
qbitincl
;
init_timer
(
&
x25
->
timer
);
init_timer
(
&
x25
->
timer
);
out:
return
sk
;
return
sk
;
}
}
...
@@ -577,21 +576,14 @@ static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
...
@@ -577,21 +576,14 @@ static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
sk
=
sock
->
sk
;
struct
sockaddr_x25
*
addr
=
(
struct
sockaddr_x25
*
)
uaddr
;
struct
sockaddr_x25
*
addr
=
(
struct
sockaddr_x25
*
)
uaddr
;
if
(
sk
->
zapped
==
0
)
if
(
!
sk
->
zapped
||
return
-
EINVAL
;
addr_len
!=
sizeof
(
struct
sockaddr_x25
)
||
addr
->
sx25_family
!=
AF_X25
)
if
(
addr_len
!=
sizeof
(
struct
sockaddr_x25
))
return
-
EINVAL
;
if
(
addr
->
sx25_family
!=
AF_X25
)
return
-
EINVAL
;
return
-
EINVAL
;
x25_sk
(
sk
)
->
source_addr
=
addr
->
sx25_addr
;
x25_sk
(
sk
)
->
source_addr
=
addr
->
sx25_addr
;
x25_insert_socket
(
sk
);
x25_insert_socket
(
sk
);
sk
->
zapped
=
0
;
sk
->
zapped
=
0
;
SOCK_DEBUG
(
sk
,
"x25_bind: socket is bound
\n
"
);
SOCK_DEBUG
(
sk
,
"x25_bind: socket is bound
\n
"
);
return
0
;
return
0
;
...
@@ -603,42 +595,49 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len
...
@@ -603,42 +595,49 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len
x25_cb
*
x25
=
x25_sk
(
sk
);
x25_cb
*
x25
=
x25_sk
(
sk
);
struct
sockaddr_x25
*
addr
=
(
struct
sockaddr_x25
*
)
uaddr
;
struct
sockaddr_x25
*
addr
=
(
struct
sockaddr_x25
*
)
uaddr
;
struct
net_device
*
dev
;
struct
net_device
*
dev
;
int
rc
=
0
;
if
(
sk
->
state
==
TCP_ESTABLISHED
&&
sock
->
state
==
SS_CONNECTING
)
{
if
(
sk
->
state
==
TCP_ESTABLISHED
&&
sock
->
state
==
SS_CONNECTING
)
{
sock
->
state
=
SS_CONNECTED
;
sock
->
state
=
SS_CONNECTED
;
return
0
;
/* Connect completed during a ERESTARTSYS event */
goto
out
;
/* Connect completed during a ERESTARTSYS event */
}
}
rc
=
-
ECONNREFUSED
;
if
(
sk
->
state
==
TCP_CLOSE
&&
sock
->
state
==
SS_CONNECTING
)
{
if
(
sk
->
state
==
TCP_CLOSE
&&
sock
->
state
==
SS_CONNECTING
)
{
sock
->
state
=
SS_UNCONNECTED
;
sock
->
state
=
SS_UNCONNECTED
;
return
-
ECONNREFUSED
;
goto
out
;
}
}
rc
=
-
EISCONN
;
/* No reconnect on a seqpacket socket */
if
(
sk
->
state
==
TCP_ESTABLISHED
)
if
(
sk
->
state
==
TCP_ESTABLISHED
)
return
-
EISCONN
;
/* No reconnect on a seqpacket socket */
goto
out
;
sk
->
state
=
TCP_CLOSE
;
sk
->
state
=
TCP_CLOSE
;
sock
->
state
=
SS_UNCONNECTED
;
sock
->
state
=
SS_UNCONNECTED
;
if
(
addr_len
!=
sizeof
(
struct
sockaddr_x25
))
rc
=
-
EINVAL
;
return
-
EINVAL
;
if
(
addr_len
!=
sizeof
(
struct
sockaddr_x25
)
||
addr
->
sx25_family
!=
AF_X25
)
if
(
addr
->
sx25_family
!=
AF_X25
)
goto
out
;
return
-
EINVAL
;
if
((
dev
=
x25_get_route
(
&
addr
->
sx25_addr
))
==
NULL
)
rc
=
-
ENETUNREACH
;
return
-
ENETUNREACH
;
dev
=
x25_get_route
(
&
addr
->
sx25_addr
);
if
(
!
dev
)
goto
out
;
if
((
x25
->
neighbour
=
x25_get_neigh
(
dev
))
==
NULL
)
x25
->
neighbour
=
x25_get_neigh
(
dev
);
return
-
ENETUNREACH
;
if
(
!
x25
->
neighbour
)
goto
out
;
x25_limit_facilities
(
&
x25
->
facilities
,
x25
->
neighbour
);
x25_limit_facilities
(
&
x25
->
facilities
,
x25
->
neighbour
);
if
((
x25
->
lci
=
x25_new_lci
(
x25
->
neighbour
))
==
0
)
x25
->
lci
=
x25_new_lci
(
x25
->
neighbour
);
return
-
ENETUNREACH
;
if
(
!
x25
->
lci
)
goto
out
;
rc
=
-
EINVAL
;
if
(
sk
->
zapped
)
/* Must bind first - autobinding does not work */
if
(
sk
->
zapped
)
/* Must bind first - autobinding does not work */
return
-
EINVAL
;
goto
out
;
if
(
!
strcmp
(
x25
->
source_addr
.
x25_addr
,
null_x25_address
.
x25_addr
))
if
(
!
strcmp
(
x25
->
source_addr
.
x25_addr
,
null_x25_address
.
x25_addr
))
memset
(
&
x25
->
source_addr
,
'\0'
,
X25_ADDR_LEN
);
memset
(
&
x25
->
source_addr
,
'\0'
,
X25_ADDR_LEN
);
...
@@ -657,49 +656,50 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len
...
@@ -657,49 +656,50 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len
x25_start_t21timer
(
sk
);
x25_start_t21timer
(
sk
);
/* Now the loop */
/* Now the loop */
rc
=
-
EINPROGRESS
;
if
(
sk
->
state
!=
TCP_ESTABLISHED
&&
(
flags
&
O_NONBLOCK
))
if
(
sk
->
state
!=
TCP_ESTABLISHED
&&
(
flags
&
O_NONBLOCK
))
return
-
EINPROGRESS
;
goto
out
;
cli
();
/* To avoid races on the sleep */
cli
();
/* To avoid races on the sleep */
/*
/*
* A Clear Request or timeout or failed routing will go to closed.
* A Clear Request or timeout or failed routing will go to closed.
*/
*/
rc
=
-
ERESTARTSYS
;
while
(
sk
->
state
==
TCP_SYN_SENT
)
{
while
(
sk
->
state
==
TCP_SYN_SENT
)
{
/* FIXME: going to sleep with interrupts disabled */
interruptible_sleep_on
(
sk
->
sleep
);
interruptible_sleep_on
(
sk
->
sleep
);
if
(
signal_pending
(
current
))
{
if
(
signal_pending
(
current
))
sti
();
goto
out_unlock
;
return
-
ERESTARTSYS
;
}
}
}
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
{
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
{
sti
();
sock
->
state
=
SS_UNCONNECTED
;
sock
->
state
=
SS_UNCONNECTED
;
return
sock_error
(
sk
);
/* Always set at this point */
rc
=
sock_error
(
sk
);
/* Always set at this point */
goto
out_unlock
;
}
}
sock
->
state
=
SS_CONNECTED
;
sock
->
state
=
SS_CONNECTED
;
rc
=
0
;
out_unlock:
sti
();
sti
();
out:
return
0
;
return
rc
;
}
}
static
int
x25_accept
(
struct
socket
*
sock
,
struct
socket
*
newsock
,
int
flags
)
static
int
x25_accept
(
struct
socket
*
sock
,
struct
socket
*
newsock
,
int
flags
)
{
{
struct
sock
*
sk
;
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
newsk
;
struct
sock
*
newsk
;
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
int
rc
=
-
EINVAL
;
if
(
(
sk
=
sock
->
sk
)
==
NULL
)
if
(
!
sk
||
sk
->
state
!=
TCP_LISTEN
)
return
-
EINVAL
;
goto
out
;
rc
=
-
EOPNOTSUPP
;
if
(
sk
->
type
!=
SOCK_SEQPACKET
)
if
(
sk
->
type
!=
SOCK_SEQPACKET
)
return
-
EOPNOTSUPP
;
goto
out
;
if
(
sk
->
state
!=
TCP_LISTEN
)
return
-
EINVAL
;
/*
/*
* The write queue this time is holding sockets ready to use
* The write queue this time is holding sockets ready to use
...
@@ -708,17 +708,16 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
...
@@ -708,17 +708,16 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
do
{
do
{
cli
();
cli
();
if
((
skb
=
skb_dequeue
(
&
sk
->
receive_queue
))
==
NULL
)
{
if
((
skb
=
skb_dequeue
(
&
sk
->
receive_queue
))
==
NULL
)
{
if
(
flags
&
O_NONBLOCK
)
{
rc
=
-
EWOULDBLOCK
;
sti
();
if
(
flags
&
O_NONBLOCK
)
return
-
EWOULDBLOCK
;
goto
out_unlock
;
}
/* FIXME: going to sleep with interrupts disabled */
interruptible_sleep_on
(
sk
->
sleep
);
interruptible_sleep_on
(
sk
->
sleep
);
if
(
signal_pending
(
current
))
{
rc
=
-
ERESTARTSYS
;
sti
();
if
(
signal_pending
(
current
))
return
-
ERESTARTSYS
;
goto
out_unlock
;
}
}
}
}
while
(
skb
==
NULL
);
}
while
(
!
skb
);
newsk
=
skb
->
sk
;
newsk
=
skb
->
sk
;
newsk
->
pair
=
NULL
;
newsk
->
pair
=
NULL
;
...
@@ -732,8 +731,12 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
...
@@ -732,8 +731,12 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
sk
->
ack_backlog
--
;
sk
->
ack_backlog
--
;
newsock
->
sk
=
newsk
;
newsock
->
sk
=
newsk
;
newsock
->
state
=
SS_CONNECTED
;
newsock
->
state
=
SS_CONNECTED
;
rc
=
0
;
return
0
;
out:
return
rc
;
out_unlock:
sti
();
goto
out
;
}
}
static
int
x25_getname
(
struct
socket
*
sock
,
struct
sockaddr
*
uaddr
,
int
*
uaddr_len
,
int
peer
)
static
int
x25_getname
(
struct
socket
*
sock
,
struct
sockaddr
*
uaddr
,
int
*
uaddr_len
,
int
peer
)
...
@@ -742,16 +745,15 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_l
...
@@ -742,16 +745,15 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_l
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
sk
=
sock
->
sk
;
x25_cb
*
x25
=
x25_sk
(
sk
);
x25_cb
*
x25
=
x25_sk
(
sk
);
if
(
peer
!=
0
)
{
if
(
peer
)
{
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
return
-
ENOTCONN
;
return
-
ENOTCONN
;
sx25
->
sx25_addr
=
x25
->
dest_addr
;
sx25
->
sx25_addr
=
x25
->
dest_addr
;
}
else
{
}
else
sx25
->
sx25_addr
=
x25
->
source_addr
;
sx25
->
sx25_addr
=
x25
->
source_addr
;
}
sx25
->
sx25_family
=
AF_X25
;
sx25
->
sx25_family
=
AF_X25
;
*
uaddr_len
=
sizeof
(
struct
sockaddr_
x25
);
*
uaddr_len
=
sizeof
(
*
s
x25
);
return
0
;
return
0
;
}
}
...
@@ -784,7 +786,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *neigh, unsigned i
...
@@ -784,7 +786,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *neigh, unsigned i
/*
/*
* We can't accept the Call Request.
* We can't accept the Call Request.
*/
*/
if
(
sk
==
NULL
||
sk
->
ack_backlog
==
sk
->
max_ack_backlog
)
{
if
(
!
sk
||
sk
->
ack_backlog
==
sk
->
max_ack_backlog
)
{
x25_transmit_clear_request
(
neigh
,
lci
,
0x01
);
x25_transmit_clear_request
(
neigh
,
lci
,
0x01
);
return
0
;
return
0
;
}
}
...
@@ -807,7 +809,8 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *neigh, unsigned i
...
@@ -807,7 +809,8 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *neigh, unsigned i
/*
/*
* Try to create a new socket.
* Try to create a new socket.
*/
*/
if
((
make
=
x25_make_new
(
sk
))
==
NULL
)
{
make
=
x25_make_new
(
sk
);
if
(
!
make
)
{
x25_transmit_clear_request
(
neigh
,
lci
,
0x01
);
x25_transmit_clear_request
(
neigh
,
lci
,
0x01
);
return
0
;
return
0
;
}
}
...
@@ -860,46 +863,53 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
...
@@ -860,46 +863,53 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
sk
=
sock
->
sk
;
x25_cb
*
x25
=
x25_sk
(
sk
);
x25_cb
*
x25
=
x25_sk
(
sk
);
struct
sockaddr_x25
*
usx25
=
(
struct
sockaddr_x25
*
)
msg
->
msg_name
;
struct
sockaddr_x25
*
usx25
=
(
struct
sockaddr_x25
*
)
msg
->
msg_name
;
int
err
;
struct
sockaddr_x25
sx25
;
struct
sockaddr_x25
sx25
;
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
unsigned
char
*
asmptr
;
unsigned
char
*
asmptr
;
int
size
,
qbit
=
0
;
int
noblock
=
msg
->
msg_flags
&
MSG_DONTWAIT
;
int
size
,
qbit
=
0
,
rc
=
-
EINVAL
;
if
(
msg
->
msg_flags
&
~
(
MSG_DONTWAIT
|
MSG_OOB
|
MSG_EOR
))
if
(
msg
->
msg_flags
&
~
(
MSG_DONTWAIT
|
MSG_OOB
|
MSG_EOR
))
return
-
EINVAL
;
goto
out
;
/* we currently don't support segmented records at the user interface */
/* we currently don't support segmented records at the user interface */
if
(
!
(
msg
->
msg_flags
&
(
MSG_EOR
|
MSG_OOB
)))
if
(
!
(
msg
->
msg_flags
&
(
MSG_EOR
|
MSG_OOB
)))
return
-
EINVAL
;
goto
out
;
rc
=
-
EADDRNOTAVAIL
;
if
(
sk
->
zapped
)
if
(
sk
->
zapped
)
return
-
EADDRNOTAVAIL
;
goto
out
;
rc
=
-
EPIPE
;
if
(
sk
->
shutdown
&
SEND_SHUTDOWN
)
{
if
(
sk
->
shutdown
&
SEND_SHUTDOWN
)
{
send_sig
(
SIGPIPE
,
current
,
0
);
send_sig
(
SIGPIPE
,
current
,
0
);
return
-
EPIPE
;
goto
out
;
}
}
if
(
x25
->
neighbour
==
NULL
)
rc
=
-
ENETUNREACH
;
return
-
ENETUNREACH
;
if
(
!
x25
->
neighbour
)
goto
out
;
if
(
usx25
!=
NULL
)
{
if
(
usx25
)
{
rc
=
-
EINVAL
;
if
(
msg
->
msg_namelen
<
sizeof
(
sx25
))
if
(
msg
->
msg_namelen
<
sizeof
(
sx25
))
return
-
EINVAL
;
goto
out
;
sx25
=
*
usx25
;
memcpy
(
&
sx25
,
usx25
,
sizeof
(
sx25
));
rc
=
-
EISCONN
;
if
(
strcmp
(
x25
->
dest_addr
.
x25_addr
,
sx25
.
sx25_addr
.
x25_addr
))
if
(
strcmp
(
x25
->
dest_addr
.
x25_addr
,
sx25
.
sx25_addr
.
x25_addr
))
return
-
EISCONN
;
goto
out
;
rc
=
-
EINVAL
;
if
(
sx25
.
sx25_family
!=
AF_X25
)
if
(
sx25
.
sx25_family
!=
AF_X25
)
return
-
EINVAL
;
goto
out
;
}
else
{
}
else
{
/*
/*
* FIXME 1003.1g - if the socket is like this because
* FIXME 1003.1g - if the socket is like this because
* it has become closed (not started closed) we ought
* it has become closed (not started closed) we ought
* to SIGPIPE, EPIPE;
* to SIGPIPE, EPIPE;
*/
*/
rc
=
-
ENOTCONN
;
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
return
-
ENOTCONN
;
goto
out
;
sx25
.
sx25_family
=
AF_X25
;
sx25
.
sx25_family
=
AF_X25
;
sx25
.
sx25_addr
=
x25
->
dest_addr
;
sx25
.
sx25_addr
=
x25
->
dest_addr
;
...
@@ -915,8 +925,9 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
...
@@ -915,8 +925,9 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
size
=
len
+
X25_MAX_L2_LEN
+
X25_EXT_MIN_LEN
;
size
=
len
+
X25_MAX_L2_LEN
+
X25_EXT_MIN_LEN
;
if
((
skb
=
sock_alloc_send_skb
(
sk
,
size
,
msg
->
msg_flags
&
MSG_DONTWAIT
,
&
err
))
==
NULL
)
skb
=
sock_alloc_send_skb
(
sk
,
size
,
noblock
,
&
rc
);
return
err
;
if
(
!
skb
)
goto
out
;
X25_SKB_CB
(
skb
)
->
flags
=
msg
->
msg_flags
;
X25_SKB_CB
(
skb
)
->
flags
=
msg
->
msg_flags
;
skb_reserve
(
skb
,
X25_MAX_L2_LEN
+
X25_EXT_MIN_LEN
);
skb_reserve
(
skb
,
X25_MAX_L2_LEN
+
X25_EXT_MIN_LEN
);
...
@@ -928,7 +939,9 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
...
@@ -928,7 +939,9 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
asmptr
=
skb
->
h
.
raw
=
skb_put
(
skb
,
len
);
asmptr
=
skb
->
h
.
raw
=
skb_put
(
skb
,
len
);
memcpy_fromiovec
(
asmptr
,
msg
->
msg_iov
,
len
);
rc
=
memcpy_fromiovec
(
asmptr
,
msg
->
msg_iov
,
len
);
if
(
rc
)
goto
out_kfree_skb
;
/*
/*
* If the Q BIT Include socket option is in force, the first
* If the Q BIT Include socket option is in force, the first
...
@@ -979,22 +992,19 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
...
@@ -979,22 +992,19 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
SOCK_DEBUG
(
sk
,
"x25_sendmsg: Built header.
\n
"
);
SOCK_DEBUG
(
sk
,
"x25_sendmsg: Built header.
\n
"
);
SOCK_DEBUG
(
sk
,
"x25_sendmsg: Transmitting buffer
\n
"
);
SOCK_DEBUG
(
sk
,
"x25_sendmsg: Transmitting buffer
\n
"
);
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
{
rc
=
-
ENOTCONN
;
kfree_skb
(
skb
);
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
return
-
ENOTCONN
;
goto
out_kfree_skb
;
}
if
(
msg
->
msg_flags
&
MSG_OOB
)
{
if
(
msg
->
msg_flags
&
MSG_OOB
)
skb_queue_tail
(
&
x25
->
interrupt_out_queue
,
skb
);
skb_queue_tail
(
&
x25
->
interrupt_out_queue
,
skb
);
}
else
{
else
{
len
=
x25_output
(
sk
,
skb
);
len
=
x25_output
(
sk
,
skb
);
if
(
len
<
0
){
if
(
len
<
0
)
kfree_skb
(
skb
);
kfree_skb
(
skb
);
}
else
{
else
if
(
x25
->
qbitincl
)
if
(
x25
->
qbitincl
)
len
++
;
len
++
;
}
}
}
/*
/*
* lock_sock() is currently only used to serialize this x25_kick()
* lock_sock() is currently only used to serialize this x25_kick()
...
@@ -1013,12 +1023,17 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
...
@@ -1013,12 +1023,17 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
lock_sock
(
sk
);
lock_sock
(
sk
);
x25_kick
(
sk
);
x25_kick
(
sk
);
release_sock
(
sk
);
release_sock
(
sk
);
rc
=
len
;
return
len
;
out:
return
rc
;
out_kfree_skb:
kfree_skb
(
skb
);
goto
out
;
}
}
static
int
x25_recvmsg
(
struct
socket
*
sock
,
struct
msghdr
*
msg
,
int
size
,
int
flags
,
struct
scm_cookie
*
scm
)
static
int
x25_recvmsg
(
struct
socket
*
sock
,
struct
msghdr
*
msg
,
int
size
,
int
flags
,
struct
scm_cookie
*
scm
)
{
{
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
sk
=
sock
->
sk
;
x25_cb
*
x25
=
x25_sk
(
sk
);
x25_cb
*
x25
=
x25_sk
(
sk
);
...
@@ -1026,18 +1041,19 @@ static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int fl
...
@@ -1026,18 +1041,19 @@ static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int fl
int
copied
,
qbit
;
int
copied
,
qbit
;
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
unsigned
char
*
asmptr
;
unsigned
char
*
asmptr
;
int
er
;
int
rc
=
-
ENOTCONN
;
/*
/*
* This works for seqpacket too. The receiver has ordered the queue for
* This works for seqpacket too. The receiver has ordered the queue for
* us! We do one quick check first though
* us! We do one quick check first though
*/
*/
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
if
(
sk
->
state
!=
TCP_ESTABLISHED
)
return
-
ENOTCONN
;
goto
out
;
if
(
flags
&
MSG_OOB
)
{
if
(
flags
&
MSG_OOB
)
{
rc
=
-
EINVAL
;
if
(
sk
->
urginline
||
!
skb_peek
(
&
x25
->
interrupt_in_queue
))
if
(
sk
->
urginline
||
!
skb_peek
(
&
x25
->
interrupt_in_queue
))
return
-
EINVAL
;
goto
out
;
skb
=
skb_dequeue
(
&
x25
->
interrupt_in_queue
);
skb
=
skb_dequeue
(
&
x25
->
interrupt_in_queue
);
...
@@ -1054,8 +1070,9 @@ static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int fl
...
@@ -1054,8 +1070,9 @@ static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int fl
msg
->
msg_flags
|=
MSG_OOB
;
msg
->
msg_flags
|=
MSG_OOB
;
}
else
{
}
else
{
/* Now we can treat all alike */
/* Now we can treat all alike */
if
((
skb
=
skb_recv_datagram
(
sk
,
flags
&
~
MSG_DONTWAIT
,
flags
&
MSG_DONTWAIT
,
&
er
))
==
NULL
)
skb
=
skb_recv_datagram
(
sk
,
flags
&
~
MSG_DONTWAIT
,
flags
&
MSG_DONTWAIT
,
&
rc
);
return
er
;
if
(
!
skb
)
goto
out
;
qbit
=
(
skb
->
data
[
0
]
&
X25_Q_BIT
)
==
X25_Q_BIT
;
qbit
=
(
skb
->
data
[
0
]
&
X25_Q_BIT
)
==
X25_Q_BIT
;
...
@@ -1080,21 +1097,25 @@ static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int fl
...
@@ -1080,21 +1097,25 @@ static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int fl
/* Currently, each datagram always contains a complete record */
/* Currently, each datagram always contains a complete record */
msg
->
msg_flags
|=
MSG_EOR
;
msg
->
msg_flags
|=
MSG_EOR
;
skb_copy_datagram_iovec
(
skb
,
0
,
msg
->
msg_iov
,
copied
);
rc
=
skb_copy_datagram_iovec
(
skb
,
0
,
msg
->
msg_iov
,
copied
);
if
(
rc
)
goto
out_free_dgram
;
if
(
sx25
!=
NULL
)
{
if
(
sx25
)
{
sx25
->
sx25_family
=
AF_X25
;
sx25
->
sx25_family
=
AF_X25
;
sx25
->
sx25_addr
=
x25
->
dest_addr
;
sx25
->
sx25_addr
=
x25
->
dest_addr
;
}
}
msg
->
msg_namelen
=
sizeof
(
struct
sockaddr_x25
);
msg
->
msg_namelen
=
sizeof
(
struct
sockaddr_x25
);
skb_free_datagram
(
sk
,
skb
);
lock_sock
(
sk
);
lock_sock
(
sk
);
x25_check_rbuf
(
sk
);
x25_check_rbuf
(
sk
);
release_sock
(
sk
);
release_sock
(
sk
);
rc
=
copied
;
return
copied
;
out_free_dgram:
skb_free_datagram
(
sk
,
skb
);
out:
return
rc
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment