Пример #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;
}
Пример #2
0
static void
transfer_boot(libusb_device_handle *handle, uint8_t endpoint, const char *name, const char *tip) {
    struct ethhdr eth_hdr;
    udp_t udp;

    memset(&eth_hdr, 0, sizeof(struct ethhdr));
    memset(&udp, 0, sizeof(udp_t));

    printf(" %s\n\n", tip);

    handle_bootp_request(handle, endpoint, name);
    handle_arp_request(handle, endpoint);
    handle_tftp_request(handle, &eth_hdr, &udp);

    if (udp.udpDst == 0 || udp.udpSrc == 0) {
        printf("Receive UDP packet failed.\n");
        exit(EXIT_FAILURE);
    }

    tftp_send_file(handle, endpoint, eth_hdr.h_source, udp.udpDst, udp.udpSrc, name);
}
Пример #3
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);

}
Пример #4
0
void sr_handlepacket(struct sr_instance* sr,
        uint8_t * packet/* lent */,
        unsigned int len,
        char* interface/* lent */)
{
    /* REQUIRES */
    assert(sr);
    assert(packet);
    assert(interface);

    printf("*** -> Received packet of length %d on interface \"%s\"\n", len, interface);

    // Deconstruct the packet's ethernet header
    struct sr_ethernet_hdr *header = malloc(sizeof(struct sr_ethernet_hdr));
    memcpy(header, packet, sizeof(struct sr_ethernet_hdr));
    header->ether_type = htons(header->ether_type);

    // Determine proper routing behavior based on ether_type
    switch(header->ether_type) {
        case ETHERTYPE_ARP:
            {
                // Unpack the ARP header
                struct sr_arphdr *arp_header = malloc(sizeof(struct sr_arphdr));
                memcpy(arp_header, packet + 14, sizeof(struct sr_arphdr));
                arp_header->ar_op = ntohs(arp_header->ar_op);

                // Check the ARP opcode
                switch(arp_header->ar_op) {
                    case ARP_REQUEST:
                        handle_arp_request(sr, header, arp_header, interface);
                        break;
                    case ARP_REPLY:
                        printf("\tIt's an ARP reply!\n");
                        add_arp_cache_entry(cache, arp_header->ar_sip, arp_header->ar_sha);

                        struct in_addr addr = {arp_header->ar_sip};
                        printf("\tMapping %s to ", inet_ntoa(addr));
                        print_ethernet_addr(arp_header->ar_sha, stdout);
                        printf("\n");

                        // Scan for packets we can retransmit
                        struct ip_cache_entry *cache_entry = next_packet_with_dest(ip_cache, addr);
                        struct sr_if *iface = sr_get_interface(sr, interface);

                        while(cache_entry) {
                            // Wrap the IP packet in an ethernet header
                            uint8_t *wrapped_packet = pack_ethernet_packet(arp_header->ar_sha,
                                    iface->addr, ETHERTYPE_IP, cache_entry->packet,
                                    cache_entry->len);

                            // Send the newly wrapped packet
                            sr_send_packet(sr, wrapped_packet,
                                    sizeof(struct sr_ethernet_hdr) + cache_entry->len,
                                    iface->name);

                            // TODO: We're dumb are forgot this
                            cache_entry = next_packet_with_dest(ip_cache, addr);
                        }
                        break;
                }
                break;
            }
        case ETHERTYPE_IP:
            {
                // TODO
                printf("\tIt's an IP packet!\n");
                route_ip_packet(sr, packet, len, interface);
                break;
            }
        default:
            {
                printf("\tIt's an unknown packet type (ether_type = 0x%X)\n", header->ether_type);
                break;
            }
    }

} /* end sr_ForwardPacket */