Example #1
0
/**
 * @function:   arp_decode
 * @param:      uint16_t, Length of the packet received.
 * @param:      uint8_t *, Pointer to the first byte of the packet.
 * @return:     uint16_t, Size of the new reply packet to be transmitted.
 * @brief:      Decodes a received packet into a ARP-packet and
 *              runs nessesary actions. Which eventually will create
 *              an appropriate reply.
 */
uint16_t
arp_decode(uint16_t length, uint8_t* packet)
{
    // Packet is valid ARP packet
    if(length < sizeof(struct arp_header_t)) {
        return 0;
    }

    // Assign ARP header pointer
    struct arp_header_t* arp_header = ((struct arp_header_t*) &packet[0]);

    // Select ARP operation
    switch(htons(arp_header->opcode)) {
        case ARP_OPCODE_REQUEST:

            // If it asked for our address, we send out a reply.
            if(!ip_addr_compare(arp_header->ip_dest_addr, ip_get_host_addr())) {
                break;
            }

            // First, we register the one who made the request in our ARP
            // table, since it is likely that we will do more communication
            // with this host in the future.
            arp_update(arp_header->ip_src_addr, arp_header->mac_src_addr);

            // Set new destination and source mac address
            memcpy(arp_header->mac_dest_addr, arp_header->mac_src_addr, 6);
            memcpy(arp_header->mac.dest_addr, arp_header->mac_src_addr, 6);
            memcpy(arp_header->mac_src_addr, mac_get_host_addr(), 6);
            memcpy(arp_header->mac.src_addr, mac_get_host_addr(), 6);

            // Set new destination and source ip address
            memcpy(arp_header->ip_dest_addr, arp_header->ip_src_addr, 4);
            memcpy(arp_header->ip_src_addr, ip_get_host_addr(), 4);

            // Set the opcode to reply
            arp_header->opcode = htons((uint16_t)ARP_OPCODE_REPLY);

            // return packet size
            return sizeof(struct arp_header_t);
            break;

        case ARP_OPCODE_REPLY:

            // We insert or update the ARP table if it was meant for us.
            if(ip_addr_compare(arp_header->ip_dest_addr, ip_get_host_addr())) {
                arp_update(arp_header->ip_src_addr, arp_header->mac_src_addr);
            }

            // XXX: Unqueue packets for received destination.
            //      See the queue_get_table and unqueue_packet funcions
            break;
    }

    return 0;
}
Example #2
0
void arp_process(void) {
   int i;
#if debug_arp
  arp_display();
#endif //debug_arp

  if (differ_subnet(ARPr->senproaddr)==0)	  // only update addresses from local network devices
    arp_update();				  // (the rest will use the Gateway's address)
  if (! memcmp(ARPr->tarproaddr, MyIP, 4)) {	  // is this ARP message for us?
    if (ARPr->opcode == HTONS(ARP_Request)) {	  // is this an ARP Request?
      ARPt->hwtype = HTONS(0x0001);
      ARPt->protype = HTONS(0x0800);
      ARPt->hwaddrlen = 6;
      ARPt->proaddrlen = 4;
      ARPt->opcode= HTONS(ARP_Reply);			      // Opcode for ARP Reply
      memcpy(ARPt->tarhwaddr, ARPr->senhwaddr, 6);	      // use the sender MAC address
      memcpy(ARPt->tarproaddr, ARPr->senproaddr, 4);          // use the sender IP address
      memcpy(ARPt->senhwaddr, MyMAC, 6);		      // use our MAC address
      memcpy(ARPt->senproaddr, MyIP, 4);		      // use our IP address
      for(i=0;i<18;i++)
        tx_buf[42+i] = 0x20;
      ethernet_send(ARP_PROTOCOL, sizeof(struct arp_hdr)+18); // Send frame (Padding)
    }
  }
}
Example #3
0
void arp_hdr_update(FAR uint16_t *pipaddr, FAR uint8_t *ethaddr)
{
  in_addr_t ipaddr = net_ip4addr_conv32(pipaddr);

  /* Update the ARP table */

  (void)arp_update(ipaddr, ethaddr);
}
Example #4
0
static inline void dhcpd_arpupdate(uint16_t *pipaddr, uint8_t *phwaddr)
{
  uip_lock_t flags;

  /* Disable interrupts and update the ARP table -- very non-portable hack.
   * REVISIT -- switch to the SIOCSARP ioctl call if/when it is implemented.
   */

  flags = uip_lock();
  arp_update(pipaddr, phwaddr);
  uip_unlock(flags);
}
Example #5
0
static int netdev_arp_ioctl(FAR struct socket *psock, int cmd,
                            FAR struct arpreq *req)
{
  int ret;

  /* Execute the command */

  switch (cmd)
    {
      case SIOCSARP:  /* Set an ARP mapping */
        {
          if (req != NULL &&
              req->arp_pa.sa_family == AF_INET &&
              req->arp_ha.sa_family == ARPHRD_ETHER)
            {
              FAR struct sockaddr_in *addr =
                (FAR struct sockaddr_in *)&req->arp_pa;

              /* Update any existing ARP table entry for this protocol
               * address -OR- add a new ARP table entry if there is not.
               */

              ret = arp_update(addr->sin_addr.s_addr,
                               (FAR uint8_t *)req->arp_ha.sa_data);
            }
          else
            {
              ret = -EINVAL;
            }
        }
        break;

      case SIOCDARP:  /* Delete an ARP mapping */
        {
          if (req != NULL && req->arp_pa.sa_family == AF_INET)
            {
              FAR struct sockaddr_in *addr =
                (FAR struct sockaddr_in *)&req->arp_pa;

              /* Find the existing ARP table entry for this protocol address. */

              FAR struct arp_entry_s *entry = arp_lookup(addr->sin_addr.s_addr);
              if (entry != NULL)
                {
                  /* The ARP table is fixed size; an entry is deleted
                   * by nullifying its protocol address.
                   */

                  entry->at_ipaddr = 0;
                  ret = OK;
                }
              else
                {
                  ret = -ENOENT;
                }
            }
          else
            {
              ret = -EINVAL;
            }
        }
        break;

      case SIOCGARP:  /* Get an ARP mapping */
        {
          if (req != NULL && req->arp_pa.sa_family == AF_INET)
            {
              FAR struct sockaddr_in *addr =
                (FAR struct sockaddr_in *)&req->arp_pa;

              /* Get the hardware address from an existing ARP table entry
               * matching this protocol address.
               */

              ret = arp_find(addr->sin_addr.s_addr,
                            (FAR struct ether_addr *)req->arp_ha.sa_data);
              if (ret >= 0)
                {
                  /* Return the mapped hardware address. */

                  req->arp_ha.sa_family = ARPHRD_ETHER;
                  ret = OK;
                }
            }
          else
            {
              ret = -EINVAL;
            }
        }
        break;

      default:
        ret = -ENOTTY;
        break;
    }

  return ret;
}
Example #6
0
void arp_arpin(FAR struct net_driver_s *dev)
{
  FAR struct arp_hdr_s *parp = ARPBUF;
  in_addr_t ipaddr;

  if (dev->d_len < (sizeof(struct arp_hdr_s) + NET_LL_HDRLEN))
    {
      nlldbg("Too small\n");
      dev->d_len = 0;
      return;
    }

  dev->d_len = 0;

  ipaddr = net_ip4addr_conv32(parp->ah_dipaddr);
  switch(parp->ah_opcode)
    {
      case HTONS(ARP_REQUEST):
        nllvdbg("ARP request for IP %04lx\n", (long)ipaddr);

        /* ARP request. If it asked for our address, we send out a reply. */

        if (net_ipaddr_cmp(ipaddr, dev->d_ipaddr))
          {
            struct eth_hdr_s *peth = ETHBUF;

            /* First, we register the one who made the request in our ARP
             * table, since it is likely that we will do more communication
             * with this host in the future.
             */

            arp_update(parp->ah_sipaddr, parp->ah_shwaddr);

            parp->ah_opcode = HTONS(ARP_REPLY);
            memcpy(parp->ah_dhwaddr, parp->ah_shwaddr, ETHER_ADDR_LEN);
            memcpy(parp->ah_shwaddr, dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);
            memcpy(peth->src, dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);
            memcpy(peth->dest, parp->ah_dhwaddr, ETHER_ADDR_LEN);

            parp->ah_dipaddr[0] = parp->ah_sipaddr[0];
            parp->ah_dipaddr[1] = parp->ah_sipaddr[1];
            net_ipaddr_hdrcopy(parp->ah_sipaddr, &dev->d_ipaddr);
            arp_dump(parp);

            peth->type          = HTONS(ETHTYPE_ARP);
            dev->d_len          = sizeof(struct arp_hdr_s) + NET_LL_HDRLEN;
          }
        break;

      case HTONS(ARP_REPLY):
        nllvdbg("ARP reply for IP %04lx\n", (long)ipaddr);

        /* ARP reply. We insert or update the ARP table if it was meant
         * for us.
         */

        if (net_ipaddr_cmp(ipaddr, dev->d_ipaddr))
          {
            /* Yes... Insert the address mapping in the ARP table */

            arp_update(parp->ah_sipaddr, parp->ah_shwaddr);

            /* Then notify any logic waiting for the ARP result */

            arp_notify(net_ip4addr_conv32(parp->ah_sipaddr));
          }
        break;
    }
}