⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ethernetif.c

📁 RT-Thread是发展中的下一代微内核嵌入式实时操作系统
💻 C
字号:
#include <rtthread.h>

#include "lwip/debug.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/netif.h"
#include "lwip/stats.h"
#include "lwip/tcpip.h"

#include "netif/etharp.h"
#include <net/ethernetif.h>

#include <string.h>

static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};

#if 0
static int ethernetif_open (void* dev);
static int ethernetif_close(void* dev);
static int ethernetif_ioctl(void* dev, int cmd, void *args);
static int ethernetif_read (void* dev, off_t pos, void* buf, rt_size_t len);
static int ethernetif_write(void* dev, off_t pos, const void* buf, rt_size_t len);


/* DOOLOO RTOS device struct */
static struct device_ops enetif_ops = 
{
	ethernetif_open,
	ethernetif_close,
	ethernetif_ioctl,
	ethernetif_read,
	ethernetif_write
};

/* DOOLOO RTOS device interface */
static int ethernetif_open(void* dev)
{
	return 0;
}

static int ethernetif_close(void* dev)
{
	return 0;
}

static int ethernetif_ioctl(void* dev, int cmd, void *args)
{
	struct ethernetif* enetif;

	enetif = (struct ethernetif*) dev;
	if (enetif == NULL) return -DEVICE_EINVAL;

	if (enetif->ops->control != NULL)
	{
		/* call driver's interface */
		return enetif->ops->control(enetif->data, cmd, args);
	}

	return -DEVICE_ENOSYS;
}

static int ethernetif_read(void* dev, off_t pos, void* buf, size_t len)
{
	struct ethernetif* enetif;

	enetif = (struct ethernetif*) dev;
	if (enetif == NULL) return -DEVICE_EINVAL;

	if (enetif->ops->poll_recv != NULL)
	{
		/* call driver's interface */
		return enetif->ops->poll_recv(enetif->data, buf, len);
	}

	return -DEVICE_ENOSYS;
}

static int ethernetif_write(void* dev, off_t pos, const void* buf, size_t len)
{
	struct ethernetif* enetif;

	enetif = (struct ethernetif*) dev;
	if (enetif == NULL) return -DEVICE_EINVAL;

	if (enetif->ops->poll_send != NULL)
	{
		/* call driver's interface */
		return enetif->ops->poll_send(enetif->data, buf, len);
	}

	return -DEVICE_ENOSYS;
}
#endif

/* the interface provided to LwIP */
err_t ethernetif_input(struct pbuf *p, struct netif *inp)
{
	struct eth_hdr *ethhdr;

	if(p != NULL)
	{
#ifdef LINK_STATS
		LINK_STATS_INC(link.recv);
#endif /* LINK_STATS */

		ethhdr = p->payload;

		switch(htons(ethhdr->type))
		{
		case ETHTYPE_IP:
			etharp_ip_input(inp, p);
			pbuf_header(p, -14);
			tcpip_input(p, inp);
			break;

		case ETHTYPE_ARP:
			etharp_arp_input(inp, (struct eth_addr *)inp->hwaddr, p);
			break;

		default:
			pbuf_free(p);
			p = NULL;
			break;
		}
	}

	return ERR_OK;
}

err_t ethernetif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
{
	return etharp_output(netif, ipaddr, p);
}

err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
{
	struct ethernetif* enetif;

	enetif = (struct ethernetif*)netif->state;
	if (enetif == NULL) return -ERR_VAL;

	if (enetif->ops->transmit)
	{
		/* call driver's interface */
		enetif->ops->transmit(enetif->data, p);	
	}

	return ERR_OK;
}

err_t ethernetif_init(struct netif* netif)
{
	return ERR_OK;
}

/* ethernetif APIs */
struct ethernetif* ethernetif_add(const char* name, struct ethernetif_ops* ops, void* data)
{
	struct ethernetif* enetif;
	struct netif* netif;

	enetif = (struct ethernetif*) rt_malloc (sizeof(struct ethernetif));
	if (enetif == NULL) return NULL;
	enetif->netif = (struct netif*) rt_malloc (sizeof(struct netif));
	if (enetif->netif == NULL)
	{
		rt_free(enetif);
		return NULL;
	}

	/* fill ethernetif */
	enetif->ops			= ops;
	enetif->data		= data;

	netif = enetif->netif;
	memset(netif, 0, sizeof(struct netif));
	/* the max length of network interface's name is 2 */
	strncpy(netif->name, name, 2);

	/* set hw address to 6 */
	netif->hwaddr_len	= 6;
	/* maximum transfer unit */
	netif->mtu			= 1500;
	/* broadcast capability */
	netif->flags		= NETIF_FLAG_BROADCAST;

	/* set output */
	netif->output		= ethernetif_output;
	netif->linkoutput	= ethernetif_linkoutput;

	/* get hw addr */
	ops->control(data, NIOCTL_GADDR, netif->hwaddr);

	if (netif_add(netif, IP_ADDR_ANY, IP_ADDR_BROADCAST, IP_ADDR_ANY, enetif, 
		ethernetif_init, ethernetif_input) == NULL)
	{
		rt_free(enetif);
		return NULL;
	}

	/* register in DOOLOO RTOS device */
	//rt_device_register((char*)name, DEV_ENETIF, &enetif_ops, enetif);

	return enetif;
}

int ethernetif_receive(struct ethernetif* enetif, struct pbuf* p)
{
	ethernetif_input(p, enetif->netif);
	return RT_EOK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -