Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
P
PPSi
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
50
Issues
50
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
PPSi
Commits
bc172173
Commit
bc172173
authored
Jul 06, 2015
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'vlan-unix-wrs'
parents
594beec6
d37136ea
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
858 additions
and
307 deletions
+858
-307
Kconfig
Kconfig
+47
-0
main-loop.c
arch-sim/main-loop.c
+1
-1
sim-startup.c
arch-sim/sim-startup.c
+3
-2
main-loop.c
arch-unix/main-loop.c
+3
-10
unix-startup.c
arch-unix/unix-startup.c
+3
-2
wrc_ptp_ppsi.c
arch-wrpc/wrc_ptp_ppsi.c
+1
-0
main-loop.c
arch-wrs/main-loop.c
+3
-10
wrs-startup.c
arch-wrs/wrs-startup.c
+3
-2
ppsi-manual.in
doc/ppsi-manual.in
+119
-0
pp-instance.h
include/ppsi/pp-instance.h
+9
-16
ppsi.h
include/ppsi/ppsi.h
+16
-15
bare-startup.c
lib-bare/bare-startup.c
+1
-0
main-loop.c
lib-bare/main-loop.c
+6
-8
conf.c
lib/conf.c
+67
-0
network_types.h
lib/network_types.h
+11
-0
wr-api.h
proto-ext-whiterabbit/wr-api.h
+1
-3
common-fun.c
proto-standard/common-fun.c
+34
-4
common-fun.h
proto-standard/common-fun.h
+1
-1
state-initializing.c
proto-standard/state-initializing.c
+1
-1
state-master.c
proto-standard/state-master.c
+56
-2
bare-socket.c
time-bare/bare-socket.c
+9
-9
sim-socket.c
time-sim/sim-socket.c
+11
-11
unix-socket.c
time-unix/unix-socket.c
+247
-134
wrpc-socket.c
time-wrpc/wrpc-socket.c
+8
-8
wrs-socket.c
time-wrs/wrs-socket.c
+154
-52
Makefile
tools/Makefile
+2
-1
dump-funcs.c
tools/dump-funcs.c
+29
-12
dump-main.c
tools/dump-main.c
+11
-2
ptpdump.h
tools/ptpdump.h
+1
-1
No files found.
Kconfig
View file @
bc172173
...
...
@@ -6,6 +6,8 @@ choice
config ARCH_UNIX
bool "Unix (Linux and likely other systems)"
select HAS_VLAN
select HAS_MULTIPLE_VLAN
help
ARCH=unix supports standard Unix system calls, although
the code most likely includes some Linux dependencies.
...
...
@@ -33,6 +35,7 @@ config ARCH_BARE_X86_64
config ARCH_WRPC
bool "White Rabbit PTP Core (WR Node)"
select CONFIG_EXT_WR
select HAS_VLAN
help
Build PPSi for use in the WRPC environment (SPEC card or similar
one). This is a freestanding build, without operating system.
...
...
@@ -41,6 +44,8 @@ config ARCH_WRPC
config ARCH_WRS
bool "White Rabbit Switch"
select CONFIG_EXT_WR
select HAS_VLAN
select HAS_MULTIPLE_VLAN
help
Build PPSi for use in the WR switch. The computer is a standard
ARM-Linux host with hardware timestamping and internal PLLs
...
...
@@ -106,3 +111,45 @@ config WRPCSW_ROOT
string "Source location of wrpc-sw"
depends on ARCH_WRPC
default "../wrpc-sw"
# Vlan support: not all architectures have it, so this is set by them
config HAS_VLAN
bool
config HAS_MULTIPLE_VLAN
bool
config VLAN
bool "Enable VLAN support for raw Ethernet"
depends on HAS_VLAN || HAS_MULTIPLE_VLAN
default y
help
PPSI is able to directly emit and receive tagged frames,
with some architectures (if you see this option, it means
the architecture you selected has such support). A
designated master port can send announce on several VLANs,
but the other roles (designated slave or auto) can only bind
to a single VLAN. This choice is a tradeoff between code
complexity and flexibility.
Please note that you can always create several PTP ports that
act on different VLANs on the same physical port, and you can
also run VLAN support in your OS without special PPSI code.
Please see the PPSI documentation for details.
config MAX_VLANS_PER_PORT
int "Maximum number of VLANs per port"
depends on HAS_MULTIPLE_VLAN
default 32
help
This configuration option is mainly used to support
the special case of 1 VLAN per port, useful for
microcontroller-class architectures. Hosted builds
feature a bigger default, because they have no size constraints.
# I want a number, to be used without ifdef
config VLAN_ARRAY_SIZE
int
default 0 if !VLAN
default 1 if !HAS_MULTIPLE_VLAN
default MAX_VLANS_PER_PORT
arch-sim/main-loop.c
View file @
bc172173
...
...
@@ -92,7 +92,7 @@ void sim_main_loop(struct pp_globals *ppg)
sim_set_global_DS
(
ppi
);
tmp_ns
=
1000LL
*
1000LL
*
pp_state_machine
(
ppi
,
ppi
->
rx_ptp
,
i
-
NP
(
ppi
)
->
ptp
_offset
);
ppi
->
rx_ptp
,
i
-
ppi
->
rx
_offset
);
if
(
tmp_ns
<
delay_ns
)
delay_ns
=
tmp_ns
;
...
...
arch-sim/sim-startup.c
View file @
bc172173
...
...
@@ -106,6 +106,7 @@ int main(int argc, char **argv)
for
(
i
=
0
;
i
<
ppg
->
max_links
;
i
++
)
{
ppi
=
INST
(
ppg
,
i
);
ppi
->
glbs
=
ppg
;
// must be done before using sim_set_global_DS
ppi
->
vlans_array_len
=
CONFIG_VLAN_ARRAY_SIZE
;
if
(
sim_ppi_init
(
ppi
,
i
))
return
-
1
;
}
...
...
@@ -145,8 +146,8 @@ int main(int argc, char **argv)
if
(
ppi
->
proto
==
PPSI_PROTO_RAW
)
pp_printf
(
"Warning: simulator doesn't support raw "
"ethernet. Using UDP
\n
"
);
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
fd
=
-
1
;
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
fd
=
-
1
;
ppi
->
ch
[
PP_NP_GEN
].
fd
=
-
1
;
ppi
->
ch
[
PP_NP_EVT
].
fd
=
-
1
;
ppi
->
t_ops
=
&
DEFAULT_TIME_OPS
;
ppi
->
n_ops
=
&
DEFAULT_NET_OPS
;
if
(
pp_sim_is_master
(
ppi
))
...
...
arch-unix/main-loop.c
View file @
bc172173
...
...
@@ -49,13 +49,6 @@ void unix_main_loop(struct pp_globals *ppg)
ppi
=
INST
(
ppg
,
j
);
/*
* If we are sending or receiving raw ethernet frames,
* the ptp payload is one-eth-header bytes into the frame
*/
if
(
ppi
->
proto
==
PPSI_PROTO_RAW
)
NP
(
ppi
)
->
ptp_offset
=
ETH_HLEN
;
/*
* The main loop here is based on select. While we are not
* doing anything else but the protocol, this allows extra stuff
...
...
@@ -107,8 +100,8 @@ void unix_main_loop(struct pp_globals *ppg)
int
tmp_d
;
ppi
=
INST
(
ppg
,
j
);
if
((
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
pkt_present
)
||
(
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
pkt_present
))
{
if
((
ppi
->
ch
[
PP_NP_GEN
].
pkt_present
)
||
(
ppi
->
ch
[
PP_NP_EVT
].
pkt_present
))
{
i
=
__recv_and_count
(
ppi
,
ppi
->
rx_frame
,
PP_MAX_FRAME_LENGTH
-
4
,
...
...
@@ -131,7 +124,7 @@ void unix_main_loop(struct pp_globals *ppg)
}
tmp_d
=
pp_state_machine
(
ppi
,
ppi
->
rx_ptp
,
i
-
NP
(
ppi
)
->
ptp
_offset
);
i
-
ppi
->
rx
_offset
);
if
((
delay_ms
==
-
1
)
||
(
tmp_d
<
delay_ms
))
delay_ms
=
tmp_d
;
...
...
arch-unix/unix-startup.c
View file @
bc172173
...
...
@@ -84,10 +84,11 @@ int main(int argc, char **argv)
for
(
i
=
0
;
i
<
ppg
->
nlinks
;
i
++
)
{
ppi
=
INST
(
ppg
,
i
);
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
fd
=
-
1
;
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
fd
=
-
1
;
ppi
->
ch
[
PP_NP_EVT
].
fd
=
-
1
;
ppi
->
ch
[
PP_NP_GEN
].
fd
=
-
1
;
ppi
->
glbs
=
ppg
;
ppi
->
vlans_array_len
=
CONFIG_VLAN_ARRAY_SIZE
,
ppi
->
iface_name
=
ppi
->
cfg
.
iface_name
;
ppi
->
port_name
=
ppi
->
cfg
.
port_name
;
...
...
arch-wrpc/wrc_ptp_ppsi.c
View file @
bc172173
...
...
@@ -78,6 +78,7 @@ struct pp_instance ppi_static = {
.
portDS
=
&
portDS
,
.
n_ops
=
&
wrpc_net_ops
,
.
t_ops
=
&
wrpc_time_ops
,
.
vlans_array_len
=
CONFIG_VLAN_ARRAY_SIZE
,
.
proto
=
PP_DEFAULT_PROTO
,
.
iface_name
=
"wr1"
,
.
port_name
=
"wr1"
,
...
...
arch-wrs/main-loop.c
View file @
bc172173
...
...
@@ -88,13 +88,6 @@ void wrs_main_loop(struct pp_globals *ppg)
ppi
=
INST
(
ppg
,
j
);
/*
* If we are sending or receiving raw ethernet frames,
* the ptp payload is one-eth-header bytes into the frame
*/
if
(
ppi
->
proto
==
PPSI_PROTO_RAW
)
NP
(
ppi
)
->
ptp_offset
=
ETH_HLEN
;
/*
* The main loop here is based on select. While we are not
* doing anything else but the protocol, this allows extra stuff
...
...
@@ -148,8 +141,8 @@ void wrs_main_loop(struct pp_globals *ppg)
int
tmp_d
;
ppi
=
INST
(
ppg
,
j
);
if
((
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
pkt_present
)
||
(
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
pkt_present
))
{
if
((
ppi
->
ch
[
PP_NP_GEN
].
pkt_present
)
||
(
ppi
->
ch
[
PP_NP_EVT
].
pkt_present
))
{
i
=
__recv_and_count
(
ppi
,
ppi
->
rx_frame
,
PP_MAX_FRAME_LENGTH
-
4
,
...
...
@@ -172,7 +165,7 @@ void wrs_main_loop(struct pp_globals *ppg)
}
tmp_d
=
pp_state_machine
(
ppi
,
ppi
->
rx_ptp
,
i
-
NP
(
ppi
)
->
ptp
_offset
);
i
-
ppi
->
rx
_offset
);
if
((
delay_ms
==
-
1
)
||
(
tmp_d
<
delay_ms
))
delay_ms
=
tmp_d
;
...
...
arch-wrs/wrs-startup.c
View file @
bc172173
...
...
@@ -199,10 +199,11 @@ int main(int argc, char **argv)
}
for
(
i
=
0
;
i
<
ppg
->
nlinks
;
i
++
)
{
ppi
=
INST
(
ppg
,
i
);
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
fd
=
-
1
;
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
fd
=
-
1
;
ppi
->
ch
[
PP_NP_EVT
].
fd
=
-
1
;
ppi
->
ch
[
PP_NP_GEN
].
fd
=
-
1
;
ppi
->
glbs
=
ppg
;
ppi
->
vlans_array_len
=
CONFIG_VLAN_ARRAY_SIZE
;
ppi
->
iface_name
=
ppi
->
cfg
.
iface_name
;
ppi
->
port_name
=
ppi
->
cfg
.
port_name
;
ppi
->
portDS
=
calloc
(
1
,
sizeof
(
*
ppi
->
portDS
));
...
...
doc/ppsi-manual.in
View file @
bc172173
...
...
@@ -508,6 +508,125 @@ transmission jitter, you can run like this:
@end smallexample
@c ##########################################################################
@node VLAN Support
@chapter VLAN Support
PPSi can support vlans, or use support the Operating System offers.
@c ==========================================================================
@node OS VLAN
@section OS VLAN
If the OS supports vlans, PPSi can rely on it. For example a
Linux-based architecture can be configured to run on interface
@t
{
eth0.20
}
and thus work on vlan 20. In this case, use of
@i
{
vconfig
}
is left to the user, and nothing special is performed by
PPSi itself, nor any special configuration is needed. In this setup
both raw Ethernet and UDP can be used.
@c ==========================================================================
@node PPSi VLAN
@section PPSi VLAN
Freestanding architectures, like the WR PTP Core (@t
{
arch-wrpc
}
) can't
rely on the underlying Operating System, so the daemon must read and
write vlan Ethernet headers by itself -- in this situation UDP is not
supported, unless your own architecture's network operations build and
decode IP and UDP headers (in official PPSi no such support is there).
Another situation where PPSi should deal with vlans directly is when
you want a port to be master on several vlans at the same time, but
this is only supported for @i
{
mandated
}
masters, at this point in
time. A mandated master is a port configured as ``@t
{
role master
}
''
in the configuration file. If you want to run multiple vlans on the
same physical ports, without forcing the port to be a mandated master,
you can create multiple PTP interfaces, one per vlan, all relying on
the same physical port (or different OS-specific vlan ports).
When running a fully-PTP network in end-to-end mode, you won't usually
need to configure multiple vlans on a single port. In particular, this
never happens in a White Rabbit network, because each link connects
two clocks, without any non-compliant switches in the middle.
However, if you have
transparent clocks or normal switches, you may want to behave
as a master for the whole network connected to your port, which may
be split in several vlans. Clearly this only applies to a @i
{
trunk
}
port in your PTP switch or workstation.
To support this we rely on @i
{
Kconfig
}
and architecture-specific
code, in the following way.
@itemize @bullet
@item Each architecture states, in @t
{
Kconfig
}
, whether it supports
vlans (@t
{
HAS
_
VLAN
}
) and multiple vlans (@t
{
HAS
_
MULTIPLE
_
VLAN
}
).
@item The configuration parser (@t
{
lib/conf.c
}
) accepts a @t
{
vlan
}
keyword, specifying one or more vlans. If several, they are
comma-separated.
@item Configuration fails (and PPSi refuses to start) if the architecture
has no vlan support, or of multiple vlans are specified for an
architecture that supports one vlan only.
@item Configuration fails also if several vlans are specified for
a port that is not a mandated master.
@end itemize
When only one vlan is specified, the network operations for the
architecture are responsible: they must do the right thing. Currently,
@t
{
wrpc
}
builds and decodes Ethernet frames (FIXME: NOT YET), ignoring
any received frame not belonging to the proper vlan. Code for @t
{
wrs
}
and
@t
{
unix
}
handles a single vlan like multiple ones; I thought
about automatically creating the vlan-specific interface, but that
would be very Linux-specific and I see no real need for it.
When multiple vlans are specified for a master port, current code
(i.e. @t
{
arch-wrs
}
and @t
{
arch-unix
}
) binds to @t
{
ETH
_
P
_
ALL
}
, in order
to receive all frames from that interface, and thus be able to tell
which vlan they belong to. A multiple-vlan master sends announce and
sync (plus follow-up) to all vlans at the same time, and will reply to
delay requests using the same vlan it receives it from. Frames from
other vlans, as well as non-PTP frames, are ignored.
Because of the @t
{
ETH
_
P
_
ALL
}
binding, a multiple-vlan master port will
receive all the non-PTP traffic that flows on the interface. Please be
warned that this may increase the load on your PPSi process. With the
current release of the White Rabbit Switch this is not a problem,
because the switching core routes only PTP frames to the CPU. This
applies to single-vlan ports, because PPSi is not creating the
Linux-specific interface to have the kernel select traffic for us.
@c ==========================================================================
@node Note about vlans in Linux
@section Note about vlans in Linux
The choices described above depend on how vlans work in Linux (the
architecture we use in the White Rabbit Switch, and the one we support
in @t
{
arch-unix
}
).
If a packet socket is bound to a specific Ethernet protocol (for
example, the PTP Ethernet type, 0x88f7), on a generic Ethernet port
like @t
{
eth0
}
, it receives all frames for that @i
{
ethertype
}
, whether
or not they are tagged on the wire. To our knowledge there is no way,
in this situation, to tell whether the frame was tagged, and which tag
were there if any. Only traffic to vlan-specific ports, like
@t
{
eth0.20
}
, si guaranteed to belong to vlan 20 (or a double-tagged
frame, whose external tag is 20).
Only a socket bound to all @i
{
ethertypes
}
(i.e. @t
{
ETH
_
P
_
ALL
}
) is able
to receive auxiliary metadata that reports whether the frame was
tagged and which tag it was carrying.
The behavior above depends on how hardware acceleration for tags work,
and even if it is suboptimal for this use case, we don't know about
alternatives. Thus, a PPSi port configured for vlan frames, is bound
to the base ethernet port, but it must receive all @i
{
ethertypes
}
.
If this is not ok for your configuration, you can create your own
vlan-aware Linux port and bind to it. It works correctly with smaller
CPU overhead, but more administrative work.
@c ##########################################################################
@node PTP Clock Class
@chapter PTP Clock Class
...
...
include/ppsi/pp-instance.h
View file @
bc172173
...
...
@@ -62,7 +62,6 @@ struct pp_channel {
};
void
*
arch_data
;
/* Other arch-private info, if any */
unsigned
char
addr
[
6
];
/* Our own MAC address */
unsigned
char
peer
[
6
];
/* Our peer's MAC address */
int
pkt_present
;
};
...
...
@@ -102,24 +101,12 @@ struct pp_servo {
struct
pp_avg_fltr
mpd_fltr
;
};
/*
* Net Path. Struct which contains the network configuration parameters and
* the event/general channels (sockets on most platforms, see above)
*/
enum
{
enum
{
/* The two sockets. They are called "net path" for historical reasons */
PP_NP_GEN
=
0
,
PP_NP_EVT
,
__NR_PP_NP
,
};
struct
pp_net_path
{
struct
pp_channel
ch
[
__NR_PP_NP
];
/* general and event ch */
Integer32
mcast_addr
;
/* FIXME: only ipv4/udp */
int
ptp_offset
;
};
/*
* Struct containg the result of ppsi.conf parsing: one for each link
* (see lib/conf.c). Actually, protocol and role are in the main ppi.
...
...
@@ -159,7 +146,11 @@ struct pp_instance {
void
*
tx_frame
,
*
rx_frame
,
*
tx_ptp
,
*
rx_ptp
;
/* The net_path used to be allocated separately, but there's no need */
struct
pp_net_path
np
;
struct
pp_channel
ch
[
__NR_PP_NP
];
/* general and event ch */
Integer32
mcast_addr
;
/* only ipv4/udp */
int
tx_offset
,
rx_offset
;
/* ptp payload vs send/recv */
unsigned
char
peer
[
6
];
/* Our peer's MAC address */
uint16_t
peer_vid
;
/* Our peer's VID (for PROTO_VLAN) */
/* Times, for the various offset computations */
TimeInternal
t1
,
t2
,
t3
,
t4
;
/* *the* stamps */
...
...
@@ -185,7 +176,9 @@ struct pp_instance {
char
*
iface_name
;
/* for direct actions on hardware */
char
*
port_name
;
/* for diagnostics, mainly */
int
port_idx
;
int
vlans_array_len
;
/* those looking at shared mem must check */
int
vlans
[
CONFIG_VLAN_ARRAY_SIZE
];
int
nvlans
;
/* according to configuration */
struct
pp_instance_cfg
cfg
;
unsigned
long
ptp_tx_count
;
...
...
include/ppsi/ppsi.h
View file @
bc172173
...
...
@@ -35,6 +35,15 @@ extern int pp_sprintf(char *s, const char *fmt, ...)
extern
int
pp_vsprintf
(
char
*
buf
,
const
char
*
,
va_list
)
__attribute__
((
format
(
printf
,
2
,
0
)));
/* This structure is never defined, it seems */
struct
pp_vlanhdr
{
uint8_t
h_dest
[
6
];
uint8_t
h_source
[
6
];
uint16_t
h_tpid
;
uint16_t
h_tci
;
uint16_t
h_proto
;
};
/* We use data sets a lot, so have these helpers */
static
inline
struct
pp_globals
*
GLBS
(
struct
pp_instance
*
ppi
)
...
...
@@ -88,9 +97,13 @@ static inline struct DSTimeProperties *DSPRO(struct pp_instance *ppi)
return
GLBS
(
ppi
)
->
timePropertiesDS
;
}
static
inline
struct
pp_net_path
*
NP
(
struct
pp_instance
*
ppi
)
/* We used to have a "netpath" structure. Keep this until we merge pdelay */
static
struct
pp_instance
*
NP
(
struct
pp_instance
*
ppi
)
__attribute__
((
deprecated
));
static
inline
struct
pp_instance
*
NP
(
struct
pp_instance
*
ppi
)
{
return
&
ppi
->
np
;
return
ppi
;
}
static
inline
struct
pp_servo
*
SRV
(
struct
pp_instance
*
ppi
)
...
...
@@ -98,21 +111,8 @@ static inline struct pp_servo *SRV(struct pp_instance *ppi)
return
GLBS
(
ppi
)
->
servo
;
}
/* Sometimes (e.g., raw ethernet frames), we need to consider an offset */
static
inline
void
*
pp_get_header
(
struct
pp_instance
*
ppi
,
void
*
ptp_payload
)
{
return
ptp_payload
-
NP
(
ppi
)
->
ptp_offset
;
}
static
inline
void
*
pp_get_payload
(
struct
pp_instance
*
ppi
,
void
*
frame_ptr
)
{
return
frame_ptr
+
NP
(
ppi
)
->
ptp_offset
;
}
extern
void
pp_prepare_pointers
(
struct
pp_instance
*
ppi
);
/*
* Each extension should fill this structure that is used to augment
* the standard states and avoid code duplications. Please remember
...
...
@@ -316,6 +316,7 @@ extern int pp_config_file(struct pp_globals *ppg, int force, char *fname);
#define PPSI_PROTO_RAW 0
#define PPSI_PROTO_UDP 1
#define PPSI_PROTO_VLAN 2
/* Actually: vlan over raw eth */
#define PPSI_ROLE_AUTO 0
#define PPSI_ROLE_MASTER 1
...
...
lib-bare/bare-startup.c
View file @
bc172173
...
...
@@ -41,6 +41,7 @@ static struct pp_instance ppi_static = {
.
t_ops
=
&
bare_time_ops
,
.
iface_name
=
"eth0"
,
.
port_name
=
"eth0"
,
.
vlans_array_len
=
CONFIG_VLAN_ARRAY_SIZE
,
.
proto
=
PP_DEFAULT_PROTO
,
.
__tx_buffer
=
__tx_buffer
,
.
__rx_buffer
=
__rx_buffer
,
...
...
lib-bare/main-loop.c
View file @
bc172173
...
...
@@ -24,8 +24,6 @@ void bare_main_loop(struct pp_instance *ppi)
{
int
delay_ms
;
NP
(
ppi
)
->
ptp_offset
=
14
;
/*
* The main loop here is based on select. While we are not
* doing anything else but the protocol, this allows extra stuff
...
...
@@ -44,11 +42,11 @@ void bare_main_loop(struct pp_instance *ppi)
again:
FD_ZERO
(
&
set
);
FD_SET
(
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
fd
,
&
set
);
FD_SET
(
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
fd
,
&
set
);
maxfd
=
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
fd
;
if
(
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
fd
>
maxfd
)
maxfd
=
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
fd
;
FD_SET
(
ppi
->
ch
[
PP_NP_GEN
].
fd
,
&
set
);
FD_SET
(
ppi
->
ch
[
PP_NP_EVT
].
fd
,
&
set
);
maxfd
=
ppi
->
ch
[
PP_NP_GEN
].
fd
;
if
(
ppi
->
ch
[
PP_NP_EVT
].
fd
>
maxfd
)
maxfd
=
ppi
->
ch
[
PP_NP_EVT
].
fd
;
i
=
sys_select
(
maxfd
+
1
,
&
set
,
NULL
,
NULL
,
&
tv
);
if
(
i
<
0
&&
bare_errno
!=
4
/* EINTR */
)
...
...
@@ -77,6 +75,6 @@ void bare_main_loop(struct pp_instance *ppi)
goto
again
;
delay_ms
=
pp_state_machine
(
ppi
,
ppi
->
rx_ptp
,
i
-
NP
(
ppi
)
->
ptp
_offset
);
i
-
ppi
->
rx
_offset
);
}
}
lib/conf.c
View file @
bc172173
...
...
@@ -118,10 +118,76 @@ static int f_diag(int lineno, struct pp_globals *ppg, union pp_cfg_arg *arg)
return
0
;
}
/* VLAN support is per-port, and it depends on configuration itmes */
static
int
f_vlan
(
int
lineno
,
struct
pp_globals
*
ppg
,
union
pp_cfg_arg
*
arg
)
{
struct
pp_instance
*
ppi
=
CUR_PPI
(
ppg
);
int
i
,
n
,
*
v
;
char
ch
,
*
s
;
CHECK_PPI
(
1
);
/* Refuse to add vlan support in non-raw mode */
if
(
ppi
->
proto
==
PPSI_PROTO_UDP
)
{
pp_printf
(
"config line %i: VLANs with UDP: not supported
\n
"
,
lineno
);
return
-
1
;
}
/* If there is no support, just warn */
if
(
CONFIG_VLAN_ARRAY_SIZE
==
0
)
{
pp_printf
(
"Warning: config line %i ignored:"
" this PPSI binary has no VLAN support
\n
"
,
lineno
);
return
0
;
}
if
(
ppi
->
nvlans
)
pp_printf
(
"Warning: config line %i overrides "
"previous vlan settings
\n
"
,
lineno
);
s
=
arg
->
s
;
for
(
v
=
ppi
->
vlans
,
n
=
0
;
n
<
CONFIG_VLAN_ARRAY_SIZE
;
n
++
,
v
++
)
{
i
=
sscanf
(
s
,
"%i %c"
,
v
,
&
ch
);
if
(
!
i
)
break
;
if
(
*
v
>
4095
||
*
v
<
0
)
{
pp_printf
(
"config line %i: vlan out of range: %i "
"(valid is 0..4095)
\n
"
,
lineno
,
*
v
);
return
-
1
;
}
if
(
i
==
2
&&
ch
!=
','
)
{
pp_printf
(
"config line %i: unexpected char '%c' "
"after %i
\n
"
,
lineno
,
ch
,
*
v
);
return
-
1
;
}
if
(
i
==
2
)
s
=
strchr
(
s
,
','
)
+
1
;
else
break
;
}
if
(
n
==
CONFIG_VLAN_ARRAY_SIZE
)
{
pp_printf
(
"config line %i: too many vlans (%i): max is %i
\n
"
,
lineno
,
n
+
1
,
CONFIG_VLAN_ARRAY_SIZE
);
return
-
1
;
}
ppi
->
nvlans
=
n
+
1
;
/* item "n" has been assigend too, 0-based */
for
(
i
=
0
;
i
<
ppi
->
nvlans
;
i
++
)
pp_diag
(
NULL
,
config
,
2
,
" parsed vlan %4i for %s (%s)
\n
"
,
ppi
->
vlans
[
i
],
ppi
->
cfg
.
port_name
,
ppi
->
cfg
.
iface_name
);
pp_diag
(
NULL
,
config
,
2
,
"role %i
\n
"
,
ppi
->
role
);
if
(
ppi
->
role
!=
PPSI_ROLE_MASTER
&&
ppi
->
nvlans
>
1
)
{
pp_printf
(
"config line %i: too many vlans (%i) for slave "
"or auto role
\n
"
,
lineno
,
ppi
->
nvlans
);
return
-
1
;
}
ppi
->
proto
=
PPSI_PROTO_VLAN
;
return
0
;
}
/* These are the tables for the parser */
static
struct
pp_argname
arg_proto
[]
=
{
{
"raw"
,
PPSI_PROTO_RAW
},
{
"udp"
,
PPSI_PROTO_UDP
},
/* PROTO_VLAN is an internal modification of PROTO_RAW */
{},
};
static
struct
pp_argname
arg_role
[]
=
{
...
...
@@ -143,6 +209,7 @@ static struct pp_argline pp_global_arglines[] = {
{
f_proto
,
"proto"
,
ARG_NAMES
,
arg_proto
},
{
f_role
,
"role"
,
ARG_NAMES
,
arg_role
},
{
f_ext
,
"extension"
,
ARG_NAMES
,
arg_ext
},
{
f_vlan
,
"vlan"
,
ARG_STR
},
{
f_diag
,
"diagnostics"
,
ARG_STR
},
{
f_class
,
"clock-class"
,
ARG_INT
},
{
f_accuracy
,
"clock-accuracy"
,
ARG_INT
},
...
...
lib/network_types.h
View file @
bc172173
...
...
@@ -41,3 +41,14 @@ struct udphdr {
uint16_t
len
;
uint16_t
check
;
};
#ifndef __PPSI_PPSI_H__
/* from ppsi.h -- never defined elsewhere */
struct
pp_vlanhdr
{
uint8_t
h_dest
[
6
];
uint8_t
h_source
[
6
];
uint16_t
h_tpid
;
uint16_t
h_tci
;
uint16_t
h_proto
;
};
#endif
/* __PPSI_PPSI_H__ */
proto-ext-whiterabbit/wr-api.h
View file @
bc172173
...
...
@@ -12,9 +12,7 @@
#include <ppsi/lib.h>
#include "wr-constants.h"
#define WRS_PPSI_SHMEM_VERSION 6
/* added fields n_err_state, n_err_offset,
* n_err_rtt, n_err_deltas to
* wr_servo_state_t */
#define WRS_PPSI_SHMEM_VERSION 11
/* peer is per-ppi, not per-chan */
/*
* This structure is used as extension-specific data in the DSPort
...
...
proto-standard/common-fun.c
View file @
bc172173
...
...
@@ -7,6 +7,13 @@
*/
#include <ppsi/ppsi.h>
#include "common-fun.h"
#include "../lib/network_types.h"
#ifdef CONFIG_ARCH_WRS
#define ARCH_IS_WRS 1
#else
#define ARCH_IS_WRS 0
#endif
static
void
*
msg_copy_header
(
MsgHeader
*
dest
,
MsgHeader
*
src
)
{
...
...
@@ -25,12 +32,35 @@ static void *__align_pointer(void *p)
void
pp_prepare_pointers
(
struct
pp_instance
*
ppi
)
{
ppi
->
tx_ptp
=
__align_pointer
(
pp_get_payload
(
ppi
,
ppi
->
__tx_buffer
));
ppi
->
rx_ptp
=
__align_pointer
(
pp_get_payload
(
ppi
,
ppi
->
__rx_buffer
));
/*
* Horrible thing: when we receive vlan, we get standard eth header,
* but when we send we must fill the complete vlan header.
* So we reserve a different number of bytes.
*/
switch
(
ppi
->
proto
)
{
case
PPSI_PROTO_RAW
:
ppi
->
tx_offset
=
ETH_HLEN
;
/* 14, I know! */
ppi
->
rx_offset
=
ETH_HLEN
;
break
;
case
PPSI_PROTO_VLAN
:
ppi
->
tx_offset
=
sizeof
(
struct
pp_vlanhdr
);
/* Hack warning: with wrs we get the whole header */
if
(
ARCH_IS_WRS
)
ppi
->
rx_offset
=
sizeof
(
struct
pp_vlanhdr
);
else
ppi
->
rx_offset
=
ETH_HLEN
;
break
;
case
PPSI_PROTO_UDP
:
ppi
->
tx_offset
=
0
;
ppi
->
rx_offset
=
0
;
break
;
}
ppi
->
tx_ptp
=
__align_pointer
(
ppi
->
__tx_buffer
+
ppi
->
tx_offset
);
ppi
->
rx_ptp
=
__align_pointer
(
ppi
->
__rx_buffer
+
ppi
->
rx_offset
);
/* Now that ptp payload is aligned, get back the header */
ppi
->
tx_frame
=
pp
_get_header
(
ppi
,
ppi
->
tx_ptp
)
;
ppi
->
rx_frame
=
pp
_get_header
(
ppi
,
ppi
->
rx_ptp
)
;
ppi
->
tx_frame
=
pp
i
->
tx_ptp
-
ppi
->
tx_offset
;
ppi
->
rx_frame
=
pp
i
->
rx_ptp
-
ppi
->
rx_offset
;
if
(
0
)
{
/* enable to verify... it works for me though */
pp_printf
(
"%p -> %p %p
\n
"
,
...
...
proto-standard/common-fun.h
View file @
bc172173
...
...
@@ -38,7 +38,7 @@ int st_com_slave_handle_followup(struct pp_instance *ppi, unsigned char *buf,
static
inline
int
__send_and_log
(
struct
pp_instance
*
ppi
,
int
msglen
,
int
msgtype
,
int
chtype
)
{
if
(
ppi
->
n_ops
->
send
(
ppi
,
ppi
->
tx_frame
,
msglen
+
NP
(
ppi
)
->
ptp
_offset
,
if
(
ppi
->
n_ops
->
send
(
ppi
,
ppi
->
tx_frame
,
msglen
+
ppi
->
tx
_offset
,
&
ppi
->
last_snt_time
,
chtype
,
0
)
<
msglen
)
{
pp_diag
(
ppi
,
frames
,
1
,
"%s(%d) Message can't be sent
\n
"
,
pp_msg_names
[
msgtype
],
msgtype
);
...
...
proto-standard/state-initializing.c
View file @
bc172173
...
...
@@ -24,7 +24,7 @@ int pp_initializing(struct pp_instance *ppi, unsigned char *pkt, int plen)
/* Clock identity comes from mac address with 0xff:0xfe intermixed */
id
=
(
unsigned
char
*
)
&
DSDEF
(
ppi
)
->
clockIdentity
;
mac
=
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
addr
;
mac
=
ppi
->
ch
[
PP_NP_GEN
].
addr
;
id
[
0
]
=
mac
[
0
];
id
[
1
]
=
mac
[
1
];
id
[
2
]
=
mac
[
2
];
...
...
proto-standard/state-master.c
View file @
bc172173
...
...
@@ -9,6 +9,57 @@
#include <ppsi/ppsi.h>
#include "common-fun.h"
/* Local functions that build to nothing when Kconfig selects 0/1 vlans */
static
int
pp_master_issue_announce
(
struct
pp_instance
*
ppi
)
{
int
i
,
vlan
=
0
;
if
(
CONFIG_VLAN_ARRAY_SIZE
&&
ppi
->
nvlans
==
1
)
vlan
=
ppi
->
vlans
[
0
];
if
(
CONFIG_VLAN_ARRAY_SIZE
<=
1
||
ppi
->
nvlans
<=
1
)
{
ppi
->
peer_vid
=
vlan
;
return
msg_issue_announce
(
ppi
);
}
/*
* If Kconfig selected 0/1 vlans, this code is not built.
* If we have several vlans, we replace peer_vid and proceed;
*/
for
(
i
=
0
;
i
<
ppi
->
nvlans
;
i
++
)
{
ppi
->
peer_vid
=
ppi
->
vlans
[
i
];
msg_issue_announce
(
ppi
);
/* ignore errors: each vlan is separate */
}
return
0
;
}
static
int
pp_master_issue_sync_followup
(
struct
pp_instance
*
ppi
)
{
int
i
,
vlan
=
0
;
if
(
CONFIG_VLAN_ARRAY_SIZE
&&
ppi
->
nvlans
==
1
)
vlan
=
ppi
->
vlans
[
0
];
if
(
CONFIG_VLAN_ARRAY_SIZE
<=
1
||
ppi
->
nvlans
<=
1
)
{
ppi
->
peer_vid
=
vlan
;
return
msg_issue_sync_followup
(
ppi
);
}
/*
* If Kconfig selected 0/1 vlans, this code is not built.
* If we have several vlans, we replace peer_vid and proceed;
*/
for
(
i
=
0
;
i
<
ppi
->
nvlans
;
i
++
)
{
ppi
->
peer_vid
=
ppi
->
vlans
[
i
];
msg_issue_sync_followup
(
ppi
);
/* ignore errors: each vlan is separate */
}
return
0
;
}
/* The real state function, relying on the two above for sending */
int
pp_master
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
plen
)
{
int
msgtype
,
d1
,
d2
;
...
...
@@ -20,7 +71,7 @@ int pp_master(struct pp_instance *ppi, unsigned char *pkt, int plen)
DSPOR
(
ppi
)
->
logAnnounceInterval
);
/* Send an announce immediately, when becomes master */
if
((
e
=
msg
_issue_announce
(
ppi
))
<
0
)
if
((
e
=
pp_master
_issue_announce
(
ppi
))
<
0
)
goto
out
;
}
...
...
@@ -28,12 +79,15 @@ int pp_master(struct pp_instance *ppi, unsigned char *pkt, int plen)
/* Restart the timeout for next time */
pp_timeout_rand
(
ppi
,
PP_TO_SYNC
,
DSPOR
(
ppi
)
->
logSyncInterval
);
if
((
e
=
msg
_issue_sync_followup
(
ppi
)
<
0
))
if
((
e
=
pp_master
_issue_sync_followup
(
ppi
)
<
0
))
goto
out
;
}
if
(
pp_timeout_z
(
ppi
,
PP_TO_ANN_INTERVAL
))
{
if
((
e
=
pp_master_issue_announce
(
ppi
)
<
0
))
goto
out
;
/* Restart the timeout for next time */
pp_timeout_rand
(
ppi
,
PP_TO_ANN_INTERVAL
,
DSPOR
(
ppi
)
->
logAnnounceInterval
);
...
...
time-bare/bare-socket.c
View file @
bc172173
...
...
@@ -18,7 +18,7 @@ static int bare_net_recv(struct pp_instance *ppi, void *pkt, int len,
if
(
t
)
ppi
->
t_ops
->
get
(
ppi
,
t
);
ret
=
sys_recv
(
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
fd
,
pkt
,
len
,
0
);
ret
=
sys_recv
(
ppi
->
ch
[
PP_NP_GEN
].
fd
,
pkt
,
len
,
0
);
if
(
ret
>
0
&&
pp_diag_allow
(
ppi
,
frames
,
2
))
dump_1588pkt
(
"recv: "
,
pkt
,
ret
,
t
);
return
ret
;
...
...
@@ -35,12 +35,12 @@ static int bare_net_send(struct pp_instance *ppi, void *pkt, int len,
memcpy
(
hdr
->
h_dest
,
PP_MCAST_MACADDRESS
,
6
);
/* raw socket implementation always uses gen socket */
memcpy
(
hdr
->
h_source
,
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
addr
,
6
);
memcpy
(
hdr
->
h_source
,
ppi
->
ch
[
PP_NP_GEN
].
addr
,
6
);
if
(
t
)
ppi
->
t_ops
->
get
(
ppi
,
t
);
ret
=
sys_send
(
NP
(
ppi
)
->
ch
[
chtype
].
fd
,
pkt
,
len
,
0
);
ret
=
sys_send
(
ppi
->
ch
[
chtype
].
fd
,
pkt
,
len
,
0
);
if
(
ret
>
0
&&
pp_diag_allow
(
ppi
,
frames
,
2
))
dump_1588pkt
(
"send: "
,
pkt
,
len
,
t
);
return
ret
;
...
...
@@ -82,9 +82,9 @@ static int bare_open_ch(struct pp_instance *ppi, char *ifname)
if
(
sys_ioctl
(
sock
,
SIOCGIFHWADDR
,
&
ifr
)
<
0
)
goto
err_out
;
memcpy
(
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
addr
,
memcpy
(
ppi
->
ch
[
PP_NP_GEN
].
addr
,
ifr
.
ifr_ifru
.
ifru_hwaddr
.
sa_data
,
6
);
memcpy
(
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
addr
,
memcpy
(
ppi
->
ch
[
PP_NP_EVT
].
addr
,
ifr
.
ifr_ifru
.
ifru_hwaddr
.
sa_data
,
6
);
/* bind */
...
...
@@ -106,8 +106,8 @@ static int bare_open_ch(struct pp_instance *ppi, char *ifname)
sys_setsockopt
(
sock
,
SOL_PACKET
,
PACKET_ADD_MEMBERSHIP
,
&
pmr
,
sizeof
(
pmr
));
/* lazily ignore errors */
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
fd
=
sock
;
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
fd
=
sock
;
ppi
->
ch
[
PP_NP_GEN
].
fd
=
sock
;
ppi
->
ch
[
PP_NP_EVT
].
fd
=
sock
;
/* make timestamps available through recvmsg() -- FIXME: hw? */
sys_setsockopt
(
sock
,
SOL_SOCKET
,
SO_TIMESTAMP
,
...
...
@@ -128,14 +128,14 @@ err_out:
static
int
bare_net_exit
(
struct
pp_instance
*
ppi
)
{
return
sys_shutdown
(
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
fd
,
SHUT_RDWR
);
return
sys_shutdown
(
ppi
->
ch
[
PP_NP_GEN
].
fd
,
SHUT_RDWR
);
}
/* This function must be able to be called twice, and clean-up internally */
static
int
bare_net_init
(
struct
pp_instance
*
ppi
)
{
/* Here, socket may not be 0 (do we have stdin even if bare) */
if
(
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
fd
)
if
(
ppi
->
ch
[
PP_NP_GEN
].
fd
)
bare_net_exit
(
ppi
);
/* The buffer is inside ppi, but we need to set pointers and align */
...
...
time-sim/sim-socket.c
View file @
bc172173
...
...
@@ -145,7 +145,7 @@ static int sim_net_recv(struct pp_instance *ppi, void *pkt, int len,
if
(
data
->
n_pending
<=
0
)
return
0
;
ch
=
&
(
NP
(
ppi
)
->
ch
[
data
->
pending
->
chtype
]);
ch
=
&
(
ppi
->
ch
[
data
->
pending
->
chtype
]);
ret
=
-
1
;
if
(
ch
->
pkt_present
>
0
)
{
...
...
@@ -181,12 +181,12 @@ static int sim_net_send(struct pp_instance *ppi, void *pkt, int len,
PP_SLAVE_GEN_PORT
:
PP_SLAVE_EVT_PORT
);
addr
.
sin_addr
.
s_addr
=
NP
(
ppi
)
->
mcast_addr
;
addr
.
sin_addr
.
s_addr
=
ppi
->
mcast_addr
;
if
(
t
)
ppi
->
t_ops
->
get
(
ppi
,
t
);
ret
=
sendto
(
NP
(
ppi
)
->
ch
[
chtype
].
fd
,
pkt
,
len
,
0
,
ret
=
sendto
(
ppi
->
ch
[
chtype
].
fd
,
pkt
,
len
,
0
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
struct
sockaddr_in
));
if
(
pp_diag_allow
(
ppi
,
frames
,
2
))
dump_payloadpkt
(
"send: "
,
pkt
,
len
,
t
);
...
...
@@ -219,7 +219,7 @@ static int sim_net_send(struct pp_instance *ppi, void *pkt, int len,
pending
.
delay_ns
=
data
->
n_delay
.
t_prop_ns
+
jit_ns
;
insert_pending
(
SIM_PPG_ARCH
(
ppi
->
glbs
),
&
pending
);
NP
(
data
->
other_ppi
)
->
ch
[
chtype
].
pkt_present
++
;
data
->
other_ppi
->
ch
[
chtype
].
pkt_present
++
;
return
ret
;
}
...
...
@@ -230,11 +230,11 @@ static int sim_net_exit(struct pp_instance *ppi)
/* only UDP */
for
(
i
=
PP_NP_GEN
;
i
<=
PP_NP_EVT
;
i
++
)
{
fd
=
NP
(
ppi
)
->
ch
[
i
].
fd
;
fd
=
ppi
->
ch
[
i
].
fd
;
if
(
fd
<
0
)
continue
;
close
(
fd
);
NP
(
ppi
)
->
ch
[
i
].
fd
=
-
1
;
ppi
->
ch
[
i
].
fd
=
-
1
;
}
return
0
;
}
...
...
@@ -253,7 +253,7 @@ static int sim_open_ch(struct pp_instance *ppi, char *ifname, int chtype)
if
(
sock
<
0
)
goto
err_out
;
NP
(
ppi
)
->
ch
[
chtype
].
fd
=
sock
;
ppi
->
ch
[
chtype
].
fd
=
sock
;
temp
=
1
;
/* allow address reuse */
if
(
setsockopt
(
sock
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
temp
,
sizeof
(
int
))
<
0
)
...
...
@@ -278,21 +278,21 @@ static int sim_open_ch(struct pp_instance *ppi, char *ifname, int chtype)
sizeof
(
struct
sockaddr_in
))
<
0
)
goto
err_out
;
NP
(
ppi
)
->
ch
[
chtype
].
fd
=
sock
;
ppi
->
ch
[
chtype
].
fd
=
sock
;
/*
* Standard ppsi state machine is designed to drop packets coming from
* itself, based on the clockIdentity. This hack avoids this behaviour,
* changing the clockIdentity of the master.
*/
if
(
pp_sim_is_master
(
ppi
))
memset
(
NP
(
ppi
)
->
ch
[
chtype
].
addr
,
111
,
1
);
memset
(
ppi
->
ch
[
chtype
].
addr
,
111
,
1
);
return
0
;
err_out:
pp_printf
(
"%s: %s: %s
\n
"
,
__func__
,
context
,
strerror
(
errno
));
if
(
sock
>=
0
)
close
(
sock
);
NP
(
ppi
)
->
ch
[
chtype
].
fd
=
-
1
;
ppi
->
ch
[
chtype
].
fd
=
-
1
;
return
-
1
;
}
...
...
@@ -300,7 +300,7 @@ static int sim_net_init(struct pp_instance *ppi)
{
int
i
;
if
(
NP
(
ppi
)
->
ch
[
0
].
fd
>
0
)
if
(
ppi
->
ch
[
0
].
fd
>
0
)
sim_net_exit
(
ppi
);
/* The buffer is inside ppi, but we need to set pointers and align */
...
...
time-unix/unix-socket.c
View file @
bc172173
This diff is collapsed.
Click to expand it.
time-wrpc/wrpc-socket.c
View file @
bc172173
...
...
@@ -26,10 +26,10 @@ static int wrpc_open_ch(struct pp_instance *ppi)
return
-
1
;
ptpd_netif_get_hw_addr
(
sock
,
&
mac
);
memcpy
(
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
addr
,
&
mac
,
sizeof
(
mac_addr_t
));
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
custom
=
sock
;
memcpy
(
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
addr
,
&
mac
,
sizeof
(
mac_addr_t
));
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
custom
=
sock
;
memcpy
(
ppi
->
ch
[
PP_NP_EVT
].
addr
,
&
mac
,
sizeof
(
mac_addr_t
));
ppi
->
ch
[
PP_NP_EVT
].
custom
=
sock
;
memcpy
(
ppi
->
ch
[
PP_NP_GEN
].
addr
,
&
mac
,
sizeof
(
mac_addr_t
));
ppi
->
ch
[
PP_NP_GEN
].
custom
=
sock
;
return
0
;
}
...
...
@@ -42,7 +42,7 @@ static int wrpc_net_recv(struct pp_instance *ppi, void *pkt, int len,
wr_socket_t
*
sock
;
wr_timestamp_t
wr_ts
;
wr_sockaddr_t
addr
;
sock
=
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
custom
;
sock
=
ppi
->
ch
[
PP_NP_EVT
].
custom
;
got
=
ptpd_netif_recvfrom
(
sock
,
&
addr
,
pkt
,
len
,
&
wr_ts
);
if
(
t
)
{
...
...
@@ -74,7 +74,7 @@ static int wrpc_net_send(struct pp_instance *ppi, void *pkt, int len,
wr_socket_t
*
sock
;
wr_timestamp_t
wr_ts
;
wr_sockaddr_t
addr
;
sock
=
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
custom
;
sock
=
ppi
->
ch
[
PP_NP_EVT
].
custom
;
addr
.
ethertype
=
ETH_P_1588
;
memcpy
(
&
addr
.
mac
,
PP_MCAST_MACADDRESS
,
sizeof
(
mac_addr_t
));
...
...
@@ -102,14 +102,14 @@ static int wrpc_net_send(struct pp_instance *ppi, void *pkt, int len,
static
int
wrpc_net_exit
(
struct
pp_instance
*
ppi
)
{
ptpd_netif_close_socket
(
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
custom
);
ptpd_netif_close_socket
(
ppi
->
ch
[
PP_NP_EVT
].
custom
);
return
0
;
}
/* This function must be able to be called twice, and clean-up internally */
static
int
wrpc_net_init
(
struct
pp_instance
*
ppi
)
{
if
(
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
custom
)
if
(
ppi
->
ch
[
PP_NP_EVT
].
custom
)
wrpc_net_exit
(
ppi
);
pp_prepare_pointers
(
ppi
);
wrpc_open_ch
(
ppi
);
...
...
time-wrs/wrs-socket.c
View file @
bc172173
...
...
@@ -158,20 +158,24 @@ static void wrs_linearize_rx_timestamp(TimeInternal *ts,
static
int
wrs_recv_msg
(
struct
pp_instance
*
ppi
,
int
fd
,
void
*
pkt
,
int
len
,
TimeInternal
*
t
)
TimeInternal
*
t
)
{
struct
ethhdr
*
hdr
=
pkt
;
struct
pp_vlanhdr
*
vhdr
=
pkt
;
struct
wrs_socket
*
s
;
struct
msghdr
msg
;
struct
iovec
entry
;
struct
sockaddr_ll
from_addr
;
struct
{
int
i
;
union
{
struct
cmsghdr
cm
;
char
control
[
1024
];
}
control
;
struct
cmsghdr
*
cmsg
;
struct
scm_timestamping
*
sts
=
NULL
;
struct
tpacket_auxdata
*
aux
=
NULL
;
s
=
(
struct
wrs_socket
*
)
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
arch_data
;
s
=
(
struct
wrs_socket
*
)
ppi
->
ch
[
PP_NP_GEN
].
arch_data
;
memset
(
&
msg
,
0
,
sizeof
(
msg
));
msg
.
msg_iov
=
&
entry
;
...
...
@@ -205,8 +209,11 @@ static int wrs_recv_msg(struct pp_instance *ppi, int fd, void *pkt, int len,
if
(
cmsg
->
cmsg_level
==
SOL_SOCKET
&&
cmsg
->
cmsg_type
==
SO_TIMESTAMPING
)
sts
=
(
struct
scm_timestamping
*
)
dp
;
sts
=
(
struct
scm_timestamping
*
)
dp
;
if
(
cmsg
->
cmsg_level
==
SOL_PACKET
&&
cmsg
->
cmsg_type
==
PACKET_AUXDATA
)
aux
=
(
struct
tpacket_auxdata
*
)
dp
;
}
if
(
sts
&&
t
)
...
...
@@ -233,6 +240,43 @@ static int wrs_recv_msg(struct pp_instance *ppi, int fd, void *pkt, int len,
}
drop:
if
(
aux
)
{
printf
(
"aux: %x proto %x
\n
"
,
aux
->
tp_vlan_tci
,
ntohs
(
hdr
->
h_proto
));
if
(
0
)
{
fprintf
(
stderr
,
"PPSi error: unexpected auxiliary data
\n
"
);
errno
=
EINVAL
;
return
-
1
;
}
}
/*
* While on PC-class ethernet driver we see the internal frame,
* our simple WR driver returns the whole frame. No aux pointer
* is there, at this point in time. So unroll vlan header.
*/
if
(
vhdr
->
h_tpid
==
htons
(
0x8100
))
{
int
vlan
=
ntohs
(
vhdr
->
h_tci
)
&
0xfff
;
/* With PROTO_VLAN, we bound to ETH_P_ALL: we got all frames */
if
(
vhdr
->
h_proto
!=
htons
(
ETH_P_1588
))
return
-
2
;
/* like "dropped", so no error message */
/* Also, we got the vlan, and we can discard it if not ours */
for
(
i
=
0
;
i
<
ppi
->
nvlans
;
i
++
)
if
(
ppi
->
vlans
[
i
]
==
vlan
)
break
;
/* ok */
if
(
i
==
ppi
->
nvlans
)
return
-
2
;
/* not ours: say it's dropped */
ppi
->
peer_vid
=
ppi
->
vlans
[
i
];
}
else
{
if
(
hdr
->
h_proto
!=
htons
(
ETH_P_1588
))
return
-
2
;
/* again: drop unrelated frames */
ppi
->
peer_vid
=
0
;
}
if
(
ppsi_drop_rx
())
{
pp_diag
(
ppi
,
frames
,
1
,
"Drop received frame
\n
"
);
return
-
2
;
...
...
@@ -245,27 +289,44 @@ int wrs_net_recv(struct pp_instance *ppi, void *pkt, int len,
TimeInternal
*
t
)
{
struct
pp_channel
*
ch1
,
*
ch2
;
struct
ethhdr
*
hdr
=
pkt
;
int
ret
=
-
1
;
if
(
ppi
->
proto
==
PPSI_PROTO_RAW
)
{
int
fd
=
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
fd
;
ret
=
wrs_recv_msg
(
ppi
,
fd
,
pkt
,
len
,
t
);
if
(
ret
>
0
&&
pp_diag_allow
(
ppi
,
frames
,
2
))
switch
(
ppi
->
proto
)
{
case
PPSI_PROTO_RAW
:
case
PPSI_PROTO_VLAN
:
ch2
=
ppi
->
ch
+
PP_NP_GEN
;
ret
=
wrs_recv_msg
(
ppi
,
ch2
->
fd
,
pkt
,
len
,
t
);
if
(
ret
<=
0
)
return
ret
;
memcpy
(
ppi
->
peer
,
hdr
->
h_source
,
ETH_ALEN
);
if
(
pp_diag_allow
(
ppi
,
frames
,
2
))
{
if
(
ppi
->
proto
==
PPSI_PROTO_VLAN
)
pp_printf
(
"recv: VLAN %i
\n
"
,
ppi
->
peer_vid
);
dump_1588pkt
(
"recv: "
,
pkt
,
ret
,
t
);
}
else
{
}
break
;
case
PPSI_PROTO_UDP
:
/* UDP: always handle EVT msgs before GEN */
ch1
=
&
(
NP
(
ppi
)
->
ch
[
PP_NP_EVT
]);
ch2
=
&
(
NP
(
ppi
)
->
ch
[
PP_NP_GEN
]);
ch1
=
&
(
ppi
->
ch
[
PP_NP_EVT
]);
ch2
=
&
(
ppi
->
ch
[
PP_NP_GEN
]);
if
(
ch1
->
pkt_present
)
ret
=
wrs_recv_msg
(
ppi
,
ch1
->
fd
,
pkt
,
len
,
t
);
else
if
(
ch2
->
pkt_present
)
ret
=
wrs_recv_msg
(
ppi
,
ch2
->
fd
,
pkt
,
len
,
t
);
if
(
ret
>
0
&&
pp_diag_allow
(
ppi
,
frames
,
2
))
if
(
ret
<
0
)
break
;
if
(
pp_diag_allow
(
ppi
,
frames
,
2
))
dump_payloadpkt
(
"recv: "
,
pkt
,
ret
,
t
);
break
;
default:
return
-
1
;
}
if
(
ret
<
0
)
return
ret
;
pp_diag
(
ppi
,
time
,
1
,
"recv stamp: (correct %i) %9li.%09li
\n
"
,
...
...
@@ -337,10 +398,10 @@ static void poll_tx_timestamp(struct pp_instance *ppi, void *pkt, int len,
/*
* Raw frames return "sock_extended_err" too, telling this is
* a tx timestamp. U
dp doesn't
so don't check in udp mode
* a tx timestamp. U
DP does not;
so don't check in udp mode
* (the pointer is only checked for non-null)
*/
if
(
!
(
ppi
->
proto
==
PPSI_PROTO_RAW
))
if
(
!
(
ppi
->
proto
!=
PPSI_PROTO_UDP
))
serr
=
(
void
*
)
1
;
for
(
cmsg
=
CMSG_FIRSTHDR
(
&
msg
);
...
...
@@ -372,10 +433,16 @@ int wrs_net_send(struct pp_instance *ppi, void *pkt, int len,
{
struct
sockaddr_in
addr
;
struct
ethhdr
*
hdr
=
pkt
;
struct
pp_vlanhdr
*
vhdr
=
pkt
;
struct
pp_channel
*
ch
=
ppi
->
ch
+
chtype
;
static
uint16_t
udpport
[]
=
{
[
PP_NP_GEN
]
=
PP_GEN_PORT
,
[
PP_NP_EVT
]
=
PP_EVT_PORT
,
};
struct
wrs_socket
*
s
;
int
ret
,
fd
,
drop
;
s
=
(
struct
wrs_socket
*
)
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
arch_data
;
s
=
(
struct
wrs_socket
*
)
ppi
->
ch
[
PP_NP_GEN
].
arch_data
;
/*
* To fake a packet loss, we must corrupt the frame; we need
...
...
@@ -384,24 +451,25 @@ int wrs_net_send(struct pp_instance *ppi, void *pkt, int len,
*/
drop
=
ppsi_drop_tx
();
if
(
ppi
->
proto
==
PPSI_PROTO_RAW
)
{
fd
=
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
fd
;
switch
(
ppi
->
proto
)
{
case
PPSI_PROTO_RAW
:
/* raw socket implementation always uses gen socket */
ch
=
ppi
->
ch
+
PP_NP_GEN
;
hdr
->
h_proto
=
htons
(
ETH_P_1588
);
if
(
drop
)
hdr
->
h_proto
++
;
memcpy
(
hdr
->
h_dest
,
PP_MCAST_MACADDRESS
,
ETH_ALEN
);
/* raw socket implementation always uses gen socket */
memcpy
(
hdr
->
h_source
,
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
addr
,
ETH_ALEN
);
memcpy
(
hdr
->
h_source
,
ch
->
addr
,
ETH_ALEN
);
if
(
t
)
ppi
->
t_ops
->
get
(
ppi
,
t
);
ret
=
send
(
fd
,
hdr
,
len
,
0
);
poll_tx_timestamp
(
ppi
,
pkt
,
len
,
s
,
fd
,
t
);
ret
=
send
(
ch
->
fd
,
hdr
,
len
,
0
);
poll_tx_timestamp
(
ppi
,
pkt
,
len
,
s
,
ch
->
fd
,
t
);
if
(
drop
)
/* avoid messaging about stamps that are not used */
goto
drop_msg
;
break
;
if
(
pp_diag_allow
(
ppi
,
frames
,
2
))
dump_1588pkt
(
"send: "
,
pkt
,
len
,
t
);
...
...
@@ -409,28 +477,62 @@ int wrs_net_send(struct pp_instance *ppi, void *pkt, int len,
t
->
correct
,
(
long
)
t
->
seconds
,
(
long
)
t
->
nanoseconds
);
return
ret
;
}
/* else: UDP */
fd
=
NP
(
ppi
)
->
ch
[
chtype
].
fd
;
addr
.
sin_family
=
AF_INET
;
addr
.
sin_port
=
htons
(
chtype
==
PP_NP_GEN
?
PP_GEN_PORT
:
PP_EVT_PORT
);
addr
.
sin_addr
.
s_addr
=
NP
(
ppi
)
->
mcast_addr
;
if
(
drop
)
addr
.
sin_port
=
3200
;
ret
=
sendto
(
fd
,
pkt
,
len
,
0
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
struct
sockaddr_in
));
poll_tx_timestamp
(
ppi
,
pkt
,
len
,
s
,
fd
,
t
);
case
PPSI_PROTO_VLAN
:
/* similar to sending raw frames, but w/ different header */
ch
=
ppi
->
ch
+
PP_NP_GEN
;
vhdr
->
h_proto
=
htons
(
ETH_P_1588
);
vhdr
->
h_tci
=
htons
(
ppi
->
peer_vid
);
/* prio is 0 */
vhdr
->
h_tpid
=
htons
(
0x8100
);
if
(
drop
)
hdr
->
h_proto
++
;
if
(
drop
)
/* like above: skil messages about timestamps */
goto
drop_msg
;
memcpy
(
vhdr
->
h_dest
,
PP_MCAST_MACADDRESS
,
ETH_ALEN
);
memcpy
(
vhdr
->
h_source
,
ch
->
addr
,
ETH_ALEN
);
if
(
t
)
ppi
->
t_ops
->
get
(
ppi
,
t
);
if
(
len
<
64
)
len
=
64
;
ret
=
send
(
ch
->
fd
,
vhdr
,
len
,
0
);
poll_tx_timestamp
(
ppi
,
pkt
,
len
,
s
,
ch
->
fd
,
t
);
if
(
drop
)
/* avoid messaging about stamps that are not used */
break
;
if
(
pp_diag_allow
(
ppi
,
frames
,
2
))
dump_1588pkt
(
"send: "
,
pkt
,
len
,
t
);
pp_diag
(
ppi
,
time
,
1
,
"send stamp: (correct %i) %9li.%09li
\n
"
,
t
->
correct
,
(
long
)
t
->
seconds
,
(
long
)
t
->
nanoseconds
);
return
ret
;
case
PPSI_PROTO_UDP
:
fd
=
ppi
->
ch
[
chtype
].
fd
;
addr
.
sin_family
=
AF_INET
;
addr
.
sin_port
=
htons
(
udpport
[
chtype
]);
addr
.
sin_addr
.
s_addr
=
ppi
->
mcast_addr
;
if
(
drop
)
addr
.
sin_port
=
3200
;
ret
=
sendto
(
fd
,
pkt
,
len
,
0
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
struct
sockaddr_in
));
poll_tx_timestamp
(
ppi
,
pkt
,
len
,
s
,
fd
,
t
);
if
(
drop
)
/* like above: skil messages about timestamps */
break
;
if
(
pp_diag_allow
(
ppi
,
frames
,
2
))
dump_payloadpkt
(
"send: "
,
pkt
,
len
,
t
);
pp_diag
(
ppi
,
time
,
1
,
"send stamp: (correct %i) %9li.%09li
\n
"
,
t
->
correct
,
(
long
)
t
->
seconds
,
(
long
)
t
->
nanoseconds
);
return
ret
;
default:
return
-
1
;
}
if
(
pp_diag_allow
(
ppi
,
frames
,
2
))
dump_payloadpkt
(
"send: "
,
pkt
,
len
,
t
);
pp_diag
(
ppi
,
time
,
1
,
"send stamp: (correct %i) %9li.%09li
\n
"
,
t
->
correct
,
(
long
)
t
->
seconds
,
(
long
)
t
->
nanoseconds
);
drop_msg:
if
(
drop
)
pp_diag
(
ppi
,
frames
,
1
,
"Drop sent frame
\n
"
);
...
...
@@ -478,7 +580,7 @@ static int wrs_net_init(struct pp_instance *ppi)
int
r
,
i
;
struct
hal_port_state
*
p
;
if
(
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
arch_data
)
if
(
ppi
->
ch
[
PP_NP_GEN
].
arch_data
)
wrs_net_exit
(
ppi
);
/* Generic OS work is done by standard Unix stuff */
...
...
@@ -512,15 +614,15 @@ static int wrs_net_init(struct pp_instance *ppi)
s
->
dmtd_phase_valid
=
0
;
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
arch_data
=
s
;
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
arch_data
=
s
;
ppi
->
ch
[
PP_NP_GEN
].
arch_data
=
s
;
ppi
->
ch
[
PP_NP_EVT
].
arch_data
=
s
;
tmo_init
(
&
s
->
dmtd_update_tmo
,
DMTD_UPDATE_INTERVAL
);
for
(
i
=
PP_NP_GEN
,
r
=
0
;
i
<=
PP_NP_EVT
&&
r
==
0
;
i
++
)
r
=
wrs_enable_timestamps
(
ppi
,
NP
(
ppi
)
->
ch
[
i
].
fd
);
r
=
wrs_enable_timestamps
(
ppi
,
ppi
->
ch
[
i
].
fd
);
if
(
r
)
{
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
arch_data
=
NULL
;
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
arch_data
=
NULL
;
ppi
->
ch
[
PP_NP_GEN
].
arch_data
=
NULL
;
ppi
->
ch
[
PP_NP_EVT
].
arch_data
=
NULL
;
free
(
s
);
}
return
r
;
...
...
@@ -529,9 +631,9 @@ static int wrs_net_init(struct pp_instance *ppi)
static
int
wrs_net_exit
(
struct
pp_instance
*
ppi
)
{
unix_net_ops
.
exit
(
ppi
);
free
(
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
arch_data
);
NP
(
ppi
)
->
ch
[
PP_NP_GEN
].
arch_data
=
NULL
;
NP
(
ppi
)
->
ch
[
PP_NP_EVT
].
arch_data
=
NULL
;
free
(
ppi
->
ch
[
PP_NP_GEN
].
arch_data
);
ppi
->
ch
[
PP_NP_GEN
].
arch_data
=
NULL
;
ppi
->
ch
[
PP_NP_EVT
].
arch_data
=
NULL
;
return
0
;
}
...
...
tools/Makefile
View file @
bc172173
...
...
@@ -9,7 +9,8 @@ STRIP = $(CROSS_COMPILE)strip
OBJCOPY
=
$(CROSS_COMPILE)
objcopy
OBJDUMP
=
$(CROSS_COMPILE)
objdump
CFLAGS
=
-Wall
-ggdb
-I
../include
include
../.config
CFLAGS
=
-Wall
-ggdb
-I
../include
-I
../arch-
$(CONFIG_ARCH)
/include
PROGS
=
ptpdump adjtime jmptime chktime adjrate
LDFLAGS
+=
-lrt
...
...
tools/dump-funcs.c
View file @
bc172173
...
...
@@ -51,15 +51,25 @@ static void dump_time(char *prefix, struct TimeInternal *ti)
}
#endif
static
void
dump_eth
(
char
*
prefix
,
struct
ethhdr
*
eth
)
/* Returns the header size, used by the caller to adjust the next pointer */
static
int
dump_eth
(
char
*
prefix
,
struct
ethhdr
*
eth
)
{
unsigned
char
*
d
=
eth
->
h_dest
;
unsigned
char
*
s
=
eth
->
h_source
;
int
proto
=
ntohs
(
eth
->
h_proto
);
struct
pp_vlanhdr
*
vhdr
=
(
void
*
)
eth
;
int
ret
=
sizeof
(
*
eth
);
if
(
proto
==
0x8100
)
{
ret
=
sizeof
(
*
vhdr
);
proto
=
ntohs
(
vhdr
->
h_proto
);
printf
(
"%sVLAN %i
\n
"
,
prefix
,
ntohs
(
vhdr
->
h_tci
)
&
0xfff
);
}
printf
(
"%sETH: %04x (%02x:%02x:%02x:%02x:%02x:%02x -> "
"%02x:%02x:%02x:%02x:%02x:%02x)
\n
"
,
prefix
,
ntohs
(
eth
->
h_proto
)
,
"%02x:%02x:%02x:%02x:%02x:%02x)
\n
"
,
prefix
,
proto
,
s
[
0
],
s
[
1
],
s
[
2
],
s
[
3
],
s
[
4
],
s
[
5
],
d
[
0
],
d
[
1
],
d
[
2
],
d
[
3
],
d
[
4
],
d
[
5
]);
return
ret
;
}
static
void
dump_ip
(
char
*
prefix
,
struct
iphdr
*
ip
)
...
...
@@ -169,7 +179,7 @@ static void dump_payload(char *prefix, void *pl, int len)
if
(
version
!=
2
)
{
printf
(
"%sVERSION: unsupported (%i)
\n
"
,
prefix
,
version
);
return
;
goto
out
;
}
printf
(
"%sVERSION: %i (type %i, len %i, domain %i)
\n
"
,
prefix
,
version
,
messageType
,
...
...
@@ -211,7 +221,7 @@ static void dump_payload(char *prefix, void *pl, int len)
donelen
=
44
;
break
;
#if __STDC_HOSTED__
/* Avoid pdelay dump within
g
ppsi, we don't use it */
#if __STDC_HOSTED__
/* Avoid pdelay dump within ppsi, we don't use it */
CASE
(
E
,
PDELAY_REQ
);
dump_msg_sync_etc
(
prefix
,
"MSG-PDELAY_REQ: "
,
msg_specific
);
donelen
=
54
;
...
...
@@ -247,7 +257,7 @@ static void dump_payload(char *prefix, void *pl, int len)
}
donelen
+=
dump_tlv
(
prefix
,
pl
+
donelen
,
n
);
}
out:
/* Finally, binary dump of it all */
dumpstruct
(
prefix
,
"DUMP: "
,
"payload"
,
pl
,
len
);
}
...
...
@@ -256,16 +266,22 @@ static void dump_payload(char *prefix, void *pl, int len)
int
dump_udppkt
(
char
*
prefix
,
void
*
buf
,
int
len
,
struct
TimeInternal
*
ti
)
{
struct
ethhdr
*
eth
=
buf
;
struct
iphdr
*
ip
=
buf
+
ETH_HLEN
;
struct
udphdr
*
udp
=
(
void
*
)(
ip
+
1
)
;
void
*
payload
=
(
void
*
)(
udp
+
1
)
;
struct
iphdr
*
ip
;
struct
udphdr
*
udp
;
void
*
payload
;
if
(
ti
)
dump_time
(
prefix
,
ti
);
dump_eth
(
prefix
,
eth
);
ip
=
buf
+
dump_eth
(
prefix
,
eth
);
dump_ip
(
prefix
,
ip
);
udp
=
(
void
*
)(
ip
+
1
);
dump_udp
(
prefix
,
udp
);
payload
=
(
void
*
)(
udp
+
1
);
dump_payload
(
prefix
,
payload
,
len
-
(
payload
-
buf
));
return
0
;
}
...
...
@@ -282,11 +298,12 @@ int dump_payloadpkt(char *prefix, void *buf, int len, struct TimeInternal *ti)
int
dump_1588pkt
(
char
*
prefix
,
void
*
buf
,
int
len
,
struct
TimeInternal
*
ti
)
{
struct
ethhdr
*
eth
=
buf
;
void
*
payload
=
(
void
*
)(
eth
+
1
)
;
void
*
payload
;
if
(
ti
)
dump_time
(
prefix
,
ti
);
dump_eth
(
prefix
,
eth
);
payload
=
buf
+
dump_eth
(
prefix
,
eth
);
dump_payload
(
prefix
,
payload
,
len
-
(
payload
-
buf
));
return
0
;
}
tools/dump-main.c
View file @
bc172173
...
...
@@ -89,6 +89,7 @@ int main(int argc, char **argv)
/* Ok, now we are promiscuous. Just read stuff forever */
while
(
1
)
{
struct
ethhdr
*
eth
;
struct
pp_vlanhdr
*
vhdr
;
struct
iphdr
*
ip
;
static
unsigned
char
prev
[
1500
];
static
int
prevlen
;
...
...
@@ -98,7 +99,7 @@ int main(int argc, char **argv)
struct
sockaddr_in
from
;
socklen_t
fromlen
=
sizeof
(
from
);
int
len
;
int
len
,
proto
;
len
=
recvfrom
(
sock
,
buf
,
sizeof
(
buf
),
MSG_TRUNC
,
(
struct
sockaddr
*
)
&
from
,
&
fromlen
);
...
...
@@ -120,7 +121,15 @@ int main(int argc, char **argv)
continue
;
eth
=
(
void
*
)
buf
;
ip
=
(
void
*
)(
buf
+
ETH_HLEN
);
switch
(
ntohs
(
eth
->
h_proto
))
{
proto
=
ntohs
(
eth
->
h_proto
);
if
(
proto
==
0x8100
)
{
/* VLAN is visible (e.g.: outgoing) */
vhdr
=
(
void
*
)
buf
;
proto
=
ntohs
(
vhdr
->
h_proto
);
ip
=
(
void
*
)(
buf
+
sizeof
(
*
vhdr
));
}
switch
(
proto
)
{
case
ETH_P_IP
:
{
struct
udphdr
*
udp
=
(
void
*
)(
ip
+
1
);
...
...
tools/ptpdump.h
View file @
bc172173
#ifndef __PTPDUMP_H__
#define __PTPDUMP_H__
#include <ppsi/ppsi.h>
#if __STDC_HOSTED__
#include <time.h>
#include <sys/time.h>
...
...
@@ -8,7 +9,6 @@
#include <netinet/udp.h>
/* struct udphdr */
#include <linux/if_ether.h>
/* struct ethhdr */
#else
#include <ppsi/ppsi.h>
#include "../lib/network_types.h"
#define printf pp_printf
#endif
...
...
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