Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Software for White Rabbit PTP Core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
32
Issues
32
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
CI / CD
CI / CD
Pipelines
Schedules
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
Software for White Rabbit PTP Core
Commits
0c72e452
Commit
0c72e452
authored
Feb 15, 2016
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'network cleanup'
parents
7bab5d84
03285ba4
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
612 additions
and
312 deletions
+612
-312
Kconfig
Kconfig
+8
-0
devel_build_test_defconfig
configs/devel_build_test_defconfig
+3
-2
minic.c
dev/minic.c
+10
-10
board-wrc.h
include/board-wrc.h
+2
-2
ptpd_netif.h
include/ptpd_netif.h
+56
-65
shell.h
include/shell.h
+4
-0
util.h
include/util.h
+4
-1
arp.c
lib/arp.c
+10
-4
bootp.c
lib/bootp.c
+12
-79
ipv4.c
lib/ipv4.c
+119
-30
ipv4.h
lib/ipv4.h
+40
-2
lib.mk
lib/lib.mk
+3
-1
net.c
lib/net.c
+101
-87
syslog.c
lib/syslog.c
+113
-0
udp.c
lib/udp.c
+75
-0
util.c
lib/util.c
+18
-4
monitor_ppsi.c
monitor/monitor_ppsi.c
+1
-1
ppsi
ppsi
+1
-1
cmd_ip.c
shell/cmd_ip.c
+10
-3
cmd_mac.c
shell/cmd_mac.c
+11
-3
cmd_time.c
shell/cmd_time.c
+3
-1
pfilter-builder.c
tools/pfilter-builder.c
+1
-0
wrc_main.c
wrc_main.c
+7
-16
No files found.
Kconfig
View file @
0c72e452
...
...
@@ -83,6 +83,14 @@ config CMD_CONFIG
reports the current configuration. This adds half a kilobyte
to the binary size (100b for the code plus the .config file).
config SYSLOG
depends on IP
boolean "Include syslog client support"
help
This enable a UDP syslog client, configured by a shell command.
The user (or init script) must use "syslog <ipaddr> <macaddr>"
to enable it. The special "off" ipaddr disables syslog.
#
# This is a set of configuration options that should not be changed by
# normal users. If the "developer" menu is used, the binary is tainted.
...
...
configs/devel_build_test_defconfig
View file @
0c72e452
...
...
@@ -13,8 +13,9 @@ CONFIG_STACKSIZE=2048
CONFIG_PPSI=y
CONFIG_UART=y
CONFIG_W1=y
# CONFIG_IP is not set
# CONFIG_CMD_CONFIG is not set
CONFIG_IP=y
CONFIG_CMD_CONFIG=y
CONFIG_SYSLOG=y
#
# wrpc-sw is tainted if you change the following options
...
...
dev/minic.c
View file @
0c72e452
...
...
@@ -194,7 +194,7 @@ int minic_poll_rx()
int
minic_rx_frame
(
uint8_t
*
hdr
,
uint8_t
*
payload
,
uint32_t
buf_size
,
struct
hw_timestamp
*
hwts
)
{
uint32_t
payload_size
,
num_words
;
uint32_t
frame_size
,
payload_size
,
num_words
;
uint32_t
desc_hdr
;
uint32_t
raw_ts
;
uint32_t
cur_avail
;
...
...
@@ -217,8 +217,8 @@ int minic_rx_frame(uint8_t * hdr, uint8_t * payload, uint32_t buf_size,
}
return
0
;
}
payload
_size
=
RX_DESC_SIZE
(
desc_hdr
);
num_words
=
((
payload
_size
+
3
)
>>
2
)
+
1
;
frame
_size
=
RX_DESC_SIZE
(
desc_hdr
);
num_words
=
((
frame
_size
+
3
)
>>
2
)
+
1
;
/* valid packet */
if
(
!
RX_DESC_ERROR
(
desc_hdr
))
{
...
...
@@ -229,15 +229,15 @@ int minic_rx_frame(uint8_t * hdr, uint8_t * payload, uint32_t buf_size,
int
cntr_diff
;
uint16_t
dhdr
;
payload
_size
-=
RX_OOB_SIZE
;
frame
_size
-=
RX_OOB_SIZE
;
/* fixme: ugly way of doing unaligned read */
minic_rx_memcpy
((
uint8_t
*
)
&
raw_ts
,
(
uint8_t
*
)
minic
.
rx_head
+
payload
_size
+
6
,
4
);
+
frame
_size
+
6
,
4
);
minic_rx_memcpy
((
uint8_t
*
)
&
dhdr
,
(
uint8_t
*
)
minic
.
rx_head
+
payload
_size
+
4
,
2
);
frame
_size
+
4
,
2
);
EXPLODE_WR_TIMESTAMP
(
raw_ts
,
counter_r
,
counter_f
);
shw_pps_gen_get_time
(
&
sec
,
&
counter_ppsg
);
...
...
@@ -258,14 +258,14 @@ int minic_rx_frame(uint8_t * hdr, uint8_t * payload, uint32_t buf_size,
hwts
->
nsec
=
counter_r
*
(
REF_CLOCK_PERIOD_PS
/
1000
);
hwts
->
valid
=
(
dhdr
&
RXOOB_TS_INCORRECT
)
?
0
:
1
;
}
payload_size
=
frame_size
-
ETH_HEADER_SIZE
;
n_recvd
=
(
buf_size
<
payload_size
?
buf_size
:
payload_size
);
minic
.
rx_count
++
;
minic_rx_memcpy
(
hdr
,
(
void
*
)
minic
.
rx_head
+
4
,
ETH_HEADER_SIZE
);
minic_rx_memcpy
(
payload
,
(
void
*
)
minic
.
rx_head
+
4
+
ETH_HEADER_SIZE
,
n_recvd
-
ETH_HEADER_SIZE
);
+
ETH_HEADER_SIZE
,
n_recvd
);
}
else
{
n_recvd
=
-
1
;
}
...
...
@@ -299,9 +299,9 @@ int minic_tx_frame(uint8_t * hdr, uint8_t * payload, uint32_t size,
memset
((
void
*
)
minic
.
tx_head
,
0x0
,
size
+
16
);
memset
((
void
*
)
minic
.
tx_head
+
4
,
0
,
size
<
60
?
60
:
size
);
memcpy
((
void
*
)
minic
.
tx_head
+
4
,
hdr
,
ETH_HEADER_SIZE
);
memcpy
((
void
*
)
minic
.
tx_head
+
4
+
ETH_HEADER_SIZE
,
payload
,
size
-
ETH_HEADER_SIZE
);
memcpy
((
void
*
)
minic
.
tx_head
+
4
+
ETH_HEADER_SIZE
,
payload
,
size
);
size
+=
ETH_HEADER_SIZE
;
if
(
size
<
60
)
size
=
60
;
...
...
include/board-wrc.h
View file @
0c72e452
...
...
@@ -31,10 +31,10 @@
#define UART_BAUDRATE 115200ULL
/* Maximum number of simultaneously created sockets */
#define NET_MAX_SOCKETS
4
#define NET_MAX_SOCKETS
8
/* Socket buffer size, determines the max. RX packet size */
#define NET_SKBUF_SIZE 512
#define NET_
MAX_
SKBUF_SIZE 512
/* Number of auxillary clock channels - usually equal to the number of FMCs */
#define NUM_AUX_CLOCKS 1
...
...
include/ptpd_netif.h
View file @
0c72e452
...
...
@@ -15,17 +15,13 @@
#include <board.h>
//#include <inttypes.h>
#define PTPD_SOCK_RAW_ETHERNET 1
/* used in ppsi to no aim: remove this */
#define PTPD_SOCK_UDP 0
/* wrong name, it should be "WRPC" */
#define PTPD_SOCK_RAW_ETHERNET 1
/* but used in ppsi, which I won't change */
#define PTPD_FLAGS_MULTICAST 0x1
// error codes (to be extended)
#define PTPD_NETIF_READY 1
#define PTPD_NETIF_OK 0
#define PTPD_NETIF_ERROR -1
#define PTPD_NETIF_NOT_READY -2
#define PTPD_NETIF_NOT_FOUND -3
#define LINK_WENT_UP 1
#define LINK_WENT_DOWN 2
#define LINK_UP 3
#define LINK_DOWN 4
// GCC-specific
#ifndef PACKED
...
...
@@ -34,35 +30,36 @@
#define PHYS_PORT_ANY (0xffff)
#define PTPD_NETIF_TX 1
#define PTPD_NETIF_RX 2
#define IFACE_NAME_LEN 16
#define SLAVE_PRIORITY_0 0
#define SLAVE_PRIORITY_1 1
#define SLAVE_PRIORITY_2 2
#define SLAVE_PRIORITY_3 3
#define SLAVE_PRIORITY_4 4
// Some system-independent definitions
typedef
uint8_t
mac_addr_t
[
6
];
typedef
uint32_t
ipv4_addr_t
;
// WhiteRabbit socket - it's void pointer as the real socket structure is private and probably platform-specific.
typedef
void
*
wr_socket_t
;
// Socket address for ptp_netif_ functions
typedef
struct
{
// MAC address
struct
wr_sockaddr
{
// MAC address
mac_addr_t
mac
;
// Destination MASC address, filled by recvfrom() function on interfaces bound to multiple addresses
// Destination MAC address, filled by recvfrom()
mac_addr_t
mac_dest
;
// RAW ethertype
// RAW ethertype
uint16_t
ethertype
;
}
wr_sockaddr_t
;
uint16_t
udpport
;
};
struct
sockq
{
uint16_t
head
,
tail
,
avail
,
size
;
uint16_t
n
;
uint8_t
*
buff
;
};
PACKED
struct
_wr_timestamp
{
struct
wrpc_socket
{
struct
wr_sockaddr
bind_addr
;
mac_addr_t
local_mac
;
uint32_t
phase_transition
;
uint32_t
dmtd_phase
;
struct
sockq
queue
;
};
PACKED
struct
wr_timestamp
{
// Seconds
int64_t
sec
;
...
...
@@ -70,7 +67,7 @@ PACKED struct _wr_timestamp {
// Nanoseconds
int32_t
nsec
;
// Phase (in picoseconds), linearized for r
eceive timestamps
, zero for send timestamps
// Phase (in picoseconds), linearized for r
x
, zero for send timestamps
int32_t
phase
;
// phase(picoseconds)
/* Raw time (non-linearized) for debugging purposes */
...
...
@@ -78,54 +75,48 @@ PACKED struct _wr_timestamp {
int32_t
raw_nsec
;
int32_t
raw_ahead
;
//
correctness flag: when 0, the timestamp MAY be incorrect (e.g. generated
during timebase adjustment)
//
when 0, tstamp MAY be incorrect (e.g.
during timebase adjustment)
int
correct
;
//int cntr_ahead;
};
typedef
struct
_wr_timestamp
wr_timestamp_t
;
/* OK. These functions we'll develop along with network card driver. You can write your own UDP-based stubs for testing purposes. */
// Initialization of network interface:
// - opens devices
// - does necessary ioctls()
// - initializes connection with the mighty HAL daemon
int
ptpd_netif_init
(
void
);
// Creates UDP or Ethernet RAW socket (determined by sock_type) bound to bind_addr. If PTPD_FLAG_MULTICAST is set, the socket is
// automatically added to multicast group. User can specify physical_port field to bind the socket to specific switch port only.
wr_socket_t
*
ptpd_netif_create_socket
(
int
unused
,
int
unused2
,
wr_sockaddr_t
*
bind_addr
);
// Creates UDP or Ethernet RAW socket (determined by sock_type) bound
// to bind_addr. If PTPD_FLAG_MULTICAST is set, the socket is
// automatically added to multicast group. User can specify
// physical_port field to bind the socket to specific switch port only.
struct
wrpc_socket
*
ptpd_netif_create_socket
(
struct
wrpc_socket
*
s
,
struct
wr_sockaddr
*
bind_addr
,
int
udp_or_raw
,
int
udpport
);
// Sends a UDP/RAW packet (data, data_length) to addr
ess provided in wr_sockaddr_t
.
// Sends a UDP/RAW packet (data, data_length) to addr
in wr_sockaddr
.
// For raw frames, mac/ethertype needs to be provided, for UDP - ip/port.
// Every transmitted frame has assigned a tag value, stored at tag parameter. This value is later used
// for recovering the precise transmit timestamp. If user doesn't need it, tag parameter can be left NULL.
int
ptpd_netif_sendto
(
wr_socket_t
*
sock
,
wr_sockaddr_t
*
to
,
void
*
data
,
size_t
data_length
,
wr_timestamp_t
*
tx_ts
);
// Receives an UDP/RAW packet. Data is written to (data) and length is returned. Maximum buffer length can be specified
// by data_length parameter. Sender information is stored in structure specified in 'from'. All RXed packets are timestamped and the timestamp
// Every transmitted frame has assigned a tag value, stored at tag parameter.
// This value is later used for recovering the precise transmit timestamp.
// If user doesn't need it, tag parameter can be left NULL.
int
ptpd_netif_sendto
(
struct
wrpc_socket
*
sock
,
struct
wr_sockaddr
*
to
,
void
*
data
,
size_t
data_length
,
struct
wr_timestamp
*
tx_ts
);
// Receives an UDP/RAW packet. Data is written to (data) and len is returned.
// Maximum buffer length can be specified by data_length parameter.
// Sender information is stored in structure specified in 'from'.
// All RXed packets are timestamped and the timestamp
// is stored in rx_timestamp (unless it's NULL).
int
ptpd_netif_recvfrom
(
wr_socket_t
*
sock
,
wr_sockaddr_t
*
from
,
void
*
data
,
size_t
data_length
,
wr_timestamp_t
*
rx_timestamp
);
int
ptpd_netif_recvfrom
(
struct
wrpc_socket
*
sock
,
struct
wr_sockaddr
*
from
,
void
*
data
,
size_t
data_length
,
struct
wr_timestamp
*
rx_timestamp
);
// Closes the socket.
int
ptpd_netif_close_socket
(
wr_socket_t
*
sock
);
int
ptpd_netif_get_hw_addr
(
wr_socket_t
*
sock
,
mac_addr_t
*
mac
);
int
ptpd_netif_close_socket
(
struct
wrpc_socket
*
sock
);
int
ptpd_netif_get_hw_addr
(
wr_socket_
t
*
sock
,
mac_addr_t
*
mac
);
int
ptpd_netif_get_hw_addr
(
struct
wrpc_socke
t
*
sock
,
mac_addr_t
*
mac
);
void
ptpd_netif_linearize_rx_timestamp
(
wr_timestamp_t
*
ts
,
int32_t
dmtd_phase
,
void
ptpd_netif_linearize_rx_timestamp
(
struct
wr_timestamp
*
ts
,
int32_t
dmtd_phase
,
int
cntr_ahead
,
int
transition_point
,
int
clock_period
);
void
ptpd_netif_set_phase_transition
(
uint32_t
phase
);
struct
hal_port_state
;
int
wrpc_get_port_state
(
struct
hal_port_state
*
port
,
const
char
*
port_name
/* unused */
);
int
wrpc_get_port_state
(
struct
hal_port_state
*
port
,
const
char
*
port_name
/* unused */
);
#endif
/* __PTPD_NETIF_H */
include/shell.h
View file @
0c72e452
...
...
@@ -14,6 +14,10 @@ extern int wrc_stat_running;
const
char
*
fromhex
(
const
char
*
hex
,
int
*
v
);
const
char
*
fromdec
(
const
char
*
dec
,
int
*
v
);
void
decode_mac
(
const
char
*
str
,
unsigned
char
*
mac
);
char
*
format_mac
(
char
*
s
,
const
unsigned
char
*
mac
);
void
decode_ip
(
const
char
*
str
,
unsigned
char
*
ip
);
char
*
format_ip
(
char
*
s
,
const
unsigned
char
*
ip
);
struct
wrc_shell_cmd
{
char
*
name
;
...
...
include/util.h
View file @
0c72e452
...
...
@@ -16,7 +16,10 @@
#define C_BLUE 4
/* Return TAI date/time in human-readable form. Non-reentrant. */
char
*
format_time
(
uint64_t
sec
);
char
*
format_time
(
uint64_t
sec
,
int
format
);
#define TIME_FORMAT_LEGACY 0
#define TIME_FORMAT_SYSLOG 1
#define TIME_FORMAT_SORTED 2
/* Color printf() variant. */
void
cprintf
(
int
color
,
const
char
*
fmt
,
...);
...
...
lib/arp.c
View file @
0c72e452
...
...
@@ -16,7 +16,12 @@
#define htons(x) x
#endif
static
wr_socket_t
*
arp_socket
;
static
uint8_t
__arp_queue
[
128
];
static
struct
wrpc_socket
__static_arp_socket
=
{
.
queue
.
buff
=
__arp_queue
,
.
queue
.
size
=
sizeof
(
__arp_queue
),
};
static
struct
wrpc_socket
*
arp_socket
;
#define ARP_HTYPE 0
#define ARP_PTYPE (ARP_HTYPE+2)
...
...
@@ -31,14 +36,15 @@ static wr_socket_t *arp_socket;
void
arp_init
(
void
)
{
wr_sockaddr_t
saddr
;
struct
wr_sockaddr
saddr
;
/* Configure socket filter */
memset
(
&
saddr
,
0
,
sizeof
(
saddr
));
memset
(
&
saddr
.
mac
,
0xFF
,
6
);
/* Broadcast */
saddr
.
ethertype
=
htons
(
0x0806
);
/* ARP */
arp_socket
=
ptpd_netif_create_socket
(
0
,
0
/* both unused */
,
&
saddr
);
arp_socket
=
ptpd_netif_create_socket
(
&
__static_arp_socket
,
&
saddr
,
PTPD_SOCK_RAW_ETHERNET
,
0
);
}
static
int
process_arp
(
uint8_t
*
buf
,
int
len
)
...
...
@@ -85,7 +91,7 @@ static int process_arp(uint8_t * buf, int len)
void
arp_poll
(
void
)
{
uint8_t
buf
[
ARP_END
+
100
];
wr_sockaddr_t
addr
;
struct
wr_sockaddr
addr
;
int
len
;
if
(
needIP
)
...
...
lib/bootp.c
View file @
0c72e452
...
...
@@ -12,30 +12,6 @@
#include "ipv4.h"
#define IP_VERSION 0
#define IP_TOS (IP_VERSION+1)
#define IP_LEN (IP_TOS+1)
#define IP_ID (IP_LEN+2)
#define IP_FLAGS (IP_ID+2)
#define IP_TTL (IP_FLAGS+2)
#define IP_PROTOCOL (IP_TTL+1)
#define IP_CHECKSUM (IP_PROTOCOL+1)
#define IP_SOURCE (IP_CHECKSUM+2)
#define IP_DEST (IP_SOURCE+4)
#define IP_END (IP_DEST+4)
#define UDP_VIRT_SADDR (IP_END-12)
#define UDP_VIRT_DADDR (UDP_VIRT_SADDR+4)
#define UDP_VIRT_ZEROS (UDP_VIRT_DADDR+4)
#define UDP_VIRT_PROTO (UDP_VIRT_ZEROS+1)
#define UDP_VIRT_LENGTH (UDP_VIRT_PROTO+1)
#define UDP_SPORT (IP_END)
#define UDP_DPORT (UDP_SPORT+2)
#define UDP_LENGTH (UDP_DPORT+2)
#define UDP_CHECKSUM (UDP_LENGTH+2)
#define UDP_END (UDP_CHECKSUM+2)
#define BOOTP_OP (UDP_END)
#define BOOTP_HTYPE (BOOTP_OP+1)
#define BOOTP_HLEN (BOOTP_HTYPE+1)
...
...
@@ -53,9 +29,9 @@
#define BOOTP_VEND (BOOTP_FILE+128)
#define BOOTP_END (BOOTP_VEND+64)
int
send_bootp
(
uint8_t
*
buf
,
int
retry
)
int
prepare_bootp
(
struct
wr_sockaddr
*
addr
,
uint8_t
*
buf
,
int
retry
)
{
unsigned
short
sum
;
struct
wr_udp_addr
uaddr
;
// ----------- BOOTP ------------
buf
[
BOOTP_OP
]
=
1
;
/* bootrequest */
...
...
@@ -86,54 +62,16 @@ int send_bootp(uint8_t * buf, int retry)
memset
(
buf
+
BOOTP_FILE
,
0
,
128
);
/* desired BOOTP file */
memset
(
buf
+
BOOTP_VEND
,
0
,
64
);
/* vendor extensions */
// ------------ UDP -------------
memset
(
buf
+
UDP_VIRT_SADDR
,
0
,
4
);
memset
(
buf
+
UDP_VIRT_DADDR
,
0xFF
,
4
);
buf
[
UDP_VIRT_ZEROS
]
=
0
;
buf
[
UDP_VIRT_PROTO
]
=
0x11
;
/* UDP */
buf
[
UDP_VIRT_LENGTH
]
=
(
BOOTP_END
-
IP_END
)
>>
8
;
buf
[
UDP_VIRT_LENGTH
+
1
]
=
(
BOOTP_END
-
IP_END
)
&
0xff
;
buf
[
UDP_SPORT
]
=
0
;
buf
[
UDP_SPORT
+
1
]
=
68
;
/* BOOTP client */
buf
[
UDP_DPORT
]
=
0
;
buf
[
UDP_DPORT
+
1
]
=
67
;
/* BOOTP server */
buf
[
UDP_LENGTH
]
=
(
BOOTP_END
-
IP_END
)
>>
8
;
buf
[
UDP_LENGTH
+
1
]
=
(
BOOTP_END
-
IP_END
)
&
0xff
;
buf
[
UDP_CHECKSUM
]
=
0
;
buf
[
UDP_CHECKSUM
+
1
]
=
0
;
sum
=
ipv4_checksum
((
unsigned
short
*
)(
buf
+
UDP_VIRT_SADDR
),
(
BOOTP_END
-
UDP_VIRT_SADDR
)
/
2
);
if
(
sum
==
0
)
sum
=
0xFFFF
;
buf
[
UDP_CHECKSUM
+
0
]
=
(
sum
>>
8
);
buf
[
UDP_CHECKSUM
+
1
]
=
sum
&
0xff
;
// ------------ IP --------------
buf
[
IP_VERSION
]
=
0x45
;
buf
[
IP_TOS
]
=
0
;
buf
[
IP_LEN
+
0
]
=
(
BOOTP_END
)
>>
8
;
buf
[
IP_LEN
+
1
]
=
(
BOOTP_END
)
&
0xff
;
buf
[
IP_ID
+
0
]
=
0
;
buf
[
IP_ID
+
1
]
=
0
;
buf
[
IP_FLAGS
+
0
]
=
0
;
buf
[
IP_FLAGS
+
1
]
=
0
;
buf
[
IP_TTL
]
=
63
;
buf
[
IP_PROTOCOL
]
=
17
;
/* UDP */
buf
[
IP_CHECKSUM
+
0
]
=
0
;
buf
[
IP_CHECKSUM
+
1
]
=
0
;
memset
(
buf
+
IP_SOURCE
,
0
,
4
);
memset
(
buf
+
IP_DEST
,
0xFF
,
4
);
sum
=
ipv4_checksum
((
unsigned
short
*
)(
buf
+
IP_VERSION
),
(
IP_END
-
IP_VERSION
)
/
2
);
buf
[
IP_CHECKSUM
+
0
]
=
sum
>>
8
;
buf
[
IP_CHECKSUM
+
1
]
=
sum
&
0xff
;
/* complete with udp helper */
memset
(
&
uaddr
.
saddr
,
0
,
4
);
memset
(
&
uaddr
.
daddr
,
0xff
,
4
);
uaddr
.
sport
=
ntohs
(
68
);
uaddr
.
dport
=
ntohs
(
67
);
fill_udp
(
buf
,
BOOTP_END
,
&
uaddr
);
/* and fix destination before sending it */
memset
(
addr
->
mac
,
0xFF
,
6
);
// pp_printf("Sending BOOTP request...\n");
return
BOOTP_END
;
}
...
...
@@ -148,12 +86,7 @@ int process_bootp(uint8_t * buf, int len)
if
(
len
!=
BOOTP_END
)
return
0
;
if
(
buf
[
IP_VERSION
]
!=
0x45
)
return
0
;
if
(
buf
[
IP_PROTOCOL
]
!=
17
||
buf
[
UDP_DPORT
]
!=
0
||
buf
[
UDP_DPORT
+
1
]
!=
68
||
buf
[
UDP_SPORT
]
!=
0
||
buf
[
UDP_SPORT
+
1
]
!=
67
)
if
(
buf
[
UDP_SPORT
]
!=
0
||
buf
[
UDP_SPORT
+
1
]
!=
67
)
return
0
;
if
(
memcmp
(
buf
+
BOOTP_CHADDR
,
mac
,
6
))
...
...
lib/ipv4.c
View file @
0c72e452
...
...
@@ -7,10 +7,12 @@
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <string.h>
#include <wrpc.h>
#include "endpoint.h"
#include "ipv4.h"
#include "ptpd_netif.h"
#include "pps_gen.h"
#include "hw/memlayout.h"
#include "hw/etherbone-config.h"
...
...
@@ -20,7 +22,37 @@
int
needIP
=
1
;
static
uint8_t
myIP
[
4
];
static
wr_socket_t
*
ipv4_socket
;
/* bootp: bigger buffer, UDP based */
static
uint8_t
__bootp_queue
[
512
];
static
struct
wrpc_socket
__static_bootp_socket
=
{
.
queue
.
buff
=
__bootp_queue
,
.
queue
.
size
=
sizeof
(
__bootp_queue
),
};
static
struct
wrpc_socket
*
bootp_socket
;
/* ICMP: smaller buffer */
static
uint8_t
__icmp_queue
[
128
];
static
struct
wrpc_socket
__static_icmp_socket
=
{
.
queue
.
buff
=
__icmp_queue
,
.
queue
.
size
=
sizeof
(
__icmp_queue
),
};
static
struct
wrpc_socket
*
icmp_socket
;
/* RDATE: even smaller buffer -- but we require 86. 96 is "even". */
static
uint8_t
__rdate_queue
[
96
];
static
struct
wrpc_socket
__static_rdate_socket
=
{
.
queue
.
buff
=
__rdate_queue
,
.
queue
.
size
=
sizeof
(
__rdate_queue
),
};
static
struct
wrpc_socket
*
rdate_socket
;
/* syslog is selected by Kconfig, so we have weak aliases here */
void
__attribute__
((
weak
))
syslog_init
(
void
)
{
}
void
__attribute__
((
weak
))
syslog_poll
(
int
l_status
)
{
}
unsigned
int
ipv4_checksum
(
unsigned
short
*
buf
,
int
shorts
)
{
...
...
@@ -29,7 +61,7 @@ unsigned int ipv4_checksum(unsigned short *buf, int shorts)
sum
=
0
;
for
(
i
=
0
;
i
<
shorts
;
++
i
)
sum
+=
buf
[
i
]
;
sum
+=
ntohs
(
buf
[
i
])
;
sum
=
(
sum
>>
16
)
+
(
sum
&
0xffff
);
sum
+=
(
sum
>>
16
);
...
...
@@ -39,47 +71,106 @@ unsigned int ipv4_checksum(unsigned short *buf, int shorts)
void
ipv4_init
(
void
)
{
wr_sockaddr_t
saddr
;
struct
wr_sockaddr
saddr
;
/* Reset => need a fresh IP */
needIP
=
1
;
/* Bootp: use UDP engine activated but function arguments */
bootp_socket
=
ptpd_netif_create_socket
(
&
__static_bootp_socket
,
NULL
,
PTPD_SOCK_UDP
,
68
/* bootpc */
);
/* Configure socket filter */
/* time (rdate): UDP */
rdate_socket
=
ptpd_netif_create_socket
(
&
__static_rdate_socket
,
NULL
,
PTPD_SOCK_UDP
,
37
/* time */
);
/* ICMP: specify raw (not UDP), with IPV4 ethtype */
memset
(
&
saddr
,
0
,
sizeof
(
saddr
));
get_mac_addr
(
&
saddr
.
mac
[
0
]);
/* Unicast */
saddr
.
ethertype
=
htons
(
0x0800
);
/* IPv4 */
saddr
.
ethertype
=
htons
(
0x0800
);
icmp_socket
=
ptpd_netif_create_socket
(
&
__static_icmp_socket
,
&
saddr
,
PTPD_SOCK_RAW_ETHERNET
,
0
);
ipv4_socket
=
ptpd_netif_create_socket
(
0
,
0
/* both unused */
,
&
saddr
);
syslog_init
(
);
}
static
int
bootp_retry
=
0
;
static
int
bootp_timer
=
0
;
static
uint32_t
bootp_tics
;
void
ipv4_poll
(
void
)
/* receive bootp through the UDP mechanism */
static
void
bootp_poll
(
void
)
{
struct
wr_sockaddr
addr
;
uint8_t
buf
[
400
];
wr_sockaddr_t
addr
;
int
len
;
if
((
len
=
ptpd_netif_recvfrom
(
ipv4_socket
,
&
addr
,
buf
,
sizeof
(
buf
),
0
))
>
0
)
{
if
(
needIP
)
if
(
!
bootp_tics
)
/* first time ever */
bootp_tics
=
timer_get_tics
()
-
1
;
len
=
ptpd_netif_recvfrom
(
bootp_socket
,
&
addr
,
buf
,
sizeof
(
buf
),
NULL
);
if
(
len
>
0
&&
needIP
)
process_bootp
(
buf
,
len
);
if
(
!
needIP
&&
(
len
=
process_icmp
(
buf
,
len
))
>
0
)
ptpd_netif_sendto
(
ipv4_socket
,
&
addr
,
buf
,
len
,
0
);
}
if
(
!
needIP
)
return
;
if
(
time_before
(
timer_get_tics
(),
bootp_tics
))
return
;
len
=
prepare_bootp
(
&
addr
,
buf
,
++
bootp_retry
);
ptpd_netif_sendto
(
bootp_socket
,
&
addr
,
buf
,
len
,
0
);
bootp_tics
=
timer_get_tics
()
+
TICS_PER_SECOND
;
}
static
void
icmp_poll
(
void
)
{
struct
wr_sockaddr
addr
;
uint8_t
buf
[
128
];
int
len
;
len
=
ptpd_netif_recvfrom
(
icmp_socket
,
&
addr
,
buf
,
sizeof
(
buf
),
NULL
);
if
(
len
<=
0
)
return
;
if
(
needIP
)
return
;
if
((
len
=
process_icmp
(
buf
,
len
))
>
0
)
ptpd_netif_sendto
(
icmp_socket
,
&
addr
,
buf
,
len
,
0
);
}
static
void
rdate_poll
(
void
)
{
struct
wr_sockaddr
addr
;
uint64_t
secs
;
uint32_t
result
;
uint8_t
buf
[
32
];
int
len
;
len
=
ptpd_netif_recvfrom
(
rdate_socket
,
&
addr
,
buf
,
sizeof
(
buf
),
NULL
);
if
(
len
<=
0
)
return
;
shw_pps_gen_get_time
(
&
secs
,
NULL
);
result
=
htonl
((
uint32_t
)(
secs
+
2208988800LL
));
/* Magic above: $(date +%s --date="Jan 1 1900 00:00:00 UTC)" */
len
=
UDP_END
+
sizeof
(
result
);
memcpy
(
buf
+
UDP_END
,
&
result
,
sizeof
(
result
));
fill_udp
(
buf
,
len
,
NULL
);
ptpd_netif_sendto
(
rdate_socket
,
&
addr
,
buf
,
len
,
0
);
}
void
ipv4_poll
(
int
l_status
)
{
if
(
l_status
==
LINK_WENT_UP
)
needIP
=
1
;
bootp_poll
();
if
(
needIP
&&
bootp_timer
==
0
)
{
len
=
send_bootp
(
buf
,
++
bootp_retry
);
icmp_poll
();
memset
(
addr
.
mac
,
0xFF
,
6
);
addr
.
ethertype
=
htons
(
0x0800
);
/* IPv4 */
ptpd_netif_sendto
(
ipv4_socket
,
&
addr
,
buf
,
len
,
0
);
}
rdate_poll
();
if
(
needIP
&&
++
bootp_timer
==
100000
)
bootp_timer
=
0
;
syslog_poll
(
l_status
);
}
void
getIP
(
unsigned
char
*
IP
)
...
...
@@ -100,8 +191,6 @@ void setIP(unsigned char *IP)
*
eb_ip
=
ip
;
needIP
=
(
ip
==
0
);
if
(
!
needIP
)
{
if
(
!
needIP
)
bootp_retry
=
0
;
bootp_timer
=
0
;
}
}
lib/ipv4.h
View file @
0c72e452
...
...
@@ -7,9 +7,34 @@
#define IPV4_H
#include <inttypes.h>
#include "ptpd_netif.h"
/* for sockaddr in prototype */
#define IP_VERSION 0
#define IP_TOS (IP_VERSION+1)
#define IP_LEN (IP_TOS+1)
#define IP_ID (IP_LEN+2)
#define IP_FLAGS (IP_ID+2)
#define IP_TTL (IP_FLAGS+2)
#define IP_PROTOCOL (IP_TTL+1)
#define IP_CHECKSUM (IP_PROTOCOL+1)
#define IP_SOURCE (IP_CHECKSUM+2)
#define IP_DEST (IP_SOURCE+4)
#define IP_END (IP_DEST+4)
#define UDP_VIRT_SADDR (IP_END-12)
#define UDP_VIRT_DADDR (UDP_VIRT_SADDR+4)
#define UDP_VIRT_ZEROS (UDP_VIRT_DADDR+4)
#define UDP_VIRT_PROTO (UDP_VIRT_ZEROS+1)
#define UDP_VIRT_LENGTH (UDP_VIRT_PROTO+1)
#define UDP_SPORT (IP_END)
#define UDP_DPORT (UDP_SPORT+2)
#define UDP_LENGTH (UDP_DPORT+2)
#define UDP_CHECKSUM (UDP_LENGTH+2)
#define UDP_END (UDP_CHECKSUM+2)
void
ipv4_init
(
void
);
void
ipv4_poll
(
void
);
void
ipv4_poll
(
int
l_status
);
/* Internal to IP stack: */
unsigned
int
ipv4_checksum
(
unsigned
short
*
buf
,
int
shorts
);
...
...
@@ -23,6 +48,19 @@ void getIP(unsigned char *IP);
int
process_icmp
(
uint8_t
*
buf
,
int
len
);
int
process_bootp
(
uint8_t
*
buf
,
int
len
);
/* non-zero if IP was set */
int
send_bootp
(
uint8_t
*
buf
,
int
retry
);
int
prepare_bootp
(
struct
wr_sockaddr
*
addr
,
uint8_t
*
buf
,
int
retry
);
/* The UDP helper needs some information, if not replying to a frame */
struct
wr_udp_addr
{
uint32_t
saddr
;
/* all fields in network order, for memcpy */
uint32_t
daddr
;
uint16_t
sport
;
uint16_t
dport
;
};
void
fill_udp
(
uint8_t
*
buf
,
int
len
,
struct
wr_udp_addr
*
uaddr
);
void
syslog_init
(
void
);
void
syslog_poll
(
int
l_status
);
#endif
lib/lib.mk
View file @
0c72e452
obj-y += lib/util.o lib/atoi.o
obj-y += lib/usleep.o
obj-$(CONFIG_WR_NODE) += lib/net.o
obj-$(CONFIG_WR_NODE) += lib/net.o
lib/udp.o
obj-$(CONFIG_WR_NODE) += lib/arp.o lib/icmp.o lib/ipv4.o lib/bootp.o
obj-$(CONFIG_SYSLOG) += lib/syslog.o
lib/net.c
View file @
0c72e452
...
...
@@ -22,47 +22,20 @@
#include "minic.h"
#include "endpoint.h"
#include "softpll_ng.h"
#include "ipv4.h"
#define min(x,y) ((x) < (y) ? (x) : (y))
__attribute__
((
packed
))
struct
ethhdr
{
uint8_t
dstmac
[
6
];
uint8_t
srcmac
[
6
];
uint16_t
ethtype
;
};
struct
timeout
{
uint64_t
start_tics
;
uint64_t
timeout
;
};
struct
sockq
{
uint8_t
buf
[
NET_SKBUF_SIZE
];
uint16_t
head
,
tail
,
avail
;
uint16_t
n
;
};
struct
my_socket
{
int
in_use
;
wr_sockaddr_t
bind_addr
;
mac_addr_t
local_mac
;
uint32_t
phase_transition
;
uint32_t
dmtd_phase
;
struct
sockq
queue
;
};
static
struct
my_socket
socks
[
NET_MAX_SOCKETS
];
int
ptpd_netif_init
()
{
memset
(
socks
,
0
,
sizeof
(
socks
));
return
PTPD_NETIF_OK
;
}
static
struct
wrpc_socket
*
socks
[
NET_MAX_SOCKETS
];
//#define net_verbose pp_printf
int
ptpd_netif_get_hw_addr
(
wr_socket_t
*
sock
,
mac_addr_t
*
mac
)
int
ptpd_netif_get_hw_addr
(
struct
wrpc_socket
*
sock
,
mac_addr_t
*
mac
)
{
get_mac_addr
((
uint8_t
*
)
mac
);
...
...
@@ -73,35 +46,45 @@ void ptpd_netif_set_phase_transition(uint32_t phase)
{
int
i
;
for
(
i
=
0
;
i
<
NET_MAX_SOCKETS
;
++
i
)
{
socks
[
i
]
.
phase_transition
=
phase
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
socks
)
;
++
i
)
{
socks
[
i
]
->
phase_transition
=
phase
;
}
}
wr_socket_t
*
ptpd_netif_create_socket
(
int
unused
,
int
unusd2
,
wr_sockaddr_t
*
bind_addr
)
struct
wrpc_socket
*
ptpd_netif_create_socket
(
struct
wrpc_socket
*
sock
,
struct
wr_sockaddr
*
bind_addr
,
int
udp_or_raw
,
int
udpport
)
{
int
i
;
struct
hal_port_state
pstate
;
st
ruct
my_socket
*
sock
;
st
atic
mac_addr_t
zero_mac
;
/* Look for the first available socket. */
for
(
sock
=
NULL
,
i
=
0
;
i
<
NET_MAX_SOCKETS
;
i
++
)
if
(
!
socks
[
i
]
.
in_use
)
{
sock
=
&
socks
[
i
]
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
socks
)
;
i
++
)
if
(
!
socks
[
i
])
{
sock
s
[
i
]
=
sock
;
break
;
}
if
(
!
sock
)
{
net_verbose
(
"No sockets left.
\n
"
);
if
(
i
==
ARRAY_SIZE
(
socks
))
{
pp_printf
(
"%s: no socket slots left
\n
"
,
__func__
);
return
NULL
;
}
if
(
wrpc_get_port_state
(
&
pstate
,
"wr0"
/* unused */
)
<
0
)
return
NULL
;
memcpy
(
&
sock
->
bind_addr
,
bind_addr
,
sizeof
(
wr_sockaddr_t
));
/* copy and complete the bind information. If MAC is 0 use unicast */
memset
(
&
sock
->
bind_addr
,
0
,
sizeof
(
struct
wr_sockaddr
));
if
(
bind_addr
)
memcpy
(
&
sock
->
bind_addr
,
bind_addr
,
sizeof
(
struct
wr_sockaddr
));
if
(
!
memcmp
(
sock
->
bind_addr
.
mac
,
zero_mac
,
ETH_ALEN
))
get_mac_addr
(
sock
->
bind_addr
.
mac
);
sock
->
bind_addr
.
udpport
=
0
;
if
(
udp_or_raw
==
PTPD_SOCK_UDP
)
{
sock
->
bind_addr
.
ethertype
=
htons
(
0x0800
);
/* IPv4 */
sock
->
bind_addr
.
udpport
=
udpport
;
}
/*get mac from endpoint */
get_mac_addr
(
sock
->
local_mac
);
...
...
@@ -111,19 +94,18 @@ wr_socket_t *ptpd_netif_create_socket(int unused, int unusd2,
/*packet queue */
sock
->
queue
.
head
=
sock
->
queue
.
tail
=
0
;
sock
->
queue
.
avail
=
NET_SKBUF_SIZE
;
sock
->
queue
.
avail
=
sock
->
queue
.
size
;
sock
->
queue
.
n
=
0
;
sock
->
in_use
=
1
;
return
(
wr_socket_t
*
)
(
sock
)
;
return
sock
;
}
int
ptpd_netif_close_socket
(
wr_socket_t
*
sock
)
int
ptpd_netif_close_socket
(
struct
wrpc_socket
*
s
)
{
struct
my_socket
*
s
=
(
struct
my_socket
*
)
sock
;
if
(
s
)
s
->
in_use
=
0
;
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
socks
);
i
++
)
if
(
socks
[
i
]
==
s
)
socks
[
i
]
=
NULL
;
return
0
;
}
...
...
@@ -136,7 +118,8 @@ int ptpd_netif_close_socket(wr_socket_t * sock)
*
* Have a look at the note at http://ohwr.org/documents/xxx for details.
*/
void
ptpd_netif_linearize_rx_timestamp
(
wr_timestamp_t
*
ts
,
int32_t
dmtd_phase
,
void
ptpd_netif_linearize_rx_timestamp
(
struct
wr_timestamp
*
ts
,
int32_t
dmtd_phase
,
int
cntr_ahead
,
int
transition_point
,
int
clock_period
)
{
...
...
@@ -202,20 +185,27 @@ void ptpd_netif_linearize_rx_timestamp(wr_timestamp_t * ts, int32_t dmtd_phase,
}
/* Slow, but we don't care much... */
static
int
wrap_copy_in
(
void
*
dst
,
struct
sockq
*
q
,
size_t
len
)
static
int
wrap_copy_in
(
void
*
dst
,
struct
sockq
*
q
,
size_t
len
,
size_t
buflen
)
{
char
*
dptr
=
dst
;
int
i
=
len
;
net_verbose
(
"copy_in: tail %d avail %d len %d
\n
"
,
q
->
tail
,
q
->
avail
,
len
);
int
i
;
if
(
!
buflen
)
buflen
=
len
;
net_verbose
(
"copy_in: tail %d avail %d len %d (buf %d)
\n
"
,
q
->
tail
,
q
->
avail
,
len
,
buflen
);
i
=
min
(
len
,
buflen
);
while
(
i
--
)
{
*
dptr
++
=
q
->
buf
[
q
->
tail
];
*
dptr
++
=
q
->
buf
f
[
q
->
tail
];
q
->
tail
++
;
if
(
q
->
tail
==
NET_SKBUF_SIZE
)
if
(
q
->
tail
==
q
->
size
)
q
->
tail
=
0
;
}
if
(
len
>
buflen
)
{
q
->
tail
+=
len
-
buflen
;
while
(
q
->
tail
>
q
->
size
)
q
->
tail
-=
q
->
size
;
}
return
len
;
}
...
...
@@ -228,17 +218,16 @@ static int wrap_copy_out(struct sockq *q, void *src, size_t len)
len
);
while
(
i
--
)
{
q
->
buf
[
q
->
head
++
]
=
*
sptr
++
;
if
(
q
->
head
==
NET_SKBUF_SIZE
)
q
->
buf
f
[
q
->
head
++
]
=
*
sptr
++
;
if
(
q
->
head
==
q
->
size
)
q
->
head
=
0
;
}
return
len
;
}
int
ptpd_netif_recvfrom
(
wr_socket_t
*
sock
,
wr_sockaddr_t
*
from
,
void
*
data
,
size_t
data_length
,
wr_timestamp_t
*
rx_timestamp
)
int
ptpd_netif_recvfrom
(
struct
wrpc_socket
*
s
,
struct
wr_sockaddr
*
from
,
void
*
data
,
size_t
data_length
,
struct
wr_timestamp
*
rx_timestamp
)
{
struct
my_socket
*
s
=
(
struct
my_socket
*
)
sock
;
struct
sockq
*
q
=
&
s
->
queue
;
uint16_t
size
;
...
...
@@ -252,10 +241,10 @@ int ptpd_netif_recvfrom(wr_socket_t * sock, wr_sockaddr_t * from, void *data,
q
->
n
--
;
q
->
avail
+=
wrap_copy_in
(
&
size
,
q
,
2
);
q
->
avail
+=
wrap_copy_in
(
&
h
dr
,
q
,
sizeof
(
struct
ethhdr
)
);
q
->
avail
+=
wrap_copy_in
(
&
h
wts
,
q
,
sizeof
(
struct
hw_timestamp
)
);
q
->
avail
+=
wrap_copy_in
(
data
,
q
,
min
(
size
,
data_length
)
);
q
->
avail
+=
wrap_copy_in
(
&
size
,
q
,
2
,
0
);
q
->
avail
+=
wrap_copy_in
(
&
h
wts
,
q
,
sizeof
(
struct
hw_timestamp
),
0
);
q
->
avail
+=
wrap_copy_in
(
&
h
dr
,
q
,
sizeof
(
struct
ethhdr
),
0
);
q
->
avail
+=
wrap_copy_in
(
data
,
q
,
size
,
data_length
);
from
->
ethertype
=
ntohs
(
hdr
.
ethtype
);
memcpy
(
from
->
mac
,
hdr
.
srcmac
,
6
);
...
...
@@ -279,28 +268,34 @@ int ptpd_netif_recvfrom(wr_socket_t * sock, wr_sockaddr_t * from, void *data,
REF_CLOCK_PERIOD_PS
);
}
net_verbose
(
"%s: called from %p
\n
"
,
__func__
,
__builtin_return_address
(
0
));
net_verbose
(
"RX: Size %d tail %d Smac %x:%x:%x:%x:%x:%x
\n
"
,
size
,
q
->
tail
,
hdr
.
srcmac
[
0
],
hdr
.
srcmac
[
1
],
hdr
.
srcmac
[
2
],
hdr
.
srcmac
[
3
],
hdr
.
srcmac
[
4
],
hdr
.
srcmac
[
5
]);
return
min
(
size
-
sizeof
(
struct
ethhdr
)
,
data_length
);
return
min
(
size
,
data_length
);
}
int
ptpd_netif_sendto
(
wr_socket_t
*
sock
,
wr_sockaddr_t
*
to
,
void
*
data
,
size_t
data_length
,
wr_timestamp_t
*
tx_timestamp
)
int
ptpd_netif_sendto
(
struct
wrpc_socket
*
sock
,
struct
wr_sockaddr
*
to
,
void
*
data
,
size_t
data_length
,
struct
wr_timestamp
*
tx_timestamp
)
{
struct
my_socket
*
s
=
(
struct
my
_socket
*
)
sock
;
struct
wrpc_socket
*
s
=
(
struct
wrpc
_socket
*
)
sock
;
struct
hw_timestamp
hwts
;
struct
ethhdr
hdr
;
int
rval
;
memcpy
(
hdr
.
dstmac
,
to
->
mac
,
6
);
memcpy
(
hdr
.
srcmac
,
s
->
local_mac
,
6
);
hdr
.
ethtype
=
to
->
ethertype
;
hdr
.
ethtype
=
sock
->
bind_addr
.
ethertype
;
net_verbose
(
"TX: socket %04x:%04x, len %i
\n
"
,
ntohs
(
s
->
bind_addr
.
ethertype
),
s
->
bind_addr
.
udpport
,
data_length
);
rval
=
minic_tx_frame
((
uint8_t
*
)
&
hdr
,
(
uint8_t
*
)
data
,
data_length
+
ETH_HEADER_SIZE
,
&
hwts
);
data_length
,
&
hwts
);
if
(
tx_timestamp
)
{
...
...
@@ -315,30 +310,46 @@ int ptpd_netif_sendto(wr_socket_t * sock, wr_sockaddr_t * to, void *data,
void
update_rx_queues
()
{
struct
my
_socket
*
s
=
NULL
;
struct
wrpc
_socket
*
s
=
NULL
;
struct
sockq
*
q
;
struct
hw_timestamp
hwts
;
static
struct
ethhdr
hdr
;
int
recvd
,
i
,
q_required
;
static
uint8_t
payload
[
NET_SKBUF_SIZE
-
32
];
uint16_t
size
;
static
uint8_t
payload
[
NET_
MAX_
SKBUF_SIZE
-
32
];
uint16_t
size
,
port
;
recvd
=
minic_rx_frame
((
uint8_t
*
)
&
hdr
,
payload
,
NET_SKBUF_SIZE
-
32
,
minic_rx_frame
((
uint8_t
*
)
&
hdr
,
payload
,
sizeof
(
payload
)
,
&
hwts
);
if
(
recvd
<=
0
)
/* No data received? */
return
;
for
(
i
=
0
;
i
<
NET_MAX_SOCKETS
;
i
++
)
{
s
=
&
socks
[
i
];
if
(
s
->
in_use
&&
!
memcmp
(
hdr
.
dstmac
,
s
->
bind_addr
.
mac
,
6
)
&&
hdr
.
ethtype
==
s
->
bind_addr
.
ethertype
)
break
;
/*they match */
s
=
NULL
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
socks
);
i
++
)
{
s
=
socks
[
i
];
if
(
!
s
)
continue
;
if
(
memcmp
(
hdr
.
dstmac
,
s
->
bind_addr
.
mac
,
6
))
continue
;
if
(
hdr
.
ethtype
!=
s
->
bind_addr
.
ethertype
)
continue
;
if
(
s
->
bind_addr
.
udpport
==
0
)
break
;
/* raw socket: match */
/* Now make IP/UDP checks */
if
(
payload
[
IP_VERSION
]
!=
0x45
)
continue
;
if
(
payload
[
IP_PROTOCOL
]
!=
17
)
continue
;
port
=
payload
[
UDP_DPORT
]
<<
8
|
payload
[
UDP_DPORT
+
1
];
if
(
port
!=
s
->
bind_addr
.
udpport
)
continue
;
break
;
/* udp match */
}
if
(
!
s
)
{
if
(
i
==
ARRAY_SIZE
(
socks
)
)
{
net_verbose
(
"%s: could not find socket for packet
\n
"
,
__FUNCTION__
);
return
;
...
...
@@ -358,8 +369,8 @@ void update_rx_queues()
size
=
recvd
;
q
->
avail
-=
wrap_copy_out
(
q
,
&
size
,
2
);
q
->
avail
-=
wrap_copy_out
(
q
,
&
hdr
,
sizeof
(
struct
ethhdr
));
q
->
avail
-=
wrap_copy_out
(
q
,
&
hwts
,
sizeof
(
struct
hw_timestamp
));
q
->
avail
-=
wrap_copy_out
(
q
,
&
hdr
,
sizeof
(
struct
ethhdr
));
q
->
avail
-=
wrap_copy_out
(
q
,
payload
,
size
);
q
->
n
++
;
...
...
@@ -367,6 +378,9 @@ void update_rx_queues()
q
->
head
,
hdr
.
srcmac
[
0
],
hdr
.
srcmac
[
1
],
hdr
.
srcmac
[
2
],
hdr
.
srcmac
[
3
],
hdr
.
srcmac
[
4
],
hdr
.
srcmac
[
5
]);
net_verbose
(
"%s: saved packet to queue [avail %d n %d size %d]
\n
"
,
__FUNCTION__
,
q
->
avail
,
q
->
n
,
q_required
);
net_verbose
(
"%s: saved packet to socket %04x:%04x "
"[avail %d n %d size %d]
\n
"
,
__FUNCTION__
,
ntohs
(
s
->
bind_addr
.
ethertype
),
s
->
bind_addr
.
udpport
,
q
->
avail
,
q
->
n
,
q_required
);
}
lib/syslog.c
0 → 100644
View file @
0c72e452
#include <string.h>
#include <wrc.h>
#include <wrpc.h>
#include "endpoint.h"
#include "minic.h"
#include "shell.h"
#include "pps_gen.h"
#include "ipv4.h"
/* syslog: a tx-only socket: no queue is there */
static
struct
wrpc_socket
__static_syslog_socket
=
{
.
queue
.
buff
=
NULL
,
.
queue
.
size
=
0
,
};
static
struct
wrpc_socket
*
syslog_socket
;
static
struct
wr_udp_addr
syslog_addr
;
unsigned
char
syslog_mac
[
6
];
static
uint32_t
tics
,
tics_zero
;
void
syslog_init
(
void
)
{
syslog_socket
=
ptpd_netif_create_socket
(
&
__static_syslog_socket
,
NULL
,
PTPD_SOCK_UDP
,
514
/* time */
);
syslog_addr
.
sport
=
syslog_addr
.
dport
=
htons
(
514
);
tics_zero
=
timer_get_tics
();
}
static
int
cmd_syslog
(
const
char
*
args
[])
{
char
b1
[
32
],
b2
[
32
];
if
(
args
[
0
]
&&
!
strcmp
(
args
[
0
],
"off"
))
{
syslog_addr
.
daddr
=
0
;
return
0
;
}
if
(
!
args
[
1
])
{
pp_printf
(
"use: syslog <ipaddr> <macaddr> (or just
\"
off
\"\n
"
);
return
-
1
;
}
decode_ip
(
args
[
0
],
(
void
*
)
&
syslog_addr
.
daddr
);
decode_mac
(
args
[
1
],
syslog_mac
);
pp_printf
(
"Syslog parameters: %s, %s
\n
"
,
format_ip
(
b1
,
(
void
*
)
&
syslog_addr
.
daddr
),
format_mac
(
b2
,
syslog_mac
));
tics
=
0
;
/* send the first frame immediately to the new host */
return
0
;
}
DEFINE_WRC_COMMAND
(
mac
)
=
{
.
name
=
"syslog"
,
.
exec
=
cmd_syslog
,
};
void
syslog_poll
(
int
l_status
)
{
struct
wr_sockaddr
addr
;
char
buf
[
256
];
char
b1
[
32
],
b2
[
32
];
unsigned
char
mac
[
6
];
unsigned
char
ip
[
4
];
uint64_t
secs
;
static
uint32_t
down_tics
;
int
len
=
0
;
if
(
needIP
)
return
;
if
(
!
syslog_addr
.
daddr
)
return
;
if
(
!
tics
)
{
/* first time ever, or new syslog server */
tics
=
timer_get_tics
()
-
1
;
shw_pps_gen_get_time
(
&
secs
,
NULL
);
get_mac_addr
(
mac
);
getIP
(
ip
);
len
=
pp_sprintf
(
buf
+
UDP_END
,
/* 8 == user + 6 == info */
"<14> %s %s (%s) Node up "
"since %i seconds
\n
"
,
format_time
(
secs
,
TIME_FORMAT_SYSLOG
),
format_ip
(
b1
,
ip
),
format_mac
(
b2
,
mac
),
(
tics
-
tics_zero
)
/
1000
);
goto
send
;
}
if
(
l_status
==
LINK_WENT_DOWN
)
down_tics
=
timer_get_tics
();
if
(
l_status
==
LINK_UP
&&
down_tics
)
{
down_tics
=
timer_get_tics
()
-
down_tics
;
shw_pps_gen_get_time
(
&
secs
,
NULL
);
getIP
(
ip
);
len
=
pp_sprintf
(
buf
+
UDP_END
,
/* 8 == user + 6 == info */
"<14> %s %s Link up after %i.%03i s
\n
"
,
format_time
(
secs
,
TIME_FORMAT_SYSLOG
),
format_ip
(
b1
,
ip
),
down_tics
/
1000
,
down_tics
%
1000
);
down_tics
=
0
;
goto
send
;
}
return
;
send:
len
+=
UDP_END
;
memcpy
(
&
syslog_addr
.
saddr
,
ip
,
4
);
fill_udp
((
void
*
)
buf
,
len
,
&
syslog_addr
);
memcpy
(
&
addr
.
mac
,
syslog_mac
,
6
);
ptpd_netif_sendto
(
syslog_socket
,
&
addr
,
buf
,
len
,
0
);
}
lib/udp.c
0 → 100644
View file @
0c72e452
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2016 GSI (www.gsi.de)
* Author: Alessandro Rubini <a.rubini@gsi.de>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <string.h>
#include "ipv4.h"
#include "ptpd_netif.h"
void
fill_udp
(
uint8_t
*
buf
,
int
len
,
struct
wr_udp_addr
*
uaddr
)
{
unsigned
short
sum
;
struct
wr_udp_addr
addr
;
/* if there is no user-provided uaddr, we are replying */
if
(
!
uaddr
)
{
memcpy
(
&
addr
.
daddr
,
buf
+
IP_SOURCE
,
4
);
memcpy
(
&
addr
.
saddr
,
buf
+
IP_DEST
,
4
);
memcpy
(
&
addr
.
dport
,
buf
+
UDP_SPORT
,
2
);
memcpy
(
&
addr
.
sport
,
buf
+
UDP_DPORT
,
2
);
uaddr
=
&
addr
;
}
// ------------ UDP -------------
memcpy
(
buf
+
UDP_VIRT_SADDR
,
&
uaddr
->
saddr
,
4
);
memcpy
(
buf
+
UDP_VIRT_DADDR
,
&
uaddr
->
daddr
,
4
);
buf
[
UDP_VIRT_ZEROS
]
=
0
;
buf
[
UDP_VIRT_PROTO
]
=
0x11
;
/* UDP */
buf
[
UDP_VIRT_LENGTH
]
=
(
len
-
IP_END
)
>>
8
;
buf
[
UDP_VIRT_LENGTH
+
1
]
=
(
len
-
IP_END
)
&
0xff
;
memcpy
(
buf
+
UDP_SPORT
,
&
uaddr
->
sport
,
2
);
memcpy
(
buf
+
UDP_DPORT
,
&
uaddr
->
dport
,
2
);
buf
[
UDP_LENGTH
]
=
(
len
-
IP_END
)
>>
8
;
buf
[
UDP_LENGTH
+
1
]
=
(
len
-
IP_END
)
&
0xff
;
buf
[
UDP_CHECKSUM
]
=
0
;
buf
[
UDP_CHECKSUM
+
1
]
=
0
;
sum
=
ipv4_checksum
((
unsigned
short
*
)(
buf
+
UDP_VIRT_SADDR
),
(
len
-
UDP_VIRT_SADDR
)
/
2
);
if
(
sum
==
0
)
sum
=
0xFFFF
;
buf
[
UDP_CHECKSUM
+
0
]
=
(
sum
>>
8
);
buf
[
UDP_CHECKSUM
+
1
]
=
sum
&
0xff
;
// ------------ IP --------------
buf
[
IP_VERSION
]
=
0x45
;
buf
[
IP_TOS
]
=
0
;
buf
[
IP_LEN
+
0
]
=
len
>>
8
;
buf
[
IP_LEN
+
1
]
=
len
&
0xff
;
buf
[
IP_ID
+
0
]
=
0
;
buf
[
IP_ID
+
1
]
=
0
;
buf
[
IP_FLAGS
+
0
]
=
0
;
buf
[
IP_FLAGS
+
1
]
=
0
;
buf
[
IP_TTL
]
=
63
;
buf
[
IP_PROTOCOL
]
=
17
;
/* UDP */
buf
[
IP_CHECKSUM
+
0
]
=
0
;
buf
[
IP_CHECKSUM
+
1
]
=
0
;
memcpy
(
buf
+
IP_SOURCE
,
&
uaddr
->
saddr
,
4
);
memcpy
(
buf
+
IP_DEST
,
&
uaddr
->
daddr
,
4
);
sum
=
ipv4_checksum
((
unsigned
short
*
)(
buf
+
IP_VERSION
),
(
IP_END
-
IP_VERSION
)
/
2
);
buf
[
IP_CHECKSUM
+
0
]
=
sum
>>
8
;
buf
[
IP_CHECKSUM
+
1
]
=
sum
&
0xff
;
return
;
}
lib/util.c
View file @
0c72e452
...
...
@@ -41,7 +41,7 @@ static const int _ytab[2][12] = {
{
31
,
29
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
}
};
char
*
format_time
(
uint64_t
sec
)
char
*
format_time
(
uint64_t
sec
,
int
format
)
{
struct
tm
t
;
static
char
buf
[
64
];
...
...
@@ -69,9 +69,23 @@ char *format_time(uint64_t sec)
t
.
tm_mday
=
dayno
+
1
;
t
.
tm_isdst
=
0
;
switch
(
format
)
{
case
TIME_FORMAT_LEGACY
:
default:
sprintf
(
buf
,
"%s, %s %d, %d, %02d:%02d:%02d"
,
_days
[
t
.
tm_wday
],
_months
[
t
.
tm_mon
],
t
.
tm_mday
,
t
.
tm_year
+
YEAR0
,
t
.
tm_hour
,
t
.
tm_min
,
t
.
tm_sec
);
_months
[
t
.
tm_mon
],
t
.
tm_mday
,
t
.
tm_year
+
YEAR0
,
t
.
tm_hour
,
t
.
tm_min
,
t
.
tm_sec
);
break
;
case
TIME_FORMAT_SYSLOG
:
sprintf
(
buf
,
"%s %2d %02d:%02d:%02d"
,
_months
[
t
.
tm_mon
],
t
.
tm_mday
,
t
.
tm_hour
,
t
.
tm_min
,
t
.
tm_sec
);
break
;
case
TIME_FORMAT_SORTED
:
sprintf
(
buf
,
"%4d-%02d-%02d-%02d:%02d:%02d"
,
t
.
tm_year
+
YEAR0
,
t
.
tm_mon
+
1
,
t
.
tm_mday
,
t
.
tm_hour
,
t
.
tm_min
,
t
.
tm_sec
);
break
;
}
return
buf
;
}
...
...
monitor/monitor_ppsi.c
View file @
0c72e452
...
...
@@ -110,7 +110,7 @@ void wrc_mon_gui(void)
shw_pps_gen_get_time
(
&
sec
,
&
nsec
);
cprintf
(
C_BLUE
,
"
\n\n
TAI Time: "
);
cprintf
(
C_WHITE
,
"%s"
,
format_time
(
sec
));
cprintf
(
C_WHITE
,
"%s"
,
format_time
(
sec
,
TIME_FORMAT_LEGACY
));
/*show_ports */
wrpc_get_port_state
(
&
state
,
NULL
);
...
...
ppsi
@
43635331
Subproject commit
b203cc96df8d4008fe311deaf7baab8e555d5c96
Subproject commit
43635331c54fa906bf54ad75e3087e336bdc7799
shell/cmd_ip.c
View file @
0c72e452
...
...
@@ -15,7 +15,7 @@
#include "shell.h"
#include "../lib/ipv4.h"
static
void
decode_ip
(
const
char
*
str
,
unsigned
char
*
ip
)
void
decode_ip
(
const
char
*
str
,
unsigned
char
*
ip
)
{
int
i
,
x
;
...
...
@@ -28,9 +28,17 @@ static void decode_ip(const char *str, unsigned char *ip)
}
}
char
*
format_ip
(
char
*
s
,
const
unsigned
char
*
ip
)
{
pp_sprintf
(
s
,
"%d.%d.%d.%d"
,
ip
[
0
],
ip
[
1
],
ip
[
2
],
ip
[
3
]);
return
s
;
}
static
int
cmd_ip
(
const
char
*
args
[])
{
unsigned
char
ip
[
4
];
char
buf
[
20
];
if
(
!
args
[
0
]
||
!
strcasecmp
(
args
[
0
],
"get"
))
{
getIP
(
ip
);
...
...
@@ -44,8 +52,7 @@ static int cmd_ip(const char *args[])
if
(
needIP
)
{
pp_printf
(
"IP-address: in training
\n
"
);
}
else
{
pp_printf
(
"IP-address: %d.%d.%d.%d
\n
"
,
ip
[
0
],
ip
[
1
],
ip
[
2
],
ip
[
3
]);
pp_printf
(
"IP-address: %s
\n
"
,
format_ip
(
buf
,
ip
));
}
return
0
;
}
...
...
shell/cmd_mac.c
View file @
0c72e452
...
...
@@ -17,7 +17,7 @@
#include "endpoint.h"
#include "../lib/ipv4.h"
static
void
decode_mac
(
const
char
*
str
,
unsigned
char
*
mac
)
void
decode_mac
(
const
char
*
str
,
unsigned
char
*
mac
)
{
int
i
,
x
;
...
...
@@ -30,9 +30,18 @@ static void decode_mac(const char *str, unsigned char *mac)
}
}
char
*
format_mac
(
char
*
s
,
const
unsigned
char
*
mac
)
{
pp_sprintf
(
s
,
"%02x:%02x:%02x:%02x:%02x:%02x"
,
mac
[
0
],
mac
[
1
],
mac
[
2
],
mac
[
3
],
mac
[
4
],
mac
[
5
]);
return
s
;
}
static
int
cmd_mac
(
const
char
*
args
[])
{
unsigned
char
mac
[
6
];
char
buf
[
32
];
if
(
!
args
[
0
]
||
!
strcasecmp
(
args
[
0
],
"get"
))
{
/* get current MAC */
...
...
@@ -52,8 +61,7 @@ static int cmd_mac(const char *args[])
return
-
EINVAL
;
}
pp_printf
(
"MAC-address: %02x:%02x:%02x:%02x:%02x:%02x
\n
"
,
mac
[
0
],
mac
[
1
],
mac
[
2
],
mac
[
3
],
mac
[
4
],
mac
[
5
]);
pp_printf
(
"MAC-address: %s
\n
"
,
format_mac
(
buf
,
mac
));
return
0
;
}
...
...
shell/cmd_time.c
View file @
0c72e452
...
...
@@ -53,7 +53,9 @@ static int cmd_time(const char *args[])
return
0
;
}
pp_printf
(
"%s +%d nanoseconds.
\n
"
,
format_time
(
sec
),
nsec
);
/* fixme: clock freq is not always 125 MHz */
pp_printf
(
"%s +%d nanoseconds.
\n
"
,
format_time
(
sec
,
TIME_FORMAT_LEGACY
),
nsec
);
/* fixme: clock freq is not always 125 MHz */
return
0
;
}
...
...
tools/pfilter-builder.c
View file @
0c72e452
...
...
@@ -409,6 +409,7 @@ void pfilter_init(int mode, char *fname)
pfilter_cmp
(
18
,
0x0044
,
0xffff
,
MOV
,
PORT_UDP_HOST
);
/* bootpc */
pfilter_cmp
(
18
,
0x013f
,
0xffff
,
OR
,
PORT_UDP_HOST
);
/* ptp event */
pfilter_cmp
(
18
,
0x0140
,
0xffff
,
OR
,
PORT_UDP_HOST
);
/* ptp general */
pfilter_cmp
(
18
,
0x0025
,
0xffff
,
OR
,
PORT_UDP_HOST
);
/* rdate */
/* The CPU gets those ports in a proper UDP frame, plus the previous selections */
pfilter_logic3
(
FRAME_FOR_CPU
,
FRAME_UDP
,
AND
,
PORT_UDP_HOST
,
OR
,
FRAME_FOR_CPU
);
...
...
wrc_main.c
View file @
0c72e452
...
...
@@ -96,11 +96,6 @@ static void wrc_initialize(void)
}
}
#define LINK_WENT_UP 1
#define LINK_WENT_DOWN 2
#define LINK_UP 3
#define LINK_DOWN 4
static
int
wrc_check_link
(
void
)
{
static
int
prev_link_state
=
-
1
;
...
...
@@ -184,24 +179,20 @@ int main(void)
}
switch
(
l_status
)
{
case
LINK_WENT_DOWN
:
if
(
wrc_ptp_get_mode
()
==
WRC_MODE_SLAVE
)
{
spll_init
(
SPLL_MODE_FREE_RUNNING_MASTER
,
0
,
1
);
shw_pps_gen_enable_output
(
0
);
}
/* fall through */
case
LINK_WENT_UP
:
needIP
=
1
;
break
;
case
LINK_UP
:
update_rx_queues
();
if
(
HAS_IP
)
{
ipv4_poll
();
ipv4_poll
(
l_status
);
arp_poll
();
}
break
;
case
LINK_WENT_DOWN
:
if
(
wrc_ptp_get_mode
()
==
WRC_MODE_SLAVE
)
{
spll_init
(
SPLL_MODE_FREE_RUNNING_MASTER
,
0
,
1
);
shw_pps_gen_enable_output
(
0
);
}
break
;
}
ui_update
();
...
...
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