Commit 0c72e452 authored by Alessandro Rubini's avatar Alessandro Rubini

Merge branch 'network cleanup'

parents 7bab5d84 03285ba4
......@@ -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.
......
......@@ -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
......
......@@ -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;
......
......@@ -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
......
......@@ -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 receive timestamps, zero for send timestamps
// Phase (in picoseconds), linearized for rx, 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 address 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_socket * 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 */
......@@ -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;
......
......@@ -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, ...);
......
......@@ -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)
......
......@@ -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))
......
......@@ -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;
/* Bootp: use UDP engine activated but function arguments */
bootp_socket = ptpd_netif_create_socket(&__static_bootp_socket, NULL,
PTPD_SOCK_UDP, 68 /* bootpc */);
/* Reset => need a fresh IP */
needIP = 1;
/* time (rdate): UDP */
rdate_socket = ptpd_netif_create_socket(&__static_rdate_socket, NULL,
PTPD_SOCK_UDP, 37 /* time */);
/* Configure socket filter */
/* 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)
process_bootp(buf, len);
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)
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)" */
if (!needIP && (len = process_icmp(buf, len)) > 0)
ptpd_netif_sendto(ipv4_socket, &addr, buf, len, 0);
}
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;
}
}
......@@ -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
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
......@@ -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))