Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
C
criu
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zhul
criu
Commits
518361dc
Commit
518361dc
authored
Apr 26, 2012
by
Pavel Emelyanov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sk: Move inet socket code to separate file
Signed-off-by:
Pavel Emelyanov
<
xemul@parallels.com
>
parent
8cd64c5a
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
379 additions
and
353 deletions
+379
-353
Makefile
Makefile
+1
-0
sockets.h
include/sockets.h
+17
-0
sk-inet.c
sk-inet.c
+356
-0
sockets.c
sockets.c
+5
-353
No files found.
Makefile
View file @
518361dc
...
@@ -39,6 +39,7 @@ OBJS += rbtree.o
...
@@ -39,6 +39,7 @@ OBJS += rbtree.o
OBJS
+=
log.o
OBJS
+=
log.o
OBJS
+=
libnetlink.o
OBJS
+=
libnetlink.o
OBJS
+=
sockets.o
OBJS
+=
sockets.o
OBJS
+=
sk-inet.o
OBJS
+=
sk-queue.o
OBJS
+=
sk-queue.o
OBJS
+=
files.o
OBJS
+=
files.o
OBJS
+=
pipes.o
OBJS
+=
pipes.o
...
...
include/sockets.h
View file @
518361dc
...
@@ -24,4 +24,21 @@ extern void show_unixsk(int fd, struct cr_options *);
...
@@ -24,4 +24,21 @@ extern void show_unixsk(int fd, struct cr_options *);
extern
void
show_inetsk
(
int
fd
,
struct
cr_options
*
);
extern
void
show_inetsk
(
int
fd
,
struct
cr_options
*
);
extern
void
show_sk_queues
(
int
fd
,
struct
cr_options
*
);
extern
void
show_sk_queues
(
int
fd
,
struct
cr_options
*
);
char
*
skfamily2s
(
u32
f
);
char
*
sktype2s
(
u32
t
);
char
*
skproto2s
(
u32
p
);
char
*
skstate2s
(
u32
state
);
struct
socket_desc
{
unsigned
int
family
;
unsigned
int
ino
;
struct
socket_desc
*
next
;
int
already_dumped
;
};
int
sk_collect_one
(
int
ino
,
int
family
,
struct
socket_desc
*
d
);
int
dump_one_inet
(
struct
socket_desc
*
_sk
,
struct
fd_parms
*
p
,
const
struct
cr_fdset
*
cr_fdset
);
struct
nlmsghdr
;
int
inet_collect_one
(
struct
nlmsghdr
*
h
,
int
family
,
int
type
,
int
proto
);
#endif
/* CR_SOCKETS_H__ */
#endif
/* CR_SOCKETS_H__ */
sk-inet.c
0 → 100644
View file @
518361dc
#include <sys/socket.h>
#include <linux/netlink.h>
#include <unistd.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include "types.h"
#include "libnetlink.h"
#include "crtools.h"
#include "inet_diag.h"
#include "files.h"
#include "image.h"
#include "log.h"
#include "util.h"
#include "sockets.h"
#define INET_ADDR_LEN 40
struct
inet_sk_desc
{
struct
socket_desc
sd
;
unsigned
int
type
;
unsigned
int
proto
;
unsigned
int
src_port
;
unsigned
int
dst_port
;
unsigned
int
state
;
unsigned
int
rqlen
;
unsigned
int
wqlen
;
unsigned
int
src_addr
[
4
];
unsigned
int
dst_addr
[
4
];
};
static
void
show_one_inet
(
const
char
*
act
,
const
struct
inet_sk_desc
*
sk
)
{
char
src_addr
[
INET_ADDR_LEN
]
=
"<unknown>"
;
if
(
inet_ntop
(
sk
->
sd
.
family
,
(
void
*
)
sk
->
src_addr
,
src_addr
,
INET_ADDR_LEN
)
==
NULL
)
{
pr_perror
(
"Failed to translate address"
);
}
pr_debug
(
"
\t
%s: ino 0x%8x family %4d type %4d port %8d "
"state %2d src_addr %s
\n
"
,
act
,
sk
->
sd
.
ino
,
sk
->
sd
.
family
,
sk
->
type
,
sk
->
src_port
,
sk
->
state
,
src_addr
);
}
static
void
show_one_inet_img
(
const
char
*
act
,
const
struct
inet_sk_entry
*
e
)
{
char
src_addr
[
INET_ADDR_LEN
]
=
"<unknown>"
;
if
(
inet_ntop
(
e
->
family
,
(
void
*
)
e
->
src_addr
,
src_addr
,
INET_ADDR_LEN
)
==
NULL
)
{
pr_perror
(
"Failed to translate address"
);
}
pr_debug
(
"
\t
%s: family %d type %d proto %d port %d "
"state %d src_addr %s
\n
"
,
act
,
e
->
family
,
e
->
type
,
e
->
proto
,
e
->
src_port
,
e
->
state
,
src_addr
);
}
static
int
can_dump_inet_sk
(
const
struct
inet_sk_desc
*
sk
)
{
if
(
sk
->
sd
.
family
!=
AF_INET
&&
sk
->
sd
.
family
!=
AF_INET6
)
{
pr_err
(
"Only IPv4/6 sockets for now
\n
"
);
return
0
;
}
if
(
sk
->
type
==
SOCK_DGRAM
)
return
1
;
if
(
sk
->
type
!=
SOCK_STREAM
)
{
pr_err
(
"Only stream and dgram inet sockets for now
\n
"
);
return
0
;
}
switch
(
sk
->
state
)
{
case
TCP_LISTEN
:
if
(
sk
->
rqlen
!=
0
)
{
/*
* Currently the ICONS nla reports the conn
* requests for listen sockets. Need to pick
* those up and fix the connect job respectively
*/
pr_err
(
"In-flight connection (l)
\n
"
);
return
0
;
}
break
;
default:
pr_err
(
"Unknown state %d
\n
"
,
sk
->
state
);
return
0
;
}
return
1
;
}
int
dump_one_inet
(
struct
socket_desc
*
_sk
,
struct
fd_parms
*
p
,
const
struct
cr_fdset
*
cr_fdset
)
{
struct
inet_sk_desc
*
sk
=
(
struct
inet_sk_desc
*
)
_sk
;
struct
inet_sk_entry
ie
;
struct
fdinfo_entry
fe
;
if
(
!
can_dump_inet_sk
(
sk
))
goto
err
;
fe
.
fd
=
p
->
fd
;
fe
.
type
=
FDINFO_INETSK
;
fe
.
id
=
sk
->
sd
.
ino
;
fe
.
flags
=
p
->
fd_flags
;
if
(
write_img
(
fdset_fd
(
cr_fdset
,
CR_FD_FDINFO
),
&
fe
))
goto
err
;
if
(
sk
->
sd
.
already_dumped
)
return
0
;
memset
(
&
ie
,
0
,
sizeof
(
ie
));
ie
.
id
=
sk
->
sd
.
ino
;
ie
.
family
=
sk
->
sd
.
family
;
ie
.
type
=
sk
->
type
;
ie
.
proto
=
sk
->
proto
;
ie
.
state
=
sk
->
state
;
ie
.
src_port
=
sk
->
src_port
;
ie
.
dst_port
=
sk
->
dst_port
;
ie
.
backlog
=
sk
->
wqlen
;
ie
.
flags
=
p
->
flags
;
ie
.
fown
=
p
->
fown
;
memcpy
(
ie
.
src_addr
,
sk
->
src_addr
,
sizeof
(
u32
)
*
4
);
memcpy
(
ie
.
dst_addr
,
sk
->
dst_addr
,
sizeof
(
u32
)
*
4
);
if
(
write_img
(
fdset_fd
(
glob_fdset
,
CR_FD_INETSK
),
&
ie
))
goto
err
;
pr_info
(
"Dumping inet socket at %d
\n
"
,
p
->
fd
);
show_one_inet
(
"Dumping"
,
sk
);
show_one_inet_img
(
"Dumped"
,
&
ie
);
sk
->
sd
.
already_dumped
=
1
;
return
0
;
err:
return
-
1
;
}
int
inet_collect_one
(
struct
nlmsghdr
*
h
,
int
family
,
int
type
,
int
proto
)
{
struct
inet_sk_desc
*
d
;
struct
inet_diag_msg
*
m
=
NLMSG_DATA
(
h
);
struct
rtattr
*
tb
[
INET_DIAG_MAX
+
1
];
int
ret
;
parse_rtattr
(
tb
,
INET_DIAG_MAX
,
(
struct
rtattr
*
)(
m
+
1
),
h
->
nlmsg_len
-
NLMSG_LENGTH
(
sizeof
(
*
m
)));
d
=
xzalloc
(
sizeof
(
*
d
));
if
(
!
d
)
return
-
1
;
d
->
type
=
type
;
d
->
proto
=
proto
;
d
->
src_port
=
ntohs
(
m
->
id
.
idiag_sport
);
d
->
dst_port
=
ntohs
(
m
->
id
.
idiag_dport
);
d
->
state
=
m
->
idiag_state
;
d
->
rqlen
=
m
->
idiag_rqueue
;
d
->
wqlen
=
m
->
idiag_wqueue
;
memcpy
(
d
->
src_addr
,
m
->
id
.
idiag_src
,
sizeof
(
u32
)
*
4
);
memcpy
(
d
->
dst_addr
,
m
->
id
.
idiag_dst
,
sizeof
(
u32
)
*
4
);
ret
=
sk_collect_one
(
m
->
idiag_inode
,
family
,
&
d
->
sd
);
show_one_inet
(
"Collected"
,
d
);
return
ret
;
}
struct
inet_sk_info
{
struct
inet_sk_entry
ie
;
struct
file_desc
d
;
};
static
int
open_inet_sk
(
struct
file_desc
*
d
);
static
struct
file_desc_ops
inet_desc_ops
=
{
.
open
=
open_inet_sk
,
};
int
collect_inet_sockets
(
void
)
{
struct
inet_sk_info
*
ii
=
NULL
;
int
fd
,
ret
=
-
1
;
fd
=
open_image_ro
(
CR_FD_INETSK
);
if
(
fd
<
0
)
return
-
1
;
while
(
1
)
{
ii
=
xmalloc
(
sizeof
(
*
ii
));
ret
=
-
1
;
if
(
!
ii
)
break
;
ret
=
read_img_eof
(
fd
,
&
ii
->
ie
);
if
(
ret
<=
0
)
break
;
file_desc_add
(
&
ii
->
d
,
FDINFO_INETSK
,
ii
->
ie
.
id
,
&
inet_desc_ops
);
}
if
(
ii
)
xfree
(
ii
);
close
(
fd
);
return
0
;
}
static
int
open_inet_sk
(
struct
file_desc
*
d
)
{
union
{
struct
sockaddr_in
v4
;
struct
sockaddr_in6
v6
;
}
addr
;
struct
inet_sk_info
*
ii
;
int
sk
,
addr_size
;
ii
=
container_of
(
d
,
struct
inet_sk_info
,
d
);
show_one_inet_img
(
"Restore"
,
&
ii
->
ie
);
if
(
ii
->
ie
.
family
!=
AF_INET
&&
ii
->
ie
.
family
!=
AF_INET6
)
{
pr_err
(
"Unsupported socket family: %d
\n
"
,
ii
->
ie
.
family
);
return
-
1
;
}
if
((
ii
->
ie
.
type
!=
SOCK_STREAM
)
&&
(
ii
->
ie
.
type
!=
SOCK_DGRAM
))
{
pr_err
(
"Unsupported socket type: %d
\n
"
,
ii
->
ie
.
type
);
return
-
1
;
}
sk
=
socket
(
ii
->
ie
.
family
,
ii
->
ie
.
type
,
ii
->
ie
.
proto
);
if
(
sk
<
0
)
{
pr_perror
(
"Can't create unix socket"
);
return
-
1
;
}
/*
* Listen sockets are easiest ones -- simply
* bind() and listen(), and that's all.
*/
memzero
(
&
addr
,
sizeof
(
addr
));
if
(
ii
->
ie
.
family
==
AF_INET
)
{
addr
.
v4
.
sin_family
=
ii
->
ie
.
family
;
addr
.
v4
.
sin_port
=
htons
(
ii
->
ie
.
src_port
);
memcpy
(
&
addr
.
v4
.
sin_addr
.
s_addr
,
ii
->
ie
.
src_addr
,
sizeof
(
ii
->
ie
.
src_addr
));
addr_size
=
sizeof
(
addr
.
v4
);
}
else
if
(
ii
->
ie
.
family
==
AF_INET6
)
{
addr
.
v6
.
sin6_family
=
ii
->
ie
.
family
;
addr
.
v6
.
sin6_port
=
htons
(
ii
->
ie
.
src_port
);
memcpy
(
&
addr
.
v6
.
sin6_addr
.
s6_addr
,
ii
->
ie
.
src_addr
,
sizeof
(
ii
->
ie
.
src_addr
));
addr_size
=
sizeof
(
addr
.
v6
);
}
else
BUG_ON
(
1
);
if
(
bind
(
sk
,
(
struct
sockaddr
*
)
&
addr
,
addr_size
)
==
-
1
)
{
pr_perror
(
"Can't bind to a socket"
);
goto
err
;
}
if
(
ii
->
ie
.
state
==
TCP_LISTEN
)
{
if
(
ii
->
ie
.
proto
!=
IPPROTO_TCP
)
{
pr_err
(
"Wrong socket in listen state %d
\n
"
,
ii
->
ie
.
proto
);
goto
err
;
}
if
(
listen
(
sk
,
ii
->
ie
.
backlog
)
==
-
1
)
{
pr_perror
(
"Can't listen on a socket"
);
goto
err
;
}
}
if
(
ii
->
ie
.
state
==
TCP_ESTABLISHED
)
{
if
(
ii
->
ie
.
proto
==
IPPROTO_TCP
)
{
pr_err
(
"Connected TCP socket in image
\n
"
);
goto
err
;
}
memzero
(
&
addr
,
sizeof
(
addr
));
if
(
ii
->
ie
.
family
==
AF_INET
)
{
addr
.
v4
.
sin_family
=
ii
->
ie
.
family
;
addr
.
v4
.
sin_port
=
htons
(
ii
->
ie
.
dst_port
);
memcpy
(
&
addr
.
v4
.
sin_addr
.
s_addr
,
ii
->
ie
.
dst_addr
,
sizeof
(
ii
->
ie
.
dst_addr
));
addr_size
=
sizeof
(
addr
.
v4
);
}
else
if
(
ii
->
ie
.
family
==
AF_INET6
)
{
addr
.
v6
.
sin6_family
=
ii
->
ie
.
family
;
addr
.
v6
.
sin6_port
=
htons
(
ii
->
ie
.
dst_port
);
memcpy
(
&
addr
.
v6
.
sin6_addr
.
s6_addr
,
ii
->
ie
.
dst_addr
,
sizeof
(
ii
->
ie
.
dst_addr
));
addr_size
=
sizeof
(
addr
.
v6
);
}
else
BUG_ON
(
1
);
if
(
connect
(
sk
,
(
struct
sockaddr
*
)
&
addr
,
addr_size
)
==
-
1
)
{
pr_perror
(
"Can't connect UDP socket back"
);
goto
err
;
}
}
if
(
rst_file_params
(
sk
,
&
ii
->
ie
.
fown
,
ii
->
ie
.
flags
))
goto
err
;
return
sk
;
err:
close
(
sk
);
return
-
1
;
}
void
show_inetsk
(
int
fd
,
struct
cr_options
*
o
)
{
struct
inet_sk_entry
ie
;
int
ret
=
0
;
pr_img_head
(
CR_FD_INETSK
);
while
(
1
)
{
char
src_addr
[
INET_ADDR_LEN
]
=
"<unknown>"
;
char
dst_addr
[
INET_ADDR_LEN
]
=
"<unknown>"
;
ret
=
read_img_eof
(
fd
,
&
ie
);
if
(
ret
<=
0
)
goto
out
;
if
(
inet_ntop
(
ie
.
family
,
(
void
*
)
ie
.
src_addr
,
src_addr
,
INET_ADDR_LEN
)
==
NULL
)
{
pr_perror
(
"Failed to translate src address"
);
}
if
(
ie
.
state
==
TCP_ESTABLISHED
)
{
if
(
inet_ntop
(
ie
.
family
,
(
void
*
)
ie
.
dst_addr
,
dst_addr
,
INET_ADDR_LEN
)
==
NULL
)
{
pr_perror
(
"Failed to translate dst address"
);
}
}
pr_msg
(
"id %#x family %s type %s proto %s state %s %s:%d <-> %s:%d flags 0x%2x
\n
"
,
ie
.
id
,
skfamily2s
(
ie
.
family
),
sktype2s
(
ie
.
type
),
skproto2s
(
ie
.
proto
),
skstate2s
(
ie
.
state
),
src_addr
,
ie
.
src_port
,
dst_addr
,
ie
.
dst_port
,
ie
.
flags
);
pr_msg
(
"
\t
"
),
show_fown_cont
(
&
ie
.
fown
),
pr_msg
(
"
\n
"
);
}
out:
if
(
ret
)
pr_info
(
"
\n
"
);
pr_img_tail
(
CR_FD_INETSK
);
}
sockets.c
View file @
518361dc
...
@@ -10,7 +10,6 @@
...
@@ -10,7 +10,6 @@
#include <errno.h>
#include <errno.h>
#include <unistd.h>
#include <unistd.h>
#include <limits.h>
#include <limits.h>
#include <arpa/inet.h>
#include <sys/sendfile.h>
#include <sys/sendfile.h>
#include "types.h"
#include "types.h"
...
@@ -39,13 +38,6 @@ static char buf[4096];
...
@@ -39,13 +38,6 @@ static char buf[4096];
#define SOCKFS_MAGIC 0x534F434B
#define SOCKFS_MAGIC 0x534F434B
#endif
#endif
struct
socket_desc
{
unsigned
int
family
;
unsigned
int
ino
;
struct
socket_desc
*
next
;
int
already_dumped
;
};
struct
unix_sk_desc
{
struct
unix_sk_desc
{
struct
socket_desc
sd
;
struct
socket_desc
sd
;
unsigned
int
type
;
unsigned
int
type
;
...
@@ -68,21 +60,6 @@ struct unix_sk_listen_icon {
...
@@ -68,21 +60,6 @@ struct unix_sk_listen_icon {
struct
unix_sk_listen_icon
*
next
;
struct
unix_sk_listen_icon
*
next
;
};
};
#define INET_ADDR_LEN 40
struct
inet_sk_desc
{
struct
socket_desc
sd
;
unsigned
int
type
;
unsigned
int
proto
;
unsigned
int
src_port
;
unsigned
int
dst_port
;
unsigned
int
state
;
unsigned
int
rqlen
;
unsigned
int
wqlen
;
unsigned
int
src_addr
[
4
];
unsigned
int
dst_addr
[
4
];
};
#define SK_HASH_SIZE 32
#define SK_HASH_SIZE 32
#define SK_HASH_LINK(head, key, elem) \
#define SK_HASH_LINK(head, key, elem) \
do { \
do { \
...
@@ -110,7 +87,7 @@ __gen_static_lookup_func(struct unix_sk_listen_icon,
...
@@ -110,7 +87,7 @@ __gen_static_lookup_func(struct unix_sk_listen_icon,
unix_listen_icons
,
unix_listen_icons
,
peer_ino
,
unsigned
int
,
ino
);
peer_ino
,
unsigned
int
,
ino
);
static
int
sk_collect_one
(
int
ino
,
int
family
,
struct
socket_desc
*
d
)
int
sk_collect_one
(
int
ino
,
int
family
,
struct
socket_desc
*
d
)
{
{
d
->
ino
=
ino
;
d
->
ino
=
ino
;
d
->
family
=
family
;
d
->
family
=
family
;
...
@@ -120,36 +97,6 @@ static int sk_collect_one(int ino, int family, struct socket_desc *d)
...
@@ -120,36 +97,6 @@ static int sk_collect_one(int ino, int family, struct socket_desc *d)
return
0
;
return
0
;
}
}
static
void
show_one_inet
(
const
char
*
act
,
const
struct
inet_sk_desc
*
sk
)
{
char
src_addr
[
INET_ADDR_LEN
]
=
"<unknown>"
;
if
(
inet_ntop
(
sk
->
sd
.
family
,
(
void
*
)
sk
->
src_addr
,
src_addr
,
INET_ADDR_LEN
)
==
NULL
)
{
pr_perror
(
"Failed to translate address"
);
}
pr_debug
(
"
\t
%s: ino 0x%8x family %4d type %4d port %8d "
"state %2d src_addr %s
\n
"
,
act
,
sk
->
sd
.
ino
,
sk
->
sd
.
family
,
sk
->
type
,
sk
->
src_port
,
sk
->
state
,
src_addr
);
}
static
void
show_one_inet_img
(
const
char
*
act
,
const
struct
inet_sk_entry
*
e
)
{
char
src_addr
[
INET_ADDR_LEN
]
=
"<unknown>"
;
if
(
inet_ntop
(
e
->
family
,
(
void
*
)
e
->
src_addr
,
src_addr
,
INET_ADDR_LEN
)
==
NULL
)
{
pr_perror
(
"Failed to translate address"
);
}
pr_debug
(
"
\t
%s: family %d type %d proto %d port %d "
"state %d src_addr %s
\n
"
,
act
,
e
->
family
,
e
->
type
,
e
->
proto
,
e
->
src_port
,
e
->
state
,
src_addr
);
}
static
void
show_one_unix
(
char
*
act
,
const
struct
unix_sk_desc
*
sk
)
static
void
show_one_unix
(
char
*
act
,
const
struct
unix_sk_desc
*
sk
)
{
{
pr_debug
(
"
\t
%s: ino 0x%8x family %4d type %4d state %2d name %s
\n
"
,
pr_debug
(
"
\t
%s: ino 0x%8x family %4d type %4d state %2d name %s
\n
"
,
...
@@ -169,90 +116,6 @@ static void show_one_unix_img(const char *act, const struct unix_sk_entry *e)
...
@@ -169,90 +116,6 @@ static void show_one_unix_img(const char *act, const struct unix_sk_entry *e)
act
,
e
->
id
,
e
->
type
,
e
->
state
,
e
->
namelen
);
act
,
e
->
id
,
e
->
type
,
e
->
state
,
e
->
namelen
);
}
}
static
int
can_dump_inet_sk
(
const
struct
inet_sk_desc
*
sk
)
{
if
(
sk
->
sd
.
family
!=
AF_INET
&&
sk
->
sd
.
family
!=
AF_INET6
)
{
pr_err
(
"Only IPv4/6 sockets for now
\n
"
);
return
0
;
}
if
(
sk
->
type
==
SOCK_DGRAM
)
return
1
;
if
(
sk
->
type
!=
SOCK_STREAM
)
{
pr_err
(
"Only stream and dgram inet sockets for now
\n
"
);
return
0
;
}
switch
(
sk
->
state
)
{
case
TCP_LISTEN
:
if
(
sk
->
rqlen
!=
0
)
{
/*
* Currently the ICONS nla reports the conn
* requests for listen sockets. Need to pick
* those up and fix the connect job respectively
*/
pr_err
(
"In-flight connection (l)
\n
"
);
return
0
;
}
break
;
default:
pr_err
(
"Unknown state %d
\n
"
,
sk
->
state
);
return
0
;
}
return
1
;
}
static
int
dump_one_inet
(
struct
socket_desc
*
_sk
,
struct
fd_parms
*
p
,
const
struct
cr_fdset
*
cr_fdset
)
{
struct
inet_sk_desc
*
sk
=
(
struct
inet_sk_desc
*
)
_sk
;
struct
inet_sk_entry
ie
;
struct
fdinfo_entry
fe
;
if
(
!
can_dump_inet_sk
(
sk
))
goto
err
;
fe
.
fd
=
p
->
fd
;
fe
.
type
=
FDINFO_INETSK
;
fe
.
id
=
sk
->
sd
.
ino
;
fe
.
flags
=
p
->
fd_flags
;
if
(
write_img
(
fdset_fd
(
cr_fdset
,
CR_FD_FDINFO
),
&
fe
))
goto
err
;
if
(
sk
->
sd
.
already_dumped
)
return
0
;
memset
(
&
ie
,
0
,
sizeof
(
ie
));
ie
.
id
=
sk
->
sd
.
ino
;
ie
.
family
=
sk
->
sd
.
family
;
ie
.
type
=
sk
->
type
;
ie
.
proto
=
sk
->
proto
;
ie
.
state
=
sk
->
state
;
ie
.
src_port
=
sk
->
src_port
;
ie
.
dst_port
=
sk
->
dst_port
;
ie
.
backlog
=
sk
->
wqlen
;
ie
.
flags
=
p
->
flags
;
ie
.
fown
=
p
->
fown
;
memcpy
(
ie
.
src_addr
,
sk
->
src_addr
,
sizeof
(
u32
)
*
4
);
memcpy
(
ie
.
dst_addr
,
sk
->
dst_addr
,
sizeof
(
u32
)
*
4
);
if
(
write_img
(
fdset_fd
(
glob_fdset
,
CR_FD_INETSK
),
&
ie
))
goto
err
;
pr_info
(
"Dumping inet socket at %d
\n
"
,
p
->
fd
);
show_one_inet
(
"Dumping"
,
sk
);
show_one_inet_img
(
"Dumped"
,
&
ie
);
sk
->
sd
.
already_dumped
=
1
;
return
0
;
err:
return
-
1
;
}
static
int
can_dump_unix_sk
(
const
struct
unix_sk_desc
*
sk
)
static
int
can_dump_unix_sk
(
const
struct
unix_sk_desc
*
sk
)
{
{
if
(
sk
->
type
!=
SOCK_STREAM
&&
if
(
sk
->
type
!=
SOCK_STREAM
&&
...
@@ -414,37 +277,6 @@ int dump_socket(struct fd_parms *p, int lfd, const struct cr_fdset *cr_fdset)
...
@@ -414,37 +277,6 @@ int dump_socket(struct fd_parms *p, int lfd, const struct cr_fdset *cr_fdset)
return
-
1
;
return
-
1
;
}
}
static
int
inet_collect_one
(
struct
nlmsghdr
*
h
,
int
family
,
int
type
,
int
proto
)
{
struct
inet_sk_desc
*
d
;
struct
inet_diag_msg
*
m
=
NLMSG_DATA
(
h
);
struct
rtattr
*
tb
[
INET_DIAG_MAX
+
1
];
int
ret
;
parse_rtattr
(
tb
,
INET_DIAG_MAX
,
(
struct
rtattr
*
)(
m
+
1
),
h
->
nlmsg_len
-
NLMSG_LENGTH
(
sizeof
(
*
m
)));
d
=
xzalloc
(
sizeof
(
*
d
));
if
(
!
d
)
return
-
1
;
d
->
type
=
type
;
d
->
proto
=
proto
;
d
->
src_port
=
ntohs
(
m
->
id
.
idiag_sport
);
d
->
dst_port
=
ntohs
(
m
->
id
.
idiag_dport
);
d
->
state
=
m
->
idiag_state
;
d
->
rqlen
=
m
->
idiag_rqueue
;
d
->
wqlen
=
m
->
idiag_wqueue
;
memcpy
(
d
->
src_addr
,
m
->
id
.
idiag_src
,
sizeof
(
u32
)
*
4
);
memcpy
(
d
->
dst_addr
,
m
->
id
.
idiag_dst
,
sizeof
(
u32
)
*
4
);
ret
=
sk_collect_one
(
m
->
idiag_inode
,
family
,
&
d
->
sd
);
show_one_inet
(
"Collected"
,
d
);
return
ret
;
}
static
int
inet_tcp_receive_one
(
struct
nlmsghdr
*
h
)
static
int
inet_tcp_receive_one
(
struct
nlmsghdr
*
h
)
{
{
return
inet_collect_one
(
h
,
AF_INET
,
SOCK_STREAM
,
IPPROTO_TCP
);
return
inet_collect_one
(
h
,
AF_INET
,
SOCK_STREAM
,
IPPROTO_TCP
);
...
@@ -838,147 +670,6 @@ static struct unix_sk_info *find_unix_sk(int id)
...
@@ -838,147 +670,6 @@ static struct unix_sk_info *find_unix_sk(int id)
return
NULL
;
return
NULL
;
}
}
struct
inet_sk_info
{
struct
inet_sk_entry
ie
;
struct
file_desc
d
;
};
static
int
open_inet_sk
(
struct
file_desc
*
d
);
static
struct
file_desc_ops
inet_desc_ops
=
{
.
open
=
open_inet_sk
,
};
int
collect_inet_sockets
(
void
)
{
struct
inet_sk_info
*
ii
=
NULL
;
int
fd
,
ret
=
-
1
;
fd
=
open_image_ro
(
CR_FD_INETSK
);
if
(
fd
<
0
)
return
-
1
;
while
(
1
)
{
ii
=
xmalloc
(
sizeof
(
*
ii
));
ret
=
-
1
;
if
(
!
ii
)
break
;
ret
=
read_img_eof
(
fd
,
&
ii
->
ie
);
if
(
ret
<=
0
)
break
;
file_desc_add
(
&
ii
->
d
,
FDINFO_INETSK
,
ii
->
ie
.
id
,
&
inet_desc_ops
);
}
if
(
ii
)
xfree
(
ii
);
close
(
fd
);
return
0
;
}
static
int
open_inet_sk
(
struct
file_desc
*
d
)
{
union
{
struct
sockaddr_in
v4
;
struct
sockaddr_in6
v6
;
}
addr
;
struct
inet_sk_info
*
ii
;
int
sk
,
addr_size
;
ii
=
container_of
(
d
,
struct
inet_sk_info
,
d
);
show_one_inet_img
(
"Restore"
,
&
ii
->
ie
);
if
(
ii
->
ie
.
family
!=
AF_INET
&&
ii
->
ie
.
family
!=
AF_INET6
)
{
pr_err
(
"Unsupported socket family: %d
\n
"
,
ii
->
ie
.
family
);
return
-
1
;
}
if
((
ii
->
ie
.
type
!=
SOCK_STREAM
)
&&
(
ii
->
ie
.
type
!=
SOCK_DGRAM
))
{
pr_err
(
"Unsupported socket type: %d
\n
"
,
ii
->
ie
.
type
);
return
-
1
;
}
sk
=
socket
(
ii
->
ie
.
family
,
ii
->
ie
.
type
,
ii
->
ie
.
proto
);
if
(
sk
<
0
)
{
pr_perror
(
"Can't create unix socket"
);
return
-
1
;
}
/*
* Listen sockets are easiest ones -- simply
* bind() and listen(), and that's all.
*/
memzero
(
&
addr
,
sizeof
(
addr
));
if
(
ii
->
ie
.
family
==
AF_INET
)
{
addr
.
v4
.
sin_family
=
ii
->
ie
.
family
;
addr
.
v4
.
sin_port
=
htons
(
ii
->
ie
.
src_port
);
memcpy
(
&
addr
.
v4
.
sin_addr
.
s_addr
,
ii
->
ie
.
src_addr
,
sizeof
(
ii
->
ie
.
src_addr
));
addr_size
=
sizeof
(
addr
.
v4
);
}
else
if
(
ii
->
ie
.
family
==
AF_INET6
)
{
addr
.
v6
.
sin6_family
=
ii
->
ie
.
family
;
addr
.
v6
.
sin6_port
=
htons
(
ii
->
ie
.
src_port
);
memcpy
(
&
addr
.
v6
.
sin6_addr
.
s6_addr
,
ii
->
ie
.
src_addr
,
sizeof
(
ii
->
ie
.
src_addr
));
addr_size
=
sizeof
(
addr
.
v6
);
}
else
BUG_ON
(
1
);
if
(
bind
(
sk
,
(
struct
sockaddr
*
)
&
addr
,
addr_size
)
==
-
1
)
{
pr_perror
(
"Can't bind to a socket"
);
goto
err
;
}
if
(
ii
->
ie
.
state
==
TCP_LISTEN
)
{
if
(
ii
->
ie
.
proto
!=
IPPROTO_TCP
)
{
pr_err
(
"Wrong socket in listen state %d
\n
"
,
ii
->
ie
.
proto
);
goto
err
;
}
if
(
listen
(
sk
,
ii
->
ie
.
backlog
)
==
-
1
)
{
pr_perror
(
"Can't listen on a socket"
);
goto
err
;
}
}
if
(
ii
->
ie
.
state
==
TCP_ESTABLISHED
)
{
if
(
ii
->
ie
.
proto
==
IPPROTO_TCP
)
{
pr_err
(
"Connected TCP socket in image
\n
"
);
goto
err
;
}
memzero
(
&
addr
,
sizeof
(
addr
));
if
(
ii
->
ie
.
family
==
AF_INET
)
{
addr
.
v4
.
sin_family
=
ii
->
ie
.
family
;
addr
.
v4
.
sin_port
=
htons
(
ii
->
ie
.
dst_port
);
memcpy
(
&
addr
.
v4
.
sin_addr
.
s_addr
,
ii
->
ie
.
dst_addr
,
sizeof
(
ii
->
ie
.
dst_addr
));
addr_size
=
sizeof
(
addr
.
v4
);
}
else
if
(
ii
->
ie
.
family
==
AF_INET6
)
{
addr
.
v6
.
sin6_family
=
ii
->
ie
.
family
;
addr
.
v6
.
sin6_port
=
htons
(
ii
->
ie
.
dst_port
);
memcpy
(
&
addr
.
v6
.
sin6_addr
.
s6_addr
,
ii
->
ie
.
dst_addr
,
sizeof
(
ii
->
ie
.
dst_addr
));
addr_size
=
sizeof
(
addr
.
v6
);
}
else
BUG_ON
(
1
);
if
(
connect
(
sk
,
(
struct
sockaddr
*
)
&
addr
,
addr_size
)
==
-
1
)
{
pr_perror
(
"Can't connect UDP socket back"
);
goto
err
;
}
}
if
(
rst_file_params
(
sk
,
&
ii
->
ie
.
fown
,
ii
->
ie
.
flags
))
goto
err
;
return
sk
;
err:
close
(
sk
);
return
-
1
;
}
static
inline
char
*
unknown
(
u32
val
)
static
inline
char
*
unknown
(
u32
val
)
{
{
static
char
unk
[
12
];
static
char
unk
[
12
];
...
@@ -986,7 +677,7 @@ static inline char *unknown(u32 val)
...
@@ -986,7 +677,7 @@ static inline char *unknown(u32 val)
return
unk
;
return
unk
;
}
}
static
inline
char
*
skfamily2s
(
u32
f
)
char
*
skfamily2s
(
u32
f
)
{
{
if
(
f
==
AF_INET
)
if
(
f
==
AF_INET
)
return
" inet"
;
return
" inet"
;
...
@@ -996,7 +687,7 @@ static inline char *skfamily2s(u32 f)
...
@@ -996,7 +687,7 @@ static inline char *skfamily2s(u32 f)
return
unknown
(
f
);
return
unknown
(
f
);
}
}
static
inline
char
*
sktype2s
(
u32
t
)
char
*
sktype2s
(
u32
t
)
{
{
if
(
t
==
SOCK_STREAM
)
if
(
t
==
SOCK_STREAM
)
return
"stream"
;
return
"stream"
;
...
@@ -1006,7 +697,7 @@ static inline char *sktype2s(u32 t)
...
@@ -1006,7 +697,7 @@ static inline char *sktype2s(u32 t)
return
unknown
(
t
);
return
unknown
(
t
);
}
}
static
inline
char
*
skproto2s
(
u32
p
)
char
*
skproto2s
(
u32
p
)
{
{
if
(
p
==
IPPROTO_UDP
)
if
(
p
==
IPPROTO_UDP
)
return
"udp"
;
return
"udp"
;
...
@@ -1018,7 +709,7 @@ static inline char *skproto2s(u32 p)
...
@@ -1018,7 +709,7 @@ static inline char *skproto2s(u32 p)
return
unknown
(
p
);
return
unknown
(
p
);
}
}
static
inline
char
*
skstate2s
(
u32
state
)
char
*
skstate2s
(
u32
state
)
{
{
if
(
state
==
TCP_ESTABLISHED
)
if
(
state
==
TCP_ESTABLISHED
)
return
" estab"
;
return
" estab"
;
...
@@ -1030,45 +721,6 @@ static inline char *skstate2s(u32 state)
...
@@ -1030,45 +721,6 @@ static inline char *skstate2s(u32 state)
return
unknown
(
state
);
return
unknown
(
state
);
}
}
void
show_inetsk
(
int
fd
,
struct
cr_options
*
o
)
{
struct
inet_sk_entry
ie
;
int
ret
=
0
;
pr_img_head
(
CR_FD_INETSK
);
while
(
1
)
{
char
src_addr
[
INET_ADDR_LEN
]
=
"<unknown>"
;
char
dst_addr
[
INET_ADDR_LEN
]
=
"<unknown>"
;
ret
=
read_img_eof
(
fd
,
&
ie
);
if
(
ret
<=
0
)
goto
out
;
if
(
inet_ntop
(
ie
.
family
,
(
void
*
)
ie
.
src_addr
,
src_addr
,
INET_ADDR_LEN
)
==
NULL
)
{
pr_perror
(
"Failed to translate src address"
);
}
if
(
ie
.
state
==
TCP_ESTABLISHED
)
{
if
(
inet_ntop
(
ie
.
family
,
(
void
*
)
ie
.
dst_addr
,
dst_addr
,
INET_ADDR_LEN
)
==
NULL
)
{
pr_perror
(
"Failed to translate dst address"
);
}
}
pr_msg
(
"id %#x family %s type %s proto %s state %s %s:%d <-> %s:%d flags 0x%2x
\n
"
,
ie
.
id
,
skfamily2s
(
ie
.
family
),
sktype2s
(
ie
.
type
),
skproto2s
(
ie
.
proto
),
skstate2s
(
ie
.
state
),
src_addr
,
ie
.
src_port
,
dst_addr
,
ie
.
dst_port
,
ie
.
flags
);
pr_msg
(
"
\t
"
),
show_fown_cont
(
&
ie
.
fown
),
pr_msg
(
"
\n
"
);
}
out:
if
(
ret
)
pr_info
(
"
\n
"
);
pr_img_tail
(
CR_FD_INETSK
);
}
void
show_unixsk
(
int
fd
,
struct
cr_options
*
o
)
void
show_unixsk
(
int
fd
,
struct
cr_options
*
o
)
{
{
struct
unix_sk_entry
ue
;
struct
unix_sk_entry
ue
;
...
...
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