Пример #1
0
static void
arp_output()
{
	struct frame_arp *ap;
	u8bits *p;
	unsigned i;

#ifdef	ARPDEBUG
	PPRINT(("Start arp_output()\n"));
#endif
	ap = (struct frame_arp *)&arp_buffer[dlink.dl_hlen];
	ap->arp_hrd = htons(dlink.dl_type);
	ap->arp_pro = htons(ETHERNET_TYPE_IP);
	ap->arp_hln = dlink.dl_len;
	ap->arp_pln = sizeof (u32bits);
	ap->arp_op = htons(ARPOP_REQUEST);
	p = (u8bits *)(ap + 1);
	for (i = 0; i < dlink.dl_len; i++)
		*p++ = dlink.dl_laddr[i];
	*p++ = (udpip_laddr >> 24) & 0xFF;
	*p++ = (udpip_laddr >> 16) & 0xFF;
	*p++ = (udpip_laddr >> 8) & 0xFF;
	*p++ = udpip_laddr & 0xFF;
	for (i = 0; i < dlink.dl_len; i++)
		*p++ = '\0';
	*p++ = (arp_waiting >> 24) & 0xFF;
	*p++ = (arp_waiting >> 16) & 0xFF;
	*p++ = (arp_waiting >> 8) & 0xFF;
	*p++ = arp_waiting & 0xFF;

	switch (dlink.dl_type) {
	case ARPHRD_ETHERNET:
		ether_output(arp_buffer, ARP_BUFLEN(ap->arp_hln), ether_broadcast, ETHERNET_TYPE_ARP);
		break;
	default:
		printf("Unknown dlink type 0x%x\n", dlink.dl_type);
		break;
	}
}
Пример #2
0
void
arp_input(void *addr,
	  unsigned len)
{
	struct frame_arp *ap;
	struct frame_arp *ap1;
	unsigned i;
	u8bits *p;
	u32bits ip;

#ifdef	ARPDEBUG
	PPRINT(("Start arp_input(0x%x, 0x%x)\n", addr, len));
#endif

	ap = (struct frame_arp *)addr;
	if (ntohs(ap->arp_hrd) != dlink.dl_type ||
	    ntohs(ap->arp_pro) != ETHERNET_TYPE_IP ||
	    ap->arp_hln != dlink.dl_len ||
	    ap->arp_pln != sizeof (u32bits) ||
	    len < sizeof (struct frame_arp) + 2 * (ap->arp_hln + sizeof (u32bits))) {
#ifdef	ARPDEBUG
		PPRINT(("arp_input: Bad type\n"));
#endif
		return;
	}
	ap->arp_op = ntohs(ap->arp_op);
	switch (ap->arp_op) {
	case ARPOP_REQUEST:
		p = (u8bits *)(ap + 1) + 2 * ap->arp_hln + ap->arp_pln;
		ip = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
		if (udpip_laddr != ip) {
#ifdef	ARPDEBUG
			PPRINT(("arp_input: Not for us\n"));
#endif
			return;
		}

		ap1 = (struct frame_arp *)&arp_buffer[dlink.dl_hlen];
		ap1->arp_hrd = htons(dlink.dl_type);
		ap1->arp_pro = htons(ETHERNET_TYPE_IP);
		ap1->arp_hln = dlink.dl_len;
		ap1->arp_pln = sizeof (u32bits);
		ap1->arp_op = htons(ARPOP_REPLY);
		p = (u8bits *)(ap1 + 1);
		for (i = 0; i < dlink.dl_len; i++)
			*p++ = dlink.dl_laddr[i];
		*p++ = (udpip_laddr >> 24) & 0xFF;
		*p++ = (udpip_laddr >> 16) & 0xFF;
		*p++ = (udpip_laddr >> 8) & 0xFF;
		*p++ = udpip_laddr & 0xFF;
		for (i = 0; i < dlink.dl_len + sizeof (u32bits); i++)
			*p++ = ((u8bits *)(ap + 1))[i];
		len = sizeof (struct frame_arp) + 2 * (dlink.dl_len + 4);
		switch (dlink.dl_type) {
		case ARPHRD_ETHERNET:
			(void)ether_output(arp_buffer, ARP_BUFLEN(ap1->arp_hln),
					   (u8bits *)(ap + 1), ETHERNET_TYPE_ARP);
			break;
		default:
			printf("Unknown dlink type 0x%x\n", dlink.dl_type);
			break;
		}
		return;

	case ARPOP_REPLY:
		if (arp_waiting != 0) {
			p = (u8bits *)(ap + 1) + ap->arp_hln;
			ip = 0;
			for (i = 0; i < sizeof (u32bits); i++)
				ip = (ip << 8) | *p++;
			if (arp_waiting == ip) {
				arp_waiting = 0;
				p = (u8bits *)(ap + 1);
				for (i = 0; i < ap->arp_hln; i++) {
					dlink.dl_raddr[i] = *p++;
				}
				break;
			}
		}
#ifdef	ARPDEBUG
		PPRINT(("arp_input: Bad sender (%x)\n", ap + 1));
#endif
		break;

	default:
#ifdef	ARPDEBUG
		PPRINT(("arp_input: Bad operation (%x)\n", ap->arp_op));
#endif
		break;
	}
}
Пример #3
0
int ieee80211_output(FAR struct ieee80211_s *ic, FAR struct iob_s *iob,
                     FAR struct sockaddr *dst, uint8_t flags)
{
  FAR struct uip_driver_s *dev;
  FAR struct ieee80211_frame *wh;
  FAR struct m_tag *mtag;
  uip_lock_t flags;
  int error = 0;

  /* Get the driver structure */

  dev = netdev_findbyaddr(ic->ic_ifname);
  if (!dev)
    {
      error = -ENODEV;
      goto bad;
    }

  /* Interface has to be up and running */

  if ((dev->d_flags & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING))
    {
      error = -ENETDOWN;
      goto bad;
    }

  /* Try to get the DLT from a buffer tag */

  if ((mtag = m_tag_find(iob, PACKET_TAG_DLT, NULL)) != NULL)
    {
      unsigned int dlt = *(unsigned int *)(mtag + 1);

      /* Fallback to Ethernet for non-802.11 linktypes */

      if (!(dlt == DLT_IEEE802_11 || dlt == DLT_IEEE802_11_RADIO))
        {
          goto fallback;
        }

      if (iob->io_pktlen < sizeof(struct ieee80211_frame_min))
        {
          return -EINVAL;
        }

      wh = (FAR struct ieee80211_frame *)IOB_DATA(iob);
      if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != IEEE80211_FC0_VERSION_0)
        {
          return -EINVAL;
        }

      if (!(ic->ic_caps & IEEE80211_C_RAWCTL) &&
          (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
        {
          return -EINVAL;
        }

      /* Queue message on interface without adding any further headers, and
       * start output if interface not yet active.
       */

      flags = uip_lock();
      error = ieee80211_ifsend(ic, iob, flags);
      if (error)
        {
          /* buffer is already freed */

          uip_unlock(flags);
          ndbg("ERROR: %s: failed to queue raw tx frame\n", ic->ic_ifname);
          return error;
        }

      uip_unlock(flags);
      return error;
    }

fallback:
  return ether_output(ic, iob, dst);

bad:
  if (iob)
    {
      iob_free_chain(iob);
    }

  return error;
}