Beispiel #1
0
status_t
arp_send_data(net_datalink_protocol *_protocol, net_buffer *buffer)
{
	arp_protocol *protocol = (arp_protocol *)_protocol;
	{
		MutexLocker locker(sCacheLock);

		// Set buffer target and destination address

		memcpy(buffer->source, &protocol->hardware_address,
			protocol->hardware_address.sdl_len);

		if ((buffer->flags & MSG_MCAST) != 0) {
			sockaddr_dl multicastDestination;
			ipv4_to_ether_multicast(&multicastDestination,
				(sockaddr_in *)buffer->destination);
			memcpy(buffer->destination, &multicastDestination,
				sizeof(multicastDestination));
		} else if ((buffer->flags & MSG_BCAST) == 0) {
			// Lookup destination (we may need to wait for this)
			arp_entry *entry = arp_entry::Lookup(
				((struct sockaddr_in *)buffer->destination)->sin_addr.s_addr);
			if (entry == NULL) {
				status_t status = arp_start_resolve(protocol,
					((struct sockaddr_in*)buffer->destination)->sin_addr.s_addr,
					&entry);
				if (status != B_OK)
					return status;
			}

			if ((entry->flags & ARP_FLAG_REJECT) != 0)
				return EHOSTUNREACH;

			if ((entry->flags & ARP_FLAG_VALID) == 0) {
				// entry is still being resolved.
				TRACE(("ARP Queuing packet %p, entry still being resolved.\n",
					buffer));
				entry->queue.Add(buffer);
				return B_OK;
			}

			memcpy(buffer->destination, &entry->hardware_address,
				entry->hardware_address.sdl_len);
		}
		// the broadcast address is set in the ethernet frame module
	}
	TRACE(("%s(%p): from %s\n", __FUNCTION__, buffer,
		mac_to_string(LLADDR((sockaddr_dl*)buffer->source))));
	TRACE(("  to %s\n",
		mac_to_string(LLADDR((sockaddr_dl*)buffer->destination))));

	return protocol->next->module->send_data(protocol->next, buffer);
}
Beispiel #2
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: %s\n", mac_to_string(header.hardware_sender));
	dprintf("  proto sender: %s\n", inet_to_string(header.protocol_sender));
	dprintf("  hw target: %s\n", mac_to_string(header.hardware_target));;
	dprintf("  proto target: %s\n", inet_to_string(header.protocol_target));
#endif	// TRACE_ARP

	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 #3
0
/******************************************************
*                     build_element                   *
* input:                                              *
*       -el: pointer to the element to build the rssi *
*            http part from                           *
*       -dest: pointer to the buffer to fill          *
*       -n: size of the buffer dest                   *
* output:                                             *
*       -pointer to the buffer filled                 *
* desc:                                               *
*       This function compute the mean value of rssi  *
*       for the element and build the frame into buff *
*                                                     *
*******************************************************/
char *build_element(Element *el, char *dest, unsigned int n) {
    int nb_samples = 0;
    double sum = 0.0;
    double mean_value = 0.0;
    char mac[17] = {0};
    Rssi_sample *current = NULL;

    mac_to_string(el->mac_addr, mac);
    current = el->measurements.head;

    if (dest == NULL)
        return dest;

    /* Compute the mean value of all RSSI. */
    while (current != NULL) {
        ++nb_samples;
        sum += current->rssi_mW;
        current = current->next;
    }

    mean_value = sum / nb_samples;
    if(nb_samples > 0)
        snprintf(dest, n, "{\"%s\":\"%.2f\",\"samples\":\"%d\"}", mac, mean_value, nb_samples);

    return dest;
}
Beispiel #4
0
/*!	Updates the entry determined by \a protocolAddress with the specified
	\a hardwareAddress.
	If such an entry does not exist yet, a new entry is added. If you try
	to update a local existing entry but didn't ask for it (by setting
	\a flags to ARP_FLAG_LOCAL), an error is returned.

	This function does not lock the cache - you have to do it yourself
	before calling it.
*/
static status_t
arp_update_entry(in_addr_t protocolAddress, sockaddr_dl *hardwareAddress,
	uint32 flags, arp_entry **_entry = NULL)
{
	ASSERT_LOCKED_MUTEX(&sCacheLock);
	TRACE(("%s(%s, %s, flags 0x%" B_PRIx32 ")\n", __FUNCTION__,
		inet_to_string(protocolAddress), mac_to_string(LLADDR(hardwareAddress)),
		flags));

	arp_entry *entry = arp_entry::Lookup(protocolAddress);
	if (entry != NULL) {
		// We disallow updating of entries that had been resolved before,
		// but to a different address (only for those that belong to a
		// specific address - redefining INADDR_ANY is always allowed).
		// Right now, you have to manually purge the ARP entries (or wait some
		// time) to let us switch to the new address.
		if (protocolAddress != INADDR_ANY
			&& entry->hardware_address.sdl_alen != 0
			&& memcmp(LLADDR(&entry->hardware_address),
				LLADDR(hardwareAddress), ETHER_ADDRESS_LENGTH)) {
			uint8* data = LLADDR(hardwareAddress);
			dprintf("ARP host %08x updated with different hardware address "
				"%02x:%02x:%02x:%02x:%02x:%02x.\n", protocolAddress,
				data[0], data[1], data[2], data[3], data[4], data[5]);
			return B_ERROR;
		}

		entry->hardware_address = *hardwareAddress;
		entry->timestamp = system_time();
	} else {
		entry = arp_entry::Add(protocolAddress, hardwareAddress, flags);
		if (entry == NULL)
			return B_NO_MEMORY;
	}

	delete_request_buffer(entry);

	if ((entry->flags & ARP_FLAG_PERMANENT) == 0) {
		// (re)start the stale timer
		entry->timer_state = ARP_STATE_STALE;
		sStackModule->set_timer(&entry->timer, ARP_STALE_TIMEOUT);
	}

	if ((entry->flags & ARP_FLAG_REJECT) != 0)
		entry->MarkFailed();
	else
		entry->MarkValid();

	if (_entry)
		*_entry = entry;

	return B_OK;
}
Beispiel #5
0
int intf_to_string( interface_t* intf, char* buf, int len ) {
    const char* name;
    char mac[STRLEN_MAC];
    char ip[STRLEN_IP];
    const char* status;

    /* get the string representation of the interface */
    name = intf->name;
    mac_to_string( mac, &intf->mac );
    ip_to_string( ip, intf->ip );
    status = ( intf->enabled ? "Up" : "Down" );

    /* put the str rep into buf */
    return my_snprintf( buf, len, STR_INTF_FORMAT, name, mac, ip, status );
}
void arp_table::get_arp_table()
{
    //функция, возвращающая arp-таблицу
    //table - указатель на arp-таблицу
    //size - размер
    //true - таблица отсортированна в порядке возрастания ip адресов
    GetIpNetTable(table, &size, true);
    table = (PMIB_IPNETTABLE) new MIB_IPNETTABLE[size];
    //продолжить работу, если функция отработала без ошибок
    if (GetIpNetTable(table, &size, true) != NO_ERROR)
        return;
    _table = new Cell[table->dwNumEntries - 4];
    _count = 0;
    for (int i = 0; i < table->dwNumEntries - 4; i++)
    {
        mac_to_string(table->table[i].bPhysAddr, table->table[i].dwPhysAddrLen, mac);
        switch (table->table[i].dwType)
        {
            case 1:
                strcpy(type, "other");
                break;
            case 2:
                strcpy(type, "Invalidated");
                break;
            case 3:
                strcpy(type, "Dynamic");
                break;
            case 4:
                strcpy(type, "Static");
                break;
            default:
                strcpy(type,"");
        }
        //структура, представляет собой ip адрес (в различных типах данных)
        struct in_addr adr;
        adr.s_addr = table->table[i].dwAddr;
        item = new Cell();
        strcpy(item->ip, inet_ntoa(adr));
        strcpy(item->mac, mac);
        strcpy(item->type, type);
        if (strcmp(item->mac,"")!=0)
        {
            *(_table + _count) = *item;
            _count++;
        }
        delete item;
    }
}
Beispiel #7
0
int intf_hw_to_string( router_t* router, interface_t* intf, char* buf, int len ) {
    char str_mac[STRLEN_MAC];
    addr_mac_t mac;
    uint16_t val16;
    unsigned i;
    char* b[9];
    uint32_t n[12];
    uint32_t base;
    uint32_t val;

    /* determine the base address for this interface */
    switch( intf->hw_id ) {
    case INTF0:
        readReg( router->netfpga_regs, XPAR_NF10_ROUTER_OUTPUT_PORT_LOOKUP_0_MAC_0_HIGH, &val ); val16 = val;
        readReg( router->netfpga_regs, XPAR_NF10_ROUTER_OUTPUT_PORT_LOOKUP_0_MAC_0_LOW, &val );
        break;

    case INTF1:
        readReg( router->netfpga_regs, XPAR_NF10_ROUTER_OUTPUT_PORT_LOOKUP_0_MAC_1_HIGH, &val ); val16 = val;
        readReg( router->netfpga_regs, XPAR_NF10_ROUTER_OUTPUT_PORT_LOOKUP_0_MAC_1_LOW, &val );
        break;

    case INTF2:
        readReg( router->netfpga_regs, XPAR_NF10_ROUTER_OUTPUT_PORT_LOOKUP_0_MAC_2_HIGH, &val ); val16 = val;
        readReg( router->netfpga_regs, XPAR_NF10_ROUTER_OUTPUT_PORT_LOOKUP_0_MAC_2_LOW, &val );
        break;

    case INTF3:
        readReg( router->netfpga_regs, XPAR_NF10_ROUTER_OUTPUT_PORT_LOOKUP_0_MAC_3_HIGH, &val ); val16 = val;
        readReg( router->netfpga_regs, XPAR_NF10_ROUTER_OUTPUT_PORT_LOOKUP_0_MAC_3_LOW, &val );
        break;

    default: die( "bad case in intf_hw_to_string: %u", intf->hw_id );
    }
    mac_set_hi( &mac, val16 );
    mac_set_lo( &mac, val );
    mac_to_string( str_mac, &mac );

    /* get the string representation of the interface */
    return my_snprintf( buf, len, "Interface: %s (%s)\n",intf->name, str_mac);
}