lwip发送ethernet ii包

有时候系统很简单时,可能想通过网口直接发送数据包给网张中的设备,这里可以发送ethernet ii包。

ethernet ii包的格式如下所示,其中FCS由硬件填充:

在etharp.h中定义了ethernet ii包的数据结构:

我们组一个pbuf包通过netif->linkoutput发送出支去,代码如下:

//ethernet_ii.c

#include "lwip/opt.h"
#include "lwip/ip_addr.h"
#include "lwip/def.h"
#include "lwip/ip.h"
#include "lwip/stats.h"
#include "lwip/snmp.h"
#include "lwip/dhcp.h"
#include "lwip/autoip.h"
#include "netif/etharp.h"

#include <string.h>
#include "ethernet_ii.h"

err_t ethernet_ii_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
           const struct eth_addr *ethdst_addr, unsigned char *buff, int len)
{
  struct pbuf *p;
  err_t result = ERR_OK;
  struct eth_hdr *ethhdr;
    unsigned char *hdr;

#if LWIP_AUTOIP
    const u8_t * ethdst_hwaddr;
#endif /* LWIP_AUTOIP */


  LWIP_ASSERT("netif != NULL", netif != NULL);

  /* allocate a pbuf for the outgoing ARP request packet */
  p = pbuf_alloc(PBUF_RAW, SIZEOF_ETHERNET_II_PACKET, PBUF_RAM);
  /* could allocate a pbuf for an ARP request? */
  if (p == NULL) {
    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
      ("etharp_raw: could not allocate pbuf for ARP request.\n"));
    ETHARP_STATS_INC(etharp.memerr);
    return ERR_MEM;
  }
  LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr",
              (p->len >= SIZEOF_ETHARP_PACKET));

  ethhdr = (struct eth_hdr *)p->payload;
  hdr = ((u8_t*)ethhdr + ETHERNET_II_HEAD);
  memcpy(hdr, buff, len);

  LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
              (netif->hwaddr_len == ETHARP_HWADDR_LEN));

#if LWIP_AUTOIP
    /* If we are using Link-Local, all ARP packets that contain a Link-Local
     * 'sender IP address' MUST be sent using link-layer broadcast instead of
     * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */
    ethdst_hwaddr = ip_addr_islinklocal(ipsrc_addr) ? (u8_t*)(ethbroadcast.addr) : ethdst_addr->addr;
#endif /* LWIP_AUTOIP */

#if LWIP_AUTOIP
  ETHADDR16_COPY(&ethhdr->dest, ethdst_hwaddr);
#else  /* LWIP_AUTOIP */
  ETHADDR16_COPY(&ethhdr->dest, ethdst_addr);
#endif /* LWIP_AUTOIP */
  ETHADDR16_COPY(&ethhdr->src, ethsrc_addr);


  ethhdr->type = PP_HTONS(ETHTYPE_ETHERNET_II);
  /* send ARP query */
  result = netif->linkoutput(netif, p);
  ETHARP_STATS_INC(etharp.xmit);
  /* free ARP query packet */
  pbuf_free(p);
  p = NULL;
  /* could not allocate pbuf for ARP request */

  return result;
}

//ethernet_ii.h

#ifndef __ETHERNET_II_H__
#define __ETHERNET_II_H__

#define ETHERNET_II_HEAD            (14)
#define ETHERNET_II_DATA_LEN        (50)
#define SIZEOF_ETHERNET_II_PACKET   (ETHERNET_II_HEAD+ETHERNET_II_DATA_LEN)
#define ETHTYPE_ETHERNET_II         (0x7002U)

err_t ethernet_ii_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
           const struct eth_addr *ethdst_addr, unsigned char *buff, int len);


#endif

在主程序中,调用ethernet_ii_raw函数即可发送ethernet ii包:

ret = ethernet_ii_raw(&enc28j60_netif, (struct eth_addr *)src_mac.addr, 
                (struct eth_addr *)des_mac.addr, sendbuff, ETHERNET_II_DATA_LEN);

参数分别为网络接口,源mac,目标mac,要发送的数据,数据长度。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值