Beispiel #1
0
static status_t
arp_receive(void *cookie, net_device *device, net_buffer *buffer)
{
	TRACE(("ARP receive\n"));

	NetBufferHeaderReader<arp_header> bufferHeader(buffer);
	if (bufferHeader.Status() < B_OK)
		return bufferHeader.Status();

	arp_header &header = bufferHeader.Data();
	uint16 opcode = ntohs(header.opcode);

#ifdef TRACE_ARP
	dprintf("  hw sender: %02x:%02x:%02x:%02x:%02x:%02x\n",
		header.hardware_sender[0], header.hardware_sender[1], header.hardware_sender[2],
		header.hardware_sender[3], header.hardware_sender[4], header.hardware_sender[5]);
	dprintf("  proto sender: %ld.%ld.%ld.%ld\n", header.protocol_sender >> 24, (header.protocol_sender >> 16) & 0xff,
		(header.protocol_sender >> 8) & 0xff, header.protocol_sender & 0xff);
	dprintf("  hw target: %02x:%02x:%02x:%02x:%02x:%02x\n",
		header.hardware_target[0], header.hardware_target[1], header.hardware_target[2],
		header.hardware_target[3], header.hardware_target[4], header.hardware_target[5]);
	dprintf("  proto target: %ld.%ld.%ld.%ld\n", header.protocol_target >> 24, (header.protocol_target >> 16) & 0xff,
		(header.protocol_target >> 8) & 0xff, header.protocol_target & 0xff);
#endif

	if (ntohs(header.protocol_type) != ETHER_TYPE_IP
		|| ntohs(header.hardware_type) != ARP_HARDWARE_TYPE_ETHER)
		return B_BAD_TYPE;

	// check if the packet is okay

	if (header.hardware_length != ETHER_ADDRESS_LENGTH
		|| header.protocol_length != sizeof(in_addr_t))
		return B_BAD_DATA;

	// handle packet

	switch (opcode) {
		case ARP_OPCODE_REQUEST:
			TRACE(("  got ARP request\n"));
			if (handle_arp_request(buffer, header) == B_OK) {
				// the function will take care of the buffer if everything
				// went well
				return B_OK;
			}
			break;
		case ARP_OPCODE_REPLY:
			TRACE(("  got ARP reply\n"));
			handle_arp_reply(buffer, header);
			break;

		default:
			dprintf("unknown ARP opcode %d\n", opcode);
			return B_ERROR;
	}

	gBufferModule->free(buffer);
	return B_OK;
}
Beispiel #2
0
/*Returns 0 on success and error code on fail*/
int sr_handlearp(struct sr_instance** sr, uint8_t** ethernet_data_addr, struct sr_if* in_f, unsigned int len){
  uint8_t *eth_pkt_buf;
  uint8_t *arp_pkt_buf; /* ARP packet buffer */
  struct sr_if* ret_if; /* return interface */
  printf("sr_handlearp");

  sr_arp_hdr_t* arp_header_buffer = (sr_arp_hdr_t*)*ethernet_data_addr;
  ntoh_arp_hdr(&arp_header_buffer); /* converts header members into host byte order where appropriate */

  /* Recieved ARP request! Reply to request. */
  if(arp_header_buffer->ar_op == arp_op_request) {
    if ((ret_if = sr_get_interface_from_ip(*sr, arp_header_buffer->ar_tip))) { /* Target IP is IP of a Router Interface*/ 
      
      /* Send an ARP reply (uint8_t*) */

      /* Create reply frame */
      eth_pkt_buf = (uint8_t *) malloc(sizeof(sr_ethernet_hdr_t) + sizeof(sr_arp_hdr_t)); /* Allocate mem for reply packet buffer */
      sr_ethernet_hdr_t *req_reply_eth_header = (sr_ethernet_hdr_t *) eth_pkt_buf;

      /* Build Ethernet Header */
      memcpy(req_reply_eth_header->ether_dhost, arp_header_buffer->ar_sha, ETHER_ADDR_LEN);
      memcpy(req_reply_eth_header->ether_shost, in_f->addr, ETHER_ADDR_LEN);
      req_reply_eth_header->ether_type = ethertype_arp;
      /* Convert to network byte ordering */
      hton_eth_hdr(&req_reply_eth_header);

      /* Get the Arp Buffer and Build the Arp packet*/
      arp_pkt_buf = eth_pkt_buf + sizeof(sr_ethernet_hdr_t);
      sr_create_arp_packet(&arp_pkt_buf, arp_header_buffer, ret_if); /* Create arp packet to be sent as ARP reply, fill arp_pkt_buf with ARP reply header data */
      
      /* Send the ARP reply packet */
      sr_send_packet(*sr, eth_pkt_buf, sizeof(sr_ethernet_hdr_t) + sizeof(sr_arp_hdr_t), in_f->name);
      free(eth_pkt_buf);


    } else { /* Target IP is *NOT* IP of a Router Interface */
      /* I'm not sure what to do here yet MAYBE NOTHING?!*/
    }
  }

  else if (arp_header_buffer->ar_op == arp_op_reply) {
    handle_arp_reply(*sr, *ethernet_data_addr, in_f);
  }
  


  return 0;
}
Beispiel #3
0
int handle_arp_packet(struct sr_instance * sr, uint8_t * packet, unsigned int len ){

      int res;

      struct sr_arp_hdr *arp_hdr = (struct sr_arp_hdr *)(packet + sizeof(sr_ethernet_hdr_t));
      int arp_op = ntohs(arp_hdr->ar_op);

      /* check to see if the target IP belongs to one of our routers */
      struct sr_if* assoc_iface = validate_ip(sr->if_list, arp_hdr->ar_tip); 

      if (!assoc_iface){
            /* if its not one of ours, ignore it */
            
            return -1;
      }

      if (arp_op == arp_op_request){ 
            /* this is an incoming request */
           

            res = send_arp_response(sr, assoc_iface,  packet,  len);

            if (res != 0){
                  fprintf(stderr, "bad send_arp_response\n");
                  return -1;
            }


      } else if (arp_op == arp_op_reply) { 
            /* this is an incoming reply */
            

            res = handle_arp_reply(sr, packet, len);
            if (res != 0){
               
                  return -1;
            }
      } else { 
            /* bad arp_op type */
          
            return -1;
      }
      return 0;
}
Beispiel #4
0
/*
Expects entire ethernet frame, still in network order.
 */
void handle_arp(struct sr_instance *sr, uint8_t *pkt, char* interface, unsigned int len) {
  sr_arp_hdr_t *arp_hdr = get_arp_hdr(pkt);
  unsigned short ar_op = ntohs(arp_hdr->ar_op);

  /*Should at least be this long*/
  if (len < sizeof(sr_ethernet_hdr_t) + sizeof(sr_arp_hdr_t)) {
    free(pkt);
    free(interface);
    return;
  }

  if (ar_op == arp_op_request) {
    handle_arp_request(sr, pkt, interface);
  } else if (ar_op == arp_op_reply) {
    handle_arp_reply(sr, pkt);
  } else {
    free(pkt);
    fprintf(stderr, "invalid arp opcode\n");
  }

  free(interface);

}