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; } }
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; } }
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; }