Newer
Older
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2012 GSI (www.gsi.de)
* Author: Wesley W. Terpstra <w.terpstra@gsi.de>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <string.h>
#include "endpoint.h"
#include "ipv4.h"
Wesley W. Terpstra
committed
#include "hw/memlayout.h"
#include "hw/etherbone-config.h"
#ifndef htons
#define htons(x) x
#endif
Wesley W. Terpstra
committed
static uint8_t myIP[4];
static wr_socket_t *ipv4_socket;
unsigned int ipv4_checksum(unsigned short *buf, int shorts)
{
int i;
unsigned int sum;
sum = 0;
for (i = 0; i < shorts; ++i)
sum += buf[i];
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
void ipv4_init(void)
{
wr_sockaddr_t saddr;
/* Reset => need a fresh IP */
needIP = 1;
/* Configure socket filter */
memset(&saddr, 0, sizeof(saddr));
get_mac_addr(&saddr.mac[0]); /* Unicast */
saddr.ethertype = htons(0x0800); /* IPv4 */
ipv4_socket = ptpd_netif_create_socket(0, 0 /* both unused */, &saddr);
Wesley W. Terpstra
committed
static int bootp_retry = 0;
static uint32_t bootp_tics;
void ipv4_poll(void)
{
uint8_t buf[400];
wr_sockaddr_t addr;
int len;
if (!bootp_tics)
bootp_tics = timer_get_tics() - 1;
if ((len = ptpd_netif_recvfrom(ipv4_socket, &addr,
buf, sizeof(buf), 0)) > 0) {
if (needIP)
process_bootp(buf, len);
if (!needIP && (len = process_icmp(buf, len)) > 0)
ptpd_netif_sendto(ipv4_socket, &addr, buf, len, 0);
}
if (needIP && time_after(timer_get_tics(), bootp_tics)) {
len = send_bootp(buf, ++bootp_retry);
memset(addr.mac, 0xFF, 6);
addr.ethertype = htons(0x0800); /* IPv4 */
ptpd_netif_sendto(ipv4_socket, &addr, buf, len, 0);
bootp_tics = timer_get_tics() + TICS_PER_SECOND;
Wesley W. Terpstra
committed
}
void getIP(unsigned char *IP)
{
memcpy(IP, myIP, 4);
Wesley W. Terpstra
committed
}
void setIP(unsigned char *IP)
{
volatile unsigned int *eb_ip =
(unsigned int *)(BASE_ETHERBONE_CFG + EB_IPV4);
unsigned int ip;
ip = (myIP[0] << 24) | (myIP[1] << 16) | (myIP[2] << 8) | (myIP[3]);
while (*eb_ip != ip)
*eb_ip = ip;
Wesley W. Terpstra
committed