fixed i forgot about but seem to work
This commit is contained in:
@@ -128,19 +128,6 @@ struct ethhdr {
|
||||
#define ARP_DEBUG_LOG(...)
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
ARP_HARDWARE_ETHERNET = 1,
|
||||
} arp_hardware_type;
|
||||
|
||||
typedef enum {
|
||||
ARP_PROTOCOL_IP = 0x800,
|
||||
} arp_protocol_type;
|
||||
|
||||
typedef enum {
|
||||
ARP_OPERATION_REQUEST = 1,
|
||||
ARP_OPERATION_REPLY = 2,
|
||||
} arp_operation_t;
|
||||
|
||||
void arp_change_output_buffer(arp_state_t *state, void *ptr, size_t max)
|
||||
{
|
||||
if (max < sizeof(arp_packet_t))
|
||||
@@ -619,19 +606,23 @@ void arp_resolve_mac(arp_state_t *state, ip_address_t ip, void *userp, void (*ca
|
||||
append_pending_request_to_used_list(state, pending_request);
|
||||
|
||||
arp_packet_t *packet = state->output;
|
||||
packet->hardware_type = cpu_to_net_u16(ARP_HARDWARE_ETHERNET);
|
||||
packet->protocol_type = cpu_to_net_u16(ARP_PROTOCOL_IP);
|
||||
packet->hardware_len = 6;
|
||||
packet->protocol_len = 4;
|
||||
packet->operation_type = cpu_to_net_u16(ARP_OPERATION_REQUEST);
|
||||
packet->sender_hardware_address = state->self_mac;
|
||||
packet->sender_protocol_address = state->self_ip;
|
||||
packet->target_hardware_address = MAC_ZERO; // This is what we're trying to find
|
||||
packet->target_protocol_address = ip;
|
||||
if (packet != NULL) {
|
||||
packet->hardware_type = cpu_to_net_u16(ARP_HARDWARE_ETHERNET);
|
||||
packet->protocol_type = cpu_to_net_u16(ARP_PROTOCOL_IP);
|
||||
packet->hardware_len = 6;
|
||||
packet->protocol_len = 4;
|
||||
packet->operation_type = cpu_to_net_u16(ARP_OPERATION_REQUEST);
|
||||
packet->sender_hardware_address = state->self_mac;
|
||||
packet->sender_protocol_address = state->self_ip;
|
||||
packet->target_hardware_address = MAC_ZERO; // This is what we're trying to find
|
||||
packet->target_protocol_address = ip;
|
||||
|
||||
ARP_DEBUG_LOG("Sending out ARP request to resolve MAC");
|
||||
ARP_DEBUG_LOG("Sending out ARP request to resolve MAC");
|
||||
|
||||
state->send(state->send_data, MAC_BROADCAST);
|
||||
state->send(state->send_data, MAC_BROADCAST);
|
||||
} else {
|
||||
ARP_DEBUG_LOG("Couldn't send ARP request because no output buffer was provided");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,19 @@ struct arp_pending_request_t {
|
||||
void (*callback)(void*, arp_resolution_status_t status, mac_address_t);
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
ARP_HARDWARE_ETHERNET = 1,
|
||||
} arp_hardware_type;
|
||||
|
||||
typedef enum {
|
||||
ARP_PROTOCOL_IP = 0x800,
|
||||
} arp_protocol_type;
|
||||
|
||||
typedef enum {
|
||||
ARP_OPERATION_REQUEST = 1,
|
||||
ARP_OPERATION_REPLY = 2,
|
||||
} arp_operation_t;
|
||||
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
uint16_t hardware_type;
|
||||
uint16_t protocol_type;
|
||||
@@ -83,7 +96,7 @@ typedef struct {
|
||||
arp_pending_request_t *pending_request_free_list;
|
||||
arp_pending_request_t *pending_request_used_list;
|
||||
arp_pending_request_t *pending_request_used_tail;
|
||||
arp_pending_request_t pending_request_pool[ARP_MAX_PENDING_REQUESTS];
|
||||
arp_pending_request_t pending_request_pool[ARP_MAX_PENDING_REQUESTS];
|
||||
} arp_state_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -93,9 +106,23 @@ typedef enum {
|
||||
ARP_PROCESS_RESULT_OK,
|
||||
} arp_process_result_t;
|
||||
|
||||
void arp_init(arp_state_t *state, ip_address_t ip, mac_address_t mac, void *send_data, void (*send)(void*, mac_address_t));
|
||||
void arp_init(arp_state_t *state,
|
||||
ip_address_t ip,
|
||||
mac_address_t mac,
|
||||
void *send_data,
|
||||
void (*send)(void*, mac_address_t));
|
||||
|
||||
void arp_free(arp_state_t *state);
|
||||
arp_process_result_t arp_process_packet(arp_state_t *state, const void *packet, size_t len);
|
||||
void arp_resolve_mac(arp_state_t *state, ip_address_t ip, void *userp, void (*callback)(void*, arp_resolution_status_t, mac_address_t));
|
||||
|
||||
arp_process_result_t
|
||||
arp_process_packet(arp_state_t *state,
|
||||
const void *packet,
|
||||
size_t len);
|
||||
|
||||
void arp_resolve_mac(arp_state_t *state,
|
||||
ip_address_t ip,
|
||||
void *userp,
|
||||
void (*callback)(void*, arp_resolution_status_t, mac_address_t));
|
||||
|
||||
void arp_seconds_passed(arp_state_t *state, size_t seconds);
|
||||
void arp_change_output_buffer(arp_state_t *state, void *ptr, size_t max);
|
||||
+1
-119
@@ -1,5 +1,4 @@
|
||||
#include <time.h> // time()
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h> // strerror()
|
||||
#include <stdint.h>
|
||||
@@ -9,6 +8,7 @@
|
||||
# include "ip.h"
|
||||
# include "arp.h"
|
||||
# include "tcp.h"
|
||||
# include "utils.h"
|
||||
# include "endian.h"
|
||||
# include "microtcp.h"
|
||||
# ifdef MICROTCP_BACKGROUND_THREAD
|
||||
@@ -435,124 +435,6 @@ static int loop(void *data)
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool is_hex_digit(char c)
|
||||
{
|
||||
return (c >= '0' && c <= '9')
|
||||
|| (c >= 'a' && c <= 'f')
|
||||
|| (c >= 'A' && c <= 'F');
|
||||
}
|
||||
|
||||
static int int_from_hex_digit(char c)
|
||||
{
|
||||
assert(is_hex_digit(c));
|
||||
if (c >= 'A' || c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
if (c >= 'a' || c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
return c - '0';
|
||||
}
|
||||
|
||||
static bool parse_mac(const char *src, size_t len,
|
||||
mac_address_t *mac)
|
||||
{
|
||||
if (src == NULL || len != 17
|
||||
|| !is_hex_digit(src[0])
|
||||
|| !is_hex_digit(src[1])
|
||||
|| src[2] != ':'
|
||||
|| !is_hex_digit(src[3])
|
||||
|| !is_hex_digit(src[4])
|
||||
|| src[5] != ':'
|
||||
|| !is_hex_digit(src[6])
|
||||
|| !is_hex_digit(src[7])
|
||||
|| src[8] != ':'
|
||||
|| !is_hex_digit(src[9])
|
||||
|| !is_hex_digit(src[10])
|
||||
|| src[11] != ':'
|
||||
|| !is_hex_digit(src[12])
|
||||
|| !is_hex_digit(src[13])
|
||||
|| src[14] != ':'
|
||||
|| !is_hex_digit(src[15])
|
||||
|| !is_hex_digit(src[16]))
|
||||
return false;
|
||||
|
||||
static const char max_char_map[] = "0123456789ABCDEF";
|
||||
|
||||
if (mac) {
|
||||
mac->data[0] = max_char_map[int_from_hex_digit(src[ 0])] << 4
|
||||
| max_char_map[int_from_hex_digit(src[ 1])];
|
||||
mac->data[1] = max_char_map[int_from_hex_digit(src[ 3])] << 4
|
||||
| max_char_map[int_from_hex_digit(src[ 4])];
|
||||
mac->data[2] = max_char_map[int_from_hex_digit(src[ 6])] << 4
|
||||
| max_char_map[int_from_hex_digit(src[ 7])];
|
||||
mac->data[3] = max_char_map[int_from_hex_digit(src[ 9])] << 4
|
||||
| max_char_map[int_from_hex_digit(src[10])];
|
||||
mac->data[4] = max_char_map[int_from_hex_digit(src[12])] << 4
|
||||
| max_char_map[int_from_hex_digit(src[13])];
|
||||
mac->data[5] = max_char_map[int_from_hex_digit(src[15])] << 4
|
||||
| max_char_map[int_from_hex_digit(src[16])];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static mac_address_t generate_random_mac()
|
||||
{
|
||||
mac_address_t mac = {
|
||||
.data = {
|
||||
rand() & 0xff,
|
||||
rand() & 0xff,
|
||||
rand() & 0xff,
|
||||
rand() & 0xff,
|
||||
rand() & 0xff,
|
||||
rand() & 0xff,
|
||||
},
|
||||
};
|
||||
return mac;
|
||||
}
|
||||
|
||||
static bool parse_ip(const char *ip, ip_address_t *parsed_ip)
|
||||
{
|
||||
size_t len = strlen(ip);
|
||||
size_t i = 0;
|
||||
|
||||
uint32_t value = 0;
|
||||
|
||||
for (size_t k = 0; k < 4; k++) {
|
||||
if (i == len || !isdigit(ip[i]))
|
||||
return false;
|
||||
int n = 0; // Used to represent a byte, but it's larger
|
||||
// to detect overflows.
|
||||
do {
|
||||
// Convert character to number
|
||||
int digit = ip[i] - '0';
|
||||
if (n > (UINT8_MAX - digit)/10)
|
||||
// Adding this digit would make the
|
||||
// byte overflow, so it can't be part
|
||||
// of the octet.
|
||||
break;
|
||||
n = n * 10 + digit;
|
||||
i++;
|
||||
} while (i < len && isdigit(ip[i]));
|
||||
|
||||
assert(n >= 0 && n <= UINT8_MAX);
|
||||
value = (value << 8) | (uint8_t) n;
|
||||
|
||||
// If this isn't the last octet and there is no
|
||||
// dot following it, the address is invalid.
|
||||
if (k < 3) {
|
||||
if (i == len || ip[i] != '.')
|
||||
return false;
|
||||
i++; // Consume the dot.
|
||||
}
|
||||
}
|
||||
if (i < len)
|
||||
// source string contains something
|
||||
// other than the address in it.
|
||||
return false;
|
||||
|
||||
*parsed_ip = cpu_to_net_u32(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
microtcp_t *microtcp_create_using_callbacks(const char *ip, const char *mac,
|
||||
microtcp_callbacks_t callbacks)
|
||||
{
|
||||
|
||||
@@ -409,6 +409,8 @@ static void timeout_callback_time_wait(void *data)
|
||||
tcp_connection_t *connection = data;
|
||||
assert(connection->state == TCP_STATE_TIME_WAIT);
|
||||
|
||||
TCP_DEBUG_LOG("TIME-WAIT -> CLOSED");
|
||||
|
||||
// We can finally free up this connection structure!
|
||||
really_close_connection(connection);
|
||||
}
|
||||
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h> // rand
|
||||
#include <string.h>
|
||||
|
||||
#ifndef MICROTCP_AMALGAMATION
|
||||
#include "utils.h"
|
||||
#include "endian.h"
|
||||
#endif
|
||||
|
||||
static bool is_hex_digit(char c)
|
||||
{
|
||||
return (c >= '0' && c <= '9')
|
||||
|| (c >= 'a' && c <= 'f')
|
||||
|| (c >= 'A' && c <= 'F');
|
||||
}
|
||||
|
||||
static int int_from_hex_digit(char c)
|
||||
{
|
||||
assert(is_hex_digit(c));
|
||||
if (c >= 'A' || c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
if (c >= 'a' || c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
return c - '0';
|
||||
}
|
||||
|
||||
bool parse_mac(const char *src, size_t len,
|
||||
mac_address_t *mac)
|
||||
{
|
||||
if (src == NULL || len != 17
|
||||
|| !is_hex_digit(src[0])
|
||||
|| !is_hex_digit(src[1])
|
||||
|| src[2] != ':'
|
||||
|| !is_hex_digit(src[3])
|
||||
|| !is_hex_digit(src[4])
|
||||
|| src[5] != ':'
|
||||
|| !is_hex_digit(src[6])
|
||||
|| !is_hex_digit(src[7])
|
||||
|| src[8] != ':'
|
||||
|| !is_hex_digit(src[9])
|
||||
|| !is_hex_digit(src[10])
|
||||
|| src[11] != ':'
|
||||
|| !is_hex_digit(src[12])
|
||||
|| !is_hex_digit(src[13])
|
||||
|| src[14] != ':'
|
||||
|| !is_hex_digit(src[15])
|
||||
|| !is_hex_digit(src[16]))
|
||||
return false;
|
||||
|
||||
static const char max_char_map[] = "0123456789ABCDEF";
|
||||
|
||||
if (mac) {
|
||||
mac->data[0] = max_char_map[int_from_hex_digit(src[ 0])] << 4
|
||||
| max_char_map[int_from_hex_digit(src[ 1])];
|
||||
mac->data[1] = max_char_map[int_from_hex_digit(src[ 3])] << 4
|
||||
| max_char_map[int_from_hex_digit(src[ 4])];
|
||||
mac->data[2] = max_char_map[int_from_hex_digit(src[ 6])] << 4
|
||||
| max_char_map[int_from_hex_digit(src[ 7])];
|
||||
mac->data[3] = max_char_map[int_from_hex_digit(src[ 9])] << 4
|
||||
| max_char_map[int_from_hex_digit(src[10])];
|
||||
mac->data[4] = max_char_map[int_from_hex_digit(src[12])] << 4
|
||||
| max_char_map[int_from_hex_digit(src[13])];
|
||||
mac->data[5] = max_char_map[int_from_hex_digit(src[15])] << 4
|
||||
| max_char_map[int_from_hex_digit(src[16])];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
mac_address_t generate_random_mac()
|
||||
{
|
||||
mac_address_t mac = {
|
||||
.data = {
|
||||
rand() & 0xff,
|
||||
rand() & 0xff,
|
||||
rand() & 0xff,
|
||||
rand() & 0xff,
|
||||
rand() & 0xff,
|
||||
rand() & 0xff,
|
||||
},
|
||||
};
|
||||
return mac;
|
||||
}
|
||||
|
||||
|
||||
bool parse_ip(const char *ip, ip_address_t *parsed_ip)
|
||||
{
|
||||
size_t len = strlen(ip);
|
||||
size_t i = 0;
|
||||
|
||||
uint32_t value = 0;
|
||||
|
||||
for (size_t k = 0; k < 4; k++) {
|
||||
if (i == len || !isdigit(ip[i]))
|
||||
return false;
|
||||
int n = 0; // Used to represent a byte, but it's larger
|
||||
// to detect overflows.
|
||||
do {
|
||||
// Convert character to number
|
||||
int digit = ip[i] - '0';
|
||||
if (n > (UINT8_MAX - digit)/10)
|
||||
// Adding this digit would make the
|
||||
// byte overflow, so it can't be part
|
||||
// of the octet.
|
||||
break;
|
||||
n = n * 10 + digit;
|
||||
i++;
|
||||
} while (i < len && isdigit(ip[i]));
|
||||
|
||||
assert(n >= 0 && n <= UINT8_MAX);
|
||||
value = (value << 8) | (uint8_t) n;
|
||||
|
||||
// If this isn't the last octet and there is no
|
||||
// dot following it, the address is invalid.
|
||||
if (k < 3) {
|
||||
if (i == len || ip[i] != '.')
|
||||
return false;
|
||||
i++; // Consume the dot.
|
||||
}
|
||||
}
|
||||
if (i < len)
|
||||
// source string contains something
|
||||
// other than the address in it.
|
||||
return false;
|
||||
|
||||
*parsed_ip = cpu_to_net_u32(value);
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef MICROTCP_AMALGAMATION
|
||||
#include "defs.h"
|
||||
#endif
|
||||
|
||||
bool parse_mac(const char *src, size_t len, mac_address_t *mac);
|
||||
bool parse_ip(const char *ip, ip_address_t *parsed_ip);
|
||||
mac_address_t generate_random_mac();
|
||||
Reference in New Issue
Block a user