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); }
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; }
/****************************************************** * 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; }
/*! 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; }
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; } }
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); }