diff --git a/include/forward/if/interface.h b/include/forward/if/interface.h index ade43a2..5969289 100644 --- a/include/forward/if/interface.h +++ b/include/forward/if/interface.h @@ -18,9 +18,6 @@ typedef struct interface_packet { typedef void (*interface_packet_callback_t)(const interface_packet_t* packet, void* userData); -int Interface_Init(void); -void Interface_Cleanup(void); - interface_v4_t* Interface_Create_v4(const char* localAddress, interface_packet_callback_t callback, void* userData); interface_v6_t* Interface_Create_v6(const char* localAddress, interface_packet_callback_t callback, void* userData); diff --git a/include/forward/route.h b/include/forward/route.h new file mode 100644 index 0000000..e046bb0 --- /dev/null +++ b/include/forward/route.h @@ -0,0 +1,14 @@ +#ifndef ROTUE_H +#define ROTUE_H + +#include +#include +#include +#include +#include +#include + +void Route_Processv4(const interface_packet_t* packet, void* userData); +void Route_Processv6(const interface_packet_t* packet, void* userData); + +#endif diff --git a/src/forward/if/interface.c b/src/forward/if/interface.c index 1e41294..f4357e8 100644 --- a/src/forward/if/interface.c +++ b/src/forward/if/interface.c @@ -219,13 +219,6 @@ static void* interface_listen_v6_thread(void* arg) { return NULL; } -int Interface_Init(void) { - return 0; -} - -void Interface_Cleanup(void) { -} - interface_v4_t* Interface_Create_v4(const char* localAddress, interface_packet_callback_t callback, void* userData) { interface_v4_t* iface = (interface_v4_t*)calloc(1, sizeof(*iface)); if (!iface) { diff --git a/src/forward/route.c b/src/forward/route.c new file mode 100644 index 0000000..36b22a1 --- /dev/null +++ b/src/forward/route.c @@ -0,0 +1,68 @@ +#include + +void Route_Processv4(const interface_packet_t* packet, void* userData) { + (void)userData; + if (!packet) return; + if (packet->family != AF_INET) return; // Check if it's an IPv4 packet + if (packet->length < 9) return; /* need at least up to TTL byte */ + + uint8_t* data = (uint8_t*)packet->data; + if (data[8] > 0) { + data[8]--; + } + + // Find the destination IP + uint32_t destIP = 0; + if (packet->destination.ss_family == AF_INET) { + struct sockaddr_in* destAddr = (struct sockaddr_in*)&packet->destination; + destIP = destAddr->sin_addr.s_addr; + } else { + return; // Not an IPv4 packet, should not happen due to earlier check + } + + // Get the next hop for the destination IP + uint32_t nextHop; + if (RouteTable_GetNextHop_v4(destIP, &nextHop) == 0) { + // Send the modified packet to the next hop + struct in_addr nextHopAddr; + nextHopAddr.s_addr = nextHop; + Interface_SendRaw_v4((interface_v4_t*)userData, &nextHopAddr, packet->data, packet->length); + } else { + // No route found for the destination IP, drop the packet (do nothing) + return; + } +} + +void Route_Processv6(const interface_packet_t* packet, void* userData) { + (void)userData; + if (!packet) return; + if (packet->family != AF_INET6) return; + if (packet->length < 8) return; /* need at least up to Hop Limit byte */ + + uint8_t* data = (uint8_t*)packet->data; + if (data[7] > 0) { + data[7]--; + } + + // Find the destination IP + __uint128_t destIP; + if (packet->destination.ss_family == AF_INET6) { + struct sockaddr_in6* destAddr = (struct sockaddr_in6*)&packet->destination; + memcpy(&destIP, &destAddr->sin6_addr, sizeof(destIP)); + } else { + return; // Not an IPv6 packet, should not happen due to earlier check + } + + // Get the next hop for the destination IP + __uint128_t nextHop; + if (RouteTable_GetNextHop_v6(destIP, &nextHop) == 0) { + // Send the modified packet to the next hop + struct in6_addr nextHopAddr; + memcpy(&nextHopAddr, &nextHop, sizeof(nextHopAddr)); + Interface_SendRaw_v6((interface_v6_t*)userData, &nextHopAddr, packet->data, packet->length); + } else { + // No route found for the destination IP, drop the packet (do nothing) + return; + } +} + diff --git a/src/log.c b/src/log.c index d33004a..75e107d 100644 --- a/src/log.c +++ b/src/log.c @@ -1,4 +1,7 @@ +#define _POSIX_C_SOURCE 199309L + #include +#include // UNIX socket for CONOUT (Console Output) - sends log datagrams to a listener on /tmp/miniroute-log.sock static int log_socket_fd = -1; diff --git a/src/main.c b/src/main.c index 83b159a..77ceaba 100644 --- a/src/main.c +++ b/src/main.c @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -20,8 +21,8 @@ int main(void) { Log_Info("Route tables initialized successfully"); } - interface_v4_t* iface = Interface_Create_v4("0.0.0.0", NULL, NULL); - interface_v6_t* iface6 = Interface_Create_v6("::", NULL, NULL); + interface_v4_t* iface = Interface_Create_v4("0.0.0.0", Route_Processv4, NULL); + interface_v6_t* iface6 = Interface_Create_v6("::", Route_Processv6, NULL); if (!iface || !iface6) { Log_Err("Failed to create interfaces"); RouteTable_Cleanup(); @@ -99,7 +100,8 @@ int main(void) { } RouteTable_Cleanup(); - Interface_Cleanup(); + Interface_Destroy_v4(iface); + Interface_Destroy_v6(iface6); Log_Cleanup();